#if defined atmega8
.include "m8def.inc"
#elif defined atmega168
- .include "m8def.inc"
+ .include "m168def.inc"
#else /* default */
.include "m88def.inc"
;FUSE_H=0xDF
;FUSE_L=0xF7
#endif
.list
-
+.listmac
#ifndef DRAM_DQ_ORDER /* If this is set to 1, the portbits */
#define DRAM_DQ_ORDER 0 /* for DRAM D1 and WE are swapped. */
.equ refr_vect = OC2Aaddr
#endif
+#define DRAM_WORD_ACCESS 0 /* experimental */
#define EM_Z80 0 /* we don't have any z80 instructions yet */
.equ ram_a6 = 6
.equ ram_a7 = 7
-.equ RAM_AH_MASK = 0xE0 ; ram_a[7..5]
-.equ PD_OUTPUT_MASK = 0xFE
+.equ P_OE = PORTD
+.equ P_AH = PORTD
+.equ P_A8 = PORTD
+.equ P_MMC_CS = PORTD
+ ; ram_a[7..5]
+.equ RAM_AH_MASK = (1<<ram_a8)|(1<<ram_a7)|(1<<ram_a6)|(1<<ram_a5)
+.equ PD_OUTPUT_MASK = (1<<mmc_cs) | (1<<ram_oe) | RAM_AH_MASK
;Port B
.equ ram_ras = 5
.equ mmc_sck = 5
-.equ RAM_AL_MASK = 0x1F ; ram_a[4..0]
-.equ PB_OUTPUT_MASK = 0x3F
+.equ P_RAS = PORTB
+
+.equ P_AL = PORTB
+ ; ram_a[4..0]
+.equ RAM_AL_MASK = (1<<ram_a4)|(1<<ram_a3)|(1<<ram_a2)|(1<<ram_a1)|(1<<ram_a0)
+.equ PB_OUTPUT_MASK = (1<<ram_ras) | RAM_AL_MASK
;Port C
#if DRAM_DQ_ORDER == 1
.equ ram_d3 = 3
.equ ram_cas= 5
+.equ P_DQ = PORTC
+.equ P_W = PORTC
+.equ P_CAS = PORTC
+
.equ RAM_DQ_MASK = (1<<ram_d3)|(1<<ram_d2)|(1<<ram_d1)|(1<<ram_d0)
.equ PC_OUTPUT_MASK = (1<<ram_cas)|(1<<ram_w)
.equ ZFL_C = 0
;Register definitions
-.def z_a = r2
+.def _tmp = r0 ; 0
+.def _0 = r1
+;.def z_a = r2
.def z_b = r3
.def z_c = r4
.def z_d = r5
.def z_e = r6
.def z_l = r7
.def z_h = r8
-.def z_spl = r9
-.def z_sph = r10
-
-.def dsk_trk = r11
-.def dsk_sec = r12
-.def dsk_dmah = r13
-.def dsk_dmal = r14
-
-;.def parityb = r15
-
-.def temp = R16 ;The temp register
-.def temp2 = R17 ;Second temp register
-.def trace = r18
-.def opl = r19
-.def oph = r20
-.def adrl = r21
-.def adrh = r22
-.def insdecl = r23
-.def z_pcl = r24
-.def z_pch = r25
-.undef xl
-.undef xh
-.def insdech = r26
-.def z_flags = r27
+;.def z_spl = r9
+;.def z_sph = r10
+
+.def z_a = r11
+
+
+.def _wl = r12
+.def _wh = r13
+.def z_spl = r14
+.def z_sph = r15 ;
+.def temp = r16 ;
+.def temp2 = r17 ;
+.def temp3 = r18
+.def temp4 = r19
+.def z_flags = r20 ;
+.def trace = r21 ;
+.def insdecl = r22 ;
+.def insdech = r23 ;
+.def z_pcl = r24 ;
+.def z_pch = r25 ;
+.undef xl ;r26
+.undef xh ;r27
+.undef yl ;r28
+.undef yh ;r29
+.def opl = r26 ;
+.def oph = r27 ;
+.def adrl = r28 ;
+.def adrh = r29 ;
+; zl ;r30 ;
+; zh ;r31 ;
; This is the base z80 port address for clock access
;SRAM
.dseg
+dsk_trk: .byte 1
+dsk_sec: .byte 1
+dsk_dmah: .byte 1
+dsk_dmal: .byte 1
+
;Sector buffer for 512 byte reads/writes from/to SD-card
sectbuff:
; - Kill wdt
wdr
#if defined __ATmega8__
- ldi temp,0
- out MCUCSR,temp
+ out MCUCSR,_0
ldi temp,(1<<WDCE) | (1<<WDE)
out WDTCSR,temp
ldi temp,(1<<WDCE)
out WDTCSR,temp
+ ldi temp,(1<<PUD) ;disable pullups
+ out SFIOR,temp
#else
- ldi temp,0
- out MCUSR,temp
+ out MCUSR,_0
ldi temp,(1<<WDCE) | (1<<WDE)
sts WDTCSR,temp
ldi temp,(1<<WDCE)
sts WDTCSR,temp
+ ldi temp,(1<<PUD) ;disable pullups
+ out MCUCR,temp
#endif
; - Setup Ports
ldi temp,PC_OUTPUT_MASK
out DDRC,temp
- sbi PORTC,ram_w
- sbi PORTC,ram_cas
- sbi PORTB,ram_ras
- sbi PORTD,ram_oe
- sbi PORTD,mmc_cs
+ sbi P_W,ram_w
+ sbi P_CAS,ram_cas
+ sbi P_RAS,ram_ras
+ sbi P_OE,ram_oe
+ sbi P_MMC_CS,mmc_cs
; - Init serial port
- ldi temp,0 ; reset receive buffer
- sts rxcount,temp
- sts rxidx_r,temp
- sts rxidx_w,temp
+ sts rxcount,_0 ; reset receive buffer
+ sts rxidx_r,_0
+ sts rxidx_w,_0
#if defined __ATmega8__
ldi zl,low(timer_base)
ldi zh,high(timer_base)
- ldi temp,0
ldi temp2,timer_size
ti_loop:
- st z+,temp
+ st z+,_0
dec temp2
brne ti_loop
.if BOOTWAIT
- ldi temp,0
-bootwait1:
- push temp ;2
- ldi temp,0 ;1
-bootwait2:
- dec temp ;1
- brne bootwait2 ;2
- pop temp ;2
- dec temp ;1
- brne bootwait1 ;2 (3*256 + 5) * 256 = 198K cycles
+ ldi temp,10
+ rcall delay_ms
.endif
.if MEMTEST
rcall printstr
- .db "Testing RAM...",13,0
+ .db "Testing RAM: fill...",0,0
;Fill RAM
ldi adrl,0
mov temp,adrh
eor temp,adrl
rcall memwritebyte
- ldi temp,1
- ldi temp2,0
- add adrl,temp
- adc adrh,temp2
+ adiw adrl,1
brcc ramtestw
+ rcall printstr
+ .db "wait...",0
+
+ ldi temp2,8
+ramtestwl:
+ ldi temp,255
+ rcall delay_ms
+ dec temp2
+ brne ramtestwl
+
+ rcall printstr
+ .db "reread...",13,0,0
;re-read RAM
ldi adrl,0
ldi temp,13
rcall uartPutc
ramtestrok:
- ldi temp,1
- ldi temp2,0
- add adrl,temp
- adc adrh,temp2
+ adiw adrl,1
brcc ramtestr
.endif
ramfillw:
ldi temp,0xcb
rcall memwritebyte
- ldi temp,1
- ldi temp2,0
- add adrl,temp
- adc adrh,temp2
+ adiw adrl,1
brcc ramfillw
.endif
rcall memWriteByte
pop zl
pop zh
- ldi temp,1
- ldi temp2,0
- add adrl,temp
- adc adrh,temp2
+ adiw adrl,1
cpi zl,low(sectbuff+128)
brne iplwriteloop
cpi zh,high(sectbuff+128)
.endif
; *** Stage 1: Fetch next opcode
- mov adrl,z_pcl
- mov adrh,z_pch
+ movw adrl,z_pcl
rcall memReadByte
adiw z_pcl,1
.endif
; *** Stage 2: Decode it using the ins_table.
- ldi temp2,0
- ldi zl,low(inst_table*2)
ldi zh,high(inst_table*2)
+ mov zl,temp
add zl,temp
- adc zh,temp2
- add zl,temp
- adc zh,temp2
+ adc zh,_0
lpm insdecl,Z+
lpm insdech,Z
; *** Stage 3: Fetch operand. Use the fetch jumptable for this.
mov temp,insdecl
andi temp,0x1F
- cpi temp,0
breq nofetch
- ldi temp2,0
- lsl temp
- ldi zl,low(fetchjumps*2)
- ldi zh,high(fetchjumps*2)
+ ldi zl,low(fetchjumps)
+ ldi zh,high(fetchjumps)
add zl,temp
- adc zh,temp2
- lpm temp,Z+
- lpm temp2,Z
- mov zl,temp
- mov zh,temp2
+ adc zh,_0
icall
.if INS_DEBUG
; *** Stage 4: Execute operation :) Use the op jumptable for this.
mov temp,insdech
andi temp,0xFC
- lsr temp
- cpi temp,0
breq nooper
- ldi zl,low(opjumps*2)
- ldi zh,high(opjumps*2)
- ldi temp2,0
+ lsr temp
+ lsr temp
+ ldi zl,low(opjumps)
+ ldi zh,high(opjumps)
add zl,temp
- adc zh,temp2
- lpm temp,Z+
- lpm temp2,Z
- mov zl,temp
- mov zh,temp2
+ adc zh,_0
icall
.if INS_DEBUG
andi insdech,0x30
or temp,insdech
breq nostore
- ldi zl,low(storejumps*2)
- ldi zh,high(storejumps*2)
- ldi temp2,0
+ lsr temp
+ ldi zl,low(storejumps)
+ ldi zh,high(storejumps)
add zl,temp
- adc zh,temp2
- lpm temp,Z+
- lpm temp2,Z
- mov zl,temp
- mov zh,temp2
+ adc zh,_0
icall
.if INS_DEBUG
dskTrackSel:
- mov dsk_trk,temp
+ sts dsk_trk,temp
ret
dskSecSel:
- mov dsk_sec,temp
+ sts dsk_sec,temp
ret
dskDmal:
- mov dsk_dmal,temp
+ sts dsk_dmal,temp
ret
dskDmah:
- mov dsk_dmah,temp
+ sts dsk_dmah,temp
ret
dskDoIt:
push temp
rcall printstr
.db "Disk read: track ",0
- mov temp,dsk_trk
+ lds temp,dsk_trk
rcall printhex
rcall printstr
.db " sector ",0
- mov temp,dsk_sec
+ lds temp,dsk_sec
rcall printhex
rcall printstr
.db " dma-addr ",0
- mov temp,dsk_dmah
+ lds temp,dsk_dmah
rcall printhex
- mov temp,dsk_dmal
+ lds temp,dsk_dmal
rcall printhex
rcall printstr
.db ".",13,0
;First, convert track/sector to an LBA address (in 128byte blocks)
push temp
- mov adrl,dsk_sec
+ lds adrl,dsk_sec
ldi adrh,0
- mov temp2,dsk_trk
+ lds temp2,dsk_trk
+ ldi temp,26
dskXlateLoop:
cpi temp2,0
breq dskXlateLoopEnd
- ldi temp,26
add adrl,temp
- ldi temp,0
- adc adrh,temp
+ adc adrh,_0
dec temp2
rjmp dskXlateLoop
dskXlateLoopEnd:
sbrc adrl,1
inc zh
- mov adrh,dsk_dmah
- mov adrl,dsk_dmal
+ lds adrh,dsk_dmah
+ lds adrl,dsk_dmal
ldi temp2,128
dskDoItReadMemLoop:
rcall memWriteByte
pop zl
pop zh
- ldi temp,1
- ldi temp2,0
- add adrl,temp
- adc adrh,temp2
+ adiw adrl,1
pop temp2
dec temp2
brne dskDoItReadMemLoop
push temp
rcall printstr
.db "Disk write: track ",0
- mov temp,dsk_trk
+ lds temp,dsk_trk
rcall printhex
rcall printstr
.db " sector ",0
- mov temp,dsk_sec
+ lds temp,dsk_sec
rcall printhex
rcall printstr
.db " dma-addr ",0
- mov temp,dsk_dmah
+ lds temp,dsk_dmah
rcall printhex
- mov temp,dsk_dmal
+ lds temp,dsk_dmal
rcall printhex
rcall printstr
.db ".",13,0
adc zh,temp2
sbrc adrl,1
inc zh
- mov adrh,dsk_dmah
- mov adrl,dsk_dmal
+ lds adrh,dsk_dmah
+ lds adrl,dsk_dmal
ldi temp2,128
dskDoItWriteMemLoop:
push temp2
pop zl
pop zh
st z+,temp
- ldi temp,1
- ldi temp2,0
- add adrl,temp
- adc adrh,temp2
+ adiw adrl,1
pop temp2
dec temp2
out SPCR,temp
;Init start: send 80 clocks with cs disabled
- sbi PORTD,mmc_cs
+ sbi P_MMC_CS,mmc_cs
- ldi temp2,20
+; ldi temp2,20
+ ldi temp2,10 ; exactly 80 clocks
mmcInitLoop:
mov temp,temp2
rcall mmcByte
dec temp2
brne mmcInitLoop
- cbi PORTD,mmc_cs
+ cbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
rcall mmcByteNoSend
rcall mmcByteNoSend
rcall mmcByteNoSend
rcall mmcByteNoSend
rcall mmcByteNoSend
- sbi PORTD,mmc_cs
+ sbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
rcall mmcByteNoSend
rcall mmcByteNoSend
rcall mmcByteNoSend
;Send init command
- cbi PORTD,mmc_cs
+ cbi P_MMC_CS,mmc_cs
ldi temp,0xff ;dummy
rcall mmcByte
ldi temp,0xff ;dummy
ldi temp,0xff ;return byte
rcall mmcByte
- ldi temp2,0
- rcall mmcWaitResp
+ ldi temp2,0 ;Error Code 0
+ rcall mmcWaitResp ;Test on CMD0 is OK
- sbi PORTD,mmc_cs
+ sbi P_MMC_CS,mmc_cs ;disable /CS
rcall mmcByteNoSend
;Read OCR till card is ready
- ldi temp2,150
+ ldi temp2,20 ;repeat counter
mmcInitOcrLoop:
push temp2
- cbi PORTD,mmc_cs
+ cbi P_MMC_CS,mmc_cs ;enable /CS
ldi temp,0xff ;dummy
rcall mmcByte
ldi temp,0x41 ;cmd
rcall mmcByte
ldi temp,0 ;pyl
rcall mmcByte
- ldi temp,0x95 ;crc
+; ldi temp,0x95 ;crc
+ ldi temp,0x01 ;crc
rcall mmcByte
rcall mmcByteNoSend
ldi temp2,1
- rcall mmcWaitResp
+ rcall mmcWaitResp ;wait until mmc-card send a byte <> 0xFF
+ ;the first answer must be 0x01 (Idle-Mode)
cpi temp,0
- breq mmcInitOcrLoopDone
+ breq mmcInitOcrLoopDone ;second answer is 0x00 (Idle-Mode leave) CMD1 is OK
- sbi PORTD,mmc_cs
- rcall mmcByteNoSend
+ sbi P_MMC_CS,mmc_cs ;disable /CS
+
+; rcall mmcByteNoSend ;unnecessary
+
+ ldi temp,10
+ rcall delay_ms
pop temp2
dec temp2
cpi temp2,0
- brne mmcInitOcrLoop
+ brne mmcInitOcrLoop ;repeat
- ldi temp,4
+ ldi temp2,4
rjmp mmcWaitErr
mmcInitOcrLoopDone:
pop temp2
- sbi PORTD,mmc_cs
+ sbi P_MMC_CS,mmc_cs ;disable /CS
rcall mmcByteNoSend
- ldi temp,0
- out SPCR,temp
+ out SPCR,_0
ret
ldi temp,0x50
out SPCR,temp
- cbi PORTD,mmc_cs
+ cbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
ldi temp,0x51 ;cmd (read sector)
rcall mmcByte
rcall mmcByteNoSend
rcall mmcByteNoSend
- sbi PORTD,mmc_cs
+ sbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
- ldi temp,0
- out SPCR,temp
+ out SPCR,_0
ret
ldi temp,0x50
out SPCR,temp
- cbi PORTD,mmc_cs
+ cbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
ldi temp,0x58 ;cmd (write sector)
cpi temp,0xff
brne mmcwaitwritten
- sbi PORTD,mmc_cs
+ sbi P_MMC_CS,mmc_cs
rcall mmcByteNoSend
- ldi temp,0
- out SPCR,temp
+ out SPCR,_0
ret
; ***************************** New DRAM routines ****************************
-; Defines how the dram nibbles are arganized.
-; RAMORG == 0 : A7 == 0: low nibble, A7 == 1: high nibble (Original Sprite_tm design)
-; RAMORG == 1 : A8 == 0: low nibble, A8 == 1: high nibble (faster)
-;
-#define RAMORG 1
-
-#if RAMORG == 0
-;Sends the address in zh:zl to the ram
-dram_setaddr:
- push temp
- in temp,PORTB
- andi temp,~RAM_AL_MASK
- sbrc zl,0
- ori temp,(1<<ram_a0)
- sbrc zl,1
- ori temp,(1<<ram_a1)
- sbrc zl,2
- ori temp,(1<<ram_a2)
- sbrc zl,3
- ori temp,(1<<ram_a3)
- sbrc zl,4
- ori temp,(1<<ram_a4)
- out PORTB,temp
-
- in temp,PORTD
- andi temp,~RAM_AH_MASK
- sbrc zl,5
- ori temp,(1<<ram_a5)
- sbrc zl,6
- ori temp,(1<<ram_a6)
- sbrc zl,7
- ori temp,(1<<ram_a7)
- sbrc zh,0
- ori temp,(1<<ram_a8)
- out PORTD,temp
- pop temp
-#else /* RAMORG == 1 */
+;todo: see below
.macro DRAM_SETADDR
- push temp
- in temp,PORTB
+#if 1
+ in temp,P_AL
andi temp,~RAM_AL_MASK
sbrc @0,0
ori temp,(1<<ram_a0)
ori temp,(1<<ram_a3)
sbrc @0,4
ori temp,(1<<ram_a4)
- out PORTB,temp
+ out P_AL,temp
+#else
+ out PORTB,@0
+#endif
- in temp,PORTD
+ in temp,P_AH
andi temp,~RAM_AH_MASK
sbrc @0,5
ori temp,(1<<ram_a5)
ori temp,(1<<ram_a6)
sbrc @0,7
ori temp,(1<<ram_a7)
- out PORTD,temp
- pop temp
+ out P_AH,temp
.endm
ret
-#endif /* RAMORG */
-
-.macro DRAM_SENDNIBBLE
- in temp2,PORTC
- andi temp2,~RAM_DQ_MASK
- andi temp,RAM_DQ_MASK
- or temp2,temp
- out PORTC,temp2
-.endm
;Loads the byte on address adrh:adrl into temp.
dram_read:
cli
-#if RAMORG == 0
- mov zl,adrh
- ldi zh,0
- mov temp2,adrl
- lsl temp2
- rol zl
- rol zh
- ;z=addr[15-7]
- rcall dram_setaddr
- cbi PORTB,ram_ras
-
- ldi zh,0
- mov zl,adrl
- andi zl,0x7F
- rcall dram_setaddr
- cbi PORTC,ram_cas
- cbi PORTD,ram_oe
- ldi zh,0
- in temp,PINC
- andi temp,0x0f
- swap temp
- sbi PORTC,ram_cas
-
- mov zl,adrl
- ori zl,0x80
- rcall dram_setaddr
- cbi PORTC,ram_cas
- nop
- in temp2,PINC
- andi temp2,0x0f
- or temp,temp2
-
- sbi PORTD,ram_oe
- sbi PORTC,ram_cas
- sbi PORTB,ram_ras
-#else
- cbi PORTD,ram_a8
+ cbi P_A8,ram_a8
DRAM_SETADDR adrh
- cbi PORTB,ram_ras
+ cbi P_RAS,ram_ras
DRAM_SETADDR adrl
- cbi PORTC,ram_cas
- cbi PORTD,ram_oe
+ cbi P_CAS,ram_cas
+ cbi P_OE,ram_oe
+ nop
nop
- in temp,PINC
+ in temp,P_DQ-2 ; PIN
+ sbi P_CAS,ram_cas
+
+ sbi P_A8,ram_a8
+ cbi P_CAS,ram_cas
andi temp,0x0f
swap temp
- sbi PORTC,ram_cas
-
- sbi PORTD,ram_a8
- cbi PORTC,ram_cas
- nop
- in temp2,PINC
+ in temp2,P_DQ-2 ; PIN
andi temp2,0x0f
or temp,temp2
swap temp
- sbi PORTD,ram_oe
- sbi PORTC,ram_cas
- sbi PORTB,ram_ras
-#endif
+ sbi P_OE,ram_oe
+ sbi P_CAS,ram_cas
+ sbi P_RAS,ram_ras
sei
ret
dram_write:
cli
-#if RAMORG == 0
- in temp2,DDRC ;DRAM data ports as outputs
- ori temp2,RAM_DQ_MASK
+ ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
out DDRC,temp2
- push temp
- DRAM_SENDNIBBLE
- pop temp
-
- mov zl,adrh
- ldi zh,0
- mov temp2,adrl
- lsl temp2
- rol zl
- rol zh
- ;z=addr[15-7]
- rcall dram_setaddr
- cbi PORTB,ram_ras
-
- ldi zh,0
- mov zl,adrl
- ori zl,0x80
- cbi PORTC,ram_w ;early write
- rcall dram_setaddr
- cbi PORTC,ram_cas
- sbi PORTC,ram_cas
-
- ldi zh,0
- mov zl,adrl
- andi zl,0x7F
- rcall dram_setaddr
- swap temp
-
- DRAM_SENDNIBBLE
-
- cbi PORTC,ram_cas
- sbi PORTC,ram_cas
- sbi PORTC,ram_w
- sbi PORTB,ram_ras
-
- in temp,DDRC
- andi temp,~RAM_DQ_MASK
- out DDRC,temp
- in temp,PORTC
- andi temp,~RAM_DQ_MASK
+ mov temp2,temp
+ andi temp,RAM_DQ_MASK & ~(1<<ram_w)
+ ori temp,(1<<ram_cas)
out PORTC,temp
-#else /* RAMORG == 1 */
- in temp2,DDRC ;DRAM data ports as outputs
- ori temp2,RAM_DQ_MASK
- out DDRC,temp2
-
- push temp
- DRAM_SENDNIBBLE
- pop temp
cbi PORTD,ram_a8
DRAM_SETADDR adrh
- cbi PORTB,ram_ras
-
- cbi PORTC,ram_w ;early write
+ cbi P_RAS,ram_ras
DRAM_SETADDR adrl
cbi PORTC,ram_cas
sbi PORTC,ram_cas
sbi PORTD,ram_a8
- swap temp
+ swap temp2
- DRAM_SENDNIBBLE
+ andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
+ ori temp2,(1<<ram_cas)
+ out PORTC,temp2
cbi PORTC,ram_cas
- nop
- sbi PORTC,ram_cas
- sbi PORTC,ram_w
- sbi PORTB,ram_ras
+ sbi P_RAS,ram_ras
- in temp,DDRC
- andi temp,~RAM_DQ_MASK
+ ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
out DDRC,temp
- in temp,PORTC
- andi temp,~RAM_DQ_MASK
out PORTC,temp
-#endif /* RAMORG */
sei
ret
; refresh interupt; exec 2 cbr cycles
refrint:
- cbi PORTC,ram_cas
- cbi PORTB,ram_ras
- nop
- sbi PORTB,ram_ras
- cbi PORTB,ram_ras
- sbi PORTC,ram_cas
- sbi PORTB,ram_ras
- reti
+ ;4 CAS RAS
+ cbi P_CAS,ram_cas ;2 1| 1|
+ ; 1| 1|
+ cbi P_RAS,ram_ras ;2 |0 1|
+ ; |0 1|
+ nop ;1 |0 |0
+; nop ;1 |0 |0
+ sbi P_RAS,ram_ras ;2 |0 |0
+ ; |0 |0
+; nop ;1 |0 |0
+ cbi P_RAS,ram_ras ;2 |0 1|
+ ; |0 1|
+ sbi P_CAS,ram_cas ;2 |0 |0
+ ; |0 |0
+ sbi P_RAS,ram_ras ;2 1| |0
+ ; 1| 1|
+ reti ;4 --> 21 cycles
; ****************************************************************************
; ------------- system timer 10ms ---------------
.dseg
+delay_timer:
+ .byte 1
timer_base:
timer_ms:
.byte 2
push zl
push zh
+ lds zl,delay_timer
+ subi zl,1
+ brcs syscl1
+ sts delay_timer,zl
+syscl1:
lds zl,cnt_1ms
lds zh,cnt_1ms+1
adiw z,1
cpc zh,zl
brlo syscl_end
- ldi zl,0
- sts cnt_1ms,zl
- sts cnt_1ms+1,zl
+ sts cnt_1ms,_0
+ sts cnt_1ms+1,_0
lds zl,uptime+0
inc zl
pop zl
reti
+; wait for temp ms
+
+delay_ms:
+ sts delay_timer,temp
+dly_loop:
+ lds temp,delay_timer
+ cpi temp,0
+ brne dly_loop
+ ret
+
+;
clockget:
ldi temp,0xFF
pop temp2
rcall print_ultoa
rcall printstr
- .db "s. ",0,0
+ .db "s.",0,0
pop opl
pop oph
print_ultoa:
push adrh
push adrl
- push yl
+ push insdech
clr adrl ;adrl = stack level
-ultoa1: ldi yl, 32 ;adrh = oph:temp % 10
+ultoa1: ldi insdech, 32 ;adrh = oph:temp % 10
clr adrh ;oph:temp /= 10
ultoa2: lsl temp
rol temp2
brcs ultoa3
subi adrh,10
inc temp
-ultoa3: dec yl
+ultoa3: dec insdech
brne ultoa2
cpi adrh, 10 ;adrh is a numeral digit '0'-'9'
subi adrh, -'0'
push adrh ;Stack it
inc adrl
- ldi yl,0
- cp temp,yl ;Repeat until oph:temp gets zero
- cpc temp2,yl
- cpc opl,yl
- cpc oph,yl
+ cp temp,_0 ;Repeat until oph:temp gets zero
+ cpc temp2,_0
+ cpc opl,_0
+ cpc oph,_0
brne ultoa1
+
+ ldi temp, '0'
+ultoa5: cpi adrl,3 ; at least 3 digits (ms)
+ brge ultoa6
+ push temp
+ inc adrl
+ rjmp ultoa5
ultoa6: pop temp ;Flush stacked digits
rcall uartputc
dec adrl
brne ultoa6
- pop yl
+ pop insdech
pop adrl
pop adrh
ret
.equ memReadByte = dram_read
.equ memWriteByte = dram_write
+#if DRAM_WORD_ACCESS
+.equ memReadWord = dram_read_w
+.equ memWriteWord = dram_write_w
+#endif
; --------------------------------------------------------------
#else
lds temp,UDR0
#endif
- lds zh,rxcount
- cpi zh,RXBUFSIZE
- brsh rxi_ov
- inc zh
- sts rxcount,zh
-
- ldi zl,low(rxfifo)
- lds zh,rxidx_w
- add zl,zh
- inc zh
- andi zh,RXBUFMASK
- sts rxidx_w,zh
- ldi zh,high(rxfifo)
- brcc PC+2
- inc zh
- st z,temp
-rxi_ov:
+ lds zh,rxcount ;if rxcount < RXBUFSIZE
+ cpi zh,RXBUFSIZE ; (room for at least 1 char?)
+ brsh rxi_ov ;
+ inc zh ;
+ sts rxcount,zh ; rxcount++
+
+ ldi zl,low(rxfifo) ;
+ lds zh,rxidx_w ;
+ add zl,zh ;
+ inc zh ;
+ andi zh,RXBUFMASK ;
+ sts rxidx_w,zh ; rxidx_w = ++rxidx_w % RXBUFSIZE
+ ldi zh,high(rxfifo) ;
+ brcc PC+2 ;
+ inc zh ;
+ st z,temp ; rxfifo[rxidx_w] = char
+rxi_ov: ;endif
pop zl
pop zh
pop temp
;Jump table for fetch routines. Make sure to keep this in sync with the .equs!
fetchjumps:
-.dw do_fetch_nop
-.dw do_fetch_a
-.dw do_fetch_b
-.dw do_fetch_c
-.dw do_fetch_d
-.dw do_fetch_e
-.dw do_fetch_h
-.dw do_fetch_l
-.dw do_fetch_af
-.dw do_fetch_bc
-.dw do_fetch_de
-.dw do_fetch_hl
-.dw do_fetch_sp
-.dw do_fetch_mbc
-.dw do_fetch_mde
-.dw do_fetch_mhl
-.dw do_fetch_msp
-.dw do_fetch_dir8
-.dw do_fetch_dir16
-.dw do_fetch_rst
+ rjmp do_fetch_nop
+ rjmp do_fetch_a
+ rjmp do_fetch_b
+ rjmp do_fetch_c
+ rjmp do_fetch_d
+ rjmp do_fetch_e
+ rjmp do_fetch_h
+ rjmp do_fetch_l
+ rjmp do_fetch_af
+ rjmp do_fetch_bc
+ rjmp do_fetch_de
+ rjmp do_fetch_hl
+ rjmp do_fetch_sp
+ rjmp do_fetch_mbc
+ rjmp do_fetch_mde
+ rjmp do_fetch_mhl
+ rjmp do_fetch_msp
+ rjmp do_fetch_dir8
+ rjmp do_fetch_dir16
+ rjmp do_fetch_rst
do_fetch_nop:
ret
ret
do_fetch_sp:
- mov opl,z_spl
- mov oph,z_sph
+ movw opl,z_spl
ret
do_fetch_mbc:
ret
do_fetch_msp:
- mov adrh,z_sph
- mov adrl,z_spl
+ movw adrl,z_spl
+#if DRAM_WORD_ACCESS
+ rcall memReadWord
+ movw opl,temp
+#else
rcall memReadByte
mov opl,temp
- ldi temp,1
- ldi temp2,0
- add adrl,temp
- adc adrh,temp2
+ adiw adrl,1
rcall memReadByte
mov oph,temp
+#endif
ret
do_fetch_dir8:
- mov adrl,z_pcl
- mov adrh,z_pch
+ movw adrl,z_pcl
rcall memReadByte
adiw z_pcl,1
mov opl,temp
ret
do_fetch_dir16:
- mov adrl,z_pcl
- mov adrh,z_pch
+ movw adrl,z_pcl
+#if DRAM_WORD_ACCESS
+ rcall memReadWord
+ movw opl,temp
+#else
rcall memReadByte
mov opl,temp
- adiw z_pcl,1
- mov adrl,z_pcl
- mov adrh,z_pch
+ adiw adrl,1
rcall memReadByte
- adiw z_pcl,1
mov oph,temp
+#endif
+ adiw z_pcl,2
ret
do_fetch_rst:
- mov adrl,z_pcl
- mov adrh,z_pch
+ movw adrl,z_pcl
subi adrl,1
sbci adrh,0
rcall memReadByte
;Jump table for store routines. Make sure to keep this in sync with the .equs!
storejumps:
-.dw do_store_nop
-.dw do_store_a
-.dw do_store_b
-.dw do_store_c
-.dw do_store_d
-.dw do_store_e
-.dw do_store_h
-.dw do_store_l
-.dw do_store_af
-.dw do_store_bc
-.dw do_store_de
-.dw do_store_hl
-.dw do_store_sp
-.dw do_store_pc
-.dw do_store_mbc
-.dw do_store_mde
-.dw do_store_mhl
-.dw do_store_msp
-.dw do_store_ret
-.dw do_store_call
-.dw do_store_am
+ rjmp do_store_nop
+ rjmp do_store_a
+ rjmp do_store_b
+ rjmp do_store_c
+ rjmp do_store_d
+ rjmp do_store_e
+ rjmp do_store_h
+ rjmp do_store_l
+ rjmp do_store_af
+ rjmp do_store_bc
+ rjmp do_store_de
+ rjmp do_store_hl
+ rjmp do_store_sp
+ rjmp do_store_pc
+ rjmp do_store_mbc
+ rjmp do_store_mde
+ rjmp do_store_mhl
+ rjmp do_store_msp
+ rjmp do_store_ret
+ rjmp do_store_call
+ rjmp do_store_am
do_store_nop:
ret
do_store_msp:
- mov adrh,z_sph
- mov adrl,z_spl
+ movw adrl,z_spl
+#if DRAM_WORD_ACCESS
+ movw temp,opl
+ rcall memWriteWord
+#else
mov temp,opl
rcall memWriteByte
-
- ldi temp,1
- ldi temp2,0
- add adrl,temp
- adc adrh,temp2
+ adiw adrl,1
mov temp,oph
rcall memWriteByte
-
+#endif
ret
do_store_sp:
- mov z_sph,oph
- mov z_spl,opl
+ movw z_spl,opl
ret
do_store_pc:
- mov z_pch,oph
- mov z_pcl,opl
+ movw z_pcl,opl
ret
do_store_ret:
rcall do_op_pop16
- mov z_pcl,opl
- mov z_pch,oph
+ movw z_pcl,opl
ret
do_store_call:
push opl
push oph
- mov opl,z_pcl
- mov oph,z_pch
+ movw opl,z_pcl
rcall do_op_push16
pop z_pch
pop z_pcl
ret
do_store_am:
- mov adrh,oph
- mov adrl,opl
+ movw adrl,opl
mov temp,z_a
rcall memWriteByte
ret
.equ OP_INV = (39<<10)
opjumps:
-.dw do_op_nop
-.dw do_op_inc
-.dw do_op_dec
-.dw do_op_inc16
-.dw do_op_dec16
-.dw do_op_rlc
-.dw do_op_rrc
-.dw do_op_rr
-.dw do_op_rl
-.dw do_op_adda
-.dw do_op_adca
-.dw do_op_subfa
-.dw do_op_sbcfa
-.dw do_op_anda
-.dw do_op_ora
-.dw do_op_xora
-.dw do_op_addhl
-.dw do_op_sthl
-.dw do_op_rmem16
-.dw do_op_rmem8
-.dw do_op_da
-.dw do_op_scf
-.dw do_op_cpl
-.dw do_op_ccf
-.dw do_op_pop16
-.dw do_op_push16
-.dw do_op_ifnz
-.dw do_op_ifz
-.dw do_op_ifnc
-.dw do_op_ifc
-.dw do_op_ifpo
-.dw do_op_ifpe
-.dw do_op_ifp
-.dw do_op_ifm
-.dw do_op_outa
-.dw do_op_in
-.dw do_op_exhl
-.dw do_op_di
-.dw do_op_ei
-.dw do_op_inv
+ rjmp do_op_nop
+ rjmp do_op_inc
+ rjmp do_op_dec
+ rjmp do_op_inc16
+ rjmp do_op_dec16
+ rjmp do_op_rlc
+ rjmp do_op_rrc
+ rjmp do_op_rr
+ rjmp do_op_rl
+ rjmp do_op_adda
+ rjmp do_op_adca
+ rjmp do_op_subfa
+ rjmp do_op_sbcfa
+ rjmp do_op_anda
+ rjmp do_op_ora
+ rjmp do_op_xora
+ rjmp do_op_addhl
+ rjmp do_op_sthl
+ rjmp do_op_rmem16
+ rjmp do_op_rmem8
+ rjmp do_op_da
+ rjmp do_op_scf
+ rjmp do_op_cpl
+ rjmp do_op_ccf
+ rjmp do_op_pop16
+ rjmp do_op_push16
+ rjmp do_op_ifnz
+ rjmp do_op_ifz
+ rjmp do_op_ifnc
+ rjmp do_op_ifc
+ rjmp do_op_ifpo
+ rjmp do_op_ifpe
+ rjmp do_op_ifp
+ rjmp do_op_ifm
+ rjmp do_op_outa
+ rjmp do_op_in
+ rjmp do_op_exhl
+ rjmp do_op_di
+ rjmp do_op_ei
+ rjmp do_op_inv
;How the flags are supposed to work:
;|SUB s |***V1*|Subtract |A=A-s |
;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
;|----------+------+--------------------------------------------|
+;| F |-*01? |Flag unaffected/affected/reset/set/unknown |
+;| S |S |Sign flag (Bit 7) |
+;| Z | Z |Zero flag (Bit 6) |
+;| HC | H |Half Carry flag (Bit 4) |
+;| P/V | P |Parity/Overflow flag (Bit 2, V=overflow) |
+;| N | N |Add/Subtract flag (Bit 1) |
+;| CY | C|Carry flag (Bit 0) |
+;|-----------------+--------------------------------------------|
+;| n |Immediate addressing |
+;| nn |Immediate extended addressing |
+;| e |Relative addressing (PC=PC+2+offset) |
+;| [nn] |Extended addressing |
+;| [xx+d] |Indexed addressing |
+;| r |Register addressing |
+;| [rr] |Register indirect addressing |
+;| |Implied addressing |
+;| b |Bit addressing |
+;| p |Modified page zero addressing (see RST) |
+;|-----------------+--------------------------------------------|
+;|DEFB n(,...) |Define Byte(s) |
+;|DEFB 'str'(,...) |Define Byte ASCII string(s) |
+;|DEFS nn |Define Storage Block |
+;|DEFW nn(,...) |Define Word(s) |
+;|-----------------+--------------------------------------------|
+;| A B C D E |Registers (8-bit) |
+;| AF BC DE HL |Register pairs (16-bit) |
+;| F |Flag register (8-bit) |
+;| I |Interrupt page address register (8-bit) |
+;| IX IY |Index registers (16-bit) |
+;| PC |Program Counter register (16-bit) |
+;| R |Memory Refresh register |
+;| SP |Stack Pointer register (16-bit) |
+;|-----------------+--------------------------------------------|
+;| b |One bit (0 to 7) |
+;| cc |Condition (C,M,NC,NZ,P,PE,PO,Z) |
+;| d |One-byte expression (-128 to +127) |
+;| dst |Destination s, ss, [BC], [DE], [HL], [nn] |
+;| e |One-byte expression (-126 to +129) |
+;| m |Any register r, [HL] or [xx+d] |
+;| n |One-byte expression (0 to 255) |
+;| nn |Two-byte expression (0 to 65535) |
+;| pp |Register pair BC, DE, IX or SP |
+;| qq |Register pair AF, BC, DE or HL |
+;| qq' |Alternative register pair AF, BC, DE or HL |
+;| r |Register A, B, C, D, E, H or L |
+;| rr |Register pair BC, DE, IY or SP |
+;| s |Any register r, value n, [HL] or [xx+d] |
+;| src |Source s, ss, [BC], [DE], [HL], nn, [nn] |
+;| ss |Register pair BC, DE, HL or SP |
+;| xx |Index register IX or IY |
+;|-----------------+--------------------------------------------|
+;| + - * / ^ |Add/subtract/multiply/divide/exponent |
+;| & ~ v x |Logical AND/NOT/inclusive OR/exclusive OR |
+;| <- -> |Rotate left/right |
+;| [ ] |Indirect addressing |
+;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement|
+;| { } |Combination of operands |
+;| # |Also BC=BC-1,DE=DE-1 |
+;| ## |Only lower 4 bits of accumulator A used |
+;----------------------------------------------------------------
.equ AVR_T = 6
; (6 words, 8 cycles)
.macro ldpmx
- ldi zl,low (@1*2)
- ldi zh,high(@1*2)
- add zl,@2
- brcc PC+2
- inc zh
+ ldi zh,high(@1*2) ; table must be page aligned
+ mov zl,@2
lpm @0,z
.endm
;
;
do_op_inc16:
- inc opl
- brne op_i16x
- inc oph
-op_i16x:
+ adiw opl,1
ret
;----------------------------------------------------------------
;
;
do_op_sthl: ;store hl to mem loc in opl:h
- mov adrl,opl
- mov adrh,oph
+ movw adrl,opl
+#if DRAM_WORD_ACCESS
+ mov temp,z_l
+ mov temp2,z_h
+ rcall memWriteWord
+#else
mov temp,z_l
rcall memWriteByte
-
- inc opl
- brne op_sthlx
- inc oph
-op_sthlx:
- mov adrl,opl
- mov adrh,oph
+ adiw adrl,1
mov temp,z_h
rcall memWriteByte
-
+#endif
ret
;----------------------------------------------------------------
;
;
do_op_rmem16:
- mov adrl,opl
- mov adrh,oph
+ movw adrl,opl
+#if DRAM_WORD_ACCESS
+ rcall memReadWord
+ movw opl,temp
+#else
rcall memReadByte
mov opl,temp
- ldi temp,1
- add adrl,temp
- ldi temp,0
- adc adrh,temp
+ adiw adrl,1
rcall memReadByte
mov oph,temp
+#endif
ret
;----------------------------------------------------------------
;
;
do_op_rmem8:
- mov adrl,opl
- mov adrh,oph
+ movw adrl,opl
rcall memReadByte
mov opl,temp
ret
;
;
do_op_push16:
-#if 1
- ldi temp,1
- ldi temp2,0
- sub z_spl,temp
- sbc z_sph,temp2
-
- mov adrl,z_spl
- mov adrh,z_sph
- mov temp,oph
- rcall memWriteByte
-
- ldi temp,1
- ldi temp2,0
- sub z_spl,temp
- sbc z_sph,temp2
-
- mov adrl,z_spl
- mov adrh,z_sph
+ movw adrl,z_spl
+ subi adrl,2
+ sbci adrh,0
+ movw z_spl,adrl
+#if DRAM_WORD_ACCESS
+ movw temp,opl
+ rcall memWriteWord
+#else
mov temp,opl
rcall memWriteByte
-#else
- subi z_spl,1
- sbci z_sph,0
-
- mov adrl,z_spl
- mov adrh,z_sph
+ adiw adrl,1
mov temp,oph
rcall memWriteByte
-
- subi z_spl,1
- sbci z_sph,0
-
- mov adrl,z_spl
- mov adrh,z_sph
- mov temp,opl
- rcall memWriteByte
#endif
.if STACK_DBG
;
;
do_op_pop16:
- mov adrl,z_spl
- mov adrh,z_sph
+ movw adrl,z_spl
+#if DRAM_WORD_ACCESS
+ rcall memReadWord
+ movw opl,temp
+#else
rcall memReadByte
mov opl,temp
-
- ldi temp,1
- ldi temp2,0
- add z_spl,temp
- adc z_sph,temp2
-
- mov adrl,z_spl
- mov adrh,z_sph
+ adiw adrl,1
rcall memReadByte
mov oph,temp
+#endif
- ldi temp,1
- ldi temp2,0
+ ldi temp,2
add z_spl,temp
- adc z_sph,temp2
+ adc z_sph,_0
.if STACK_DBG
rcall printstr
.endif
ret
-;----------------------------------------------------------------
-
-#if 0
-do_op_calcparity:
- ldi temp2,1
- sbrc parityb,0
- inc temp2
- sbrc parityb,1
- inc temp2
- sbrc parityb,2
- inc temp2
- sbrc parityb,3
- inc temp2
- sbrc parityb,4
- inc temp2
- sbrc parityb,5
- inc temp2
- sbrc parityb,6
- inc temp2
- sbrc parityb,7
- inc temp2
- andi temp2,1
- ret
-#endif
;----------------------------------------------------------------
do_op_inv:
; http://z80ex.sourceforge.net/
; The S, Z, 5 and 3 bits and the parity of the lookup value
+.org (PC+255) & 0xff00
sz53p_tab:
.db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
.db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store
; operation (bit 5-9).
+.org (PC+255) & 0xff00
inst_table:
-.dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
-.dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
-.dw (FETCH_A | OP_NOP | STORE_MBC ) ; 02 LD (BC),A
-.dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
-.dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
-.dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
-.dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
-.dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
-.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
-.dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
-.dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
-.dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
-.dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
-.dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
-.dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
-.dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
-.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
+.dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
+.dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
+.dw (FETCH_A | OP_NOP | STORE_MBC) ; 02 LD (BC),A
+.dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
+.dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
+.dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
+.dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
+.dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
+.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
+.dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
+.dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
+.dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
+.dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
+.dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
+.dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
+.dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
+.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
.dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn
.dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A
-.dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
+.dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
.dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D
.dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D
.dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n
.dw (FETCH_DIR8 | OP_SUBFA | STORE_A ) ; D6 nn SUB n
.dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H
.dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C
-.dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
+.dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
.dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn
.dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
.dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn