⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 midimmcm8.asm

📁 用ATMEGA8开发的MMC程式,可用AVR-GCC开发
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	ldi	work,	KEYMASK
	out	PORTD,	work
	out	DDRD,	null
	ldi	work,	0xFF
	out	DDRC,	work
	out	PORTC,	work

	rcall	LCD_INIT
   RTI:	rcall	LCD_CLEAR
	rcall	SENDALLOFF

	rcall	INIT_MMC
	rcall	delay
	rcall	INIT_MMC
	cpi	work,	0
	breq	COK

	; Card failed
	ldi	work,	0
	ldi	ZL,	LOW(t_initf<<1)
	ldi	ZH,	HIGH(t_initf<<1)
	rcall	ROM_LINE
	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_error<<1)
	ldi	ZH,	HIGH(t_error<<1)
	rcall	ROM_LINE
	ldi	work,	31
	rcall	SET_CURSOR
	rcall	INIT_MMC
	ldi	temp,	'0'
	add	temp,	work
	rcall	LCD_DATA

   v:	sbic	KEYs,	KEY1
	  rjmp v
	rjmp	RTI

	; Card OK
  COK:	ldi	temp,	1
	rcall	EEread
	mov	cfilel,	work
	ldi	temp,	2
	rcall	EEread
	mov	cfileh,	work
	rcall	CALCSECTOR

	rcall	SHOWFILENR
	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_init<<1)
	ldi	ZH,	HIGH(t_init<<1)
	rcall	ROM_LINE

	ret


SENDSTRING:; Sends a string from ROM over serial conn.
	lpm	cnt,	Z+
	out	UDR,	cnt
  ml1:	brtc	ml1
	clt
	cpi	cnt,	13
	brne	SENDSTRING
	ret


SENDCHAR:; Sends a char in work
	out	UDR,	work
  ml_:	brtc	ml_
	clt
	ret


WRITESTOP:; Schreibt Stoppevent
	ldi	work,	MIDIstop
	mov	inreg,	work
	rcall	WRITEMIDI
	rcall	BUF2MMC
	ret


SENDRESET:; Setzt MIDI Ger鋞 zur點k
	ldi	work,	GMreset
	out	UDR,	work
  WFS:	brtc	WFS
	ret


SENDALLOFF:; All off
	ldi	temp,	0x7B
	rcall	SENDALLCH
	ldi	temp,	0x79
	rcall	SENDALLCH
	ret


SENDALLCH:; Sends to all channels
	clr	cnt
 SAO:	ldi	work,	0xB0
	add	work,	cnt
	rcall	SENDCHAR
	mov	work,	temp
	rcall	SENDCHAR
	ldi	work,	0x00
	rcall	SENDCHAR
	inc	cnt
	cpi	cnt,	0x10
	brlo	SAO
	ret


RECMIDI:; Zeichnet ein Midievent auf
;	sbrs	intf,	fURX	; Nur wenn ein Zeichen gekommen ist
;	  ret
	push	XL
	push	XH
	push	ZL
	push	ZH
	push	work
	push	cnt
	push	temp
;	cbr	intf,	sURX
	;Timer t2 check
	;rcall	compT1
	; Pr黤e Daten
	mov	work,	inreg
	cpi	work,	MIDIclk
	breq	EXR
	cpi	work,	MIDIalv
	breq	EXR
	; Anzeige
	cbi	LEDs,	LEDp
	; Timer start
	in	work,	TCCR1B
	andi	work,	7
	cpi	work,	T1SCL
	breq	RM1

	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_rec<<1)
	ldi	ZH,	HIGH(t_rec<<1)
	rcall	ROM_LINE
	ldi 	work, 	T1SCL
	out 	TCCR1B,	work

	; Schreibe Daten
  RM1:	rcall	WRITEMIDI
	
  EXR:	pop	temp
	pop	cnt
	pop	work
	pop	ZH
	pop	ZL
	pop	XH
	pop	XL
	ret


READMIDI:; Liest einen Datensatz ein
;	sbrc	mode,	mMMCBS
;	  rjmp	READMIDI
;	ldi	ZL,	LOW(t_getdata<<1)
;	ldi	ZH,	HIGH(t_getdata<<1)
;	rcall	SENDSTRING

	rcall	RDCHAR
	mov	p2,	work
	rcall	RDCHAR
	mov	p1,	work
	rcall	RDCHAR
	mov	p0,	work
	rcall	RDCHAR
	mov	sd,	work
	cpi	work,	MIDIstop
	breq	H_EOS
	sbrc	mode,	mFULL		; Voll?
	  rjmp	H_FULL
	ret
 H_EOS:	; Ende vom Lied
	out	TCCR1B,	NULL
	clr	mode
	; Midiger鋞 ausmachen
	rcall	SENDALLOFF
	rcall	READ_SECTOR_END
	sbi	MMC_Write,	MMC_Chip_Select
	sbi	LEDs,	LEDp
	rcall	CALCSECTOR

	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_stop<<1)
	ldi	ZH,	HIGH(t_stop<<1)
	rcall	ROM_LINE

	rcall	INIT_MMC
	rcall	delay
	rcall	INIT_MMC
	ret


WRITEMIDI:; Speichert Miditiming und Byte
	in	cnt,	TCNT1L
	in	temp,	TCNT1H
	mov 	work, 	t2
	rcall 	WRTCHAR
	mov 	work, 	temp
	rcall 	WRTCHAR
	mov 	work, 	cnt
	rcall 	WRTCHAR
	mov 	work, 	inreg
	rcall 	WRTCHAR
	sbrc	mode,	mFULL		; Voll?
	  rjmp	H_FULL
	ret
 H_FULL:; Speicher f黵 Song voll!
	out	TCCR1B,	NULL
	clr	mode
	; Midiger鋞 ausmachen
;	rcall	sendRESET
	
	ret


WRTCHAR:; Speichert 1 Byte <work>->BUFFER
	st	Y+,	work
	cpi	YH,	HIGH(RXBUF)+BUFSIZE
	brne	WRS
	ldi	YH,	HIGH(RXBUF)
  WRS:	cp	ZH,	YH
	brne	WCEX
	cp	ZL,	YL
	breq	BFULL
  WCEX:	ret

 BFULL:	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_buffull<<1)
	ldi	ZH,	HIGH(t_buffull<<1)
	rcall	ROM_LINE
	rjmp	EW


BUF2MMC:;BUFFER->MMC kopieren
	sbrs	mode,	mMMCWR
	  ret
	sbrc	mode,	mMMCBS
	  ret
	cp	ZL,	YL
	brne	HR
	cp	ZH,	YH
	brne	HR
	ret

  HR:	ld	work,	Z+
	cpi	ZH,	HIGH(RXBUF)+BUFSIZE
	brne	BRS
	ldi	ZH,	HIGH(RXBUF)
  BRS:	rcall	WCHAR
	cp	ZL,	YL
	brne	HR
	ret

 WCHAR:	rcall	Write_Byte_MMC
	rcall	INCMCNT
	cpi	work,	1
	ldi	work,	0
	brne	EXWC
	cbr	mode,	smMMCWR
	rcall	WRITE_SECTOR_END
  WOK:	inc	scntl
	brne	NSCW
	inc	scnth
	brne	NSCW
	inc	scnts
  NSCW:	rcall	SHOWSECTOR
	rcall	WRITE_SECTOR_START
  WOK2:	sbr	mode,	smMMCWR
	ldi	work,	1
  EXWC:	ret
	

RDCHAR:; Liest 1 Byte MMC-><work>
	rcall	Read_Byte_MMC
	push	work
	rcall	INCMCNT
	cpi	work,	1
	brne	EXRC
	rcall	READ_SECTOR_END
  RDOK:	inc	scntl
	brne	NSCT
	inc	scnth
	brne	NSCT
	inc	scnts
  NSCT:	rcall	READ_SECTOR_START
  RDOK2:rcall	SHOWSECTOR
  EXRC:	pop	work
	ret


INCMCNT:; Erh鰄t den Bytez鋒ler, work=1 falls 512 erreicht! (und Reset Z鋒ler)
	clr	work
	inc	mcntl
	brne	EXC
	inc	mcnth
	mov	temp,	mcnth
	cpi	temp,	2
	brlo	EXC
	clr	mcnth
	clr	mcntl
	ldi	work,	1
  EXC:	ret


INITMIDI: ; Midi Rekorder/Player vorbereiten
	; Z鋒ler reset
	clr 	t2
	cbr	mode,	smFULL
	cbr	mode,	smEOS
	; Timer 1 Reset
	out	TCCR1B,	NULL
	out	TCNT1H,	NULL
	out	TCNT1L,	NULL
	; L鋎t Seiten-Adresse
;	rcall	CALCSECTOR
	clr	mcntl
	clr	mcnth
	ret



;***************************************************************************
;* 
;* EERead
;*
;* This subroutine waits until the EEPROM is ready to be programmed, then
;* reads the register variable "EEdrd" from address "EEard"
;*
;* Number of words	:6 + return
;* Number of cycles	:12 + return (if EEPROM is ready)
;* Low Registers used	:1 (EEdrd)
;* High Registers used:	:1 (EEard)
;*
;***************************************************************************


;***** Code

EERead:	; Reads byte from EEPROM
	sbic	EECR,	EEWE	;if EEWE not clear
	rjmp	EERead		;    wait more
	out	EEARH,	null
	out	EEARL,	temp	;output address
	sbi	EECR,	EERE	;set EEPROM Read strobe
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	sbi	EECR,	EERE	;set EEPROM Read strobe 2nd time
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	in	work,	EEDR	;get data
	ret


;***************************************************************************
;* 
;* EEWrite
;*
;* This subroutine waits until the EEPROM is ready to be programmed, then
;* programs the EEPROM with register variable "EEdwr" at address "EEawr"
;*
;* Number of words	:5 + return
;* Number of cycles	:10 + return (if EEPROM is ready)
;* Low Registers used	:None
;* High Registers used:	;2 (EEdrd,EEard)
;*
;***************************************************************************

;***** Code

EEWrite:
	sbic	EECR,	EEWE	;if EEWE not clear
	rjmp	EEWrite		;    wait more
	out	EEARH,	null
	out	EEARL,	temp	;output address
	out	EEDR,	work	;output data
	sbi	EECR,	EEMWE
	sbi	EECR,	EEWE	;set EEPROM Write strobe
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	ret



;***********************************************************
;* 	LCD routines
;*

SET_CURSOR: ; Sets the cursor (DD-RAM address) to 0..31
	; SET_CURSOR (<work> cursorpos 0..31)
	mov	temp,	work		; temp holds the address in DD-RAM of LCD
	cpi	work,	CHRLN		; line 1?
	brlo	SC3
	ldi	temp,	64-CHRLN	; set address for line 1
	add	temp,	work

  SC3:	ori	temp,	0b10000000	; set command bit
	rcall	LCD_COMMAND		; send command "SET DD-RAM ADDRESS"
	ret


LINE_OUT: ; Writes a line to the LCD
	; LINE_OUT (<SRAM @Z> *text)

  LO1:	ldi	cnt,	CHRLN		; write 19 chars
  LO2:	ld	temp,	Z+		; load char from SRAM
	rcall	LCD_DATA		; write it
	dec	cnt			; dec cnt
	brne	LO2			; until cnt = 0
	ret


NUMBER_OUT: ; Writes a decimal number 0..99 at DD-RAM pos
	; NUMBER_OUT (<work> number)
	mov	temp,	work
	clr	cnt

	clr	cnt			; count 10s
  NO3:	cpi	work,	10
	brlo	NO4
	subi	work,	10
	inc	cnt
	rjmp	NO3

  NO4:	ldi	temp,	'0'		; write 10s
	add	temp,	cnt
	push	work
	rcall	LCD_DATA
	pop	work

	ldi	temp,	'0'		; write 1s
	add	temp,	work
	rcall	LCD_DATA

	ret


HEX_OUT:; Writes hex number to LCD
	push	work
	swap	work
	rcall	nibble2hex
	mov	temp,	work
	rcall	LCD_DATA
	pop	work
	rcall	nibble2hex
	mov	temp,	work
	rcall	LCD_DATA
	ret


