;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
+;
+; $Id$
+;
;.nolist
#if defined atmega8
.include "m8def.inc"
#elif defined atmega168
.include "m168def.inc"
+#elif defined atmega328P
+ .include "m328Pdef.inc"
#else /* default */
.include "m88def.inc"
;FUSE_H=0xDF
.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. */
-#endif
#ifndef F_CPU
#define BAUD 38400 /* console baud rate */
#endif
+#define PARTID 0x52 /* Partition table id */
+ /* http://www.win.tue.nl/~aeb/partitions/partition_types-1.html */
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) /* clever rounding */
#define RXBUFSIZE 64 /* USART recieve buffer size. Must be power of 2 */
+#define TXBUFSIZE 64 /* USART transmit buffer size. Must be power of 2 */
+#define DRAM_WAITSTATES 1 /* Number of additional clock cycles for dram read access */
#define REFR_RATE 64000 /* dram refresh rate in cycles/s. */
/* Most drams need 1/15.6µs. */
#define REFR_PRE 8 /* timer prescale factor */
#define REFR_CNT F_CPU / REFR_RATE / REFR_PRE
-#if defined __ATmega8__
- .equ refr_vect = OC2addr
-#else
- .equ refr_vect = OC2Aaddr
-#endif
#define DRAM_WORD_ACCESS 0 /* experimental */
-#define EM_Z80 0 /* we don't have any z80 instructions yet */
+#define EM_Z80 0 /* we don't have any z80 instructions yet */
.equ MMC_DEBUG = 0
.equ INS_DEBUG = 0
.equ BOOTWAIT = 1
.equ PORT_DEBUG = 0
.equ DISK_DEBUG = 0
+.equ HOSTRW_DEBUG= 0
.equ MEMFILL_CB = 1
.equ STACK_DBG = 0
.equ PRINT_PC = 0
.equ ram_ras = 5
.equ mmc_sck = 5
-.equ P_RAS = PORTB
+.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_d1 = 1
-.equ ram_w = 4
-#else /* original */
-.equ ram_d1 = 4
-.equ ram_w = 1
-#endif
.equ ram_d0 = 0
+.equ ram_d1 = 1
.equ ram_d2 = 2
.equ ram_d3 = 3
+.equ ram_w = 4
.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 _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 z_a = r11
+.def z_c = r4
+.def z_b = r5
+.def z_e = r6
+.def z_d = r7
+.def z_l = r8
+.def z_h = r9
+.def z_a = r10
-
-.def _wl = r12
-.def _wh = r13
+.def insdecl = r12 ;
+.def insdech = r13 ;
.def z_spl = r14
.def z_sph = r15 ;
.def temp = r16 ;
.def temp3 = r18
.def temp4 = r19
.def z_flags = r20 ;
-.def trace = r21 ;
-.def insdecl = r22 ;
-.def insdech = r23 ;
+ ;
+.def opl = r22 ;
+.def oph = 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 ;
+; xl ;r26
+; xh ;r27
+; yl ;r28
+; yh ;r29
; zl ;r30 ;
; zh ;r31 ;
+
+#if defined __ATmega8__
+.equ flags = TWBR
+.equ P_PUD = SFIOR
+#else
+.equ flags = GPIOR0
+.equ P_PUD = MCUCR
+#endif
+
+; Flags:
+ .equ hostact = 7 ;host active flag
+ .equ hostwrt = 6 ;host written flag
+ .equ rsflag = 5 ;read sector flag
+ .equ readop = 4 ;1 if read operation
+ .equ trace = 0
+
; This is the base z80 port address for clock access
#define TIMERPORT 0x40
#define TIMER_CTL TIMERPORT
#define printTimerCmd 15
#define uptimeCmd 16
+#if defined __ATmega8__
+.equ RXTXDR0 = UDR
+.equ UCSR0A = UCSRA
+.equ UDRE0 = UDRE
+.equ UCSR0B = UCSRB
+.equ RXCIE0 = RXCIE
+.equ UDRIE0 = UDRIE
+.equ RXEN0 = RXEN
+.equ TXEN0 = TXEN
+.equ UCSR0C = UCSRC
+.equ UCSZ00 = UCSZ0
+.equ UCSZ01 = UCSZ1
+.equ UBRR0H = UBRRH
+.equ UBRR0L = UBRRL
+.equ OCR2A = OCR2
+.equ OC2Aaddr= OC2addr
+.equ TCCR2A = TCCR2
+.equ TCCR2B = TCCR2
+.equ TIMSK1 = TIMSK
+.equ TIMSK2 = TIMSK
+.equ OCIE2A = OCIE2
+.equ TIFR1 = TIFR
+.equ ICIE1 = TICIE1
+#else
+.equ RXTXDR0 = UDR0
+#endif
- ;SRAM
- .dseg
-
-dsk_trk: .byte 1
-dsk_sec: .byte 1
-dsk_dmah: .byte 1
-dsk_dmal: .byte 1
+;----------------------------------------
+;
+.macro outm8
+.if @0 > 0x3f
+ sts @0,@1
+.else
+ out @0,@1
+.endif
+.endm
+
+;----------------------------------------
+;
+.macro inm8
+.if @1 > 0x3f
+ lds @0,@1
+.else
+ in @0,@1
+.endif
+.endm
-;Sector buffer for 512 byte reads/writes from/to SD-card
-sectbuff:
- .byte 512
+
+;----------------------------------------
+; add wait states
+; dram_wait number_of_cycles
+
+.macro dram_wait
+.if @0 > 1
+ rjmp PC+1
+ dram_wait @0 - 2
+.elif @0 > 0
+ nop
+ dram_wait @0 - 1
+.endif
+.endm
.cseg
.org 0
rjmp start ; reset vector
-.org refr_vect
+.org OC2Aaddr
rjmp refrint ; tim2cmpa
.org OC1Aaddr ; Timer/Counter1 Compare Match A
rjmp sysclockint ; 1ms system timer
.org URXCaddr
rjmp rxint ; USART receive int.
-;.org UDREaddr
-; rjmp txint
+.org UDREaddr
+ rjmp txint ; USART transmit int.
.org INT_VECTORS_SIZE
ldi temp,high(RAMEND) ; top of memory
out SPH,temp ; init stack pointer
+ clr _0
+
; - Kill wdt
wdr
-#if defined __ATmega8__
- 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
out MCUSR,_0
ldi temp,(1<<WDCE) | (1<<WDE)
- sts WDTCSR,temp
+ outm8 WDTCSR,temp
ldi temp,(1<<WDCE)
- sts WDTCSR,temp
- ldi temp,(1<<PUD) ;disable pullups
- out MCUCR,temp
-#endif
+ outm8 WDTCSR,temp
+
+; - Clear RAM
+
+ ldi zl,low(SRAM_START)
+ ldi zh,high(SRAM_START)
+ ldi temp2,high(ramtop)
+clr_l:
+ st z+,_0
+ cpi zl,low(ramtop)
+ cpc zh,temp2
+ brne clr_l
; - Setup Ports
- ldi temp,PB_OUTPUT_MASK
- out DDRB,temp
- ldi temp,PD_OUTPUT_MASK
- out DDRD,temp
- ldi temp,PC_OUTPUT_MASK
- out DDRC,temp
+ ldi temp,(1<<PUD) ;disable pullups
+ outm8 P_PUD,temp
+ ldi temp,0xFF
+ out PORTD,temp ;all pins high
+ out PORTB,temp
+ out PORTC,temp
+ out DDRD,temp ; all outputs
+ out DDRB,temp
+ out DDRC,temp
- 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
+ outm8 TIMSK1,_0
+ outm8 TIMSK2,_0
+ outm8 TCCR2A,_0
+ outm8 TCCR2B,_0
; - Init serial port
- sts rxcount,_0 ; reset receive buffer
- sts rxidx_r,_0
- sts rxidx_w,_0
-
-
-#if defined __ATmega8__
- ldi temp, (1<<TXEN) | (1<<RXEN) | (1<<RXCIE)
- out UCSRB,temp
- ldi temp, (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0)
- out UCSRC,temp
- ldi temp, HIGH(UBRR_VAL)
- out UBRRH,temp
- ldi temp, LOW(UBRR_VAL)
- out UBRRL,temp
-#else
ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
- sts UCSR0B,temp
+ outm8 UCSR0B,temp
+.ifdef URSEL
+ ldi temp, (1<<URSEL) | (1<<UCSZ01) | (1<<UCSZ00)
+.else
ldi temp, (1<<UCSZ01) | (1<<UCSZ00)
- sts UCSR0C,temp
+.endif
+ outm8 UCSR0C,temp
ldi temp, HIGH(UBRR_VAL)
- sts UBRR0H,temp
+ outm8 UBRR0H,temp
ldi temp, LOW(UBRR_VAL)
- sts UBRR0L,temp
-#endif
-
-;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
-
-#ifdef __ATmega8__
- ldi temp,REFR_CNT*2 ; 2 cycles per int
- out OCR2,temp
- ldi temp,(1<<WGM21) | REFR_CS ;CTC, clk/REFR_PRE
- out TCCR2,temp
- ldi temp, (1<<OCIE2)
- out TIMSK,temp
-#else
- ldi temp,REFR_CNT ;=312 cycles
- sts OCR2A,temp
- ldi temp, (1<<WGM21)
- sts TCCR2A,temp
- ldi temp, REFR_CS ;clk/REFR_PRE
- sts TCCR2B,temp
- ldi temp,(1<<OCIE2A)
- sts TIMSK2,temp
-#endif
-
+ outm8 UBRR0L,temp
; Init clock/timer system
- ldi zl,low(timer_base)
- ldi zh,high(timer_base)
- ldi temp2,timer_size
-ti_loop:
- st z+,_0
- dec temp2
- brne ti_loop
-
; Init timer 1 as 1 ms system clock tick.
-#ifdef __ATmega8__
ldi temp,high(F_CPU/1000)
- out OCR1AH,temp
+ outm8 OCR1AH,temp
ldi temp,low(F_CPU/1000)
- out OCR1AL,temp
+ outm8 OCR1AL,temp
ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
- out TCCR1B,temp
- in temp,TIMSK
+ outm8 TCCR1B,temp
+ inm8 temp,TIMSK1
ori temp,(1<<OCIE1A)
- out TIMSK,temp
-#else
- ldi temp,high(F_CPU/1000)
- sts OCR1AH,temp
- ldi temp,low(F_CPU/1000)
- sts OCR1AL,temp
- ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
- sts TCCR1B,temp
- lds temp,TIMSK1
- ori temp,(1<<OCIE1A)
- sts TIMSK1,temp
-#endif
+ outm8 TIMSK1,temp
+
+;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
+
+ ldi temp,REFR_CNT*2 ; 2 cycles per int
+ outm8 OCR2A,temp
+ inm8 temp,TCCR2A
+ ori temp,(1<<WGM21) ;CTC mode
+ outm8 TCCR2A,temp
+ inm8 temp,TCCR2B
+ ori temp,REFR_CS ;clk/REFR_PRE
+ outm8 TCCR2B,temp
+ inm8 temp,TIMSK2
+ ori temp, (1<<OCIE2A)
+ outm8 TIMSK2,temp
+
sei
.db "CPM on an AVR, v1.0",13,0,0
- rcall printstr
- .db "Initing mmc...",13,0
- rcall mmcInit
-
-
.if MEMTEST
rcall printstr
.db "Testing RAM: fill...",0,0
;Fill RAM
- ldi adrl,0
- ldi adrh,0
+ ldi xl,0
+ ldi xh,0
ramtestw:
- mov temp,adrh
- eor temp,adrl
+ mov temp,xh
+ eor temp,xl
rcall memwritebyte
- adiw adrl,1
+ adiw xl,1
brcc ramtestw
rcall printstr
.db "wait...",0
.db "reread...",13,0,0
;re-read RAM
- ldi adrl,0
- ldi adrh,0
+ ldi xl,0
+ ldi xh,0
ramtestr:
- rcall memreadbyte
- mov temp2,adrh
- eor temp2,adrl
+ rcall memReadByte
+ mov temp2,xh
+ eor temp2,xl
cp temp,temp2
breq ramtestrok
rcall printhex
ldi temp,'<'
rcall uartPutc
- mov temp,adrh
- eor temp,adrl
+ mov temp,xh
+ eor temp,xl
rcall printhex
ldi temp,'@'
rcall uartPutc
- mov temp,adrh
+ mov temp,xh
rcall printhex
- mov temp,adrl
+ mov temp,xl
rcall printhex
ldi temp,13
rcall uartPutc
ramtestrok:
- adiw adrl,1
+ adiw xl,1
brcc ramtestr
.endif
.if MEMFILL_CB
;Fill ram with cbs, which (for now) will trigger an invalid opcode error.
- ldi adrl,0
- ldi adrh,0
+ ldi xl,0
+ ldi xh,0
ramfillw:
ldi temp,0xcb
rcall memwritebyte
- adiw adrl,1
+ adiw xl,1
brcc ramfillw
.endif
+ rcall printstr
+ .db "Initing mmc...",13,0
+ rcall mmcInit
+
+;----------------------------------------------------------------------------
+
+; Partition table offsets:
+#define PART_TYPE 4
+#define PART_START 8
+#define PART_SIZE 12
+
+;Load first sector from MMC (boot sector)
+
+boot_again:
+ ldi yh,0
+ ldi yl,0
+ movw x,y
+ rcall mmcReadSect
-;Load initial sector from MMC (512 bytes)
- ldi adrh,0
- ldi adrl,0
- rcall mmcReadSect
+;Test, if it has a valid MBR
+
+ lds temp,hostbuf+510 ;MBR signature (0xAA55) at and of sector?
+ lds temp2,hostbuf+511
+ ldi temp4,0xAA
+ cpi temp,0x55
+ cpc temp2,temp4
+ ldi opl,0 ;opl holds number of found disks (paritions)
+ breq boot_part
+
+;No MBR, no partition table ...
+ inc opl ;pretend we have one.
+ rjmp boot_ipl
+
+;Search Partition Table for CP/M partitions
+boot_part:
+ ldi zl,low(hostbuf+510-64)
+ ldi zh,high(hostbuf+510-64)
+ ldi yl,low(hostparttbl)
+ ldi yh,high(hostparttbl)
+ ldi oph,high(hostbuf+510)
+boot_ploop:
+ ldd temp,z+PART_TYPE
+ cpi temp,PARTID
+ brne boot_nextp
+
+; Found a CP/M partition
+
+ ldd temp,z+PART_START
+ st y+,temp
+ ldd temp2,z+PART_START+1
+ st y+,temp2
+ ldd temp3,z+PART_START+2
+ st y+,temp3
+ ldd temp4,z+PART_START+3
+ st y+,temp4
+
+ rcall printstr
+ .db "CP/M partition at: ",0
+ rcall print_ultoa
+ rcall printstr
+ .db ", size: ",0,0
+ ldd temp,z+PART_SIZE
+ st y+,temp
+ ldd temp2,z+PART_SIZE+1
+ st y+,temp2
+ ldd temp3,z+PART_SIZE+2
+ st y+,temp3
+ ldd temp4,z+PART_SIZE+3
+ st y+,temp4
+ lsr temp4
+ ror temp3
+ ror temp2
+ ror temp
+ rcall print_ultoa
+ rcall printstr
+ .db "KB.",13,0,0
+
+ inc opl
+ cpi opl,MAXDISKS
+ breq boot_pend
+boot_nextp:
+ adiw zl,16
+ cpi zl,low(hostbuf+510)
+ cpc zh,oph
+ brsh boot_pend
+ rjmp boot_ploop
+boot_pend:
+
+; Read first sector of first CP/M partition
+
+ lds xl,hostparttbl
+ lds xh,hostparttbl+1
+ lds yl,hostparttbl+2
+ lds yh,hostparttbl+3
+ rcall mmcReadSect
+
+boot_ipl:
+ sts ndisks,opl
+ tst opl
+ brne boot_ipl2
+ rcall printstr
+ .db "No bootable CP/M disk found! Please change MMC/SD-Card",13,0
+ ldi temp2,18
+boot_wl:
+ ldi temp,255
+ rcall delay_ms
+ dec temp2
+ brne boot_wl
+ rjmp boot_again
+
+
+boot_ipl2:
+
+;First sector of disk or first CP/M partition is in hostbuf.
;Save to Z80 RAM (only 128 bytes because that's retro)
- ldi zl,low(sectbuff)
- ldi zh,high(sectbuff)
- ldi adrh,0x20
- ldi adrl,0x00
+ ldi zl,low(hostbuf)
+ ldi zh,high(hostbuf)
+ ldi xh,0x20
+ ldi xl,0x00
iplwriteloop:
ld temp,z+
- push zh
- push zl
rcall memWriteByte
- pop zl
- pop zh
- adiw adrl,1
- cpi zl,low(sectbuff+128)
+ adiw xl,1
+ cpi zl,low(hostbuf+128)
brne iplwriteloop
- cpi zh,high(sectbuff+128)
+ cpi zh,high(hostbuf+128)
brne iplwriteloop
-
+ rcall dsk_boot ;init (de)blocking buffer
;Init z80
ldi temp,0x20
mov z_pch,temp
- ldi trace,0
+ cbi flags,trace
rcall printstr
.db 13,"Ok, CPU is live!",13,0,0
main:
- ldi trace,0
+ cbi flags,trace
cpi z_pch,1
brlo notraceon
cpi z_pch,$dc
brsh notraceon
- ldi trace,1
+ sbi flags,trace
notraceon:
brsh noprintpc
rcall printstr
- .db "PC=",0
+ .db 13,"PC=",0
mov temp,z_pch
rcall printhex
mov temp,z_pcl
rcall printhex
- ldi temp,10
- rcall uartputc
+ ldi temp,' '
+; ldi temp,10
+; rcall uartputc
noprintpc:
.endif
; *** Stage 1: Fetch next opcode
- movw adrl,z_pcl
+ movw xl,z_pcl
rcall memReadByte
- adiw z_pcl,1
.if INS_DEBUG
- cpi trace,0
- breq notrace1
+ sbis flags,trace
+ rjmp notrace1
rcall printstr
.db "PC=",0
push temp
- mov temp,adrh
+ mov temp,z_pch
rcall printhex
- mov temp,adrl
+ mov temp,z_pcl
rcall printhex
pop temp
rcall printstr
rcall printhex
notrace1:
.endif
+ adiw z_pcl,1
; *** Stage 2: Decode it using the ins_table.
ldi zh,high(inst_table*2)
lpm insdech,Z
.if INS_DEBUG
- cpi trace,0
- breq notrace2
+ sbis flags,trace
+ rjmp notrace2
rcall printstr
- .db ", decoded=",0
+ .db ", decoded=",0,0
mov temp,insdech
rcall printhex
mov temp,insdecl
rcall printhex
rcall printstr
- .db ".",13,0
+ .db ".",13,0,0
notrace2:
.endif
icall
.if INS_DEBUG
- cpi trace,0
- breq notrace3
+ sbis flags,trace
+ rjmp notrace3
rcall printstr
.db "pre: oph:l=",0
mov temp,oph
mov temp,opl
rcall printhex
rcall printstr
- .db " -- ",0
+ .db " -- ",0,0
notrace3:
.endif
icall
.if INS_DEBUG
- cpi trace,0
- breq notrace4
+ sbis flags,trace
+ rjmp notrace4
rcall printstr
- .db ",post:oph:l=",0
+ .db ",post:oph:l=",0,0
mov temp,oph
rcall printhex
mov temp,opl
; *** Stage 5: Store operand. Use the store jumptable for this.
swap insdecl
swap insdech
- mov temp,insdecl
+ movw temp,insdecl
andi temp,0x0E
- andi insdech,0x30
- or temp,insdech
+ andi temp2,0x30
+ or temp,temp2
breq nostore
lsr temp
ldi zl,low(storejumps)
icall
.if INS_DEBUG
- cpi trace,0
- breq notrace5
+ sbis flags,trace
+ rjmp notrace5
rcall printstr
.db ", stored.",0
notrace5:
nostore:
.if INS_DEBUG
- cpi trace,0
- breq notrace6
+ sbis flags,trace
+ rjmp notrace6
rcall printstr
.db 13,0
notrace6:
;The hw is modelled to make writing a CPM BIOS easier.
;Ports:
-;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise.
-;1 - Console input, aka UDR.
-;2 - Console output
-;16 - Track select
-;18 - Sector select
-;20 - Write addr l
-;21 - Write addr h
-;22 - Trigger - write 1 to read, 2 to write a sector using the above info.
-; This will automatically move track, sector and dma addr to the next sector.
+;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise.
+;1 - Console input, aka UDR.
+;2 - Console output
+;15 - Disk select
+;16,17 - Track select
+;18 - Sector select
+;20 - Write addr l
+;21 - Write addr h
+;22 - Trigger - write to read, to write a sector using the above info;
+; , write to allocated/dirctory/unallocated
+
+ .equ READ_FUNC = 7
+ .equ WRITE_FUNC = 6
+ .equ BOOT_FUNC = 5
+ .equ HOME_FUNC = 4
+
+
+
+;*****************************************************
+;* CP/M to host disk constants *
+;*****************************************************
+ .equ MAXDISKS = 4 ;Max number of Disks (partitions)
+ .equ blksize = 1024 ;CP/M allocation size
+ .equ hostsize = 512 ;host disk sector size
+; .equ hostspt = 20 ;host disk sectors/trk
+ .equ hostblk = hostsize/128 ;CP/M sects/host buff
+; .equ CPMSPT = hostblk*hostspt;CP/M sectors/track
+ .equ CPMSPT = 26 ;
+ .equ SECMSK = hostblk-1 ;sector mask
+ .equ SECSHF = log2(hostblk) ;sector shift
+
+;*****************************************************
+;* BDOS constants on entry to write *
+;*****************************************************
+ .equ WRALL = 0 ;write to allocated
+ .equ WRDIR = 1 ;write to directory
+ .equ WRUAL = 2 ;write to unallocated
+ .equ WRTMSK= 3 ;write type mask
+
+
+ .dseg
+ndisks: .byte 1 ;Number of CP/M disks
+
+seekdsk: .byte 1 ;seek disk number
+seektrk: .byte 2 ;seek track number
+seeksec: .byte 1 ;seek sector number
+hostparttbl: .byte 8*MAXDISKS ; host partition table (start sector, sector count)
+hostdsk: .byte 1 ;host disk number
+hostlba: .byte 3 ;host sector number (relative to partition start)
+
+unacnt: .byte 1 ;unalloc rec cnt
+unadsk: .byte 1 ;last unalloc disk
+unatrk: .byte 2 ;last unalloc track
+unasec: .byte 1 ;last unalloc sector
+
+erflag: .byte 1 ;error reporting
+wrtype: .byte 1 ;write operation type
+dmaadr: .byte 2 ;last dma address
+hostbuf: .byte hostsize;host buffer (from/to SD-card)
+
+
+ .cseg
+
;Called with port in temp2. Should return value in temp.
portRead:
cpi temp2,0
cpi temp2,1
breq conInp
+ cpi temp2,15
+ breq dskDiskCheck
+ cpi temp2,22
+ breq dskErrorRet
+
cpi temp2,TIMER_MSECS
brlo pr_noclock
cpi temp2,TIMER_MSECS+6
breq dbgOut
cpi temp2,2
breq conOut
+
+ cpi temp2,15
+ breq dskDiskSel
cpi temp2,16
- breq dskTrackSel
+ breq dskTrackSel_l
+ cpi temp2,17
+ breq dskTrackSel_h
cpi temp2,18
breq dskSecSel
cpi temp2,20
breq dskDmaL
cpi temp2,21
breq dskDmaH
+
cpi temp2,22
breq dskDoIt
ret
conInp:
- rcall uartGetc
- ret
+ rjmp uartGetc
dbgOut:
rcall printstr
ret
conOut:
- rcall uartputc
+ rjmp uartputc
+
+
+dskDiskCheck:
+ lds temp,seekdsk
+ lds temp2,ndisks ;check if selected disk # is less then # of disks
+ cp temp,temp2
+ ldi temp,0
+ brlt PC+2
+ ldi temp,0xff ;error return
+ ret
+
+dsk_dchend:
+ ldi temp,0
+ ret
+
+dskErrorRet:
+ lds temp,erflag
ret
+dskDiskSel:
+ sts seekdsk,temp
+ ret
+dskTrackSel_l:
+ sts seektrk,temp
+ sts seektrk+1,_0
+ ret
-dskTrackSel:
- sts dsk_trk,temp
+dskTrackSel_h:
+ sts seektrk+1,temp
ret
dskSecSel:
- sts dsk_sec,temp
+ sts seeksec,temp
ret
dskDmal:
- sts dsk_dmal,temp
+ sts dmaadr,temp
ret
dskDmah:
- sts dsk_dmah,temp
+ sts dmaadr+1,temp
ret
dskDoIt:
.if DISK_DEBUG
push temp
+ sbrc temp,READ_FUNC
+ rjmp dskdbgr
+ sbrc temp,WRITE_FUNC
+ rjmp dskdbgw
+ rjmp dskdbge
+
+dskdbgr:
+ rcall printstr
+ .db 13,"Disk read: ",0
+ rjmp dskdbg1
+dskdbgw:
rcall printstr
- .db "Disk read: track ",0
- lds temp,dsk_trk
+ .db 13,"Disk write: ",0
+dskdbg1:
+ lds temp,seekdsk
+ subi temp,-('A')
+ rcall uartputc
+ rcall printstr
+ .db ": track ",0,0
+ lds temp,seektrk+1
+ rcall printhex
+ lds temp,seektrk
rcall printhex
rcall printstr
- .db " sector ",0
- lds temp,dsk_sec
+ .db " sector ",0,0
+ lds temp,seeksec
rcall printhex
rcall printstr
- .db " dma-addr ",0
- lds temp,dsk_dmah
+ .db " dma-addr ",0,0
+ lds temp,dmaadr+1
rcall printhex
- lds temp,dsk_dmal
+ lds temp,dmaadr
rcall printhex
+ pop temp
+ push temp
+ sbrs temp,WRITE_FUNC
+ rjmp dskdbge
rcall printstr
- .db ".",13,0
+ .db " wrtype ",0,0
+ andi temp,3
+ rcall printhex
+dskdbge:
pop temp
.endif
+ ;See what has to be done.
+ sbrc temp,READ_FUNC
+ rjmp dsk_read
+ sbrc temp,WRITE_FUNC
+ rjmp dsk_write
+ sbrc temp,HOME_FUNC
+ rjmp dsk_home
+ sbrc temp,BOOT_FUNC
+ rjmp dsk_boot
+
+ rcall printstr
+ .db "DISK I/O: Invalid Function code: ",0
+ rcall printhex
+ rjmp haltinv
+
+dsk_boot:
+ cbi flags,hostact ;host buffer inactive
+ sts unacnt,_0 ;clear unalloc count
+ ret
+
+dsk_home:
+ sbis flags,hostwrt ;check for pending write
+ cbi flags,hostact ;clear host active flag
+ ret
+
+
+dsk_read:
+
+ sbi flags,readop ;read operation
+ ;RAM disk?
+ lds temp2,seekdsk
+; cpi temp2,RAMDISKNR
+; brlt PC+2
+; rjmp rdskDoIt
+
+ sts unacnt,_0
+ sbi flags,rsflag ;must read data
+ ldi temp,WRUAL ;write type
+ sts wrtype,temp ;treat as unalloc
+ rjmp dsk_rwoper ;to perform the read
+
+
+dsk_write:
+ ;write the selected CP/M sector
+
+ cbi flags,readop ;not a read operation
+
+ ;RAM disk?
+ lds temp2,seekdsk
+; cpi temp2,RAMDISKNR
+; brlt PC+2
+; rjmp rdskDoIt
+ andi temp,WRTMSK
+ sts wrtype,temp ;save write type
+
+ cpi temp,WRUAL ;write unallocated?
+ brne dsk_chkuna ;check for unalloc
+
+; write to unallocated, set parameters
+ ldi temp,blksize/128 ;next unalloc recs
+ sts unacnt,temp
+ lds temp,seekdsk ;disk to seek
+ sts unadsk,temp ;unadsk = sekdsk
+ lds temp,seektrk
+ sts unatrk,temp ;unatrk = sectrk
+ lds temp,seektrk+1
+ sts unatrk+1,temp ;unatrk = sectrk
+ lds temp,seeksec
+ sts unasec,temp ;unasec = seksec
+;
+dsk_chkuna:
+ ;check for write to unallocated sector
+ lds temp,unacnt ;any unalloc remain?
+ tst temp
+ breq dsk_alloc ;skip if not
+
+; more unallocated records remain
+ dec temp ;unacnt = unacnt-1
+ sts unacnt,temp
+ lds temp,seekdsk ;same disk?
+ lds temp2,unadsk
+ cp temp,temp2 ;seekdsk = unadsk?
+ brne dsk_alloc ;skip if not
+
+; disks are the same
+ lds temp,unatrk
+ lds temp2,unatrk+1
+ lds temp3,seektrk
+ lds temp4,seektrk+1
+ cp temp,temp3 ;seektrk = unatrk?
+ cpc temp2,temp4
+ brne dsk_alloc ;skip if not
+
+; tracks are the same
+ lds temp,seeksec ;same sector?
+ lds temp2,unasec
+ cp temp,temp2 ;seeksec = unasec?
+ brne dsk_alloc ;skip if not
+
+; match, move to next sector for future ref
+ inc temp2 ;unasec = unasec+1
+ sts unasec,temp2
+ cpi temp2,CPMSPT ;end of track? (count CP/M sectors)
+ brlo dsk_noovf ;skip if no overflow
+
+; overflow to next track
+ sts unasec,_0 ;unasec = 0
+ lds temp,unatrk
+ lds temp2,unatrk+1
+ subi temp, low(-1) ;unatrk = unatrk+1
+ sbci temp2,high(-1)
+ sts unatrk,temp
+ sts unatrk+1,temp2
+;
+dsk_noovf:
+ cbi flags,rsflag ;rsflag = 0
+ rjmp dsk_rwoper ;to perform the write
+;
+dsk_alloc:
+ ;not an unallocated record, requires pre-read
+ sts unacnt,_0 ;unacnt = 0
+ sbi flags,rsflag ;rsflag = 1
- ;First, convert track/sector to an LBA address (in 128byte blocks)
- push temp
- lds adrl,dsk_sec
- ldi adrh,0
- lds temp2,dsk_trk
- ldi temp,26
-dskXlateLoop:
- cpi temp2,0
- breq dskXlateLoopEnd
- add adrl,temp
- adc adrh,_0
- dec temp2
- rjmp dskXlateLoop
-dskXlateLoopEnd:
- pop temp
-
- ;Now, see what has to be done.
- cpi temp,1
- breq dskDoItRead
- cpi temp,2
- breq dskDoItWrite
-
-dskDoItRead:
- push adrl
- ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
- lsr adrh
- ror adrl
- lsr adrh
- ror adrl
- ;Read 512-byte sector
- rcall mmcReadSect
- pop adrl
-
- ;Now, move the correct portion of the sector from AVR ram to Z80 ram
- ldi zl,low(sectbuff)
- ldi zh,high(sectbuff)
- ldi temp,128
- ldi temp2,0
- sbrc adrl,0
- add zl,temp
- sbrc adrl,0
- adc zh,temp2
- sbrc adrl,1
- inc zh
-
- lds adrh,dsk_dmah
- lds adrl,dsk_dmal
-
- ldi temp2,128
-dskDoItReadMemLoop:
- push temp2
- ld temp,z+
- push zh
- push zl
- rcall memWriteByte
- pop zl
- pop zh
- adiw adrl,1
- pop temp2
- dec temp2
- brne dskDoItReadMemLoop
- ret
-
-dskDoItWrite:
-;The write routines is a bit naive: it'll read the 512-byte sector the 128byte CPM-sector
-;resides in into memory, will overwrite the needed 128 byte with the Z80s memory buffer
-;and will then write it back to disk. In theory, this would mean that every 512 bytes
-;written will take 4 write cycles, while theoretically the writes could be deferred so we
-;would only have to do one write cycle.
+;*****************************************************
+;* Common code for READ and WRITE follows *
+;*****************************************************
+dsk_rwoper:
+ ;enter here to perform the read/write
.if DISK_DEBUG
- push temp
- rcall printstr
- .db "Disk write: track ",0
- lds temp,dsk_trk
- rcall printhex
- rcall printstr
- .db " sector ",0
- lds temp,dsk_sec
- rcall printhex
+ rcall printstr
+ .db ", flags: ",0
+ in temp,flags
+ rcall printhex
+.endif
+ sts erflag,_0 ;no errors (yet)
+
+ ;Convert track/sector to an LBA address (in 128byte blocks)
+
+ lds xl,seeksec ;
+ ldi xh,0 ;
+ ldi yl,0 ;
+ lds temp3,seektrk ;
+ lds temp4,seektrk+1 ;
+ ldi temp,CPMSPT ;
+ mul temp3,temp ;
+ add xl,r0 ;
+ adc xh,r1 ;
+ mul temp4,temp ;
+ add xh,r0 ;yl:xh:xl := sec + trk * SectorsPerTrack
+ adc yl,r1 ;
+ clr _0
+
+ mov temp,xl
+ andi temp,SECMSK ;mask buffer number
+ push temp ;save for later
+
+ ;Convert from CP/M LBA blocks to host LBA blocks
+ ldi temp,SECSHF
+dsk_sh1:
+ lsr yl
+ ror xh
+ ror xl
+ dec temp
+ brne dsk_sh1
+ ;yl:xh:xl = host block to seek
+; active host sector?
+ in _tmp,flags ;host active flag
+ sbi flags,hostact ;always becomes 1
+ sbrs _tmp,hostact ;was it already?
+ rjmp dsk_filhst ;fill host if not
+
+; host buffer active, same as seek buffer?
+ lds temp,seekdsk
+ lds temp2,hostdsk ;same disk?
+ cp temp,temp2 ;seekdsk = hostdsk?
+ brne dsk_nomatch
+
+; same disk, same block?
+ lds temp,hostlba
+ lds temp2,hostlba+1
+ lds temp3,hostlba+2
+ cp xl,temp
+ cpc xh,temp2
+ cpc yl,temp3
+ breq dsk_match
+;
+dsk_nomatch:
+ ;proper disk, but not correct sector
+ sbis flags,hostwrt ;host written?
+ rjmp dsk_filhst
+ push xl
+ push xh
+ push yl
+ rcall dsk_writehost ;clear host buff
+ pop yl
+ pop xh
+ pop xl
+
+dsk_filhst:
+ ;may have to fill the host buffer
+ lds temp,seekdsk
+ sts hostdsk,temp
+ sts hostlba,xl
+ sts hostlba+1,xh
+ sts hostlba+2,yl
+
+ sbic flags,rsflag ;need to read?
+ rcall dsk_readhost ;yes, if 1
+ cbi flags,hostwrt ;no pending write
+
+dsk_match:
+
+ ;copy data to or from buffer
+ ldi zl,low(hostbuf)
+ ldi zh,high(hostbuf)
+ ldi temp,128
+ pop temp2 ;get buffer number (which part of hostbuf)
+ mul temp2,temp
+ add zl,r0 ;offset in hostbuf
+ adc zh,r1
+.if 0 ; DISK_DEBUG
+ push r0
+ push r1
+ clr _0
rcall printstr
- .db " dma-addr ",0
- lds temp,dsk_dmah
+ .db "; host buf adr: ",0,0
+ pop temp
rcall printhex
- lds temp,dsk_dmal
+ pop temp
rcall printhex
- rcall printstr
- .db ".",13,0
- pop temp
.endif
+ clr _0
+
+ lds xl,dmaadr
+ lds xh,dmaadr+1
+ ldi temp3,128 ;length of move
+ sbic flags,readop ;which way?
+ rjmp dsk_rmove ;skip if read
+
+; mark write operation
+ sbi flags,hostwrt ;hostwrt = 1
+dsk_wmove:
+ rcall memReadByte
+ st z+,temp
+ adiw xl,1
+ dec temp3
+ brne dsk_wmove
+ rjmp dsk_rwmfin
+
+dsk_rmove:
+ ld temp,z+
+ rcall memWriteByte
+ adiw xl,1
+ dec temp3
+ brne dsk_rmove
+dsk_rwmfin:
+; data has been moved to/from host buffer
+ lds temp,wrtype ;write type
+ cpi temp,WRDIR ;to directory?
+ breq dsk_wdir
+ ret ;no further processing
+dsk_wdir:
+; clear host buffer for directory write
+ lds temp,erflag
+ tst temp ;errors?
+ breq dsk_wdir1
+ ret ;skip if so
+dsk_wdir1:
+ rcall dsk_writehost ;clear host buff
+ cbi flags,hostwrt ;buffer written
+ ret
+
+;*****************************************************
+
+; hostdsk = host disk #, (partition #)
+; hostlba = host block #, relative to partition start
+; Read/Write "hostsize" bytes to/from hostbuf
+
+dsk_hostparam:
+ ldi zl,low(hostparttbl)
+ ldi zh,high(hostparttbl)
+ lds temp,hostdsk
+.if HOSTRW_DEBUG
+ push temp
+ subi temp,-('A')
+ rcall uartputc
+ rcall printstr
+ .db ": ",0,0
+ pop temp
+.endif
- push adrl
- push adrh
- ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
- lsr adrh
- ror adrl
- lsr adrh
- ror adrl
- ;Read 512-byte sector
- rcall mmcReadSect
- pop adrh
- pop adrl
-
- push adrl
- push adrh
-
-;Copy the data from the Z80 DMA buffer in external memory to the right place in the
-;sector buffer.
- ;Now, move the correct portion of the sector from AVR ram to Z80 ram
- ldi zl,low(sectbuff)
- ldi zh,high(sectbuff)
- ldi temp,128
- ldi temp2,0
- sbrc adrl,0
- add zl,temp
- sbrc adrl,0
- adc zh,temp2
- sbrc adrl,1
- inc zh
- lds adrh,dsk_dmah
- lds adrl,dsk_dmal
- ldi temp2,128
-dskDoItWriteMemLoop:
- push temp2
+ lsl temp
+ lsl temp
+ lsl temp
+ add zl,temp
+ adc zh,_0
- push zh
- push zl
- rcall memReadByte
- pop zl
- pop zh
- st z+,temp
- adiw adrl,1
+ lds temp,hostlba
+ lds temp2,hostlba+1
+ lds temp3,hostlba+2
- pop temp2
- dec temp2
- brne dskDoItWriteMemLoop
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db "lba: ",0
+ clr temp4
+ rcall print_ultoa
+.endif
+
+ ldd xl,z+4
+ ldd xh,z+5
+ ldd yl,z+6
+
+ cp temp,xl
+ cpc temp2,xh
+ cpc temp3,yl
+ brcs dsk_hp1
+
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db ", max: ",0
+ push temp4
+ push temp3
+ push temp2
+ push temp
+ movw temp,x
+ mov temp3,yl
+ clr temp4
+ rcall print_ultoa
+ pop temp
+ pop temp2
+ pop temp3
+ pop temp4
+ rcall printstr
+ .db " ",0
+.endif
+
+ clr temp
+ ret
+
+dsk_hp1:
+ ldd xl,z+0
+ ldd xh,z+1
+ ldd yl,z+2
+ ldd yh,z+3
+
+ add xl,temp
+ adc xh,temp2
+ adc zl,temp3
+ adc zh,_0
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db ", abs:",0,0
+ push temp4
+ push temp3
+ push temp2
+ push temp
+ movw temp,x
+ movw temp3,y
+ rcall print_ultoa
+ pop temp
+ pop temp2
+ pop temp3
+ pop temp4
+ rcall printstr
+ .db " ",0
+.endif
+ ori temp,255
+dsk_hpex:
+ ret
- pop adrh
- pop adrl
+;*****************************************************
+;* WRITEhost performs the physical write to *
+;* the host disk, READhost reads the physical *
+;* disk. *
+;*****************************************************
- ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
- lsr adrh
- ror adrl
- lsr adrh
- ror adrl
- ;Write the sector back.
- rcall mmcWriteSect
+dsk_writehost:
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db 13,"host write ",0,0
+.endif
+ rcall dsk_hostparam
+ brne dsk_wr1
+ ldi temp,255
+ sts erflag,temp
+ ret
+
+dsk_wr1:
+ rcall mmcWriteSect
+ sts erflag,_0
+ ret
- ;All done :)
+dsk_readhost:
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db 13,"host read ",0,0
+.endif
+ rcall dsk_hostparam
+ brne dsk_rd1
+ ldi temp,255
+ sts erflag,temp
ret
+dsk_rd1:
+ rcall mmcReadSect
+ sts erflag,_0
+ ret
+
+
+;***************************************************************************
; ----------------- MMC/SD routines ------------------
mmcByte:
.if MMC_DEBUG
- push zl
- push zh
rcall printstr
.db "MMC: <--",0
rcall printhex
in temp,SPDR
.if MMC_DEBUG
- push temp
rcall printstr
.db ", -->",0
rcall printhex
rcall printstr
.db ".",13,0
- pop temp
- pop zh
- pop zl
.endif
ret
ret
-;Call this with adrh:adrl = sector number
-;16bit lba address means a max reach of 32M.
+;Call this with yh:yl:xh:xl = sector number
+;
mmcReadSect:
ldi temp,0x50
out SPCR,temp
rcall mmcByteNoSend
ldi temp,0x51 ;cmd (read sector)
rcall mmcByte
- ldi temp,0
- lsl adrl
- rol adrh
- rol temp
+ lsl xl ;convert to byte address (*512)
+ rol xh
+ rol yl
+ mov temp,yl
rcall mmcByte
- mov temp,adrh ;pxl
+ mov temp,xh ;pxl
rcall mmcByte
- mov temp,adrl ;pyh
+ mov temp,xl ;pyh
rcall mmcByte
ldi temp,0 ;pyl
rcall mmcByte
rcall mmcWaitResp
;Read sector to AVR RAM
- ldi zl,low(sectbuff)
- ldi zh,high(sectbuff)
+ ldi zl,low(hostbuf)
+ ldi zh,high(hostbuf)
mmcreadloop:
rcall mmcByteNoSend
st z+,temp
- cpi zl,low(sectbuff+512)
+ cpi zl,low(hostbuf+512)
brne mmcreadloop
- cpi zh,high(sectbuff+512)
+ cpi zh,high(hostbuf+512)
brne mmcreadloop
;CRC
ret
-;Call this with adrh:adrl = sector number
-;16bit lba address means a max reach of 32M.
+;Call this with yh:yl:xh:xl = sector number
+;
mmcWriteSect:
ldi temp,0x50
out SPCR,temp
ldi temp,0x58 ;cmd (write sector)
rcall mmcByte
- ldi temp,0
- lsl adrl
- rol adrh
- rol temp
+ lsl xl ;convert to byte address (*512)
+ rol xh
+ rol yl
+ mov temp,yl
rcall mmcByte
- mov temp,adrh ;pxl
+ mov temp,xh ;pxl
rcall mmcByte
- mov temp,adrl ;pyh
+ mov temp,xl ;pyh
rcall mmcByte
ldi temp,0 ;pyl
rcall mmcByte
rcall mmcByte
;Write sector from AVR RAM
- ldi zl,low(sectbuff)
- ldi zh,high(sectbuff)
+ ldi zl,low(hostbuf)
+ ldi zh,high(hostbuf)
mmcwriteloop:
ld temp,z+
rcall mmcByte
- cpi zl,low(sectbuff+512)
+ cpi zl,low(hostbuf+512)
brne mmcwriteloop
- cpi zh,high(sectbuff+512)
+ cpi zh,high(hostbuf+512)
brne mmcwriteloop
;CRC
rcall mmcByteNoSend
- rcall mmcByteNoSend
-
- ;Status. Ignored for now.
- rcall mmcByteNoSend
-
-;Wait till the mmc has written everything
-mmcwaitwritten:
- rcall mmcByteNoSend
- cpi temp,0xff
- brne mmcwaitwritten
-
- sbi P_MMC_CS,mmc_cs
- rcall mmcByteNoSend
-
- out SPCR,_0
- ret
-
-
-;Set up wdt to time out after 1 sec.
-resetAVR:
- cli
-#if defined __ATmega8__
- ldi temp,(1<<WDCE)
- out WDTCSR,temp
- ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
- out WDTCSR,temp
-#else
- ldi temp,(1<<WDCE)
- sts WDTCSR,temp
- ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
- sts WDTCSR,temp
-#endif
-resetwait:
- rjmp resetwait
-
-
-; ------------------ DRAM routines -------------
-
-; TODO:
-
-#if DRAM_DQ_ORDER == 1
- #define CLASSIC_DRAM 0
-#else
- #define CLASSIC_DRAM 1 /* Change manualy, if you want new hw w/ old sw */
-#endif
-
-
-#if DRAM_DQ_ORDER == 0
- #if CLASSIC_DRAM == 1
- #error "Old harware can not work with new software!"
- #endif
-#endif
-
-; ****************************************************************************
-
-#if CLASSIC_DRAM
-
-; ********************** DRAM routines from Sprite_tm ************************
-
-;Sends the address in zh:zl to the ram
-dram_setaddr:
- push temp
- in temp,portd
- andi temp,0x17
- out portd,temp
- in temp,portb
- andi temp,0xE0
- out portb,temp
- sbrc zl,0
- sbi portb,ram_a0
- sbrc zl,1
- sbi portb,ram_a1
- sbrc zl,2
- sbi portb,ram_a2
- sbrc zl,3
- sbi portb,ram_a3
- sbrc zl,4
- sbi portb,ram_a4
- sbrc zl,5
- sbi portd,ram_a5
- sbrc zl,6
- sbi portd,ram_a6
- sbrc zl,7
- sbi portd,ram_a7
- sbrc zh,0
- sbi portd,ram_a8
- pop temp
- ret
-
-dram_getnibble:
- andi temp,0xf0
- sbic pinc,ram_d0
- ori temp,0x1
- sbic pinc,ram_d1
- ori temp,0x2
- sbic pinc,ram_d2
- ori temp,0x4
- sbic pinc,ram_d3
- ori temp,0x8
- ret
-
-dram_sendnibble:
- push temp2
- in temp2,portc
- andi temp2,~RAM_DQ_MASK
-
- sbrc temp,0
- ori temp2,(1<<ram_d0)
- sbrc temp,1
- ori temp2,(1<<ram_d1)
- sbrc temp,2
- ori temp2,(1<<ram_d2)
- sbrc temp,3
- ori temp2,(1<<ram_d3)
-
- out portc,temp2
- pop temp2
- ret
-
-
-;Loads the byte on address adrh:adrl into temp.
-dram_read:
- cli
- 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
- nop
- cbi portc,ram_cas
- nop
- nop
- cbi portd,ram_oe
- nop
- rcall dram_getnibble
- sbi portd,ram_oe
- swap temp
- sbi portc,ram_cas
-
- ldi zh,0
- mov zl,adrl
- ori zl,0x80
- rcall dram_setaddr
- nop
- cbi portc,ram_cas
- nop
- cbi portd,ram_oe
- nop
- nop
- rcall dram_getnibble
-
- sbi portd,ram_oe
- sbi portc,ram_cas
- sbi portb,ram_ras
- sei
- ret
-
-;Writes the byte in temp to adrh:adrl
-dram_write:
- cli
-
- in temp2,ddrc
- ori temp2,RAM_DQ_MASK
- out ddrc,temp2
-
- rcall dram_sendnibble
+ rcall mmcByteNoSend
- mov zl,adrh
- ldi zh,0
- mov temp2,adrl
- lsl temp2
- rol zl
- rol zh
- ;z=addr[15-7]
- rcall dram_setaddr
- nop
- nop
- cbi portb,ram_ras
+ ;Status. Ignored for now.
+ rcall mmcByteNoSend
- ldi zh,0
- mov zl,adrl
- ori zl,0x80
- rcall dram_setaddr
- nop
- nop
- cbi portc,ram_cas
- nop
- nop
- cbi portc,ram_w
- nop
- nop
- nop
- sbi portc,ram_w
- sbi portc,ram_cas
+;Wait till the mmc has written everything
+mmcwaitwritten:
+ rcall mmcByteNoSend
+ cpi temp,0xff
+ brne mmcwaitwritten
+ sbi P_MMC_CS,mmc_cs
+ rcall mmcByteNoSend
- ldi zh,0
- mov zl,adrl
- andi zl,0x7F
- rcall dram_setaddr
- swap temp
- rcall dram_sendnibble
- cbi portc,ram_cas
- nop
- nop
- cbi portc,ram_w
- nop
- nop
- sbi portc,ram_w
- nop
- nop
- sbi portc,ram_cas
- sbi portb,ram_ras
-
- in temp,ddrc
- andi temp,~RAM_DQ_MASK
- out ddrc,temp
- in temp,portc
- andi temp,~RAM_DQ_MASK
- out portc,temp
- sei
+ out SPCR,_0
ret
-#endif /* CLASSIC_DRAM == 1 */
-; ****************************************************************************
-#if ! CLASSIC_DRAM
+;Set up wdt to time out after 1 sec.
+resetAVR:
+ cli
+ ldi temp,(1<<WDCE)
+ outm8 WDTCSR,temp
+ ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
+ outm8 WDTCSR,temp
+resetwait:
+ rjmp resetwait
-; ***************************** New DRAM routines ****************************
+; ------------------ DRAM routines -------------
-;todo: see below
+; DRAM_SETADDR val, low_and_mask, low_or_mask, high_and_mask, high_or_mask
.macro DRAM_SETADDR
-#if 1
- in temp,P_AL
- andi temp,~RAM_AL_MASK
- sbrc @0,0
- ori temp,(1<<ram_a0)
- sbrc @0,1
- ori temp,(1<<ram_a1)
- sbrc @0,2
- ori temp,(1<<ram_a2)
- sbrc @0,3
- ori temp,(1<<ram_a3)
- sbrc @0,4
- ori temp,(1<<ram_a4)
+ mov temp,@0
+.if low(@1) != 0xff
+ andi temp,@1
+.endif
+.if low(@2) != 0
+ ori temp, @2
+.endif
out P_AL,temp
-#else
- out PORTB,@0
-#endif
-
- in temp,P_AH
- andi temp,~RAM_AH_MASK
- sbrc @0,5
- ori temp,(1<<ram_a5)
- sbrc @0,6
- ori temp,(1<<ram_a6)
- sbrc @0,7
- ori temp,(1<<ram_a7)
+
+ mov temp,@0
+.if low(@3) != 0xff
+ andi temp,@3
+.endif
+ ori temp, @4 | (1<<mmc_cs)
out P_AH,temp
.endm
- ret
-
-;Loads the byte on address adrh:adrl into temp.
-;must not alter adrh:adrl
+;Loads the byte on address xh:xl into temp.
+;must not alter xh:xl
dram_read:
cli
- cbi P_A8,ram_a8
- DRAM_SETADDR adrh
+ DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8), (1<<ram_oe)
cbi P_RAS,ram_ras
-
- DRAM_SETADDR adrl
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
cbi P_CAS,ram_cas
- cbi P_OE,ram_oe
- nop
- nop
+ cbi P_A8,ram_a8
+ dram_wait DRAM_WAITSTATES ;
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
+ dram_wait DRAM_WAITSTATES ;
in temp2,P_DQ-2 ; PIN
andi temp2,0x0f
or temp,temp2
- swap temp
sbi P_OE,ram_oe
sbi P_CAS,ram_cas
sei
ret
+#if DRAM_WORD_ACCESS
+dram_read_w:
+ cpi xl,255
+ brne dram_read_w1
+
+ rcall dram_read
+ push temp
+ adiw xl,1
+ rcall dram_read
+ mov temp2,temp
+ pop temp
+ ret
+
+dram_read_w1:
+ cli
+ DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
+ cbi P_RAS,ram_ras
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+ cbi P_CAS,ram_cas
+ cbi P_A8,ram_a8
+ nop
+ in temp,P_DQ-2 ; PIN
+ sbi P_CAS,ram_cas
+ cbi P_CAS,ram_cas
+ andi temp,0x0f
+ swap temp
+ nop
+ in temp2,P_DQ-2 ; PIN
+ sbi P_CAS,ram_cas
+ andi temp2,0x0f
+ or temp,temp2
+
+; push temp
+ mov _wl,temp
+ inc xl
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+ cbi P_CAS,ram_cas
+ cbi P_A8,ram_a8
+ nop
+ in temp,P_DQ-2 ; PIN
+ sbi P_CAS,ram_cas
+ cbi P_CAS,ram_cas
+ andi temp,0x0f
+ swap temp
+ nop
+ in temp2,P_DQ-2 ; PIN
+ sbi P_CAS,ram_cas
+ andi temp2,0x0f
+ or temp2,temp
+; pop temp
+ mov temp,_wl
+
+ sbi P_OE,ram_oe
+ sbi P_RAS,ram_ras
+ sei
+ ret
+#endif
-;Writes the byte in temp to adrh:adrl
-;must not alter adrh:adrl
+;Writes the byte in temp to xh:xl
+;must not alter xh:xl
dram_write:
cli
andi temp,RAM_DQ_MASK & ~(1<<ram_w)
ori temp,(1<<ram_cas)
out PORTC,temp
-
- cbi PORTD,ram_a8
- DRAM_SETADDR adrh
+ DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
cbi P_RAS,ram_ras
- DRAM_SETADDR adrl
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
cbi PORTC,ram_cas
sbi PORTC,ram_cas
sei
ret
-#endif /* CLASSIC_DRAM == 0 */
+#if DRAM_WORD_ACCESS
+dram_write_w:
+ cpi xl,255
+ brne dram_write_w1
+
+ push temp2
+ rcall dram_write
+ pop temp
+ adiw xl,1
+ rcall dram_write
+ ret
+
+dram_write_w1:
+ cli
+ push temp2
+ ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
+ out DDRC,temp2
+
+ mov temp2,temp
+ andi temp,RAM_DQ_MASK & ~(1<<ram_w)
+ ori temp,(1<<ram_cas)
+ out PORTC,temp
+
+ DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
+ cbi P_RAS,ram_ras
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+ cbi PORTC,ram_cas
+ sbi PORTC,ram_cas
+
+ sbi PORTD,ram_a8
+ swap temp2
+
+ andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
+ ori temp2,(1<<ram_cas)
+ out PORTC,temp2
+
+ cbi PORTC,ram_cas
+ sbi PORTC,ram_cas
+
+ pop temp
+ inc xl
+ mov temp2,temp
+ andi temp,RAM_DQ_MASK & ~(1<<ram_w)
+ ori temp,(1<<ram_cas)
+ out PORTC,temp
+
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+ cbi PORTC,ram_cas
+ sbi PORTC,ram_cas
+
+ sbi PORTD,ram_a8
+ swap temp2
+
+ andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
+ ori temp2,(1<<ram_cas)
+ out PORTC,temp2
+ cbi PORTC,ram_cas
+
+ sbi P_RAS,ram_ras
+
+ ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
+ out DDRC,temp
+ out PORTC,temp
+ sei
+ ret
+#endif
; ****************************************************************************
; refresh interupt; exec 2 cbr cycles
-refrint:
- ;4 CAS RAS
+refrint: ;4
+
+ sbis P_RAS,ram_ras ;2
+ reti
+ ; CAS RAS
cbi P_CAS,ram_cas ;2 1| 1|
; 1| 1|
cbi P_RAS,ram_ras ;2 |0 1|
; nop ;1 |0 |0
sbi P_RAS,ram_ras ;2 |0 |0
; |0 |0
+ dram_wait DRAM_WAITSTATES-1 ;
; nop ;1 |0 |0
cbi P_RAS,ram_ras ;2 |0 1|
; |0 1|
; 1| 1|
reti ;4 --> 21 cycles
-; ****************************************************************************
-; ------------- system timer 10ms ---------------
+; ------------- system timer 1ms ---------------
.dseg
delay_timer:
;
timer_print:
- push adrh
- push adrl
- push oph
- push opl
+ push yh
+ push yl
ldi zl,low(timer_ms)
ldi zh,high(timer_ms)
; put ms on stack (16 bit)
cli
- ldd adrl,z+timerofs
+ ldd yl,z+timerofs
ld temp2,z+
- sub adrl,temp2
- ldd adrh,z+timerofs
+ sub yl,temp2
+ ldd yh,z+timerofs
ld temp2,z+
- sbc adrh,temp2
+ sbc yh,temp2
brsh tp_s
- subi adrl,low(-1000)
- sbci adrh,high(-1000)
+ subi yl,low(-1000)
+ sbci yh,high(-1000)
sec
tp_s:
- push adrh
- push adrl
+ push yh
+ push yl
-;
-
ldd temp,z+timerofs
- ld adrl,z+
- sbc temp,adrl
+ ld yl,z+
+ sbc temp,yl
ldd temp2,z+timerofs
- ld adrh,z+
- sbc temp2,adrh
+ ld yh,z+
+ sbc temp2,yh
- ldd opl,z+timerofs
- ld adrl,z+
- sbc opl,adrl
+ ldd temp3,z+timerofs
+ ld yl,z+
+ sbc temp3,yl
sei
- ldd oph,z+timerofs
- ld adrh,z+
- sbc oph,adrh
+ ldd temp4,z+timerofs
+ ld yh,z+
+ sbc temp4,yh
rcall printstr
.db 13,"Timer running. Elapsed: ",0
rcall print_ultoa
rcall printstr
- .db ",",0
- ldi opl,0
- ldi oph,0
+ .db ".",0
pop temp
pop temp2
+ ldi temp3,0
+ ldi temp4,0
rcall print_ultoa
rcall printstr
.db "s.",0,0
- pop opl
- pop oph
- pop adrl
- pop adrh
+ pop yl
+ pop yh
ret
uptime_print:
- push oph
- push opl
ldi zl,low(cnt_1ms)
ldi zh,high(cnt_1ms)
ld temp,z+
ld temp2,z+
- ld opl,z+
+ ld temp3,z+
sei
- ld oph,z+
+ ld temp4,z+
rcall printstr
.db 13,"Uptime: ",0
rcall printstr
.db ",",0
- ldi opl,0
- ldi oph,0
+ ldi temp3,0
+ ldi temp4,0
pop temp2
pop temp
rcall print_ultoa
rcall printstr
.db "s.",0,0
- pop opl
- pop oph
ret
; --------------- Debugging stuff ---------------
;Print a unsigned lonng value to the uart
-; oph:opl:temp2:temp = value
+; temp4:temp3:temp2:temp = value
print_ultoa:
- push adrh
- push adrl
- push insdech
+ push yh
+ push yl
+ push z_flags
+ push temp4
+ push temp3
+ push temp2
+ push temp
- clr adrl ;adrl = stack level
+ clr yl ;yl = stack level
-ultoa1: ldi insdech, 32 ;adrh = oph:temp % 10
- clr adrh ;oph:temp /= 10
+ultoa1: ldi z_flags, 32 ;yh = temp4:temp % 10
+ clr yh ;temp4:temp /= 10
ultoa2: lsl temp
rol temp2
- rol opl
- rol oph
- rol adrh
- cpi adrh,10
+ rol temp3
+ rol temp4
+ rol yh
+ cpi yh,10
brcs ultoa3
- subi adrh,10
+ subi yh,10
inc temp
-ultoa3: dec insdech
+ultoa3: dec z_flags
brne ultoa2
- cpi adrh, 10 ;adrh is a numeral digit '0'-'9'
- subi adrh, -'0'
- push adrh ;Stack it
- inc adrl
- cp temp,_0 ;Repeat until oph:temp gets zero
+ cpi yh, 10 ;yh is a numeral digit '0'-'9'
+ subi yh, -'0'
+ push yh ;Stack it
+ inc yl
+ cp temp,_0 ;Repeat until temp4:temp gets zero
cpc temp2,_0
- cpc opl,_0
- cpc oph,_0
+ cpc temp3,_0
+ cpc temp4,_0
brne ultoa1
ldi temp, '0'
-ultoa5: cpi adrl,3 ; at least 3 digits (ms)
+ultoa5: cpi yl,3 ; at least 3 digits (ms)
brge ultoa6
push temp
- inc adrl
+ inc yl
rjmp ultoa5
ultoa6: pop temp ;Flush stacked digits
rcall uartputc
- dec adrl
+ dec yl
brne ultoa6
- pop insdech
- pop adrl
- pop adrh
+ pop temp
+ pop temp2
+ pop temp3
+ pop temp4
+ pop z_flags
+ pop yl
+ pop yh
ret
rcall printhexn
ret
-;Prints the zero-terminated string following the call statement. WARNING: Destroys temp.
+;Prints the zero-terminated string following the call statement.
+
printstr:
- pop zh
- pop zl
- push temp
+ push zh
+ push zl
+ push yh
+ push yl
+ push temp
+ in yh,sph
+ in yl,spl
+ ldd zl,y+7
+ ldd zh,y+6
lsl zl
rol zh
-
printstr_loop:
lpm temp,z+
cpi temp,0
lsr zh
ror zl
- pop temp
- push zl
- push zh
+ std y+7,zl
+ std y+6,zh
+ pop temp
+ pop yl
+ pop yh
+ pop zl
+ pop zh
ret
-
; --------------- AVR HW <-> Z80 periph stuff ------------------
.equ memReadByte = dram_read
.dseg
#define RXBUFMASK RXBUFSIZE-1
+#define TXBUFMASK TXBUFSIZE-1
rxcount:
.byte 1
.byte 1
rxidx_r:
.byte 1
+txcount:
+ .byte 1
+txidx_w:
+ .byte 1
+txidx_r:
+ .byte 1
rxfifo:
.byte RXBUFSIZE
- .byte 0
+txfifo:
+ .byte TXBUFSIZE
+ramtop:
.cseg
; Save received character in a circular buffer. Do nothing if buffer overflows.
push temp
push zh
push zl
-#ifdef __ATmega8__
- in temp,UDR
-#else
- lds temp,UDR0
-#endif
+ inm8 temp,RXTXDR0
lds zh,rxcount ;if rxcount < RXBUFSIZE
cpi zh,RXBUFSIZE ; (room for at least 1 char?)
brsh rxi_ov ;
uartgetc:
lds temp,rxcount ; Number of characters in buffer
tst temp
- breq uartgetc
+ breq uartgetc ;Wait for char
push zh
push zl
pop zh
ret
+txint:
+ push temp
+ in temp,sreg
+ push temp
+ lds temp,txcount ;if txcount != 0
+ tst temp ;
+ breq txi_e ;
+
+ dec temp ;
+ sts txcount,temp ; --txcount
+ push zh ;
+ push zl ;
+ ldi zl,low(txfifo) ;
+ ldi zh,high(txfifo) ;
+ lds temp,txidx_r ;
+ add zl,temp ;
+ brcc PC+2 ;
+ inc zh ;
+ inc temp ;
+ andi temp,TXBUFMASK ;
+ sts txidx_r,temp ;
+ ld temp,z
+ outm8 RXTXDR0,temp
+ pop zl
+ pop zh
+txi_e: ;endif
+ lds temp,txcount
+ tst temp
+ brne txi_x
+ ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
+ outm8 UCSR0B,temp
+txi_x:
+ pop temp
+ out sreg,temp
+ pop temp
+ reti
;Sends a char from temp to the uart.
uartputc:
-#if defined __ATmega8__
-uartputc_l:
- sbis UCSRA,UDRE
- rjmp uartputc_l
- out UDR,temp
-#else
- push temp
-uartputc_l:
- lds temp,UCSR0A
- sbrs temp,UDRE0
- rjmp uartputc_l
- pop temp
- sts UDR0,temp
-#endif
+ push zh
+ push zl
+ push temp
+putc_l:
+ lds temp,txcount ;do {
+ cpi temp,TXBUFSIZE ;
+ brsh putc_l ;} while (txcount >= TXBUFSIZE)
+
+ ldi zl,low(txfifo) ;
+ ldi zh,high(txfifo) ;
+ lds temp,txidx_w ;
+ add zl,temp ;
+ brcc PC+2 ;
+ inc zh ;
+ inc temp ;
+ andi temp,TXBUFMASK ;
+ sts txidx_w,temp ; txidx_w = ++txidx_w % TXBUFSIZE
+ pop temp ;
+ st z,temp ; txfifo[txidx_w] = char
+ cli
+ lds zl,txcount
+ inc zl
+ sts txcount,zl
+ ldi zl, (1<<UDRIE0) | (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
+ outm8 UCSR0B,zl
+ sei
+ pop zl
+ pop zh
ret
; ------------ Fetch phase stuff -----------------
ret
do_fetch_bc:
- mov opl,z_c
- mov oph,z_b
+ movw opl,z_c
ret
do_fetch_de:
- mov opl,z_e
- mov oph,z_d
+ movw opl,z_e
ret
do_fetch_hl:
- mov opl,z_l
- mov oph,z_h
+ movw opl,z_l
ret
do_fetch_sp:
ret
do_fetch_mbc:
- mov adrh,z_b
- mov adrl,z_c
+ movw xl,z_c
rcall memReadByte
mov opl,temp
ret
do_fetch_mde:
- mov adrh,z_d
- mov adrl,z_e
+ movw xl,z_e
rcall memReadByte
mov opl,temp
ret
do_fetch_mhl:
- mov adrh,z_h
- mov adrl,z_l
+ movw xl,z_l
rcall memReadByte
mov opl,temp
ret
do_fetch_msp:
- movw adrl,z_spl
+ movw xl,z_spl
#if DRAM_WORD_ACCESS
rcall memReadWord
movw opl,temp
#else
rcall memReadByte
mov opl,temp
-
- adiw adrl,1
+ adiw xl,1
rcall memReadByte
mov oph,temp
#endif
ret
do_fetch_dir8:
- movw adrl,z_pcl
+ movw xl,z_pcl
rcall memReadByte
adiw z_pcl,1
mov opl,temp
ret
do_fetch_dir16:
- movw adrl,z_pcl
+ movw xl,z_pcl
#if DRAM_WORD_ACCESS
rcall memReadWord
movw opl,temp
#else
rcall memReadByte
mov opl,temp
- adiw adrl,1
+ adiw xl,1
rcall memReadByte
mov oph,temp
#endif
ret
do_fetch_rst:
- movw adrl,z_pcl
- subi adrl,1
- sbci adrh,0
+ movw xl,z_pcl
+ subi xl,1
+ sbci xh,0
rcall memReadByte
andi temp,0x38
ldi oph,0
ret
do_store_mbc:
- mov adrh,z_b
- mov adrl,z_c
+ movw xl,z_c
mov temp,opl
rcall memWriteByte
ret
do_store_mde:
- mov adrh,z_d
- mov adrl,z_e
+ movw xl,z_e
mov temp,opl
rcall memWriteByte
ret
do_store_mhl:
- mov adrh,z_h
- mov adrl,z_l
+ movw xl,z_l
mov temp,opl
rcall memWriteByte
ret
do_store_msp:
- movw adrl,z_spl
+ movw xl,z_spl
#if DRAM_WORD_ACCESS
movw temp,opl
rcall memWriteWord
#else
mov temp,opl
rcall memWriteByte
- adiw adrl,1
+ adiw xl,1
mov temp,oph
rcall memWriteByte
#endif
ret
do_store_am:
- movw adrl,opl
+ movw xl,opl
mov temp,z_a
rcall memWriteByte
ret
.equ OP_DI = (37<<10)
.equ OP_EI = (38<<10)
.equ OP_INV = (39<<10)
+.equ OP_CPFA = (40<<10)
+.equ OP_INCA = (41<<10)
+.equ OP_DECA = (42<<10)
opjumps:
rjmp do_op_nop
rjmp do_op_di
rjmp do_op_ei
rjmp do_op_inv
+ rjmp do_op_cpfa
+ rjmp do_op_inca
+ rjmp do_op_deca
;How the flags are supposed to work:
;----------------------------------------------------------------
-.equ AVR_T = 6
-.equ AVR_H = 5
-.equ AVR_S = 4
-.equ AVR_V = 3
-.equ AVR_N = 2
-.equ AVR_Z = 1
-.equ AVR_C = 0
+.equ AVR_T = SREG_T
+.equ AVR_H = SREG_H
+.equ AVR_S = SREG_S
+.equ AVR_V = SREG_V
+.equ AVR_N = SREG_N
+.equ AVR_Z = SREG_Z
+.equ AVR_C = SREG_C
;------------------------------------------------;
; Move single bit between two registers
mov zl,@2
lpm @0,z
.endm
-
.macro do_z80_flags_HP
#if EM_Z80
bmov z_flags, ZFL_P, temp, AVR_V
;
;
do_op_inc:
- ldi temp,1
- add opl,temp
+ inc opl
+#if EM_Z80
in temp, sreg
+#endif
andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
ldpmx temp2, sz53p_tab, opl
or z_flags,temp2 ;
do_z80_flags_HP
ret
+do_op_inca:
+ inc z_a
+#if EM_Z80
+ in temp, sreg
+#endif
+ andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
+ ldpmx temp2, sz53p_tab, z_a
+ or z_flags,temp2 ;
+ do_z80_flags_HP
+ ret
+
;----------------------------------------------------------------
;|Mnemonic |SZHPNC|Description |Notes |
;----------------------------------------------------------------
;
;
do_op_dec:
- subi opl,1
+ dec opl
+#if EM_Z80
in temp, sreg
+#endif
andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
ldpmx temp2, sz53p_tab, opl
or z_flags,temp2 ;
do_z80_flags_set_N
ret
+do_op_deca:
+ dec z_a
+#if EM_Z80
+ in temp, sreg
+#endif
+ andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
+ ldpmx temp2, sz53p_tab, z_a
+ or z_flags,temp2 ;
+ do_z80_flags_HP
+ do_z80_flags_set_N
+ ret
;----------------------------------------------------------------
;|Mnemonic |SZHPNC|Description |Notes |
;
;
do_op_inc16:
- adiw opl,1
+ subi opl,low(-1)
+ sbci oph,high(-1)
ret
;----------------------------------------------------------------
;
;
do_op_adda:
- add opl,z_a
+ add z_a,opl
in temp,sreg
- ldpmx z_flags,sz53p_tab,opl ;S,Z,P flag
+ ldpmx z_flags,sz53p_tab,z_a ;S,Z,P flag
bmov z_flags,ZFL_C, temp,AVR_C
do_z80_flags_HP
ret
clc
sbrc z_flags,ZFL_C
sec
- adc opl,z_a
+ adc z_a,opl
in temp,sreg
- ldpmx z_flags,sz53p_tab,opl ;S,Z,P
+ ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
bmov z_flags,ZFL_C, temp,AVR_C
do_z80_flags_HP
ret
;|Mnemonic |SZHPNC|Description |Notes |
;----------------------------------------------------------------
;|SUB s |***V1*|Subtract |A=A-s |
-;|CP s |***V1*|Compare |A-s |
;|----------|SZHP C|---------- 8080 ----------------------------|
;|SUB s |***P *|Subtract |A=A-s |
-;|CP s |***P *|Compare |A-s |
;
do_op_subfa:
+ sub z_a,opl
+ in temp,sreg
+ ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
+ bmov z_flags,ZFL_C, temp,AVR_C
+ do_z80_flags_HP
+ do_z80_flags_set_N
+ ret
+
+;----------------------------------------------------------------
+;|Mnemonic |SZHPNC|Description |Notes |
+;----------------------------------------------------------------
+;|CP s |***V1*|Compare |A-s |
+;|----------|SZHP C|---------- 8080 ----------------------------|
+;|CP s |***P *|Compare |A-s |
+
+;
+do_op_cpfa:
mov temp,z_a
sub temp,opl
mov opl,temp
;
;
do_op_sbcfa:
- mov temp,z_a
clc
sbrc z_flags,ZFL_C
sec
- sbc temp,opl
- mov opl,temp
+ sbc z_a,opl
in temp,sreg
- ldpmx z_flags,sz53p_tab,opl ;S,Z,P
+ ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
bmov z_flags,ZFL_C, temp,AVR_C
do_z80_flags_HP
do_z80_flags_set_N
;
; TODO H-Flag
do_op_anda:
- and opl,z_a ;
- ldpmx z_flags,sz53p_tab,opl ;S,Z,P,N,C
+ and z_a,opl ;
+ ldpmx z_flags,sz53p_tab,z_a ;S,Z,P,N,C
do_z80_flags_op_and
ret
;
; TODO: H-Flag
do_op_ora:
- or opl,z_a
- ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
+ or z_a,opl
+ ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
do_z80_flags_op_or
ret
;
; TODO: H-Flag
do_op_xora:
- eor opl,z_a
- ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
+ eor z_a,opl
+ ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
do_z80_flags_op_or
ret
;
;
do_op_sthl: ;store hl to mem loc in opl:h
- movw adrl,opl
+ movw xl,opl
#if DRAM_WORD_ACCESS
- mov temp,z_l
- mov temp2,z_h
+ movw temp,z_l
rcall memWriteWord
#else
mov temp,z_l
rcall memWriteByte
- adiw adrl,1
+ adiw xl,1
mov temp,z_h
rcall memWriteByte
#endif
;
;
do_op_rmem16:
- movw adrl,opl
+ movw xl,opl
#if DRAM_WORD_ACCESS
rcall memReadWord
movw opl,temp
#else
rcall memReadByte
mov opl,temp
- adiw adrl,1
+ adiw xl,1
rcall memReadByte
mov oph,temp
#endif
;
;
do_op_rmem8:
- movw adrl,opl
+ movw xl,opl
rcall memReadByte
mov opl,temp
ret
;
;
do_op_cpl:
- com opl
+ com z_a
do_z80_flags_set_HN
ret
;
;
do_op_push16:
- movw adrl,z_spl
- subi adrl,2
- sbci adrh,0
- movw z_spl,adrl
+ movw xl,z_spl
+ subi xl,2
+ sbci xh,0
+ movw z_spl,xl
#if DRAM_WORD_ACCESS
movw temp,opl
rcall memWriteWord
#else
mov temp,opl
rcall memWriteByte
- adiw adrl,1
+ adiw xl,1
mov temp,oph
rcall memWriteByte
#endif
;
;
do_op_pop16:
- movw adrl,z_spl
+ movw xl,z_spl
#if DRAM_WORD_ACCESS
rcall memReadWord
movw opl,temp
#else
rcall memReadByte
mov opl,temp
- adiw adrl,1
+ adiw xl,1
rcall memReadByte
mov oph,temp
#endif
add z_spl,temp
adc z_sph,_0
+
.if STACK_DBG
rcall printstr
.db "Stack pop: val ",0
do_op_ifnz:
sbrs z_flags, ZFL_Z
ret
- ldi insdech, 0
- ldi insdecl, 0
+ clr insdech
+ clr insdecl
ret
;----------------------------------------------------------------
do_op_ifz:
sbrc z_flags, ZFL_Z
ret
- ldi insdech, 0
- ldi insdecl, 0
+ clr insdech
+ clr insdecl
ret
;----------------------------------------------------------------
do_op_ifnc:
sbrs z_flags, ZFL_C
ret
- ldi insdech, 0
- ldi insdecl, 0
+ clr insdech
+ clr insdecl
ret
;----------------------------------------------------------------
do_op_ifc:
sbrc z_flags, ZFL_C
ret
- ldi insdech, 0
- ldi insdecl, 0
+ clr insdech
+ clr insdecl
ret
;----------------------------------------------------------------
do_op_ifpo:
sbrs z_flags, ZFL_P
ret
- ldi insdech, 0
- ldi insdecl, 0
+ clr insdech
+ clr insdecl
ret
;----------------------------------------------------------------
do_op_ifpe:
sbrc z_flags, ZFL_P
ret
- ldi insdech, 0
- ldi insdecl, 0
+ clr insdech
+ clr insdecl
ret
;----------------------------------------------------------------
do_op_ifp: ;sign positive, aka s=0
sbrs z_flags, ZFL_S
ret
- ldi insdech,0
- ldi insdecl,0
+ clr insdech
+ clr insdecl
ret
;----------------------------------------------------------------
do_op_ifm: ;sign negative, aka s=1
sbrc z_flags, ZFL_S
ret
- ldi insdech, 0
- ldi insdecl, 0
+ clr insdech
+ clr insdecl
ret
;----------------------------------------------------------------
; The table is made of 256 words. These 16-bit words consist of
; 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_L | OP_INC | STORE_L ) ; 2C INC L
.dw (FETCH_L | OP_DEC | STORE_L ) ; 2D DEC L
.dw (FETCH_DIR8 | OP_NOP | STORE_L ) ; 2E nn LD L,n
-.dw (FETCH_A | OP_CPL | STORE_A ) ; 2F CPL
+.dw (FETCH_NOP | OP_CPL | STORE_NOP) ; 2F CPL
.dw (FETCH_NOP | OP_INV | STORE_NOP) ; 30 oo JR NC,o (Z80)
.dw (FETCH_DIR16| OP_NOP | STORE_SP ) ; 31 nn nn LD SP,nn
.dw (FETCH_DIR16| OP_NOP | STORE_AM ) ; 32 nn nn LD (nn),A
.dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
.dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
.dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
-.dw (FETCH_A | OP_INC | STORE_A ) ; 3C INC A
-.dw (FETCH_A | OP_DEC | STORE_A ) ; 3D DEC A
+.dw (FETCH_NOP | OP_INCA | STORE_NOP) ; 3C INC A
+.dw (FETCH_NOP | OP_DECA | STORE_NOP) ; 3D DEC A
.dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
.dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
.dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r
.dw (FETCH_L | OP_NOP | STORE_A ) ; 7D LD A,r
.dw (FETCH_MHL | OP_NOP | STORE_A ) ; 7E LD A,r
.dw (FETCH_A | OP_NOP | STORE_A ) ; 7F LD A,r
-.dw (FETCH_B | OP_ADDA | STORE_A ) ; 80 ADD A,r
-.dw (FETCH_C | OP_ADDA | STORE_A ) ; 81 ADD A,r
-.dw (FETCH_D | OP_ADDA | STORE_A ) ; 82 ADD A,r
-.dw (FETCH_E | OP_ADDA | STORE_A ) ; 83 ADD A,r
-.dw (FETCH_H | OP_ADDA | STORE_A ) ; 84 ADD A,r
-.dw (FETCH_L | OP_ADDA | STORE_A ) ; 85 ADD A,r
-.dw (FETCH_MHL | OP_ADDA | STORE_A ) ; 86 ADD A,r
-.dw (FETCH_A | OP_ADDA | STORE_A ) ; 87 ADD A,r
-.dw (FETCH_B | OP_ADCA | STORE_A ) ; 88 ADC A,r
-.dw (FETCH_C | OP_ADCA | STORE_A ) ; 89 ADC A,r
-.dw (FETCH_D | OP_ADCA | STORE_A ) ; 8A ADC A,r
-.dw (FETCH_E | OP_ADCA | STORE_A ) ; 8B ADC A,r
-.dw (FETCH_H | OP_ADCA | STORE_A ) ; 8C ADC A,r
-.dw (FETCH_L | OP_ADCA | STORE_A ) ; 8D ADC A,r
-.dw (FETCH_MHL | OP_ADCA | STORE_A ) ; 8E ADC A,r
-.dw (FETCH_A | OP_ADCA | STORE_A ) ; 8F ADC A,r
-.dw (FETCH_B | OP_SUBFA | STORE_A ) ; 90 SUB A,r
-.dw (FETCH_C | OP_SUBFA | STORE_A ) ; 91 SUB A,r
-.dw (FETCH_D | OP_SUBFA | STORE_A ) ; 92 SUB A,r
-.dw (FETCH_E | OP_SUBFA | STORE_A ) ; 93 SUB A,r
-.dw (FETCH_H | OP_SUBFA | STORE_A ) ; 94 SUB A,r
-.dw (FETCH_L | OP_SUBFA | STORE_A ) ; 95 SUB A,r
-.dw (FETCH_MHL | OP_SUBFA | STORE_A ) ; 96 SUB A,r
-.dw (FETCH_A | OP_SUBFA | STORE_A ) ; 97 SUB A,r
-.dw (FETCH_B | OP_SBCFA | STORE_A ) ; 98 SBC A,r
-.dw (FETCH_C | OP_SBCFA | STORE_A ) ; 99 SBC A,r
-.dw (FETCH_D | OP_SBCFA | STORE_A ) ; 9A SBC A,r
-.dw (FETCH_E | OP_SBCFA | STORE_A ) ; 9B SBC A,r
-.dw (FETCH_H | OP_SBCFA | STORE_A ) ; 9C SBC A,r
-.dw (FETCH_L | OP_SBCFA | STORE_A ) ; 9D SBC A,r
-.dw (FETCH_MHL | OP_SBCFA | STORE_A ) ; 9E SBC A,r
-.dw (FETCH_A | OP_SBCFA | STORE_A ) ; 9F SBC A,r
-.dw (FETCH_B | OP_ANDA | STORE_A ) ; A0 AND A,r
-.dw (FETCH_C | OP_ANDA | STORE_A ) ; A1 AND A,r
-.dw (FETCH_D | OP_ANDA | STORE_A ) ; A2 AND A,r
-.dw (FETCH_E | OP_ANDA | STORE_A ) ; A3 AND A,r
-.dw (FETCH_H | OP_ANDA | STORE_A ) ; A4 AND A,r
-.dw (FETCH_L | OP_ANDA | STORE_A ) ; A5 AND A,r
-.dw (FETCH_MHL | OP_ANDA | STORE_A ) ; A6 AND A,r
-.dw (FETCH_A | OP_ANDA | STORE_A ) ; A7 AND A,r
-.dw (FETCH_B | OP_XORA | STORE_A ) ; A8 XOR A,r
-.dw (FETCH_C | OP_XORA | STORE_A ) ; A9 XOR A,r
-.dw (FETCH_D | OP_XORA | STORE_A ) ; AA XOR A,r
-.dw (FETCH_E | OP_XORA | STORE_A ) ; AB XOR A,r
-.dw (FETCH_H | OP_XORA | STORE_A ) ; AC XOR A,r
-.dw (FETCH_L | OP_XORA | STORE_A ) ; AD XOR A,r
-.dw (FETCH_MHL | OP_XORA | STORE_A ) ; AE XOR A,r
-.dw (FETCH_A | OP_XORA | STORE_A ) ; AF XOR A,r
-.dw (FETCH_B | OP_ORA | STORE_A ) ; B0 OR A,r
-.dw (FETCH_C | OP_ORA | STORE_A ) ; B1 OR A,r
-.dw (FETCH_D | OP_ORA | STORE_A ) ; B2 OR A,r
-.dw (FETCH_E | OP_ORA | STORE_A ) ; B3 OR A,r
-.dw (FETCH_H | OP_ORA | STORE_A ) ; B4 OR A,r
-.dw (FETCH_L | OP_ORA | STORE_A ) ; B5 OR A,r
-.dw (FETCH_MHL | OP_ORA | STORE_A ) ; B6 OR A,r
-.dw (FETCH_A | OP_ORA | STORE_A ) ; B7 OR A,r
-.dw (FETCH_B | OP_SUBFA | STORE_NOP) ; B8 CP A,r
-.dw (FETCH_C | OP_SUBFA | STORE_NOP) ; B9 CP A,r
-.dw (FETCH_D | OP_SUBFA | STORE_NOP) ; BA CP A,r
-.dw (FETCH_E | OP_SUBFA | STORE_NOP) ; BB CP A,r
-.dw (FETCH_H | OP_SUBFA | STORE_NOP) ; BC CP A,r
-.dw (FETCH_L | OP_SUBFA | STORE_NOP) ; BD CP A,r
-.dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; BE CP A,r
-.dw (FETCH_A | OP_SUBFA | STORE_NOP) ; BF CP A,r
+.dw (FETCH_B | OP_ADDA | STORE_NOP) ; 80 ADD A,r
+.dw (FETCH_C | OP_ADDA | STORE_NOP) ; 81 ADD A,r
+.dw (FETCH_D | OP_ADDA | STORE_NOP) ; 82 ADD A,r
+.dw (FETCH_E | OP_ADDA | STORE_NOP) ; 83 ADD A,r
+.dw (FETCH_H | OP_ADDA | STORE_NOP) ; 84 ADD A,r
+.dw (FETCH_L | OP_ADDA | STORE_NOP) ; 85 ADD A,r
+.dw (FETCH_MHL | OP_ADDA | STORE_NOP) ; 86 ADD A,r
+.dw (FETCH_A | OP_ADDA | STORE_NOP) ; 87 ADD A,r
+.dw (FETCH_B | OP_ADCA | STORE_NOP) ; 88 ADC A,r
+.dw (FETCH_C | OP_ADCA | STORE_NOP) ; 89 ADC A,r
+.dw (FETCH_D | OP_ADCA | STORE_NOP) ; 8A ADC A,r
+.dw (FETCH_E | OP_ADCA | STORE_NOP) ; 8B ADC A,r
+.dw (FETCH_H | OP_ADCA | STORE_NOP) ; 8C ADC A,r
+.dw (FETCH_L | OP_ADCA | STORE_NOP) ; 8D ADC A,r
+.dw (FETCH_MHL | OP_ADCA | STORE_NOP) ; 8E ADC A,r
+.dw (FETCH_A | OP_ADCA | STORE_NOP) ; 8F ADC A,r
+.dw (FETCH_B | OP_SUBFA | STORE_NOP) ; 90 SUB A,r
+.dw (FETCH_C | OP_SUBFA | STORE_NOP) ; 91 SUB A,r
+.dw (FETCH_D | OP_SUBFA | STORE_NOP) ; 92 SUB A,r
+.dw (FETCH_E | OP_SUBFA | STORE_NOP) ; 93 SUB A,r
+.dw (FETCH_H | OP_SUBFA | STORE_NOP) ; 94 SUB A,r
+.dw (FETCH_L | OP_SUBFA | STORE_NOP) ; 95 SUB A,r
+.dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; 96 SUB A,r
+.dw (FETCH_A | OP_SUBFA | STORE_NOP) ; 97 SUB A,r
+.dw (FETCH_B | OP_SBCFA | STORE_NOP) ; 98 SBC A,r
+.dw (FETCH_C | OP_SBCFA | STORE_NOP) ; 99 SBC A,r
+.dw (FETCH_D | OP_SBCFA | STORE_NOP) ; 9A SBC A,r
+.dw (FETCH_E | OP_SBCFA | STORE_NOP) ; 9B SBC A,r
+.dw (FETCH_H | OP_SBCFA | STORE_NOP) ; 9C SBC A,r
+.dw (FETCH_L | OP_SBCFA | STORE_NOP) ; 9D SBC A,r
+.dw (FETCH_MHL | OP_SBCFA | STORE_NOP) ; 9E SBC A,r
+.dw (FETCH_A | OP_SBCFA | STORE_NOP) ; 9F SBC A,r
+.dw (FETCH_B | OP_ANDA | STORE_NOP) ; A0 AND A,r
+.dw (FETCH_C | OP_ANDA | STORE_NOP) ; A1 AND A,r
+.dw (FETCH_D | OP_ANDA | STORE_NOP) ; A2 AND A,r
+.dw (FETCH_E | OP_ANDA | STORE_NOP) ; A3 AND A,r
+.dw (FETCH_H | OP_ANDA | STORE_NOP) ; A4 AND A,r
+.dw (FETCH_L | OP_ANDA | STORE_NOP) ; A5 AND A,r
+.dw (FETCH_MHL | OP_ANDA | STORE_NOP) ; A6 AND A,r
+.dw (FETCH_A | OP_ANDA | STORE_NOP) ; A7 AND A,r
+.dw (FETCH_B | OP_XORA | STORE_NOP) ; A8 XOR A,r
+.dw (FETCH_C | OP_XORA | STORE_NOP) ; A9 XOR A,r
+.dw (FETCH_D | OP_XORA | STORE_NOP) ; AA XOR A,r
+.dw (FETCH_E | OP_XORA | STORE_NOP) ; AB XOR A,r
+.dw (FETCH_H | OP_XORA | STORE_NOP) ; AC XOR A,r
+.dw (FETCH_L | OP_XORA | STORE_NOP) ; AD XOR A,r
+.dw (FETCH_MHL | OP_XORA | STORE_NOP) ; AE XOR A,r
+.dw (FETCH_A | OP_XORA | STORE_NOP) ; AF XOR A,r
+.dw (FETCH_B | OP_ORA | STORE_NOP) ; B0 OR A,r
+.dw (FETCH_C | OP_ORA | STORE_NOP) ; B1 OR A,r
+.dw (FETCH_D | OP_ORA | STORE_NOP) ; B2 OR A,r
+.dw (FETCH_E | OP_ORA | STORE_NOP) ; B3 OR A,r
+.dw (FETCH_H | OP_ORA | STORE_NOP) ; B4 OR A,r
+.dw (FETCH_L | OP_ORA | STORE_NOP) ; B5 OR A,r
+.dw (FETCH_MHL | OP_ORA | STORE_NOP) ; B6 OR A,r
+.dw (FETCH_A | OP_ORA | STORE_NOP) ; B7 OR A,r
+.dw (FETCH_B | OP_CPFA | STORE_NOP) ; B8 CP A,r
+.dw (FETCH_C | OP_CPFA | STORE_NOP) ; B9 CP A,r
+.dw (FETCH_D | OP_CPFA | STORE_NOP) ; BA CP A,r
+.dw (FETCH_E | OP_CPFA | STORE_NOP) ; BB CP A,r
+.dw (FETCH_H | OP_CPFA | STORE_NOP) ; BC CP A,r
+.dw (FETCH_L | OP_CPFA | STORE_NOP) ; BD CP A,r
+.dw (FETCH_MHL | OP_CPFA | STORE_NOP) ; BE CP A,r
+.dw (FETCH_A | OP_CPFA | STORE_NOP) ; BF CP A,r
.dw (FETCH_NOP | OP_IFNZ | STORE_RET) ; C0 RET NZ
.dw (FETCH_NOP | OP_POP16 | STORE_BC ) ; C1 POP BC
.dw (FETCH_DIR16| OP_IFNZ | STORE_PC ) ; C2 nn nn JP NZ,nn
.dw (FETCH_DIR16| OP_NOP | STORE_PC ) ; C3 nn nn JP nn
.dw (FETCH_DIR16| OP_IFNZ | STORE_CALL) ; C4 nn nn CALL NZ,nn
.dw (FETCH_BC | OP_PUSH16 | STORE_NOP) ; C5 PUSH BC
-.dw (FETCH_DIR8 | OP_ADDA | STORE_A ) ; C6 nn ADD A,n
+.dw (FETCH_DIR8 | OP_ADDA | STORE_NOP) ; C6 nn ADD A,n
.dw (FETCH_RST | OP_NOP | STORE_CALL) ; C7 RST 0
.dw (FETCH_NOP | OP_IFZ | STORE_RET) ; C8 RET Z
.dw (FETCH_NOP | OP_NOP | STORE_RET) ; C9 RET
.dw (FETCH_NOP | OP_INV | STORE_NOP) ; CB (Z80 specific)
.dw (FETCH_DIR16| OP_IFZ | STORE_CALL) ; CC nn nn CALL Z,nn
.dw (FETCH_DIR16| OP_NOP | STORE_CALL) ; CD nn nn CALL nn
-.dw (FETCH_DIR8 | OP_ADCA | STORE_A ) ; CE nn ADC A,n
+.dw (FETCH_DIR8 | OP_ADCA | STORE_NOP) ; CE nn ADC A,n
.dw (FETCH_RST | OP_NOP | STORE_CALL) ; CF RST 8H
.dw (FETCH_NOP | OP_IFNC | STORE_RET) ; D0 RET NC
.dw (FETCH_NOP | OP_POP16 | STORE_DE ) ; D1 POP DE
.dw (FETCH_DIR8 | OP_OUTA | STORE_NOP) ; D3 nn OUT (n),A
.dw (FETCH_DIR16| OP_IFNC | STORE_CALL) ; D4 nn nn CALL NC,nn
.dw (FETCH_DE | OP_PUSH16 | STORE_NOP) ; D5 PUSH DE
-.dw (FETCH_DIR8 | OP_SUBFA | STORE_A ) ; D6 nn SUB n
+.dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; 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_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
.dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn
.dw (FETCH_NOP | OP_INV | STORE_NOP) ; DD (Z80)
-.dw (FETCH_DIR8 | OP_SBCFA | STORE_A ) ; DE nn SBC A,n
+.dw (FETCH_DIR8 | OP_SBCFA | STORE_NOP) ; DE nn SBC A,n
.dw (FETCH_RST | OP_NOP | STORE_CALL) ; DF RST 18H
.dw (FETCH_NOP | OP_IFPO | STORE_RET) ; E0 RET PO
.dw (FETCH_NOP | OP_POP16 | STORE_HL ) ; E1 POP HL
.dw (FETCH_MSP | OP_EXHL | STORE_MSP) ; E3 EX (SP),HL
.dw (FETCH_DIR16| OP_IFPO | STORE_CALL) ; E4 nn nn CALL PO,nn
.dw (FETCH_HL | OP_PUSH16 | STORE_NOP) ; E5 PUSH HL
-.dw (FETCH_DIR8 | OP_ANDA | STORE_A ) ; E6 nn AND n
+.dw (FETCH_DIR8 | OP_ANDA | STORE_NOP) ; E6 nn AND n
.dw (FETCH_RST | OP_NOP | STORE_CALL) ; E7 RST 20H
.dw (FETCH_NOP | OP_IFPE | STORE_RET) ; E8 RET PE
.dw (FETCH_HL | OP_NOP | STORE_PC ) ; E9 JP (HL)
.dw (FETCH_DE | OP_EXHL | STORE_DE ) ; EB EX DE,HL
.dw (FETCH_DIR16| OP_IFPE | STORE_CALL) ; EC nn nn CALL PE,nn
.dw (FETCH_NOP | OP_INV | STORE_NOP) ; ED (Z80 specific)
-.dw (FETCH_DIR8 | OP_XORA | STORE_A ) ; EE nn XOR n
+.dw (FETCH_DIR8 | OP_XORA | STORE_NOP) ; EE nn XOR n
.dw (FETCH_RST | OP_NOP | STORE_CALL) ; EF RST 28H
.dw (FETCH_NOP | OP_IFP | STORE_RET) ; F0 RET P
.dw (FETCH_NOP | OP_POP16 | STORE_AF ) ; F1 POP AF
.dw (FETCH_NOP | OP_DI | STORE_NOP) ; F3 DI
.dw (FETCH_DIR16| OP_IFP | STORE_CALL) ; F4 nn nn CALL P,nn
.dw (FETCH_AF | OP_PUSH16 | STORE_NOP) ; F5 PUSH AF
-.dw (FETCH_DIR8 | OP_ORA | STORE_A ) ; F6 nn OR n
+.dw (FETCH_DIR8 | OP_ORA | STORE_NOP) ; F6 nn OR n
.dw (FETCH_RST | OP_NOP | STORE_CALL) ; F7 RST 30H
.dw (FETCH_NOP | OP_IFM | STORE_RET) ; F8 RET M
.dw (FETCH_HL | OP_NOP | STORE_SP ) ; F9 LD SP,HL
.dw (FETCH_NOP | OP_EI | STORE_NOP) ; FB EI
.dw (FETCH_DIR16| OP_IFM | STORE_CALL) ; FC nn nn CALL M,nn
.dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific)
-.dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; FE nn CP n
+.dw (FETCH_DIR8 | OP_CPFA | STORE_NOP) ; FE nn CP n
.dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H
; vim:set ts=8 noet nowrap
-