📄 midimmcm8.asm
字号:
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 + -