1 ; Z80 emulator with CP/M support. The Z80-specific instructions themselves actually aren't
2 ; implemented yet, making this more of an i8080 emulator.
4 ; Copyright (C) 2010 Sprite_tm
6 ; This program is free software: you can redistribute it and/or modify
7 ; it under the terms of the GNU General Public License as published by
8 ; the Free Software Foundation, either version 3 of the License, or
9 ; (at your option) any later version.
11 ; This program is distributed in the hope that it will be useful,
12 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ; GNU General Public License for more details.
16 ; You should have received a copy of the GNU General Public License
17 ; along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #elif defined atmega168
23 .include "m168def.inc"
33 #ifndef DRAM_DQ_ORDER /* If this is set to 1, the portbits */
34 #define DRAM_DQ_ORDER 0 /* for DRAM D1 and WE are swapped. */
39 #define F_CPU 20000000 /* system clock in Hz; defaults to 20MHz */
42 #define BAUD 38400 /* console baud rate */
46 #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) /* clever rounding */
48 #define RXBUFSIZE 64 /* USART recieve buffer size. Must be power of 2 */
50 #define REFR_RATE 64000 /* dram refresh rate in cycles/s. */
51 /* Most drams need 1/15.6µs. */
52 #define REFR_PRE 8 /* timer prescale factor */
53 #define REFR_CS 0x02 /* timer clock select for 1/8 */
54 #define REFR_CNT F_CPU / REFR_RATE / REFR_PRE
57 #if defined __ATmega8__
58 .equ refr_vect = OC2addr
60 .equ refr_vect = OC2Aaddr
64 #define EM_Z80 0 /* we don't have any z80 instructions yet */
89 .equ RAM_AH_MASK = 0xE0 ; ram_a[7..5]
90 .equ PD_OUTPUT_MASK = 0xFE
105 .equ RAM_AL_MASK = 0x1F ; ram_a[4..0]
106 .equ PB_OUTPUT_MASK = 0x3F
109 #if DRAM_DQ_ORDER == 1
123 .equ RAM_DQ_MASK = (1<<ram_d3)|(1<<ram_d2)|(1<<ram_d1)|(1<<ram_d0)
124 .equ PC_OUTPUT_MASK = (1<<ram_cas)|(1<<ram_w)
127 ;Flag bits in z_flags
135 ;Register definitions
153 .def temp = R16 ;The temp register
154 .def temp2 = R17 ;Second temp register
169 ; This is the base z80 port address for clock access
170 #define TIMERPORT 0x40
171 #define TIMER_CTL TIMERPORT
172 #define TIMER_MSECS TIMERPORT+1
173 #define TIMER_SECS TIMER_MSECS+2
175 #define starttimercmd 1
176 #define quitTimerCmd 2
177 #define printTimerCmd 15
185 ;Sector buffer for 512 byte reads/writes from/to SD-card
193 rjmp start ; reset vector
195 rjmp refrint ; tim2cmpa
196 .org OC1Aaddr ; Timer/Counter1 Compare Match A
197 rjmp sysclockint ; 1ms system timer
199 rjmp rxint ; USART receive int.
203 .org INT_VECTORS_SIZE
206 ldi temp,low(RAMEND) ; top of memory
207 out SPL,temp ; init stack pointer
208 ldi temp,high(RAMEND) ; top of memory
209 out SPH,temp ; init stack pointer
213 #if defined __ATmega8__
217 ldi temp,(1<<WDCE) | (1<<WDE)
225 ldi temp,(1<<WDCE) | (1<<WDE)
232 ldi temp,PB_OUTPUT_MASK
234 ldi temp,PD_OUTPUT_MASK
236 ldi temp,PC_OUTPUT_MASK
248 ldi temp,0 ; reset receive buffer
254 #if defined __ATmega8__
255 ldi temp, (1<<TXEN) | (1<<RXEN) | (1<<RXCIE)
257 ldi temp, (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0)
259 ldi temp, HIGH(UBRR_VAL)
261 ldi temp, LOW(UBRR_VAL)
264 ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
266 ldi temp, (1<<UCSZ01) | (1<<UCSZ00)
268 ldi temp, HIGH(UBRR_VAL)
270 ldi temp, LOW(UBRR_VAL)
274 ;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
277 ldi temp,REFR_CNT*2 ; 2 cycles per int
279 ldi temp,(1<<WGM21) | REFR_CS ;CTC, clk/REFR_PRE
284 ldi temp,REFR_CNT ;=312 cycles
288 ldi temp, REFR_CS ;clk/REFR_PRE
295 ; Init clock/timer system
297 ldi zl,low(timer_base)
298 ldi zh,high(timer_base)
306 ; Init timer 1 as 1 ms system clock tick.
309 ldi temp,high(F_CPU/1000)
311 ldi temp,low(F_CPU/1000)
313 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
319 ldi temp,high(F_CPU/1000)
321 ldi temp,low(F_CPU/1000)
323 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
339 .db "CPM on an AVR, v1.0",13,0,0
343 .db "Initing mmc...",13,0
349 .db "Testing RAM: fill...",0,0
374 .db "reread...",13,0,0
409 ;Fill ram with cbs, which (for now) will trigger an invalid opcode error.
424 ;Load initial sector from MMC (512 bytes)
429 ;Save to Z80 RAM (only 128 bytes because that's retro)
431 ldi zh,high(sectbuff)
445 cpi zl,low(sectbuff+128)
447 cpi zh,high(sectbuff+128)
460 .db 13,"Ok, CPU is live!",13,0,0
489 ; *** Stage 1: Fetch next opcode
513 ; *** Stage 2: Decode it using the ins_table.
515 ldi zl,low(inst_table*2)
516 ldi zh,high(inst_table*2)
538 ; *** Stage 3: Fetch operand. Use the fetch jumptable for this.
545 ldi zl,low(fetchjumps*2)
546 ldi zh,high(fetchjumps*2)
570 ; *** Stage 4: Execute operation :) Use the op jumptable for this.
576 ldi zl,low(opjumps*2)
577 ldi zh,high(opjumps*2)
600 ; *** Stage 5: Store operand. Use the store jumptable for this.
608 ldi zl,low(storejumps*2)
609 ldi zh,high(storejumps*2)
641 ; ----------------Virtual peripherial interface ------
643 ;The hw is modelled to make writing a CPM BIOS easier.
645 ;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise.
646 ;1 - Console input, aka UDR.
652 ;22 - Trigger - write 1 to read, 2 to write a sector using the above info.
653 ; This will automatically move track, sector and dma addr to the next sector.
655 ;Called with port in temp2. Should return value in temp.
662 cpi temp2,TIMER_MSECS
664 cpi temp2,TIMER_MSECS+6
672 ;Called with port in temp2 and value in temp.
691 cpi temp2,TIMER_MSECS+6
745 .db "Disk read: track ",0
763 ;First, convert track/sector to an LBA address (in 128byte blocks)
780 ;Now, see what has to be done.
788 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
793 ;Read 512-byte sector
797 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
799 ldi zh,high(sectbuff)
827 brne dskDoItReadMemLoop
831 ;The write routines is a bit naive: it'll read the 512-byte sector the 128byte CPM-sector
832 ;resides in into memory, will overwrite the needed 128 byte with the Z80s memory buffer
833 ;and will then write it back to disk. In theory, this would mean that every 512 bytes
834 ;written will take 4 write cycles, while theoretically the writes could be deferred so we
835 ;would only have to do one write cycle.
840 .db "Disk write: track ",0
861 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
866 ;Read 512-byte sector
874 ;Copy the data from the Z80 DMA buffer in external memory to the right place in the
876 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
878 ldi zh,high(sectbuff)
906 brne dskDoItWriteMemLoop
911 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
916 ;Write the sector back.
923 ; ----------------- MMC/SD routines ------------------
958 ;Wait till the mmc answers with the response in temp2, or till a timeout happens.
965 brne mmcWaitResploopEnd
978 .db ": Error: MMC resp timeout!",13,0
985 ;Init start: send 80 clocks with cs disabled
1010 ldi temp,0xff ;dummy
1012 ldi temp,0xff ;dummy
1026 ldi temp,0xff ;return byte
1036 ;Read OCR till card is ready
1042 ldi temp,0xff ;dummy
1061 breq mmcInitOcrLoopDone
1084 ;Call this with adrh:adrl = sector number
1085 ;16bit lba address means a max reach of 32M.
1092 ldi temp,0x51 ;cmd (read sector)
1107 ldi temp,0xff ;return byte
1118 ;Read sector to AVR RAM
1119 ldi zl,low(sectbuff)
1120 ldi zh,high(sectbuff)
1124 cpi zl,low(sectbuff+512)
1126 cpi zh,high(sectbuff+512)
1141 ;Call this with adrh:adrl = sector number
1142 ;16bit lba address means a max reach of 32M.
1150 ldi temp,0x58 ;cmd (write sector)
1165 ldi temp,0xff ;return byte
1176 ;Write sector from AVR RAM
1177 ldi zl,low(sectbuff)
1178 ldi zh,high(sectbuff)
1182 cpi zl,low(sectbuff+512)
1184 cpi zh,high(sectbuff+512)
1191 ;Status. Ignored for now.
1194 ;Wait till the mmc has written everything
1208 ;Set up wdt to time out after 1 sec.
1211 #if defined __ATmega8__
1214 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1219 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1226 ; ------------------ DRAM routines -------------
1230 #if DRAM_DQ_ORDER == 1
1231 #define CLASSIC_DRAM 0
1233 #define CLASSIC_DRAM 1 /* Change manualy, if you want new hw w/ old sw */
1237 #if DRAM_DQ_ORDER == 0
1238 #if CLASSIC_DRAM == 1
1239 #error "Old harware can not work with new software!"
1243 ; ****************************************************************************
1247 ; ********************** DRAM routines from Sprite_tm ************************
1249 ;Sends the address in zh:zl to the ram
1294 andi temp2,~RAM_DQ_MASK
1297 ori temp2,(1<<ram_d0)
1299 ori temp2,(1<<ram_d1)
1301 ori temp2,(1<<ram_d2)
1303 ori temp2,(1<<ram_d3)
1310 ;Loads the byte on address adrh:adrl into temp.
1333 rcall dram_getnibble
1348 rcall dram_getnibble
1356 ;Writes the byte in temp to adrh:adrl
1361 ori temp2,RAM_DQ_MASK
1364 rcall dram_sendnibble
1400 rcall dram_sendnibble
1414 andi temp,~RAM_DQ_MASK
1417 andi temp,~RAM_DQ_MASK
1421 #endif /* CLASSIC_DRAM == 1 */
1423 ; ****************************************************************************
1427 ; ***************************** New DRAM routines ****************************
1429 ; Defines how the dram nibbles are arganized.
1430 ; RAMORG == 0 : A7 == 0: low nibble, A7 == 1: high nibble (Original Sprite_tm design)
1431 ; RAMORG == 1 : A8 == 0: low nibble, A8 == 1: high nibble (faster)
1436 ;Sends the address in zh:zl to the ram
1440 andi temp,~RAM_AL_MASK
1442 ori temp,(1<<ram_a0)
1444 ori temp,(1<<ram_a1)
1446 ori temp,(1<<ram_a2)
1448 ori temp,(1<<ram_a3)
1450 ori temp,(1<<ram_a4)
1454 andi temp,~RAM_AH_MASK
1456 ori temp,(1<<ram_a5)
1458 ori temp,(1<<ram_a6)
1460 ori temp,(1<<ram_a7)
1462 ori temp,(1<<ram_a8)
1465 #else /* RAMORG == 1 */
1469 andi temp,~RAM_AL_MASK
1471 ori temp,(1<<ram_a0)
1473 ori temp,(1<<ram_a1)
1475 ori temp,(1<<ram_a2)
1477 ori temp,(1<<ram_a3)
1479 ori temp,(1<<ram_a4)
1483 andi temp,~RAM_AH_MASK
1485 ori temp,(1<<ram_a5)
1487 ori temp,(1<<ram_a6)
1489 ori temp,(1<<ram_a7)
1496 .macro DRAM_SENDNIBBLE
1498 andi temp2,~RAM_DQ_MASK
1499 andi temp,RAM_DQ_MASK
1505 ;Loads the byte on address adrh:adrl into temp.
1506 ;must not alter adrh:adrl
1575 ;Writes the byte in temp to adrh:adrl
1576 ;must not alter adrh:adrl
1581 in temp2,DDRC ;DRAM data ports as outputs
1582 ori temp2,RAM_DQ_MASK
1602 cbi PORTC,ram_w ;early write
1621 andi temp,~RAM_DQ_MASK
1624 andi temp,~RAM_DQ_MASK
1626 #else /* RAMORG == 1 */
1627 in temp2,DDRC ;DRAM data ports as outputs
1628 ori temp2,RAM_DQ_MASK
1639 cbi PORTC,ram_w ;early write
1655 andi temp,~RAM_DQ_MASK
1658 andi temp,~RAM_DQ_MASK
1664 #endif /* CLASSIC_DRAM == 0 */
1666 ; ****************************************************************************
1668 ; refresh interupt; exec 2 cbr cycles
1671 cbi P_CAS,ram_cas ;2 1| 1|
1673 cbi P_RAS,ram_ras ;2 |0 1|
1677 sbi P_RAS,ram_ras ;2 |0 |0
1680 cbi P_RAS,ram_ras ;2 |0 1|
1682 sbi P_CAS,ram_cas ;2 |0 |0
1684 sbi P_RAS,ram_ras ;2 1| |0
1686 reti ;4 --> 21 cycles
1688 ; ****************************************************************************
1690 ; ------------- system timer 10ms ---------------
1700 ; don't change order here, clock put/get depends on it.
1701 cntms_out: ; register for ms
1703 utime_io: ; register for uptime.
1710 .equ timer_size = timer_top - timer_base
1712 .equ clkofs = cnt_1ms-cntms_out
1713 .equ timerofs = cnt_1ms-timer_ms
1734 ldi zl,high(1000) ;doesn't change flags
1768 sts delay_timer,temp
1770 lds temp,delay_timer
1779 subi temp2,TIMER_MSECS
1780 brcs clkget_end ;Port number in range?
1781 ldi zl,low(cntms_out)
1782 ldi zh,high(cntms_out)
1783 breq clkget_copy ;lowest byte requestet, latch clock
1785 brsh clkget_end ;Port number to high?
1810 subi temp2,TIMERPORT
1811 brcs clkput_end ;Port number in range?
1816 cpi temp,starttimercmd
1818 cpi temp,quitTimerCmd
1820 cpi temp,printTimerCmd
1834 ldi zl,low(cntms_out)
1835 ldi zh,high(cntms_out)
1836 breq clkput_copy ;lowest byte requestet, latch clock
1838 brsh clkput_end ;Port number to high?
1863 ldi zl,low(timer_ms)
1864 ldi zh,high(timer_ms)
1884 ldi zl,low(timer_ms)
1885 ldi zh,high(timer_ms)
1887 ; put ms on stack (16 bit)
1898 subi adrl,low(-1000)
1899 sbci adrh,high(-1000)
1911 ldd temp2,z+timerofs
1925 .db 13,"Timer running. Elapsed: ",0
1949 ldi zh,high(cnt_1ms)
1984 ; --------------- Debugging stuff ---------------
1986 ;Print a unsigned lonng value to the uart
1987 ; oph:opl:temp2:temp = value
1994 clr adrl ;adrl = stack level
1996 ultoa1: ldi insdech, 32 ;adrh = oph:temp % 10
1997 clr adrh ;oph:temp /= 10
2009 cpi adrh, 10 ;adrh is a numeral digit '0'-'9'
2014 cp temp,insdech ;Repeat until oph:temp gets zero
2021 ultoa5: cpi adrl,3 ; at least 3 digits (ms)
2027 ultoa6: pop temp ;Flush stacked digits
2038 ;Prints the lower nibble of temp in hex to the uart
2054 ;Prints temp in hex to the uart
2062 ;Prints the zero-terminated string following the call statement. WARNING: Destroys temp.
2093 ; --------------- AVR HW <-> Z80 periph stuff ------------------
2095 .equ memReadByte = dram_read
2096 .equ memWriteByte = dram_write
2098 ; --------------------------------------------------------------
2102 #define RXBUFMASK RXBUFSIZE-1
2116 ; Save received character in a circular buffer. Do nothing if buffer overflows.
2129 lds zh,rxcount ;if rxcount < RXBUFSIZE
2130 cpi zh,RXBUFSIZE ; (room for at least 1 char?)
2133 sts rxcount,zh ; rxcount++
2135 ldi zl,low(rxfifo) ;
2140 sts rxidx_w,zh ; rxidx_w = ++rxidx_w % RXBUFSIZE
2141 ldi zh,high(rxfifo) ;
2144 st z,temp ; rxfifo[rxidx_w] = char
2154 ;Fetches a char from the buffer to temp. If none available, waits till one is.
2157 lds temp,rxcount ; Number of characters in buffer
2177 ld temp,z ;don't forget to get the char
2184 ;Sends a char from temp to the uart.
2186 #if defined __ATmega8__
2202 ; ------------ Fetch phase stuff -----------------
2204 .equ FETCH_NOP = (0<<0)
2205 .equ FETCH_A = (1<<0)
2206 .equ FETCH_B = (2<<0)
2207 .equ FETCH_C = (3<<0)
2208 .equ FETCH_D = (4<<0)
2209 .equ FETCH_E = (5<<0)
2210 .equ FETCH_H = (6<<0)
2211 .equ FETCH_L = (7<<0)
2212 .equ FETCH_AF = (8<<0)
2213 .equ FETCH_BC = (9<<0)
2214 .equ FETCH_DE = (10<<0)
2215 .equ FETCH_HL = (11<<0)
2216 .equ FETCH_SP = (12<<0)
2217 .equ FETCH_MBC = (13<<0)
2218 .equ FETCH_MDE = (14<<0)
2219 .equ FETCH_MHL = (15<<0)
2220 .equ FETCH_MSP = (16<<0)
2221 .equ FETCH_DIR8 = (17<<0)
2222 .equ FETCH_DIR16= (18<<0)
2223 .equ FETCH_RST = (19<<0)
2226 ;Jump table for fetch routines. Make sure to keep this in sync with the .equs!
2374 ; ------------ Store phase stuff -----------------
2376 .equ STORE_NOP = (0<<5)
2377 .equ STORE_A = (1<<5)
2378 .equ STORE_B = (2<<5)
2379 .equ STORE_C = (3<<5)
2380 .equ STORE_D = (4<<5)
2381 .equ STORE_E = (5<<5)
2382 .equ STORE_H = (6<<5)
2383 .equ STORE_L = (7<<5)
2384 .equ STORE_AF = (8<<5)
2385 .equ STORE_BC = (9<<5)
2386 .equ STORE_DE = (10<<5)
2387 .equ STORE_HL = (11<<5)
2388 .equ STORE_SP = (12<<5)
2389 .equ STORE_PC = (13<<5)
2390 .equ STORE_MBC = (14<<5)
2391 .equ STORE_MDE = (15<<5)
2392 .equ STORE_MHL = (16<<5)
2393 .equ STORE_MSP = (17<<5)
2394 .equ STORE_RET = (18<<5)
2395 .equ STORE_CALL = (19<<5)
2396 .equ STORE_AM = (20<<5)
2398 ;Jump table for store routines. Make sure to keep this in sync with the .equs!
2544 ; ------------ Operation phase stuff -----------------
2547 .equ OP_NOP = (0<<10)
2548 .equ OP_INC = (1<<10)
2549 .equ OP_DEC = (2<<10)
2550 .equ OP_INC16 = (3<<10)
2551 .equ OP_DEC16 = (4<<10)
2552 .equ OP_RLC = (5<<10)
2553 .equ OP_RRC = (6<<10)
2554 .equ OP_RR = (7<<10)
2555 .equ OP_RL = (8<<10)
2556 .equ OP_ADDA = (9<<10)
2557 .equ OP_ADCA = (10<<10)
2558 .equ OP_SUBFA = (11<<10)
2559 .equ OP_SBCFA = (12<<10)
2560 .equ OP_ANDA = (13<<10)
2561 .equ OP_ORA = (14<<10)
2562 .equ OP_XORA = (15<<10)
2563 .equ OP_ADDHL = (16<<10)
2564 .equ OP_STHL = (17<<10) ;store HL in fetched address
2565 .equ OP_RMEM16 = (18<<10) ;read mem at fetched address
2566 .equ OP_RMEM8 = (19<<10) ;read mem at fetched address
2567 .equ OP_DA = (20<<10)
2568 .equ OP_SCF = (21<<10)
2569 .equ OP_CPL = (22<<10)
2570 .equ OP_CCF = (23<<10)
2571 .equ OP_POP16 = (24<<10)
2572 .equ OP_PUSH16 = (25<<10)
2573 .equ OP_IFNZ = (26<<10)
2574 .equ OP_IFZ = (27<<10)
2575 .equ OP_IFNC = (28<<10)
2576 .equ OP_IFC = (29<<10)
2577 .equ OP_IFPO = (30<<10)
2578 .equ OP_IFPE = (31<<10)
2579 .equ OP_IFP = (32<<10)
2580 .equ OP_IFM = (33<<10)
2581 .equ OP_OUTA = (34<<10)
2582 .equ OP_IN = (35<<10)
2583 .equ OP_EXHL = (36<<10)
2584 .equ OP_DI = (37<<10)
2585 .equ OP_EI = (38<<10)
2586 .equ OP_INV = (39<<10)
2631 ;How the flags are supposed to work:
2632 ;7 ZFL_S - Sign flag (=MSBit of result)
2633 ;6 ZFL_Z - Zero flag. Is 1 when the result is 0
2634 ;4 ZFL_H - Half-carry (carry from bit 3 to 4)
2635 ;2 ZFL_P - Parity/2-complement Overflow
2636 ;1 ZFL_N - Subtract - set if last op was a subtract
2639 ;I sure hope I got the mapping between flags and instructions correct...
2641 ;----------------------------------------------------------------
2645 ;| ZZZZZZZ 88888 000 |
2651 ;| ZZZZZZZ 88888 000 |
2653 ;| Z80 MICROPROCESSOR Instruction Set Summary |
2655 ;----------------------------------------------------------------
2656 ;----------------------------------------------------------------
2657 ;|Mnemonic |SZHPNC|Description |Notes |
2658 ;|----------+------+---------------------+----------------------|
2659 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
2660 ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
2661 ;|ADD A,s |***V0*|Add |A=A+s |
2662 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
2663 ;|ADD IX,pp |--?-0*|Add |IX=IX+pp |
2664 ;|ADD IY,rr |--?-0*|Add |IY=IY+rr |
2665 ;|AND s |**1P00|Logical AND |A=A&s |
2666 ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
2667 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
2668 ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
2669 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
2670 ;|CP s |***V1*|Compare |A-s |
2671 ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
2672 ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
2673 ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
2674 ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
2675 ;|CPL |--1-1-|Complement |A=~A |
2676 ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
2677 ;|DEC s |***V1-|Decrement |s=s-1 |
2678 ;|DEC xx |------|Decrement |xx=xx-1 |
2679 ;|DEC ss |------|Decrement |ss=ss-1 |
2680 ;|DI |------|Disable Interrupts | |
2681 ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
2682 ;|EI |------|Enable Interrupts | |
2683 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
2684 ;|EX [SP],xx|------|Exchange |[SP]<->xx |
2685 ;|EX AF,AF' |------|Exchange |AF<->AF' |
2686 ;|EX DE,HL |------|Exchange |DE<->HL |
2687 ;|EXX |------|Exchange |qq<->qq' (except AF)|
2688 ;|HALT |------|Halt | |
2689 ;|IM n |------|Interrupt Mode | (n=0,1,2)|
2690 ;|IN A,[n] |------|Input |A=[n] |
2691 ;|IN r,[C] |***P0-|Input |r=[C] |
2692 ;|INC r |***V0-|Increment |r=r+1 |
2693 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2694 ;|INC xx |------|Increment |xx=xx+1 |
2695 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2696 ;|INC ss |------|Increment |ss=ss+1 |
2697 ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
2698 ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
2699 ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
2700 ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
2701 ;|JP [HL] |------|Unconditional Jump |PC=[HL] |
2702 ;|JP [xx] |------|Unconditional Jump |PC=[xx] |
2703 ;|JP nn |------|Unconditional Jump |PC=nn |
2704 ;|JP cc,nn |------|Conditional Jump |If cc JP |
2705 ;|JR e |------|Unconditional Jump |PC=PC+e |
2706 ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
2707 ;|LD dst,src|------|Load |dst=src |
2708 ;|LD A,i |**0*0-|Load |A=i (i=I,R)|
2709 ;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
2710 ;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
2711 ;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
2712 ;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
2713 ;|NEG |***V1*|Negate |A=-A |
2714 ;|NOP |------|No Operation | |
2715 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
2716 ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
2717 ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
2718 ;|OUT [C],r |------|Output |[C]=r |
2719 ;|OUT [n],A |------|Output |[n]=A |
2720 ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
2721 ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
2722 ;|POP xx |------|Pop |xx=[SP]+ |
2723 ;|POP qq |------|Pop |qq=[SP]+ |
2724 ;|PUSH xx |------|Push |-[SP]=xx |
2725 ;|PUSH qq |------|Push |-[SP]=qq |
2726 ;|RES b,m |------|Reset bit |m=m&{~2^b} |
2727 ;|RET |------|Return |PC=[SP]+ |
2728 ;|RET cc |------|Conditional Return |If cc RET |
2729 ;|RETI |------|Return from Interrupt|PC=[SP]+ |
2730 ;|RETN |------|Return from NMI |PC=[SP]+ |
2731 ;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
2732 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2733 ;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
2734 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
2735 ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
2736 ;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
2737 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2738 ;|RRC m |**0P0*|Rotate Right Circular|m=->m |
2739 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2740 ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
2741 ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
2742 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
2743 ;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY |
2744 ;|SCF |--0-01|Set Carry Flag |CY=1 |
2745 ;|SET b,m |------|Set bit |m=mv{2^b} |
2746 ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
2747 ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
2748 ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
2749 ;|SUB s |***V1*|Subtract |A=A-s |
2750 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
2751 ;|----------+------+--------------------------------------------|
2762 ;------------------------------------------------;
2763 ; Move single bit between two registers
2765 ; bmov dstreg,dstbit,srcreg.srcbit
2773 ;------------------------------------------------;
2774 ; Load table value from flash indexed by source reg.
2776 ; ldpmx dstreg,tablebase,indexreg
2778 ; (6 words, 8 cycles)
2789 .macro do_z80_flags_HP
2791 bmov z_flags, ZFL_P, temp, AVR_V
2792 bmov z_flags, ZFL_H, temp, AVR_H
2796 .macro do_z80_flags_set_N
2798 ori z_flags, (1<<ZFL_N) ; Negation auf 1
2802 .macro do_z80_flags_set_HN
2804 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
2808 .macro do_z80_flags_clear_N
2810 andi z_flags,~(1<<ZFL_N)
2814 .macro do_z80_flags_op_rotate
2815 ; must not change avr carry flag!
2817 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
2819 andi z_flags, ~( (1<<ZFL_C) )
2823 .macro do_z80_flags_op_and
2825 ori z_flags,(1<<ZFL_H)
2827 ori z_flags,(1<<ZFL_H)
2831 .macro do_z80_flags_op_or
2840 ;----------------------------------------------------------------
2841 ;|Mnemonic |SZHPNC|Description |Notes |
2842 ;----------------------------------------------------------------
2843 ;|INC r |***V0-|Increment |r=r+1 |
2844 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2845 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2846 ;|----------|SZHP C|---------- 8080 ----------------------------|
2847 ;|INC r |**-P0-|Increment |r=r+1 |
2848 ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 |
2855 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2856 ldpmx temp2, sz53p_tab, opl
2861 ;----------------------------------------------------------------
2862 ;|Mnemonic |SZHPNC|Description |Notes |
2863 ;----------------------------------------------------------------
2864 ;|DEC r |***V1-|Decrement |s=s-1 |
2865 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2866 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2867 ;|----------|SZHP C|---------- 8080 ----------------------------|
2868 ;|DEC r |**-P -|Increment |r=r+1 |
2869 ;|DEC [HL] |**-P -|Increment |[HL]=[HL]+1 |
2875 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2876 ldpmx temp2, sz53p_tab, opl
2883 ;----------------------------------------------------------------
2884 ;|Mnemonic |SZHPNC|Description |Notes |
2885 ;----------------------------------------------------------------
2886 ;|INC xx |------|Increment |xx=xx+1 |
2887 ;|INC ss |------|Increment |ss=ss+1 |
2897 ;----------------------------------------------------------------
2898 ;|Mnemonic |SZHPNC|Description |Notes |
2899 ;----------------------------------------------------------------
2900 ;|DEC xx |------|Decrement |xx=xx-1 |
2901 ;|DEC ss |------|Decrement |ss=ss-1 |
2909 ;----------------------------------------------------------------
2910 ;|Mnemonic |SZHPNC|Description |Notes |
2911 ;----------------------------------------------------------------
2912 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
2913 ;|----------|SZHP C|---------- 8080 ----------------------------|
2914 ;|RLCA |---- *|Rotate Left Circular |A=A<- |
2918 ;Rotate Left Cyclical. All bits move 1 to the
2919 ;left, the msb becomes c and lsb.
2920 do_z80_flags_op_rotate
2924 ori z_flags, (1<<ZFL_C)
2928 ;----------------------------------------------------------------
2929 ;|Mnemonic |SZHPNC|Description |Notes |
2930 ;----------------------------------------------------------------
2931 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2932 ;|----------|SZHP C|---------- 8080 ----------------------------|
2933 ;|RRCA |---- *|Rotate Right Circular|A=->A |
2937 ;Rotate Right Cyclical. All bits move 1 to the
2938 ;right, the lsb becomes c and msb.
2939 do_z80_flags_op_rotate
2943 ori z_flags, (1<<ZFL_C)
2947 ;----------------------------------------------------------------
2948 ;|Mnemonic |SZHPNC|Description |Notes |
2949 ;----------------------------------------------------------------
2950 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2951 ;|----------|SZHP C|---------- 8080 ----------------------------|
2952 ;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} |
2956 ;Rotate Right. All bits move 1 to the right, the lsb
2957 ;becomes c, c becomes msb.
2958 clc ; get z80 carry to avr carry
2961 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
2962 bmov z_flags,ZFL_C, opl,0 ; Bit 0 --> CY
2966 ;----------------------------------------------------------------
2967 ;|Mnemonic |SZHPNC|Description |Notes |
2968 ;----------------------------------------------------------------
2969 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2970 ;|----------|SZHP C|---------- 8080 ----------------------------|
2971 ;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- |
2975 ;Rotate Left. All bits move 1 to the left, the msb
2976 ;becomes c, c becomes lsb.
2980 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
2981 bmov z_flags,ZFL_C, opl,7 ; Bit 7 --> CY
2985 ;----------------------------------------------------------------
2986 ;|Mnemonic |SZHPNC|Description |Notes |
2987 ;----------------------------------------------------------------
2988 ;|ADD A,s |***V0*|Add |A=A+s |
2989 ;|----------|SZHP C|---------- 8080 ----------------------------|
2990 ;|ADD A,s |***P *|Add |A=A+s |
2996 ldpmx z_flags,sz53p_tab,opl ;S,Z,P flag
2997 bmov z_flags,ZFL_C, temp,AVR_C
3001 ;----------------------------------------------------------------
3002 ;|Mnemonic |SZHPNC|Description |Notes |
3003 ;----------------------------------------------------------------
3004 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
3005 ;|----------|SZHP C|---------- 8080 ----------------------------|
3006 ;|ADC A,s |***P *|Add with Carry |A=A+s+CY |
3015 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
3016 bmov z_flags,ZFL_C, temp,AVR_C
3020 ;----------------------------------------------------------------
3021 ;|Mnemonic |SZHPNC|Description |Notes |
3022 ;----------------------------------------------------------------
3023 ;|SUB s |***V1*|Subtract |A=A-s |
3024 ;|CP s |***V1*|Compare |A-s |
3025 ;|----------|SZHP C|---------- 8080 ----------------------------|
3026 ;|SUB s |***P *|Subtract |A=A-s |
3027 ;|CP s |***P *|Compare |A-s |
3035 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
3036 bmov z_flags,ZFL_C, temp,AVR_C
3041 ;----------------------------------------------------------------
3042 ;|Mnemonic |SZHPNC|Description |Notes |
3043 ;----------------------------------------------------------------
3044 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
3045 ;|----------|SZHP C|---------- 8080 ----------------------------|
3046 ;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY |
3057 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
3058 bmov z_flags,ZFL_C, temp,AVR_C
3063 ;----------------------------------------------------------------
3064 ;|Mnemonic |SZHPNC|Description |Notes |
3065 ;----------------------------------------------------------------
3066 ;|AND s |**1P00|Logical AND |A=A&s |
3067 ;|----------|SZHP C|---------- 8080 ----------------------------|
3068 ;|AND s |**-P 0|Logical AND |A=A&s |
3073 ldpmx z_flags,sz53p_tab,opl ;S,Z,P,N,C
3078 ;----------------------------------------------------------------
3079 ;|Mnemonic |SZHPNC|Description |Notes |
3080 ;----------------------------------------------------------------
3081 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
3082 ;|----------|SZHP C|---------- 8080 ----------------------------|
3083 ;|OR s |**-P00|Logical inclusive OR |A=Avs |
3088 ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
3092 ;----------------------------------------------------------------
3093 ;|Mnemonic |SZHPNC|Description |Notes |
3094 ;----------------------------------------------------------------
3095 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
3096 ;|----------|SZHP C|---------- 8080 ----------------------------|
3097 ;|XOR s |**-P 0|Logical Exclusive OR |A=Axs |
3102 ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
3106 ;----------------------------------------------------------------
3107 ;|Mnemonic |SZHPNC|Description |Notes |
3108 ;----------------------------------------------------------------
3109 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
3110 ;|----------|SZHP C|---------- 8080 ----------------------------|
3111 ;|ADD HL,ss |---- *|Add |HL=HL+ss |
3118 bmov z_flags,ZFL_H, temp,AVR_H
3119 bmov z_flags,ZFL_C, temp,AVR_C
3120 do_z80_flags_clear_N
3123 ;----------------------------------------------------------------
3124 ;|Mnemonic |SZHPNC|Description |Notes |
3125 ;----------------------------------------------------------------
3126 ;|LD dst,src|------|Load |dst=src |
3129 do_op_sthl: ;store hl to mem loc in opl:h
3146 ;----------------------------------------------------------------
3147 ;|Mnemonic |SZHPNC|Description |Notes |
3148 ;----------------------------------------------------------------
3149 ;|LD dst,src|------|Load |dst=src |
3165 ;----------------------------------------------------------------
3166 ;|Mnemonic |SZHPNC|Description |Notes |
3167 ;----------------------------------------------------------------
3168 ;|LD dst,src|------|Load |dst=src |
3178 ;----------------------------------------------------------------
3179 ;|Mnemonic |SZHPNC|Description |Notes |
3180 ;----------------------------------------------------------------
3181 ;|DAA |***P-*|Decimal Adjust Acc. | |
3182 ;|----------|SZHP C|---------- 8080 ----------------------------|
3186 ; Description (http://www.z80.info/z80syntx.htm#DAA):
3187 ; This instruction conditionally adjusts the accumulator for BCD addition
3188 ; and subtraction operations. For addition (ADD, ADC, INC) or subtraction
3189 ; (SUB, SBC, DEC, NEC), the following table indicates the operation performed:
3191 ; -------------------------------------------------------------------------------
3192 ; | | C Flag | HEX value in | H Flag | HEX value in | Number | C flag|
3193 ; | Operation| Before | upper digit | Before | lower digit | added | After |
3194 ; | | DAA | (bit 7-4) | DAA | (bit 3-0) | to byte | DAA |
3195 ; |-----------------------------------------------------------------------------|
3196 ; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3197 ; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
3198 ; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
3199 ; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
3200 ; | | 0 | 9-F | 0 | A-F | 66 | 1 |
3201 ; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
3202 ; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
3203 ; | | 1 | 0-2 | 0 | A-F | 66 | 1 |
3204 ; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
3205 ; |-----------------------------------------------------------------------------|
3206 ; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3207 ; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
3208 ; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
3209 ; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
3210 ; |-----------------------------------------------------------------------------|
3213 ; C: See instruction.
3215 ; P/V: Set if Acc. is even parity after operation, reset otherwise.
3216 ; H: See instruction.
3217 ; Z: Set if Acc. is Zero after operation, reset otherwise.
3218 ; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise.
3224 ldi oph,0 ; what to add
3225 sbrc z_flags,ZFL_H ; if H-Flag
3228 andi temp,0x0f ; ... or lower digit > 9
3234 sbrc z_flags,(1<<ZFL_C)
3243 ori z_flags,(1<<ZFL_C); set C
3245 sbrs z_flags,ZFL_N ; if sub-op
3246 rjmp op_da_add ; then
3249 op_da_add: ; else add-op
3262 ori z_flags,(1<<ZFL_C)
3263 andi z_flags,(1<<ZFL_N)|(1<<ZFL_C) ; preserve C,N
3264 ldpmx temp2, sz53p_tab, opl ; get S,Z,P
3266 bmov z_flags,ZFL_H, temp,AVR_H ; H (?)
3271 sbrc z_flags,ZFL_N ; if add-op
3272 rjmp do_op_da_sub ; then
3276 cpi temp,0x0a ; if lower digit > 9
3278 ori temp2,0x06 ; add 6 to lower digit
3280 sbrc z_flags,ZFL_H ; ... or H-Flag
3290 do_op_da_c: ; else sub-op
3291 sbrc z_flags,ZFL_C ;
3293 andi z_flags, ~( (1<<ZFL_S) | (1<<ZFL_Z) | (1<<ZFL_H) )
3296 bst temp,AVR_Z ;Z-Flag
3298 bst temp,AVR_N ;S-Flag
3300 sbrc temp2,5 ;C-Flag, set if 0x06 added
3301 ori z_flags,(1<<ZFL_C) ;
3305 do_op_da_sub: ;TODO:
3310 ;----------------------------------------------------------------
3311 ;|Mnemonic |SZHPNC|Description |Notes |
3312 ;----------------------------------------------------------------
3313 ;|SCF |--0-01|Set Carry Flag |CY=1 |
3314 ;|----------|SZHP C|---------- 8080 ----------------------------|
3318 andi z_flags,~((1<<ZFL_H)|(1<<ZFL_N))
3319 ori z_flags,(1<<ZFL_C)
3322 ;----------------------------------------------------------------
3323 ;|Mnemonic |SZHPNC|Description |Notes |
3324 ;----------------------------------------------------------------
3325 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
3326 ;|----------|SZHP C|---------- 8080 ----------------------------|
3327 ;|SCF |---- 1|Set Carry Flag |CY=1 |
3331 do_z80_flags_clear_N
3336 ;----------------------------------------------------------------
3337 ;|Mnemonic |SZHPNC|Description |Notes |
3338 ;----------------------------------------------------------------
3339 ;|CPL |--1-1-|Complement |A=~A |
3340 ;|----------|SZHP C|---------- 8080 ----------------------------|
3341 ;|CPL |---- -|Complement |A=~A |
3350 ;----------------------------------------------------------------
3351 ;|Mnemonic |SZHPNC|Description |Notes |
3352 ;----------------------------------------------------------------
3353 ;|PUSH xx |------|Push |-[SP]=xx |
3354 ;|PUSH qq |------|Push |-[SP]=qq |
3404 .db ", SP is now ",0
3415 ;----------------------------------------------------------------
3416 ;|Mnemonic |SZHPNC|Description |Notes |
3417 ;----------------------------------------------------------------
3418 ;|POP xx |------|Pop |xx=[SP]+ |
3419 ;|POP qq |------|Pop |qq=[SP]+ |
3445 .db "Stack pop: val ",0
3461 ;----------------------------------------------------------------
3462 ;|Mnemonic |SZHPNC|Description |Notes |
3463 ;----------------------------------------------------------------
3464 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
3465 ;|EX DE,HL |------|Exchange |DE<->HL |
3477 ;----------------------------------------------------------------
3478 ;|Mnemonic |SZHPNC|Description |Notes |
3479 ;----------------------------------------------------------------
3481 ; TODO: Implement IFF1, IFF2
3485 ;----------------------------------------------------------------
3486 ;|Mnemonic |SZHPNC|Description |Notes |
3487 ;----------------------------------------------------------------
3489 ; TODO: Implement IFF1, IFF2
3493 ;----------------------------------------------------------------
3494 ;|Mnemonic |SZHPNC|Description |Notes |
3495 ;----------------------------------------------------------------
3496 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3497 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3498 ;|RET cc |------|Conditional Return |If cc RET |
3508 ;----------------------------------------------------------------
3509 ;|Mnemonic |SZHPNC|Description |Notes |
3510 ;----------------------------------------------------------------
3511 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3512 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3513 ;|RET cc |------|Conditional Return |If cc RET |
3523 ;----------------------------------------------------------------
3524 ;|Mnemonic |SZHPNC|Description |Notes |
3525 ;----------------------------------------------------------------
3526 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3527 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3528 ;|RET cc |------|Conditional Return |If cc RET |
3538 ;----------------------------------------------------------------
3539 ;|Mnemonic |SZHPNC|Description |Notes |
3540 ;----------------------------------------------------------------
3541 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3542 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3543 ;|RET cc |------|Conditional Return |If cc RET |
3553 ;----------------------------------------------------------------
3554 ;|Mnemonic |SZHPNC|Description |Notes |
3555 ;----------------------------------------------------------------
3556 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3557 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3558 ;|RET cc |------|Conditional Return |If cc RET |
3568 ;----------------------------------------------------------------
3569 ;|Mnemonic |SZHPNC|Description |Notes |
3570 ;----------------------------------------------------------------
3571 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3572 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3573 ;|RET cc |------|Conditional Return |If cc RET |
3583 ;----------------------------------------------------------------
3584 ;|Mnemonic |SZHPNC|Description |Notes |
3585 ;----------------------------------------------------------------
3586 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3587 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3588 ;|RET cc |------|Conditional Return |If cc RET |
3591 do_op_ifp: ;sign positive, aka s=0
3598 ;----------------------------------------------------------------
3599 ;|Mnemonic |SZHPNC|Description |Notes |
3600 ;----------------------------------------------------------------
3601 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3602 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3603 ;|RET cc |------|Conditional Return |If cc RET |
3606 do_op_ifm: ;sign negative, aka s=1
3613 ;----------------------------------------------------------------
3614 ;|Mnemonic |SZHPNC|Description |Notes |
3615 ;----------------------------------------------------------------
3616 ;|OUT [n],A |------|Output |[n]=A |
3619 ;Interface with peripherials goes here :)
3620 do_op_outa: ; out (opl),a
3623 .db 13,"Port write: ",0
3638 ;----------------------------------------------------------------
3639 ;|Mnemonic |SZHPNC|Description |Notes |
3640 ;----------------------------------------------------------------
3641 ;|IN A,[n] |------|Input |A=[n] |
3644 do_op_in: ; in a,(opl)
3647 .db 13,"Port read: (",0
3665 ;----------------------------------------------------------------
3690 ;----------------------------------------------------------------
3693 .db "Invalid opcode @ PC=",0,0
3699 ;----------------------------------------------------------------
3703 ;----------------------------------------------------------------
3704 ; Lookup table, stolen from z80ex, Z80 emulation library.
3705 ; http://z80ex.sourceforge.net/
3707 ; The S, Z, 5 and 3 bits and the parity of the lookup value
3709 .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3710 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3711 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3712 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3713 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3714 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3715 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3716 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3717 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3718 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3719 .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3720 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3721 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3722 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3723 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3724 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3725 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3726 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3727 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3728 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3729 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3730 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3731 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3732 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3733 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3734 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3735 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3736 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3737 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3738 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3739 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3740 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3743 ; ----------------------- Opcode decoding -------------------------
3745 ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
3746 ; operations: fetch, do something, store.
3747 ; The table is made of 256 words. These 16-bit words consist of
3748 ; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store
3749 ; operation (bit 5-9).
3752 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
3753 .dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
3754 .dw (FETCH_A | OP_NOP | STORE_MBC ) ; 02 LD (BC),A
3755 .dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
3756 .dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
3757 .dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
3758 .dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
3759 .dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
3760 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
3761 .dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
3762 .dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
3763 .dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
3764 .dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
3765 .dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
3766 .dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
3767 .dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
3768 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
3769 .dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn
3770 .dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A
3771 .dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
3772 .dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D
3773 .dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D
3774 .dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n
3775 .dw (FETCH_A | OP_RL | STORE_A ) ; 17 RLA
3776 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 18 oo JR o (Z80)
3777 .dw (FETCH_DE | OP_ADDHL | STORE_HL ) ; 19 ADD HL,DE
3778 .dw (FETCH_MDE | OP_NOP | STORE_A ) ; 1A LD A,(DE)
3779 .dw (FETCH_DE | OP_DEC16 | STORE_DE ) ; 1B DEC DE
3780 .dw (FETCH_E | OP_INC | STORE_E ) ; 1C INC E
3781 .dw (FETCH_E | OP_DEC | STORE_E ) ; 1D DEC E
3782 .dw (FETCH_DIR8 | OP_NOP | STORE_E ) ; 1E nn LD E,n
3783 .dw (FETCH_A | OP_RR | STORE_A ) ; 1F RRA
3784 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 20 oo JR NZ,o (Z80)
3785 .dw (FETCH_DIR16| OP_NOP | STORE_HL ) ; 21 nn nn LD HL,nn
3786 .dw (FETCH_DIR16| OP_STHL | STORE_NOP) ; 22 nn nn LD (nn),HL
3787 .dw (FETCH_HL | OP_INC16 | STORE_HL ) ; 23 INC HL
3788 .dw (FETCH_H | OP_INC | STORE_H ) ; 24 INC H
3789 .dw (FETCH_H | OP_DEC | STORE_H ) ; 25 DEC H
3790 .dw (FETCH_DIR8 | OP_NOP | STORE_H ) ; 26 nn LD H,n
3791 .dw (FETCH_A | OP_DA | STORE_A ) ; 27 DAA
3792 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 28 oo JR Z,o (Z80)
3793 .dw (FETCH_HL | OP_ADDHL | STORE_HL ) ; 29 ADD HL,HL
3794 .dw (FETCH_DIR16| OP_RMEM16 | STORE_HL ) ; 2A nn nn LD HL,(nn)
3795 .dw (FETCH_HL | OP_DEC16 | STORE_HL ) ; 2B DEC HL
3796 .dw (FETCH_L | OP_INC | STORE_L ) ; 2C INC L
3797 .dw (FETCH_L | OP_DEC | STORE_L ) ; 2D DEC L
3798 .dw (FETCH_DIR8 | OP_NOP | STORE_L ) ; 2E nn LD L,n
3799 .dw (FETCH_A | OP_CPL | STORE_A ) ; 2F CPL
3800 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 30 oo JR NC,o (Z80)
3801 .dw (FETCH_DIR16| OP_NOP | STORE_SP ) ; 31 nn nn LD SP,nn
3802 .dw (FETCH_DIR16| OP_NOP | STORE_AM ) ; 32 nn nn LD (nn),A
3803 .dw (FETCH_SP | OP_INC16 | STORE_SP ) ; 33 INC SP
3804 .dw (FETCH_MHL | OP_INC | STORE_MHL) ; 34 INC (HL)
3805 .dw (FETCH_MHL | OP_DEC | STORE_MHL) ; 35 DEC (HL)
3806 .dw (FETCH_DIR8 | OP_NOP | STORE_MHL) ; 36 nn LD (HL),n
3807 .dw (FETCH_NOP | OP_SCF | STORE_NOP) ; 37 SCF
3808 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 38 oo JR C,o (Z80)
3809 .dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
3810 .dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
3811 .dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
3812 .dw (FETCH_A | OP_INC | STORE_A ) ; 3C INC A
3813 .dw (FETCH_A | OP_DEC | STORE_A ) ; 3D DEC A
3814 .dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
3815 .dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
3816 .dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r
3817 .dw (FETCH_C | OP_NOP | STORE_B ) ; 41 LD B,r
3818 .dw (FETCH_D | OP_NOP | STORE_B ) ; 42 LD B,r
3819 .dw (FETCH_E | OP_NOP | STORE_B ) ; 43 LD B,r
3820 .dw (FETCH_H | OP_NOP | STORE_B ) ; 44 LD B,r
3821 .dw (FETCH_L | OP_NOP | STORE_B ) ; 45 LD B,r
3822 .dw (FETCH_MHL | OP_NOP | STORE_B ) ; 46 LD B,r
3823 .dw (FETCH_A | OP_NOP | STORE_B ) ; 47 LD B,r
3824 .dw (FETCH_B | OP_NOP | STORE_C ) ; 48 LD C,r
3825 .dw (FETCH_C | OP_NOP | STORE_C ) ; 49 LD C,r
3826 .dw (FETCH_D | OP_NOP | STORE_C ) ; 4A LD C,r
3827 .dw (FETCH_E | OP_NOP | STORE_C ) ; 4B LD C,r
3828 .dw (FETCH_H | OP_NOP | STORE_C ) ; 4C LD C,r
3829 .dw (FETCH_L | OP_NOP | STORE_C ) ; 4D LD C,r
3830 .dw (FETCH_MHL | OP_NOP | STORE_C ) ; 4E LD C,r
3831 .dw (FETCH_A | OP_NOP | STORE_C ) ; 4F LD C,r
3832 .dw (FETCH_B | OP_NOP | STORE_D ) ; 50 LD D,r
3833 .dw (FETCH_C | OP_NOP | STORE_D ) ; 51 LD D,r
3834 .dw (FETCH_D | OP_NOP | STORE_D ) ; 52 LD D,r
3835 .dw (FETCH_E | OP_NOP | STORE_D ) ; 53 LD D,r
3836 .dw (FETCH_H | OP_NOP | STORE_D ) ; 54 LD D,r
3837 .dw (FETCH_L | OP_NOP | STORE_D ) ; 55 LD D,r
3838 .dw (FETCH_MHL | OP_NOP | STORE_D ) ; 56 LD D,r
3839 .dw (FETCH_A | OP_NOP | STORE_D ) ; 57 LD D,r
3840 .dw (FETCH_B | OP_NOP | STORE_E ) ; 58 LD E,r
3841 .dw (FETCH_C | OP_NOP | STORE_E ) ; 59 LD E,r
3842 .dw (FETCH_D | OP_NOP | STORE_E ) ; 5A LD E,r
3843 .dw (FETCH_E | OP_NOP | STORE_E ) ; 5B LD E,r
3844 .dw (FETCH_H | OP_NOP | STORE_E ) ; 5C LD E,r
3845 .dw (FETCH_L | OP_NOP | STORE_E ) ; 5D LD E,r
3846 .dw (FETCH_MHL | OP_NOP | STORE_E ) ; 5E LD E,r
3847 .dw (FETCH_A | OP_NOP | STORE_E ) ; 5F LD E,r
3848 .dw (FETCH_B | OP_NOP | STORE_H ) ; 60 LD H,r
3849 .dw (FETCH_C | OP_NOP | STORE_H ) ; 61 LD H,r
3850 .dw (FETCH_D | OP_NOP | STORE_H ) ; 62 LD H,r
3851 .dw (FETCH_E | OP_NOP | STORE_H ) ; 63 LD H,r
3852 .dw (FETCH_H | OP_NOP | STORE_H ) ; 64 LD H,r
3853 .dw (FETCH_L | OP_NOP | STORE_H ) ; 65 LD H,r
3854 .dw (FETCH_MHL | OP_NOP | STORE_H ) ; 66 LD H,r
3855 .dw (FETCH_A | OP_NOP | STORE_H ) ; 67 LD H,r
3856 .dw (FETCH_B | OP_NOP | STORE_L ) ; 68 LD L,r
3857 .dw (FETCH_C | OP_NOP | STORE_L ) ; 69 LD L,r
3858 .dw (FETCH_D | OP_NOP | STORE_L ) ; 6A LD L,r
3859 .dw (FETCH_E | OP_NOP | STORE_L ) ; 6B LD L,r
3860 .dw (FETCH_H | OP_NOP | STORE_L ) ; 6C LD L,r
3861 .dw (FETCH_L | OP_NOP | STORE_L ) ; 6D LD L,r
3862 .dw (FETCH_MHL | OP_NOP | STORE_L ) ; 6E LD L,r
3863 .dw (FETCH_A | OP_NOP | STORE_L ) ; 6F LD L,r
3864 .dw (FETCH_B | OP_NOP | STORE_MHL) ; 70 LD (HL),r
3865 .dw (FETCH_C | OP_NOP | STORE_MHL) ; 71 LD (HL),r
3866 .dw (FETCH_D | OP_NOP | STORE_MHL) ; 72 LD (HL),r
3867 .dw (FETCH_E | OP_NOP | STORE_MHL) ; 73 LD (HL),r
3868 .dw (FETCH_H | OP_NOP | STORE_MHL) ; 74 LD (HL),r
3869 .dw (FETCH_L | OP_NOP | STORE_MHL) ; 75 LD (HL),r
3870 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 76 HALT
3871 .dw (FETCH_A | OP_NOP | STORE_MHL) ; 77 LD (HL),r
3872 .dw (FETCH_B | OP_NOP | STORE_A ) ; 78 LD A,r
3873 .dw (FETCH_C | OP_NOP | STORE_A ) ; 79 LD A,r
3874 .dw (FETCH_D | OP_NOP | STORE_A ) ; 7A LD A,r
3875 .dw (FETCH_E | OP_NOP | STORE_A ) ; 7B LD A,r
3876 .dw (FETCH_H | OP_NOP | STORE_A ) ; 7C LD A,r
3877 .dw (FETCH_L | OP_NOP | STORE_A ) ; 7D LD A,r
3878 .dw (FETCH_MHL | OP_NOP | STORE_A ) ; 7E LD A,r
3879 .dw (FETCH_A | OP_NOP | STORE_A ) ; 7F LD A,r
3880 .dw (FETCH_B | OP_ADDA | STORE_A ) ; 80 ADD A,r
3881 .dw (FETCH_C | OP_ADDA | STORE_A ) ; 81 ADD A,r
3882 .dw (FETCH_D | OP_ADDA | STORE_A ) ; 82 ADD A,r
3883 .dw (FETCH_E | OP_ADDA | STORE_A ) ; 83 ADD A,r
3884 .dw (FETCH_H | OP_ADDA | STORE_A ) ; 84 ADD A,r
3885 .dw (FETCH_L | OP_ADDA | STORE_A ) ; 85 ADD A,r
3886 .dw (FETCH_MHL | OP_ADDA | STORE_A ) ; 86 ADD A,r
3887 .dw (FETCH_A | OP_ADDA | STORE_A ) ; 87 ADD A,r
3888 .dw (FETCH_B | OP_ADCA | STORE_A ) ; 88 ADC A,r
3889 .dw (FETCH_C | OP_ADCA | STORE_A ) ; 89 ADC A,r
3890 .dw (FETCH_D | OP_ADCA | STORE_A ) ; 8A ADC A,r
3891 .dw (FETCH_E | OP_ADCA | STORE_A ) ; 8B ADC A,r
3892 .dw (FETCH_H | OP_ADCA | STORE_A ) ; 8C ADC A,r
3893 .dw (FETCH_L | OP_ADCA | STORE_A ) ; 8D ADC A,r
3894 .dw (FETCH_MHL | OP_ADCA | STORE_A ) ; 8E ADC A,r
3895 .dw (FETCH_A | OP_ADCA | STORE_A ) ; 8F ADC A,r
3896 .dw (FETCH_B | OP_SUBFA | STORE_A ) ; 90 SUB A,r
3897 .dw (FETCH_C | OP_SUBFA | STORE_A ) ; 91 SUB A,r
3898 .dw (FETCH_D | OP_SUBFA | STORE_A ) ; 92 SUB A,r
3899 .dw (FETCH_E | OP_SUBFA | STORE_A ) ; 93 SUB A,r
3900 .dw (FETCH_H | OP_SUBFA | STORE_A ) ; 94 SUB A,r
3901 .dw (FETCH_L | OP_SUBFA | STORE_A ) ; 95 SUB A,r
3902 .dw (FETCH_MHL | OP_SUBFA | STORE_A ) ; 96 SUB A,r
3903 .dw (FETCH_A | OP_SUBFA | STORE_A ) ; 97 SUB A,r
3904 .dw (FETCH_B | OP_SBCFA | STORE_A ) ; 98 SBC A,r
3905 .dw (FETCH_C | OP_SBCFA | STORE_A ) ; 99 SBC A,r
3906 .dw (FETCH_D | OP_SBCFA | STORE_A ) ; 9A SBC A,r
3907 .dw (FETCH_E | OP_SBCFA | STORE_A ) ; 9B SBC A,r
3908 .dw (FETCH_H | OP_SBCFA | STORE_A ) ; 9C SBC A,r
3909 .dw (FETCH_L | OP_SBCFA | STORE_A ) ; 9D SBC A,r
3910 .dw (FETCH_MHL | OP_SBCFA | STORE_A ) ; 9E SBC A,r
3911 .dw (FETCH_A | OP_SBCFA | STORE_A ) ; 9F SBC A,r
3912 .dw (FETCH_B | OP_ANDA | STORE_A ) ; A0 AND A,r
3913 .dw (FETCH_C | OP_ANDA | STORE_A ) ; A1 AND A,r
3914 .dw (FETCH_D | OP_ANDA | STORE_A ) ; A2 AND A,r
3915 .dw (FETCH_E | OP_ANDA | STORE_A ) ; A3 AND A,r
3916 .dw (FETCH_H | OP_ANDA | STORE_A ) ; A4 AND A,r
3917 .dw (FETCH_L | OP_ANDA | STORE_A ) ; A5 AND A,r
3918 .dw (FETCH_MHL | OP_ANDA | STORE_A ) ; A6 AND A,r
3919 .dw (FETCH_A | OP_ANDA | STORE_A ) ; A7 AND A,r
3920 .dw (FETCH_B | OP_XORA | STORE_A ) ; A8 XOR A,r
3921 .dw (FETCH_C | OP_XORA | STORE_A ) ; A9 XOR A,r
3922 .dw (FETCH_D | OP_XORA | STORE_A ) ; AA XOR A,r
3923 .dw (FETCH_E | OP_XORA | STORE_A ) ; AB XOR A,r
3924 .dw (FETCH_H | OP_XORA | STORE_A ) ; AC XOR A,r
3925 .dw (FETCH_L | OP_XORA | STORE_A ) ; AD XOR A,r
3926 .dw (FETCH_MHL | OP_XORA | STORE_A ) ; AE XOR A,r
3927 .dw (FETCH_A | OP_XORA | STORE_A ) ; AF XOR A,r
3928 .dw (FETCH_B | OP_ORA | STORE_A ) ; B0 OR A,r
3929 .dw (FETCH_C | OP_ORA | STORE_A ) ; B1 OR A,r
3930 .dw (FETCH_D | OP_ORA | STORE_A ) ; B2 OR A,r
3931 .dw (FETCH_E | OP_ORA | STORE_A ) ; B3 OR A,r
3932 .dw (FETCH_H | OP_ORA | STORE_A ) ; B4 OR A,r
3933 .dw (FETCH_L | OP_ORA | STORE_A ) ; B5 OR A,r
3934 .dw (FETCH_MHL | OP_ORA | STORE_A ) ; B6 OR A,r
3935 .dw (FETCH_A | OP_ORA | STORE_A ) ; B7 OR A,r
3936 .dw (FETCH_B | OP_SUBFA | STORE_NOP) ; B8 CP A,r
3937 .dw (FETCH_C | OP_SUBFA | STORE_NOP) ; B9 CP A,r
3938 .dw (FETCH_D | OP_SUBFA | STORE_NOP) ; BA CP A,r
3939 .dw (FETCH_E | OP_SUBFA | STORE_NOP) ; BB CP A,r
3940 .dw (FETCH_H | OP_SUBFA | STORE_NOP) ; BC CP A,r
3941 .dw (FETCH_L | OP_SUBFA | STORE_NOP) ; BD CP A,r
3942 .dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; BE CP A,r
3943 .dw (FETCH_A | OP_SUBFA | STORE_NOP) ; BF CP A,r
3944 .dw (FETCH_NOP | OP_IFNZ | STORE_RET) ; C0 RET NZ
3945 .dw (FETCH_NOP | OP_POP16 | STORE_BC ) ; C1 POP BC
3946 .dw (FETCH_DIR16| OP_IFNZ | STORE_PC ) ; C2 nn nn JP NZ,nn
3947 .dw (FETCH_DIR16| OP_NOP | STORE_PC ) ; C3 nn nn JP nn
3948 .dw (FETCH_DIR16| OP_IFNZ | STORE_CALL) ; C4 nn nn CALL NZ,nn
3949 .dw (FETCH_BC | OP_PUSH16 | STORE_NOP) ; C5 PUSH BC
3950 .dw (FETCH_DIR8 | OP_ADDA | STORE_A ) ; C6 nn ADD A,n
3951 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; C7 RST 0
3952 .dw (FETCH_NOP | OP_IFZ | STORE_RET) ; C8 RET Z
3953 .dw (FETCH_NOP | OP_NOP | STORE_RET) ; C9 RET
3954 .dw (FETCH_DIR16| OP_IFZ | STORE_PC ) ; CA nn nn JP Z,nn
3955 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; CB (Z80 specific)
3956 .dw (FETCH_DIR16| OP_IFZ | STORE_CALL) ; CC nn nn CALL Z,nn
3957 .dw (FETCH_DIR16| OP_NOP | STORE_CALL) ; CD nn nn CALL nn
3958 .dw (FETCH_DIR8 | OP_ADCA | STORE_A ) ; CE nn ADC A,n
3959 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; CF RST 8H
3960 .dw (FETCH_NOP | OP_IFNC | STORE_RET) ; D0 RET NC
3961 .dw (FETCH_NOP | OP_POP16 | STORE_DE ) ; D1 POP DE
3962 .dw (FETCH_DIR16| OP_IFNC | STORE_PC ) ; D2 nn nn JP NC,nn
3963 .dw (FETCH_DIR8 | OP_OUTA | STORE_NOP) ; D3 nn OUT (n),A
3964 .dw (FETCH_DIR16| OP_IFNC | STORE_CALL) ; D4 nn nn CALL NC,nn
3965 .dw (FETCH_DE | OP_PUSH16 | STORE_NOP) ; D5 PUSH DE
3966 .dw (FETCH_DIR8 | OP_SUBFA | STORE_A ) ; D6 nn SUB n
3967 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H
3968 .dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C
3969 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
3970 .dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn
3971 .dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
3972 .dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn
3973 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; DD (Z80)
3974 .dw (FETCH_DIR8 | OP_SBCFA | STORE_A ) ; DE nn SBC A,n
3975 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; DF RST 18H
3976 .dw (FETCH_NOP | OP_IFPO | STORE_RET) ; E0 RET PO
3977 .dw (FETCH_NOP | OP_POP16 | STORE_HL ) ; E1 POP HL
3978 .dw (FETCH_DIR16| OP_IFPO | STORE_PC ) ; E2 nn nn JP PO,nn
3979 .dw (FETCH_MSP | OP_EXHL | STORE_MSP) ; E3 EX (SP),HL
3980 .dw (FETCH_DIR16| OP_IFPO | STORE_CALL) ; E4 nn nn CALL PO,nn
3981 .dw (FETCH_HL | OP_PUSH16 | STORE_NOP) ; E5 PUSH HL
3982 .dw (FETCH_DIR8 | OP_ANDA | STORE_A ) ; E6 nn AND n
3983 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; E7 RST 20H
3984 .dw (FETCH_NOP | OP_IFPE | STORE_RET) ; E8 RET PE
3985 .dw (FETCH_HL | OP_NOP | STORE_PC ) ; E9 JP (HL)
3986 .dw (FETCH_DIR16| OP_IFPE | STORE_PC ) ; EA nn nn JP PE,nn
3987 .dw (FETCH_DE | OP_EXHL | STORE_DE ) ; EB EX DE,HL
3988 .dw (FETCH_DIR16| OP_IFPE | STORE_CALL) ; EC nn nn CALL PE,nn
3989 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; ED (Z80 specific)
3990 .dw (FETCH_DIR8 | OP_XORA | STORE_A ) ; EE nn XOR n
3991 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; EF RST 28H
3992 .dw (FETCH_NOP | OP_IFP | STORE_RET) ; F0 RET P
3993 .dw (FETCH_NOP | OP_POP16 | STORE_AF ) ; F1 POP AF
3994 .dw (FETCH_DIR16| OP_IFP | STORE_PC ) ; F2 nn nn JP P,nn
3995 .dw (FETCH_NOP | OP_DI | STORE_NOP) ; F3 DI
3996 .dw (FETCH_DIR16| OP_IFP | STORE_CALL) ; F4 nn nn CALL P,nn
3997 .dw (FETCH_AF | OP_PUSH16 | STORE_NOP) ; F5 PUSH AF
3998 .dw (FETCH_DIR8 | OP_ORA | STORE_A ) ; F6 nn OR n
3999 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; F7 RST 30H
4000 .dw (FETCH_NOP | OP_IFM | STORE_RET) ; F8 RET M
4001 .dw (FETCH_HL | OP_NOP | STORE_SP ) ; F9 LD SP,HL
4002 .dw (FETCH_DIR16| OP_IFM | STORE_PC ) ; FA nn nn JP M,nn
4003 .dw (FETCH_NOP | OP_EI | STORE_NOP) ; FB EI
4004 .dw (FETCH_DIR16| OP_IFM | STORE_CALL) ; FC nn nn CALL M,nn
4005 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific)
4006 .dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; FE nn CP n
4007 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H
4009 ; vim:set ts=8 noet nowrap