ROM_LINE: ; Writes a line from ROM
	; ROM_LINE (<work> cursorposition, <ROM @Z> *Text)
	rcall	SET_CURSOR

	ldi	cnt,	CHRLN		; write 24 chars
  RL1:	lpm	temp,	Z+		; load char from ROM
	rcall	LCD_DATA		; write it
	dec	cnt			; dec cnt
	brne	RL1			; until cnt = 0

	ret


nibble2hex:; work bits 0..3 are converted in "0".."F"
	andi	work,	0x0F
	cpi	work,	10
	brlo	NH1
	subi	work,	249
  NH1:	subi	work,	208
	ret


SHOWFILENR:
	ldi	work,	0
	ldi	ZL,	LOW(t_file<<1)
	ldi	ZH,	HIGH(t_file<<1)
	rcall	ROM_LINE
	ldi	work,	6
	rcall	SET_CURSOR
	mov	work,	cfileh
	rcall	HEX_OUT
	mov	work,	cfilel
	rcall	HEX_OUT
	ldi	temp,	' '
	rcall	LCD_DATA
	ldi	temp,	'-'
	rcall	LCD_DATA
SHOWSECTOR:
	ldi	work,	13
	rcall	SET_CURSOR
	ldi	temp,	'S'
	rcall	LCD_DATA
	ldi	temp,	' '
	rcall	LCD_DATA
	mov	work,	scnts
	rcall	HEX_OUT
	mov	work,	scnth
	rcall	HEX_OUT
	mov	work,	scntl
	rcall	HEX_OUT
	ret


READERROR:
	sbi	LEDs,	LEDp
	cbr	mode,	smPLAY
	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_readerr<<1)
	ldi	ZH,	HIGH(t_readerr<<1)
	rcall	ROM_LINE
	rjmp	EW


WRITEERROR:
	sbi	LEDs,	LEDr
	cbr	mode,	smREC
	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_writeerr<<1)
	ldi	ZH,	HIGH(t_writeerr<<1)
	rcall	ROM_LINE
  EW:	sbic	KEYs,	KEY1
	  rjmp	EW
	rjmp	RESET


CALCTIME:
	ldi	work,	0b00010001	;0,065536 shift 8
	in	temp,	TCNT1H
	mul	work,	temp
	;push	r0			;Kommaanteil
	push	r1			;ganze Sekunden
	ldi	work,	0b01000011	;16,777216 shift 2
	mul	work,	t2
	clc
	ror	r1			;Sekunden H
	ror	r0			;Sekunden L
	clc
	ror	r1
	ror	r0
	
	pop	SL
	add	SL,	r0
	clr	SH
	adc	SH,	r1
	;pop	r0

	clr	work
  LMIN:	cpi	SH,	1
	brsh	MCNT
	cpi	SL,	60
	brlo	ATM
  MCNT:	sbiw	SH:SL,	60
	inc	work			;Minuten in work
	rjmp	LMIN

  ATM:	push	work
	ldi	work,	42
	rcall	SET_CURSOR
	pop	work
	rcall	NUMBER_OUT
	ldi	temp,	':'
	rcall	LCD_DATA
	mov	work,	SL
	rcall	NUMBER_OUT	
	clr	r1
	ret


t_init:
.DB	"Mr.MIDI by Simon-INIT OK"

t_initf:
.DB	"Mr. MIDI - CARD FAILED  "

t_error:
.DB	"ERROR #  - PLAY TO RETRY"

t_play:
.DB	"Playing...        00:00 "

t_pause:
.DB	"Paused.           00:00 "

t_rec:
.DB	"Recording...      00:00 "

t_recsb:
.DB	"Ready To Record   00:00 "

t_stop:
.DB	"Stopped.                "

t_file:
.DB	"FILE #                  "

t_readerr:
.DB	"ERROR WHEN READING CARD!"

t_writeerr:
.DB	"ERROR WHEN WRITING CARD!"

t_buffull:
.DB	"INPUT BUFFER RAN FULL!  "

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -