]> cloudbase.mooo.com Git - avrcpm.git/blobdiff - avrcpm/avr/z80.asm
* avr/z80.asm:
[avrcpm.git] / avrcpm / avr / z80.asm
index 0f2e46bfc7d8c308bb127e7f9401b3ae2dc73a0e..3aca6452d3ce3f0856c3e596b361f3f54330c38f 100644 (file)
@@ -15,6 +15,9 @@
 ;
 ;    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
@@ -31,9 +34,6 @@
 .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 */
 
@@ -71,6 +70,7 @@
 .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 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 ZFL_C     =       0
 
 ;Register definitions
-.undef xl              ;r26
-.undef xh              ;r27
 
 .def   _tmp    = r0    ;  0
 .def   _0      = r1
 .def   oph     = r23   ;
 .def   z_pcl   = r24   ;
 .def   z_pch   = r25   ;
-.def   adrl    = r26   ;
-.def   adrh    = r27   ;
+; xl           ;r26
+; xh           ;r27
 ; yl           ;r28
 ; yh           ;r29
 ; zl           ;r30    ;
 ; zh           ;r31    ;
 
 
-#if 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   _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    ;
-#endif
 
 #if defined __ATmega8__
-       .equ    flags = TWBR
+.equ   flags   = TWBR
+.equ   P_PUD   = SFIOR
 #else
-       .equ    flags = GPIOR0
+.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
 #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
+
+
+;----------------------------------------
+; 
+.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
+
+
+
+;----------------------------------------
+; 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
 
@@ -264,124 +284,88 @@ start:
        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
-       ldi     temp,low(F_CPU/1000)
-       out     OCR1AL,temp
-       ldi     temp,(1<<WGM12) | (1<<CS10)     ;CTC, clk/1
-       out     TCCR1B,temp
-       in      temp,TIMSK
-       ori     temp,(1<<OCIE1A)
-       out     TIMSK,temp
-#else
        ldi     temp,high(F_CPU/1000)
-       sts     OCR1AH,temp
+       outm8   OCR1AH,temp
        ldi     temp,low(F_CPU/1000)
-       sts     OCR1AL,temp
+       outm8   OCR1AL,temp
        ldi     temp,(1<<WGM12) | (1<<CS10)     ;CTC, clk/1
-       sts     TCCR1B,temp
-       lds     temp,TIMSK1
+       outm8   TCCR1B,temp
+       inm8    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
 
 
@@ -395,23 +379,18 @@ ti_loop:
        .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
@@ -427,65 +406,170 @@ ramtestwl:
        .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
 
-;Load initial sector from MMC (512 bytes)
-       ldi adrh,0
-       ldi adrl,0
-       rcall mmcReadSect
+;----------------------------------------------------------------------------
+
+; 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
+
+;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(hostbuf)
        ldi zh,high(hostbuf)
-       ldi adrh,0x20
-       ldi adrl,0x00
+       ldi xh,0x20
+       ldi xl,0x00
 iplwriteloop:
        ld temp,z+
-       push zh
-       push zl
        rcall memWriteByte
-       pop zl
-       pop zh
-       adiw adrl,1
+       adiw xl,1
        cpi zl,low(hostbuf+128)
        brne iplwriteloop
        cpi zh,high(hostbuf+128)
@@ -520,20 +604,20 @@ 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
@@ -542,9 +626,9 @@ noprintpc:
        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
@@ -552,6 +636,7 @@ noprintpc:
        rcall printhex
 notrace1:
 .endif
+       adiw z_pcl,1
 
        ; *** Stage 2: Decode it using the ins_table.
        ldi zh,high(inst_table*2)
@@ -565,13 +650,13 @@ notrace1:
        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
 
@@ -595,7 +680,7 @@ notrace2:
        mov temp,opl
        rcall printhex
        rcall printstr
-       .db " -- ",0
+       .db " -- ",0,0
 notrace3:
 .endif
 
@@ -616,7 +701,7 @@ nofetch:
        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
@@ -674,8 +759,8 @@ notrace6:
 ;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;
-;                      3 - 5, write to allocated/dirctory/unallocated
+;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
@@ -687,6 +772,7 @@ notrace6:
 ;*****************************************************
 ;*         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
@@ -706,13 +792,15 @@ notrace6:
 
 
        .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   2       ;host track number
+hostlba:       .byte   3       ;host sector number (relative to partition start)
 
 unacnt:                .byte   1       ;unalloc rec cnt
 unadsk:                .byte   1       ;last unalloc disk
@@ -734,6 +822,11 @@ portRead:
        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
@@ -750,6 +843,9 @@ portWrite:
        breq dbgOut
        cpi temp2,2
        breq conOut
+
+       cpi temp2,15
+       breq dskDiskSel
        cpi temp2,16
        breq dskTrackSel_l
        cpi temp2,17
@@ -783,8 +879,7 @@ conStatus:
        ret
 
 conInp:
-       rcall uartGetc
-       ret
+       rjmp uartGetc
 
 dbgOut:
        rcall printstr
@@ -795,10 +890,29 @@ dbgOut:
        ret
 
 conOut:
-       rcall uartputc
-       ret
+       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
@@ -822,6 +936,52 @@ dskDmah:
        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 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,0
+       lds temp,seeksec
+       rcall printhex
+       rcall printstr
+       .db " dma-addr ",0,0
+       lds temp,dmaadr+1
+       rcall printhex
+       lds temp,dmaadr
+       rcall printhex
+       pop     temp
+       push    temp
+       sbrs    temp,WRITE_FUNC
+        rjmp   dskdbge
+       rcall printstr
+       .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
@@ -850,38 +1010,14 @@ dsk_home:
 
 dsk_read:
 
-.if 0
-       rcall   timer_quit
-       rcall printstr
-       .db " In",0
-.endif
+       sbi     flags,readop            ;read operation
+       ;RAM disk?
+       lds     temp2,seekdsk
+;      cpi     temp2,RAMDISKNR
+;      brlt    PC+2
+;       rjmp   rdskDoIt
 
-.if DISK_DEBUG
-       push temp
-       rcall printstr
-       .db 13,0
-       rcall printstr
-       .db "Disk read: track ",0
-       lds temp,seektrk+1
-       rcall printhex
-       lds temp,seektrk
-       rcall printhex
-       rcall printstr
-       .db " sector ",0,0
-       lds temp,seeksec
-       rcall printhex
-       rcall printstr
-       .db " dma-addr ",0,0
-       lds temp,dmaadr+1
-       rcall printhex
-       lds temp,dmaadr
-       rcall printhex
-;      rcall printstr
-;      .db ".",13,0,0
-       pop temp
-.endif
        sts     unacnt,_0
-       sbi     flags,readop            ;read operation
        sbi     flags,rsflag            ;must read data
        ldi     temp,WRUAL              ;write type
        sts     wrtype,temp             ;treat as unalloc
@@ -891,38 +1027,15 @@ dsk_read:
 dsk_write:
        ;write the selected CP/M sector
 
-       andi    temp,WRTMSK
-       sts     wrtype,temp             ;save write type
        cbi     flags,readop            ;not a read operation
 
-.if DISK_DEBUG
-       push temp
-       rcall printstr
-       .db 13,0
-       rcall printstr
-       .db "Disk write: track ",0,0
-       lds temp,seektrk+1
-       rcall printhex
-       lds temp,seektrk
-       rcall printhex
-       rcall printstr
-       .db " sector ",0,0
-       lds temp,seeksec
-       rcall printhex
-       rcall printstr
-       .db " dma-addr ",0,0
-       lds temp,dmaadr+1
-       rcall printhex
-       lds temp,dmaadr
-       rcall printhex
-       rcall printstr
-       .db " wrtype ",0,0
-       lds temp,wrtype
-       rcall printhex
-;      rcall printstr
-;      .db ".",13,0,0
-       pop temp
-.endif
+       ;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
@@ -998,74 +1111,89 @@ dsk_alloc:
 
 dsk_rwoper:
        ;enter here to perform the read/write
+.if DISK_DEBUG
+       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     adrl,seeksec            ;
-       ldi     adrh,0                  ;
+       lds     xl,seeksec              ;
+       ldi     xh,0                    ;
+       ldi     yl,0                    ;
        lds     temp3,seektrk           ;
        lds     temp4,seektrk+1         ;
        ldi     temp,CPMSPT             ;
        mul     temp3,temp              ;
-       add     adrl,r0                 ;
-       adc     adrh,r1                 ;
+       add     xl,r0                   ;
+       adc     xh,r1                   ;
        mul     temp4,temp              ;
-       add     adrh,r0                 ;adrh:adrl := sec + trk * SectorsPerTrack
+       add     xh,r0                   ;yl:xh:xl := sec + trk * SectorsPerTrack
+       adc     yl,r1                   ;
        clr     _0
 
-       mov     temp,adrl
+       mov     temp,xl
        andi    temp,SECMSK             ;mask buffer number
        push    temp                    ;save for later
-.if DISK_DEBUG
-       rcall printstr
-       .db "; bufnr: ",0,0
-       rcall printhex
-.endif
 
        ;Convert from CP/M LBA blocks to host LBA blocks
        ldi temp,SECSHF
 dsk_sh1:
-       lsr     adrh
-       ror     adrl
+       lsr     yl
+       ror     xh
+       ror     xl
        dec     temp
        brne    dsk_sh1
-                                       ;adrh:adrl = host block to seek
+                                       ;yl:xh:xl = host block to seek
 ;      active host sector?
-       sbis    flags,hostact           ;host active?
+       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     temp3,hostdsk           ;same disk?
-       cp      temp,temp3              ;seekdsk = hostdsk?
+       lds     temp2,hostdsk           ;same disk?
+       cp      temp,temp2              ;seekdsk = hostdsk?
        brne    dsk_nomatch
 
 ;      same disk, same block?
-       lds     temp3,hostlba
-       lds     temp4,hostlba+1
-       cp      adrl,temp3
-       cpc     adrh,temp4      
+       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
-       sbic    flags,hostwrt           ;host written?
+       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,adrl
-       sts     hostlba+1,adrh
+       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:
-       sbi     flags,hostact           ;host buffer active now
 
        ;copy data to or from buffer
        ldi     zl,low(hostbuf)
@@ -1075,7 +1203,7 @@ dsk_match:
        mul     temp2,temp
        add     zl,r0                   ;offset in hostbuf
        adc     zh,r1
-.if DISK_DEBUG
+.if 0 ; DISK_DEBUG
        push    r0
        push    r1
        clr     _0
@@ -1088,41 +1216,33 @@ dsk_match:
 .endif
        clr     _0
 
-       lds     adrl,dmaadr
-       lds     adrh,dmaadr+1
-       push    yl
-       ldi     yl,128                  ;length of move
+       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 adrl,1
-       dec yl
+       rcall   memReadByte
+       st      z+,temp
+       adiw    xl,1
+       dec     temp3
        brne dsk_wmove
        rjmp    dsk_rwmfin
        
 dsk_rmove:
        ld      temp,z+
        rcall   memWriteByte
-       adiw    adrl,1
-       dec     yl
+       adiw    xl,1
+       dec     temp3
        brne    dsk_rmove
 dsk_rwmfin:
-       pop     yl
 ;      data has been moved to/from host buffer
        lds     temp,wrtype     ;write type
        cpi     temp,WRDIR      ;to directory?
        breq    dsk_wdir
-       lds     temp,erflag
-.if 0
-       rcall   timer_quit
-       rcall printstr
-       .db " Out",0
-.endif
        ret                     ;no further processing
 dsk_wdir:
 ;      clear host buffer for directory write
@@ -1133,9 +1253,106 @@ dsk_wdir:
 dsk_wdir1:
        rcall   dsk_writehost   ;clear host buff
        cbi     flags,hostwrt   ;buffer written
-       lds     temp,erflag
        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
+
+       lsl     temp            
+       lsl     temp            
+       lsl     temp            
+       add     zl,temp         
+       adc     zh,_0           
+
+       lds     temp,hostlba
+       lds     temp2,hostlba+1
+       lds     temp3,hostlba+2
+
+.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
 
 ;*****************************************************
 ;*     WRITEhost performs the physical write to     *
@@ -1144,33 +1361,34 @@ dsk_wdir1:
 ;*****************************************************
 
 dsk_writehost:
-       ;hostdsk = host disk #, hostlba = host block #.
-       ;Write "hostsize" bytes from hostbuf and return 
-       ;error flag in erflag.
-       ;Return erflag non-zero if error
+.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
        
-       push    adrh
-       push    adrl
-       lds     adrl,hostlba
-       lds     adrh,hostlba+1
+dsk_wr1:
        rcall   mmcWriteSect
-       pop     adrl
-       pop     adrh
        sts     erflag,_0
        ret
 
 dsk_readhost:
-       ;hostdsk = host disk #, hostlba = host block #.
-       ;Read "hostsiz" bytes into hostbuf and return 
-       ;error flag in erflag.
-
-       push    adrh
-       push    adrl
-       lds     adrl,hostlba
-       lds     adrh,hostlba+1
+.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
-       pop     adrl
-       pop     adrh
        sts     erflag,_0
        ret
 
@@ -1184,8 +1402,6 @@ mmcByteNoSend:
 mmcByte:
 
 .if MMC_DEBUG
-       push zl
-       push zh
        rcall printstr
        .db "MMC: <--",0
        rcall printhex
@@ -1199,15 +1415,11 @@ mmcWrByteW:
        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
 
@@ -1344,8 +1556,8 @@ mmcInitOcrLoopDone:
        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
@@ -1354,14 +1566,14 @@ mmcReadSect:
        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
@@ -1400,8 +1612,8 @@ mmcreadloop:
        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
@@ -1411,14 +1623,14 @@ mmcWriteSect:
 
        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
@@ -1469,17 +1681,10 @@ mmcwaitwritten:
 ;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
+       outm8 WDTCSR,temp
        ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
-       sts WDTCSR,temp
-#endif
+       outm8 WDTCSR,temp
 resetwait:
        rjmp resetwait
 
@@ -1504,22 +1709,24 @@ resetwait:
        out P_AH,temp
 .endm
 
-;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
-       DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8), (1<<ram_oe)
+       DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8), (1<<ram_oe)
        cbi P_RAS,ram_ras
-       DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+       DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
        cbi P_CAS,ram_cas
        cbi P_A8,ram_a8
+       dram_wait DRAM_WAITSTATES       ;
        in  temp,P_DQ-2         ; PIN
        sbi P_CAS,ram_cas
 
        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
@@ -1532,12 +1739,12 @@ dram_read:
 
 #if DRAM_WORD_ACCESS
 dram_read_w:
-       cpi adrl,255
+       cpi xl,255
        brne dram_read_w1
        
        rcall dram_read
        push temp
-       adiw adrl,1
+       adiw xl,1
        rcall dram_read
        mov temp2,temp
        pop temp
@@ -1545,16 +1752,18 @@ dram_read_w:
 
 dram_read_w1:
        cli
-       DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
+       DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
        cbi P_RAS,ram_ras
-       DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+       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
@@ -1562,15 +1771,17 @@ dram_read_w1:
        
 ;      push temp
        mov _wl,temp
-       inc adrl
-       DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+       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
@@ -1584,8 +1795,8 @@ dram_read_w1:
        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
@@ -1596,9 +1807,9 @@ dram_write:
        andi temp,RAM_DQ_MASK & ~(1<<ram_w)
        ori temp,(1<<ram_cas)
        out PORTC,temp
-       DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
+       DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
        cbi P_RAS,ram_ras
-       DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+       DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
        cbi PORTC,ram_cas
        sbi PORTC,ram_cas
 
@@ -1620,13 +1831,13 @@ dram_write:
 
 #if DRAM_WORD_ACCESS
 dram_write_w:
-       cpi adrl,255
+       cpi xl,255
        brne dram_write_w1
        
        push temp2
        rcall dram_write
        pop temp
-       adiw adrl,1
+       adiw xl,1
        rcall dram_write
        ret     
 
@@ -1641,9 +1852,9 @@ dram_write_w1:
        ori temp,(1<<ram_cas)
        out PORTC,temp
 
-       DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
+       DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
        cbi P_RAS,ram_ras
-       DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+       DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
        cbi PORTC,ram_cas
        sbi PORTC,ram_cas
 
@@ -1658,13 +1869,13 @@ dram_write_w1:
        sbi PORTC,ram_cas
 
        pop temp
-       inc adrl
+       inc xl
        mov  temp2,temp
        andi temp,RAM_DQ_MASK & ~(1<<ram_w)
        ori temp,(1<<ram_cas)
        out PORTC,temp
 
-       DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+       DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
        cbi PORTC,ram_cas
        sbi PORTC,ram_cas
 
@@ -1688,8 +1899,11 @@ dram_write_w1:
 ; ****************************************************************************
 
 ; 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|  
@@ -1698,6 +1912,7 @@ refrint:
 ;      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|  
@@ -1707,9 +1922,8 @@ refrint:
                                ;        1|   1|  
        reti                    ;4  --> 21 cycles
 
-; ****************************************************************************
 
-; ------------- system timer 10ms ---------------
+; ------------- system timer 1ms ---------------
     .dseg
 
 delay_timer:
@@ -2001,6 +2215,10 @@ print_ultoa:
        push    yh
        push    yl
        push    z_flags
+       push    temp4
+       push    temp3
+       push    temp2
+       push    temp
                                
        clr     yl              ;yl = stack level
 
@@ -2039,6 +2257,10 @@ ultoa6:  pop     temp            ;Flush stacked digits
        dec     yl      
        brne    ultoa6  
 
+       pop     temp
+       pop     temp2
+       pop     temp3
+       pop     temp4
        pop     z_flags
        pop     yl
        pop     yh
@@ -2074,11 +2296,11 @@ printhex:
 printstr:
        push    zh
        push    zl
-       push    r29
-       push    r28
+       push    yh
+       push    yl
        push    temp
-       in      r29,sph
-       in      r28,spl
+       in      yh,sph
+       in      yl,spl
        ldd     zl,y+7
        ldd     zh,y+6
 
@@ -2103,8 +2325,8 @@ printstr_end:
        std     y+7,zl
        std     y+6,zh
        pop     temp
-       pop     r28
-       pop     r29
+       pop     yl
+       pop     yh
        pop     zl
        pop     zh
        ret
@@ -2123,6 +2345,7 @@ printstr_end:
        .dseg
        
 #define RXBUFMASK  RXBUFSIZE-1
+#define TXBUFMASK  TXBUFSIZE-1
 
 rxcount:
        .byte   1
@@ -2130,10 +2353,18 @@ rxidx_w:
        .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.
@@ -2144,11 +2375,7 @@ rxint:
        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                  ; 
@@ -2179,7 +2406,7 @@ rxi_ov:                                   ;endif
 uartgetc:
        lds     temp,rxcount            ; Number of characters in buffer
        tst     temp
-       breq    uartgetc
+       breq    uartgetc                ;Wait for char
        
        push    zh
        push    zl
@@ -2202,24 +2429,74 @@ uartgetc:
        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 -----------------
@@ -2322,53 +2599,53 @@ do_fetch_sp:
        ret
 
 do_fetch_mbc:
-       movw adrl,z_c
+       movw xl,z_c
        rcall memReadByte
        mov opl,temp
        ret
 
 do_fetch_mde:
-       movw adrl,z_e
+       movw xl,z_e
        rcall memReadByte
        mov opl,temp
        ret
 
 do_fetch_mhl:
-       movw 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 
@@ -2376,9 +2653,9 @@ do_fetch_dir16:
        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
@@ -2488,32 +2765,32 @@ do_store_hl:
        ret
 
 do_store_mbc:
-       movw adrl,z_c
+       movw xl,z_c
        mov temp,opl
        rcall memWriteByte
        ret
 
 do_store_mde:
-       movw adrl,z_e
+       movw xl,z_e
        mov temp,opl
        rcall memWriteByte
        ret
 
 do_store_mhl:
-       movw 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
@@ -2542,7 +2819,7 @@ do_store_call:
        ret
 
 do_store_am:
-       movw adrl,opl
+       movw xl,opl
        mov temp,z_a
        rcall memWriteByte
        ret
@@ -2591,6 +2868,9 @@ do_store_am:
 .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
@@ -2633,6 +2913,9 @@ opjumps:
        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:
@@ -2818,13 +3101,13 @@ opjumps:
 ;----------------------------------------------------------------
 
 
-.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
@@ -2912,15 +3195,27 @@ do_op_nop:
 ;
 ; 
 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                 |
 ;----------------------------------------------------------------
@@ -2933,8 +3228,10 @@ do_op_inc:
 ;
 ;
 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           ;
@@ -2942,6 +3239,17 @@ do_op_dec:
        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                 |
@@ -3052,9 +3360,9 @@ do_op_rl:
 ;
 ;
 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
@@ -3071,9 +3379,9 @@ do_op_adca:
        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
@@ -3082,13 +3390,28 @@ do_op_adca:
 ;|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
@@ -3108,14 +3431,12 @@ do_op_subfa:
 ;
 ;
 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
@@ -3130,8 +3451,8 @@ do_op_sbcfa:
 ;
 ; 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
 
@@ -3145,8 +3466,8 @@ do_op_anda:
 ;
 ; 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
 
@@ -3159,8 +3480,8 @@ do_op_ora:
 ;
 ; 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
 
@@ -3188,14 +3509,14 @@ do_op_addhl:
 ;
 ;
 do_op_sthl: ;store hl to mem loc in opl:h
-       movw adrl,opl
+       movw xl,opl
 #if DRAM_WORD_ACCESS
        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
@@ -3208,14 +3529,14 @@ do_op_sthl: ;store hl to mem loc in opl:h
 ;
 ; 
 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 
@@ -3228,7 +3549,7 @@ do_op_rmem16:
 ;
 ;
 do_op_rmem8:
-       movw adrl,opl
+       movw xl,opl
        rcall memReadByte
        mov opl,temp
        ret
@@ -3400,7 +3721,7 @@ do_op_ccf:
 ;
 ;
 do_op_cpl:
-       com opl
+       com z_a
        do_z80_flags_set_HN
        ret
 
@@ -3413,17 +3734,17 @@ do_op_cpl:
 ;
 ;
 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
@@ -3455,14 +3776,14 @@ do_op_push16:
 ;
 ;
 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 
@@ -3805,7 +4126,7 @@ inst_table:
 .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
@@ -3818,8 +4139,8 @@ inst_table:
 .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
@@ -3886,77 +4207,77 @@ inst_table:
 .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
@@ -3964,7 +4285,7 @@ inst_table:
 .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
@@ -3972,7 +4293,7 @@ inst_table:
 .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)
@@ -3980,7 +4301,7 @@ inst_table:
 .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
@@ -3988,7 +4309,7 @@ inst_table:
 .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)
@@ -3996,7 +4317,7 @@ inst_table:
 .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
@@ -4004,7 +4325,7 @@ inst_table:
 .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
@@ -4012,7 +4333,7 @@ inst_table:
 .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