📄 midimmcm8.asm
字号:
;********************************************************************
;*
;* MIDI Rekorder v2
;* "Mr. MIDI"
;* MMC/SD-card, LCD display, 5 buttons, 2 LEDs, MIDI I/O
;*
;*
;*** Includes
.include "m8def.inc"
.include "mmc.asm"
.include "lcd.asm"
;*** Constants
.equ CPUFRQ =1000000
.equ BR =31250
.equ BAUDRC =1 ; CPUFRQ/(16*BR)-1
.equ SECTOR =113
.equ T0SCL =0x05
.equ T0FST =0x04
.equ T1SCL =0x04
.equ T1FST =0x03
.equ T2SCL =0x05
.equ CHRLN =24
.equ KEYDELAY=4
; Midi Befehle
.EQU GMreset =255
.EQU MIDIalv =0xFE
.EQU MIDIclk =0xF8
.EQU MIDIstop=0xFC
; Modi
.EQU smPLAY =0x01
.EQU mPLAY =0
.EQU smREC =0x02
.EQU mREC =1
.EQU smFULL =0x04
.EQU mFULL =2
.EQU smEOS =0x08
.EQU mEOS =3
.EQU smMMCBS =0x10
.EQU mMMCBS =4
.EQU smMMCWR =0x20
.EQU mMMCWR =5
.EQU smPAUSE =0x40
.EQU mPAUSE =6
.EQU smFFWD =0x80
.EQU mFFWD =7
;*** Addresses in SRAM
.equ CMD =0x0060 ; MMC command (5 bytes)
.equ RXBUF =0x0100 ; MIDI RxBuffer
.equ BUFSIZE =3
;*** Ports & Pins
; PORT D
.equ RxD =0 ; HW-UART
.equ TxD =1 ; -"-
.equ KEYs =PIND
.equ KEY1 =2 ; Play
.equ KEY2 =3 ; Stop
.equ KEY3 =4 ; Rec
.equ KEY4 =5 ; Up
.equ KEY5 =6 ; Down
.equ KEYMASK =0x7C
; PORT C
.equ LCD =PORTC
; PORT B
.equ LEDr =6 ; Record LED
.equ LEDp =7 ; Play LED
.equ LEDs =PORTB
.equ KEY6 =0 ; FFW
.equ KEY7 =1 ; RWD
.equ KEYs2 =PINB
.equ KEYMSK2 =0x03
;*** REG defs
.def null =r1 ; 0
.def oldkey =r2
.def work =r16 ; General working register
.def temp =r17 ; -"-
.def cnt =r18 ; General counter
.def inreg =r3
.def mode =r19 ; Mode of state machine
.def t2 =r5 ; Timer 1 is used as counter t0, t1
.def p0 =r6 ; Set of midi data and timing
.def p1 =r7
.def p2 =r8
.def sd =r9
.def regs =r10 ; Saves SREG
.def mcntl =r11 ; Bytecounter im Sektor
.def mcnth =r12
.def scntl =r13 ; Sektorcounter in MMC
.def scnth =r14
.def scnts =r15
.def dcnt =r20
.def cfilel =r21
.def cfileh =r22
;.def t0cntl =r23
;.def t0cnth =r24
.def PCLK =r23
.def SL =r24
.def SH =r25
.ESEG
.ORG 1
.DB 1
.ORG 2
.DB 0
.ORG 3
.DB SECTOR
.CSEG
;***********************************************************
;* INT table
;*
.ORG 0
rjmp RESET
.ORG OVF1addr
rjmp T1_OVF
.ORG OVF0addr
rjmp T0_OVF
.ORG OVF2addr
rjmp T2_OVF
.ORG URXCaddr
rjmp UART_RXCP
.ORG UTXCaddr
rjmp UART_TXCP
;***********************************************************
;* INT routines
;*
T0_OVF: ; Timer 0 overflow
; in regs, SREG
; inc t0cntl
; brne ET0
; inc t0cnth
; ET0: out SREG, regs
reti
T2_OVF: ; Timer 2 overflow
reti
T1_OVF: ; Timer 1 overflow
in regs, SREG
inc t2
out SREG, regs
reti
UART_RXCP: ; Received a midi event
in regs, SREG
in inreg, UDR ; fetch byte from UART data reg.
sbrc mode, mREC
rcall RECMIDI
out SREG, regs
set
reti
UART_TXCP: ; Sent a midi event
set
reti
;***********************************************************
;* The program
;*
RESET: ; Start up
ldi work, LOW(RAMEND) ; set up stack
out SPL, work
ldi work, HIGH(RAMEND)
out SPH, work
clr mode
clr scntl
clr scnth
clr scnts
clr cfilel
clr cfileh
rcall INIT_HW
in work, KEYs
andi work, KEYMASK
in temp, KEYs2
andi temp, KEYMSK2
or work, temp
mov oldkey, work
MAIN: in work, KEYs ; get keys
andi work, KEYMASK
in temp, KEYs2
andi temp, KEYMSK2
or work, temp
cp work, oldkey
brne KEY_HDL
; cpi work, KEYMASK|KEYMSK2
; brne H_T0
RK: sbrc mode, mPLAY
rcall PLAY1
sbrc mode, mREC
rcall BUF2MMC
sbrc mode, mREC
rcall CALCTIME
ldi work, (1<<SE)
out MCUCR, work
sbrs mode, mPLAY
sleep
clt
rjmp MAIN
;H_T0: cpi t0cnth, KEYDELAY
; brlo RK
; ldi work, T0FST
; out TCCR0, work
; clr t0cntl
; clr t0cnth
; ldi work, KEYMASK|KEYMSK2
; mov oldkey, work
; rjmp MAIN
H_FAST: ;out TCCR0, null
;clr t0cntl
;clr t0cnth
sbrs mode, mFFWD
rjmp RH
cbr mode, smFFWD
ldi work, T1SCL
sbrc mode, mPLAY
out TCCR1B, work
rjmp RH
KEY_HDL:mov oldkey, work
cpi work, KEYMASK|KEYMSK2
breq H_FAST
clr PCLK
sbis PIND, 2
rjmp PLAY
sbis PIND, 4
rjmp REC
sbis PIND, 3
rjmp STOP
sbis PIND, 5
rjmp INCFN
sbis PIND, 6
rjmp DECFN
sbis PINB, 0
rjmp FFW
sbis PINB, 1
rjmp RWD
RH: rcall delay
rjmp RK
; *** PLAY Taste
PLAY: sbrc mode, mREC
rjmp RH
sbrc mode, mPAUSE
rjmp H_PAUSE
sbrc mode, mPLAY
rjmp H_PLAY
; Modus Play
sbr mode, smPLAY
cbi LEDs, LEDp
sbi LEDs, LEDr
ldi work, CHRLN
ldi ZL, LOW(t_play<<1)
ldi ZH, HIGH(t_play<<1)
rcall ROM_LINE
rcall SHOWFILENR
; Pointer auf song start
rcall INITMIDI
; Lies ersten Datensatz
rcall READ_SECTOR_START
PLAYOK:rcall READMIDI
mov t2, p2
out TCNT1H, p1
out TCNT1L, p0
; Timer start
ldi work, T1SCL
out TCCR1B, work
rjmp RH
H_PLAY:sbr mode, smPAUSE
out TCCR1B, null
rcall SENDALLOFF
ldi work, CHRLN
ldi ZL, LOW(t_pause<<1)
ldi ZH, HIGH(t_pause<<1)
rcall ROM_LINE
rcall CALCTIME
rjmp RH
H_PAUSE:cbr mode, smPAUSE
ldi work, CHRLN
ldi ZL, LOW(t_play<<1)
ldi ZH, HIGH(t_play<<1)
rcall ROM_LINE
ldi work, T1SCL
out TCCR1B, work
rjmp RH
; *** REC Taste
REC: sbrc mode, mPLAY
rjmp RH
sbrc mode, mREC
rjmp RH
; Modus Record
sbr mode, smREC
cbi LEDs, LEDr
sbi LEDs, LEDp
ldi work, CHRLN
ldi ZL, LOW(t_recsb<<1)
ldi ZH, HIGH(t_recsb<<1)
rcall ROM_LINE
rcall SHOWFILENR
; Z鋒ler reset
rcall INITMIDI
ldi YH, HIGH(RXBUF)
ldi ZH, HIGH(RXBUF)
clr YL
clr ZL
rcall WRITE_SECTOR_START
RECOK: sbr mode, smMMCWR
in work, UDR
sbi UCSRB, RXCIE
rjmp RH
; *** STOP Taste
STOP: ; Stoppt REC und PLAY
out TCCR1B, NULL
; Wenn im Rec Mode, schreibe STOPP Event und RxInt Disable
sbrs mode, mREC
rjmp ST_
; ldi ZL, LOW(t_stop<<1)
; ldi ZH, HIGH(t_stop<<1)
; rcall SENDSTRING
rcall WRITESTOP
cbi UCSRB, RXCIE
STP: ldi work, MIDISTOP
rcall WCHAR
cpi work, 0
brne STP
cbr mode, smMMCWR
rcall WRITE_SECTOR_END
ST_: sbrc mode, mPLAY
rcall READ_SECTOR_END
sbi MMC_Write, MMC_Chip_Select
clr mode
sbi LEDs, LEDr
sbi LEDs, LEDp
rcall CALCSECTOR
rcall delay
rcall INIT_MMC
; Midiger鋞 ausmachen
rcall SENDALLOFF
ldi work, CHRLN
ldi ZL, LOW(t_stop<<1)
ldi ZH, HIGH(t_stop<<1)
rcall ROM_LINE
rcall INIT_MMC
rjmp RH
; *** UP Taste
INCFN: sbrc mode, mREC
rjmp RH
sbrc mode, mPLAY
rjmp RH
; ldi work, T0SCL
; out TCCR0, work
inc cfilel
brne CEQ
inc cfileh
CEQ: mov work, cfilel
ldi temp, 1
rcall EEwrite
mov work, cfileh
ldi temp, 2
rcall EEwrite
rcall CALCSECTOR
rjmp RH
; *** DOWN Taste
DECFN: sbrc mode, mREC
rjmp RH
sbrc mode, mPLAY
rjmp RH
; ldi work, T0SCL
; out TCCR0, work
subi cfilel, 1
brsh CSH
dec cfileh
CSH: mov work, cfilel
ldi temp, 1
rcall EEwrite
mov work, cfileh
ldi temp, 2
rcall EEwrite
rcall CALCSECTOR
rjmp RH
CALCSECTOR:; Calculates sector address for current file
ldi temp, 3
rcall EEread ; Read sector offset
mov scntl, work
mov scnth, cfilel
mov scnts, cfileh
rcall SHOWFILENR
; com work
; out LEDs, work
ret
; *** FFWD Taste
FFW: sbrc mode, mREC
rjmp RH
sbrc mode, mPLAY
rjmp SPDUP
; ldi work, T0SCL
; out TCCR0, work
inc scntl
brne EFFW
inc scnth
brne EFFW
inc scnts
EFFW: rcall SHOWSECTOR
rjmp RH
SPDUP: sbrc mode, mPAUSE
rjmp P_FWD
ldi work, T1FST
out TCCR1B, work
sbr mode, smFFWD
rjmp RH
P_FWD: inc scntl
brne EPF
inc scnth
brne EPF
inc scnts
EPF: rcall SHOWSECTOR
rcall RESR
rjmp RH
; *** RWD Taste
RWD: sbrc mode, mREC
rjmp RH
; ldi work, T0SCL
; out TCCR0, work
ldi work, 1
sub scntl, work
brsh ERWD
sub scnth, work
brsh ERWD
dec scnts
ERWD: rcall SHOWSECTOR
sbrs mode, mPLAY
rjmp RH
rcall RESR
ldi work, T1SCL
out TCCR1B, work
rjmp RH
RESR:
out TCCR1B, null
rcall SENDALLOFF
RLS: rcall Read_Byte_MMC
rcall INCMCNT
cpi work, 0
breq RLS
rcall READ_SECTOR_END
; sbi MMC_Write, MMC_Chip_Select
rcall delay
rcall READ_SECTOR_START
rcall SHOWSECTOR
rcall READMIDI
mov t2, p2
out TCNT1H, p1
out TCNT1L, p0
rcall CALCTIME
ret
; *** PLAY Polling
PLAY1: sbrs mode, mPLAY ; Check Modus Play
ret
sbrc mode, mREC ; Check Modus Play
ret
sbrc mode, mPAUSE ; Check Modus Pause
ret
;Timer t2 check
;rcall compT1
;Vergleiche t (Timerstand) mit p (Liedposition)
; ldi ZL, LOW(t_playpoll<<1)
; ldi ZH, HIGH(t_playpoll<<1)
; rcall SENDSTRING
in work, TCNT1L
in temp, TCNT1H
cp t2, p2
breq NCHK1
brlo PEXIT
rjmp POSOK
NCHK1: cp temp, p1
breq NCHK2
brlo PEXIT
rjmp POSOK
NCHK2: cp work, p0
brlo PEXIT
; Pos. passt: Gebe Daten wieder, lade neue Daten
POSOK: ;cbr intf, sUTX
clt
out UDR, sd
WPLAY: brtc WPLAY
; cbr intf, sUTX
clt
rcall READMIDI
PEXIT: inc PCLK
brne PPEX
rcall CALCTIME
PPEX: ret
;***********************************************************
;* Additional routines
;*
INIT_HW: ; Inits the micro; no params
clr null
; Timer setup
out TCCR1B, NULL ; T1SCL to start
out TCNT1H, NULL
out TCNT1L, NULL ; Timer 0.5ms
ldi work, T2SCL
out TCCR2, work
out TCCR0, NULL
; clr t0cnth
ldi work, (1<<TOIE1)|(1<<TOIE2)|(1<<TOIE0)
out TIMSK, work ; Timer interrupts
; UART setup
ldi work, BAUDRC ; baudrate constant
out UBRRL, work ; prepare baud rate register
sbi UCSRB, RXEN ; set "receive enable flag"
sbi UCSRB, TXEN ; set "transmitter enable flag"
cbi UCSRB, RXCIE ; and "received character interrupt enable flag"
sbi UCSRB, TXCIE ; and "received character interrupt enable flag"
sei
in inreg, UDR
clt
; PORT setup
ldi work, 0xEC
out DDRB, work ; //PB7=SCK,PB6=MISO,PB5=MOSI,PB4=MMC_CS,PB3..0 not used
ldi work, 0xC7
out PORTB, work
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -