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 */
93 .equ RAM_AH_MASK = (1<<ram_a8)|(1<<ram_a7)|(1<<ram_a6)|(1<<ram_a5)
94 .equ PD_OUTPUT_MASK = (1<<mmc_cs) | (1<<ram_oe) | RAM_AH_MASK
112 .equ RAM_AL_MASK = (1<<ram_a4)|(1<<ram_a3)|(1<<ram_a2)|(1<<ram_a1)|(1<<ram_a0)
113 .equ PB_OUTPUT_MASK = (1<<ram_ras) | RAM_AL_MASK
116 #if DRAM_DQ_ORDER == 1
132 .equ RAM_DQ_MASK = (1<<ram_d3)|(1<<ram_d2)|(1<<ram_d1)|(1<<ram_d0)
133 .equ PC_OUTPUT_MASK = (1<<ram_cas)|(1<<ram_w)
136 ;Flag bits in z_flags
144 ;Register definitions
162 .def temp = R16 ;The temp register
163 .def temp2 = R17 ;Second temp register
178 ; This is the base z80 port address for clock access
179 #define TIMERPORT 0x40
180 #define TIMER_CTL TIMERPORT
181 #define TIMER_MSECS TIMERPORT+1
182 #define TIMER_SECS TIMER_MSECS+2
184 #define starttimercmd 1
185 #define quitTimerCmd 2
186 #define printTimerCmd 15
194 ;Sector buffer for 512 byte reads/writes from/to SD-card
202 rjmp start ; reset vector
204 rjmp refrint ; tim2cmpa
205 .org OC1Aaddr ; Timer/Counter1 Compare Match A
206 rjmp sysclockint ; 1ms system timer
208 rjmp rxint ; USART receive int.
212 .org INT_VECTORS_SIZE
215 ldi temp,low(RAMEND) ; top of memory
216 out SPL,temp ; init stack pointer
217 ldi temp,high(RAMEND) ; top of memory
218 out SPH,temp ; init stack pointer
222 #if defined __ATmega8__
226 ldi temp,(1<<WDCE) | (1<<WDE)
234 ldi temp,(1<<WDCE) | (1<<WDE)
241 ldi temp,PB_OUTPUT_MASK
243 ldi temp,PD_OUTPUT_MASK
245 ldi temp,PC_OUTPUT_MASK
257 ldi temp,0 ; reset receive buffer
263 #if defined __ATmega8__
264 ldi temp, (1<<TXEN) | (1<<RXEN) | (1<<RXCIE)
266 ldi temp, (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0)
268 ldi temp, HIGH(UBRR_VAL)
270 ldi temp, LOW(UBRR_VAL)
273 ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
275 ldi temp, (1<<UCSZ01) | (1<<UCSZ00)
277 ldi temp, HIGH(UBRR_VAL)
279 ldi temp, LOW(UBRR_VAL)
283 ;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
286 ldi temp,REFR_CNT*2 ; 2 cycles per int
288 ldi temp,(1<<WGM21) | REFR_CS ;CTC, clk/REFR_PRE
293 ldi temp,REFR_CNT ;=312 cycles
297 ldi temp, REFR_CS ;clk/REFR_PRE
304 ; Init clock/timer system
306 ldi zl,low(timer_base)
307 ldi zh,high(timer_base)
315 ; Init timer 1 as 1 ms system clock tick.
318 ldi temp,high(F_CPU/1000)
320 ldi temp,low(F_CPU/1000)
322 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
328 ldi temp,high(F_CPU/1000)
330 ldi temp,low(F_CPU/1000)
332 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
348 .db "CPM on an AVR, v1.0",13,0,0
352 .db "Initing mmc...",13,0
358 .db "Testing RAM: fill...",0,0
383 .db "reread...",13,0,0
418 ;Fill ram with cbs, which (for now) will trigger an invalid opcode error.
433 ;Load initial sector from MMC (512 bytes)
438 ;Save to Z80 RAM (only 128 bytes because that's retro)
440 ldi zh,high(sectbuff)
454 cpi zl,low(sectbuff+128)
456 cpi zh,high(sectbuff+128)
469 .db 13,"Ok, CPU is live!",13,0,0
498 ; *** Stage 1: Fetch next opcode
522 ; *** Stage 2: Decode it using the ins_table.
524 ldi zl,low(inst_table*2)
525 ldi zh,high(inst_table*2)
547 ; *** Stage 3: Fetch operand. Use the fetch jumptable for this.
554 ldi zl,low(fetchjumps*2)
555 ldi zh,high(fetchjumps*2)
579 ; *** Stage 4: Execute operation :) Use the op jumptable for this.
585 ldi zl,low(opjumps*2)
586 ldi zh,high(opjumps*2)
609 ; *** Stage 5: Store operand. Use the store jumptable for this.
617 ldi zl,low(storejumps*2)
618 ldi zh,high(storejumps*2)
650 ; ----------------Virtual peripherial interface ------
652 ;The hw is modelled to make writing a CPM BIOS easier.
654 ;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise.
655 ;1 - Console input, aka UDR.
661 ;22 - Trigger - write 1 to read, 2 to write a sector using the above info.
662 ; This will automatically move track, sector and dma addr to the next sector.
664 ;Called with port in temp2. Should return value in temp.
671 cpi temp2,TIMER_MSECS
673 cpi temp2,TIMER_MSECS+6
681 ;Called with port in temp2 and value in temp.
700 cpi temp2,TIMER_MSECS+6
754 .db "Disk read: track ",0
772 ;First, convert track/sector to an LBA address (in 128byte blocks)
789 ;Now, see what has to be done.
797 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
802 ;Read 512-byte sector
806 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
808 ldi zh,high(sectbuff)
836 brne dskDoItReadMemLoop
840 ;The write routines is a bit naive: it'll read the 512-byte sector the 128byte CPM-sector
841 ;resides in into memory, will overwrite the needed 128 byte with the Z80s memory buffer
842 ;and will then write it back to disk. In theory, this would mean that every 512 bytes
843 ;written will take 4 write cycles, while theoretically the writes could be deferred so we
844 ;would only have to do one write cycle.
849 .db "Disk write: track ",0
870 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
875 ;Read 512-byte sector
883 ;Copy the data from the Z80 DMA buffer in external memory to the right place in the
885 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
887 ldi zh,high(sectbuff)
915 brne dskDoItWriteMemLoop
920 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
925 ;Write the sector back.
932 ; ----------------- MMC/SD routines ------------------
967 ;Wait till the mmc answers with the response in temp2, or till a timeout happens.
974 brne mmcWaitResploopEnd
987 .db ": Error: MMC resp timeout!",13,0
994 ;Init start: send 80 clocks with cs disabled
998 ldi temp2,10 ; exactly 80 clocks
1020 ldi temp,0xff ;dummy
1022 ldi temp,0xff ;dummy
1036 ldi temp,0xff ;return byte
1039 ldi temp2,0 ;Error Code 0
1040 rcall mmcWaitResp ;Test on CMD0 is OK
1042 sbi P_MMC_CS,mmc_cs ;disable /CS
1046 ;Read OCR till card is ready
1047 ldi temp2,20 ;repeat counter
1051 cbi P_MMC_CS,mmc_cs ;enable /CS
1052 ldi temp,0xff ;dummy
1064 ; ldi temp,0x95 ;crc
1070 rcall mmcWaitResp ;wait until mmc-card send a byte <> 0xFF
1071 ;the first answer must be 0x01 (Idle-Mode)
1073 breq mmcInitOcrLoopDone ;second answer is 0x00 (Idle-Mode leave) CMD1 is OK
1075 sbi P_MMC_CS,mmc_cs ;disable /CS
1077 ; rcall mmcByteNoSend ;unnecessary
1085 brne mmcInitOcrLoop ;repeat
1092 sbi P_MMC_CS,mmc_cs ;disable /CS
1100 ;Call this with adrh:adrl = sector number
1101 ;16bit lba address means a max reach of 32M.
1108 ldi temp,0x51 ;cmd (read sector)
1123 ldi temp,0xff ;return byte
1134 ;Read sector to AVR RAM
1135 ldi zl,low(sectbuff)
1136 ldi zh,high(sectbuff)
1140 cpi zl,low(sectbuff+512)
1142 cpi zh,high(sectbuff+512)
1157 ;Call this with adrh:adrl = sector number
1158 ;16bit lba address means a max reach of 32M.
1166 ldi temp,0x58 ;cmd (write sector)
1181 ldi temp,0xff ;return byte
1192 ;Write sector from AVR RAM
1193 ldi zl,low(sectbuff)
1194 ldi zh,high(sectbuff)
1198 cpi zl,low(sectbuff+512)
1200 cpi zh,high(sectbuff+512)
1207 ;Status. Ignored for now.
1210 ;Wait till the mmc has written everything
1224 ;Set up wdt to time out after 1 sec.
1227 #if defined __ATmega8__
1230 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1235 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1242 ; ------------------ DRAM routines -------------
1246 #if DRAM_DQ_ORDER == 1
1247 #define CLASSIC_DRAM 0
1249 #define CLASSIC_DRAM 1 /* Change manualy, if you want new hw w/ old sw */
1253 #if DRAM_DQ_ORDER == 0
1254 #if CLASSIC_DRAM == 1
1255 #error "Old harware can not work with new software!"
1259 ; ****************************************************************************
1263 ; ********************** DRAM routines from Sprite_tm ************************
1265 ;Sends the address in zh:zl to the ram
1310 andi temp2,~RAM_DQ_MASK
1313 ori temp2,(1<<ram_d0)
1315 ori temp2,(1<<ram_d1)
1317 ori temp2,(1<<ram_d2)
1319 ori temp2,(1<<ram_d3)
1326 ;Loads the byte on address adrh:adrl into temp.
1349 rcall dram_getnibble
1364 rcall dram_getnibble
1372 ;Writes the byte in temp to adrh:adrl
1377 ori temp2,RAM_DQ_MASK
1380 rcall dram_sendnibble
1416 rcall dram_sendnibble
1430 andi temp,~RAM_DQ_MASK
1433 andi temp,~RAM_DQ_MASK
1437 #endif /* CLASSIC_DRAM == 1 */
1439 ; ****************************************************************************
1443 ; ***************************** New DRAM routines ****************************
1449 andi temp,~RAM_AL_MASK
1451 ori temp,(1<<ram_a0)
1453 ori temp,(1<<ram_a1)
1455 ori temp,(1<<ram_a2)
1457 ori temp,(1<<ram_a3)
1459 ori temp,(1<<ram_a4)
1466 andi temp,~RAM_AH_MASK
1468 ori temp,(1<<ram_a5)
1470 ori temp,(1<<ram_a6)
1472 ori temp,(1<<ram_a7)
1478 ;Loads the byte on address adrh:adrl into temp.
1479 ;must not alter adrh:adrl
1492 in temp,P_DQ-2 ; PIN
1499 in temp2,P_DQ-2 ; PIN
1511 ;Writes the byte in temp to adrh:adrl
1512 ;must not alter adrh:adrl
1516 ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1520 andi temp,RAM_DQ_MASK & ~(1<<ram_w)
1521 ori temp,(1<<ram_cas)
1534 andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
1535 ori temp2,(1<<ram_cas)
1541 ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1547 #endif /* CLASSIC_DRAM == 0 */
1549 ; ****************************************************************************
1551 ; refresh interupt; exec 2 cbr cycles
1554 cbi P_CAS,ram_cas ;2 1| 1|
1556 cbi P_RAS,ram_ras ;2 |0 1|
1560 sbi P_RAS,ram_ras ;2 |0 |0
1563 cbi P_RAS,ram_ras ;2 |0 1|
1565 sbi P_CAS,ram_cas ;2 |0 |0
1567 sbi P_RAS,ram_ras ;2 1| |0
1569 reti ;4 --> 21 cycles
1571 ; ****************************************************************************
1573 ; ------------- system timer 10ms ---------------
1583 ; don't change order here, clock put/get depends on it.
1584 cntms_out: ; register for ms
1586 utime_io: ; register for uptime.
1593 .equ timer_size = timer_top - timer_base
1595 .equ clkofs = cnt_1ms-cntms_out
1596 .equ timerofs = cnt_1ms-timer_ms
1617 ldi zl,high(1000) ;doesn't change flags
1651 sts delay_timer,temp
1653 lds temp,delay_timer
1662 subi temp2,TIMER_MSECS
1663 brcs clkget_end ;Port number in range?
1664 ldi zl,low(cntms_out)
1665 ldi zh,high(cntms_out)
1666 breq clkget_copy ;lowest byte requestet, latch clock
1668 brsh clkget_end ;Port number to high?
1693 subi temp2,TIMERPORT
1694 brcs clkput_end ;Port number in range?
1699 cpi temp,starttimercmd
1701 cpi temp,quitTimerCmd
1703 cpi temp,printTimerCmd
1717 ldi zl,low(cntms_out)
1718 ldi zh,high(cntms_out)
1719 breq clkput_copy ;lowest byte requestet, latch clock
1721 brsh clkput_end ;Port number to high?
1746 ldi zl,low(timer_ms)
1747 ldi zh,high(timer_ms)
1767 ldi zl,low(timer_ms)
1768 ldi zh,high(timer_ms)
1770 ; put ms on stack (16 bit)
1781 subi adrl,low(-1000)
1782 sbci adrh,high(-1000)
1794 ldd temp2,z+timerofs
1808 .db 13,"Timer running. Elapsed: ",0
1832 ldi zh,high(cnt_1ms)
1867 ; --------------- Debugging stuff ---------------
1869 ;Print a unsigned lonng value to the uart
1870 ; oph:opl:temp2:temp = value
1877 clr adrl ;adrl = stack level
1879 ultoa1: ldi insdech, 32 ;adrh = oph:temp % 10
1880 clr adrh ;oph:temp /= 10
1892 cpi adrh, 10 ;adrh is a numeral digit '0'-'9'
1897 cp temp,insdech ;Repeat until oph:temp gets zero
1904 ultoa5: cpi adrl,3 ; at least 3 digits (ms)
1910 ultoa6: pop temp ;Flush stacked digits
1921 ;Prints the lower nibble of temp in hex to the uart
1937 ;Prints temp in hex to the uart
1945 ;Prints the zero-terminated string following the call statement. WARNING: Destroys temp.
1976 ; --------------- AVR HW <-> Z80 periph stuff ------------------
1978 .equ memReadByte = dram_read
1979 .equ memWriteByte = dram_write
1981 ; --------------------------------------------------------------
1985 #define RXBUFMASK RXBUFSIZE-1
1999 ; Save received character in a circular buffer. Do nothing if buffer overflows.
2012 lds zh,rxcount ;if rxcount < RXBUFSIZE
2013 cpi zh,RXBUFSIZE ; (room for at least 1 char?)
2016 sts rxcount,zh ; rxcount++
2018 ldi zl,low(rxfifo) ;
2023 sts rxidx_w,zh ; rxidx_w = ++rxidx_w % RXBUFSIZE
2024 ldi zh,high(rxfifo) ;
2027 st z,temp ; rxfifo[rxidx_w] = char
2037 ;Fetches a char from the buffer to temp. If none available, waits till one is.
2040 lds temp,rxcount ; Number of characters in buffer
2060 ld temp,z ;don't forget to get the char
2067 ;Sends a char from temp to the uart.
2069 #if defined __ATmega8__
2085 ; ------------ Fetch phase stuff -----------------
2087 .equ FETCH_NOP = (0<<0)
2088 .equ FETCH_A = (1<<0)
2089 .equ FETCH_B = (2<<0)
2090 .equ FETCH_C = (3<<0)
2091 .equ FETCH_D = (4<<0)
2092 .equ FETCH_E = (5<<0)
2093 .equ FETCH_H = (6<<0)
2094 .equ FETCH_L = (7<<0)
2095 .equ FETCH_AF = (8<<0)
2096 .equ FETCH_BC = (9<<0)
2097 .equ FETCH_DE = (10<<0)
2098 .equ FETCH_HL = (11<<0)
2099 .equ FETCH_SP = (12<<0)
2100 .equ FETCH_MBC = (13<<0)
2101 .equ FETCH_MDE = (14<<0)
2102 .equ FETCH_MHL = (15<<0)
2103 .equ FETCH_MSP = (16<<0)
2104 .equ FETCH_DIR8 = (17<<0)
2105 .equ FETCH_DIR16= (18<<0)
2106 .equ FETCH_RST = (19<<0)
2109 ;Jump table for fetch routines. Make sure to keep this in sync with the .equs!
2257 ; ------------ Store phase stuff -----------------
2259 .equ STORE_NOP = (0<<5)
2260 .equ STORE_A = (1<<5)
2261 .equ STORE_B = (2<<5)
2262 .equ STORE_C = (3<<5)
2263 .equ STORE_D = (4<<5)
2264 .equ STORE_E = (5<<5)
2265 .equ STORE_H = (6<<5)
2266 .equ STORE_L = (7<<5)
2267 .equ STORE_AF = (8<<5)
2268 .equ STORE_BC = (9<<5)
2269 .equ STORE_DE = (10<<5)
2270 .equ STORE_HL = (11<<5)
2271 .equ STORE_SP = (12<<5)
2272 .equ STORE_PC = (13<<5)
2273 .equ STORE_MBC = (14<<5)
2274 .equ STORE_MDE = (15<<5)
2275 .equ STORE_MHL = (16<<5)
2276 .equ STORE_MSP = (17<<5)
2277 .equ STORE_RET = (18<<5)
2278 .equ STORE_CALL = (19<<5)
2279 .equ STORE_AM = (20<<5)
2281 ;Jump table for store routines. Make sure to keep this in sync with the .equs!
2427 ; ------------ Operation phase stuff -----------------
2430 .equ OP_NOP = (0<<10)
2431 .equ OP_INC = (1<<10)
2432 .equ OP_DEC = (2<<10)
2433 .equ OP_INC16 = (3<<10)
2434 .equ OP_DEC16 = (4<<10)
2435 .equ OP_RLC = (5<<10)
2436 .equ OP_RRC = (6<<10)
2437 .equ OP_RR = (7<<10)
2438 .equ OP_RL = (8<<10)
2439 .equ OP_ADDA = (9<<10)
2440 .equ OP_ADCA = (10<<10)
2441 .equ OP_SUBFA = (11<<10)
2442 .equ OP_SBCFA = (12<<10)
2443 .equ OP_ANDA = (13<<10)
2444 .equ OP_ORA = (14<<10)
2445 .equ OP_XORA = (15<<10)
2446 .equ OP_ADDHL = (16<<10)
2447 .equ OP_STHL = (17<<10) ;store HL in fetched address
2448 .equ OP_RMEM16 = (18<<10) ;read mem at fetched address
2449 .equ OP_RMEM8 = (19<<10) ;read mem at fetched address
2450 .equ OP_DA = (20<<10)
2451 .equ OP_SCF = (21<<10)
2452 .equ OP_CPL = (22<<10)
2453 .equ OP_CCF = (23<<10)
2454 .equ OP_POP16 = (24<<10)
2455 .equ OP_PUSH16 = (25<<10)
2456 .equ OP_IFNZ = (26<<10)
2457 .equ OP_IFZ = (27<<10)
2458 .equ OP_IFNC = (28<<10)
2459 .equ OP_IFC = (29<<10)
2460 .equ OP_IFPO = (30<<10)
2461 .equ OP_IFPE = (31<<10)
2462 .equ OP_IFP = (32<<10)
2463 .equ OP_IFM = (33<<10)
2464 .equ OP_OUTA = (34<<10)
2465 .equ OP_IN = (35<<10)
2466 .equ OP_EXHL = (36<<10)
2467 .equ OP_DI = (37<<10)
2468 .equ OP_EI = (38<<10)
2469 .equ OP_INV = (39<<10)
2514 ;How the flags are supposed to work:
2515 ;7 ZFL_S - Sign flag (=MSBit of result)
2516 ;6 ZFL_Z - Zero flag. Is 1 when the result is 0
2517 ;4 ZFL_H - Half-carry (carry from bit 3 to 4)
2518 ;2 ZFL_P - Parity/2-complement Overflow
2519 ;1 ZFL_N - Subtract - set if last op was a subtract
2522 ;I sure hope I got the mapping between flags and instructions correct...
2524 ;----------------------------------------------------------------
2528 ;| ZZZZZZZ 88888 000 |
2534 ;| ZZZZZZZ 88888 000 |
2536 ;| Z80 MICROPROCESSOR Instruction Set Summary |
2538 ;----------------------------------------------------------------
2539 ;----------------------------------------------------------------
2540 ;|Mnemonic |SZHPNC|Description |Notes |
2541 ;|----------+------+---------------------+----------------------|
2542 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
2543 ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
2544 ;|ADD A,s |***V0*|Add |A=A+s |
2545 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
2546 ;|ADD IX,pp |--?-0*|Add |IX=IX+pp |
2547 ;|ADD IY,rr |--?-0*|Add |IY=IY+rr |
2548 ;|AND s |**1P00|Logical AND |A=A&s |
2549 ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
2550 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
2551 ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
2552 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
2553 ;|CP s |***V1*|Compare |A-s |
2554 ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
2555 ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
2556 ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
2557 ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
2558 ;|CPL |--1-1-|Complement |A=~A |
2559 ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
2560 ;|DEC s |***V1-|Decrement |s=s-1 |
2561 ;|DEC xx |------|Decrement |xx=xx-1 |
2562 ;|DEC ss |------|Decrement |ss=ss-1 |
2563 ;|DI |------|Disable Interrupts | |
2564 ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
2565 ;|EI |------|Enable Interrupts | |
2566 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
2567 ;|EX [SP],xx|------|Exchange |[SP]<->xx |
2568 ;|EX AF,AF' |------|Exchange |AF<->AF' |
2569 ;|EX DE,HL |------|Exchange |DE<->HL |
2570 ;|EXX |------|Exchange |qq<->qq' (except AF)|
2571 ;|HALT |------|Halt | |
2572 ;|IM n |------|Interrupt Mode | (n=0,1,2)|
2573 ;|IN A,[n] |------|Input |A=[n] |
2574 ;|IN r,[C] |***P0-|Input |r=[C] |
2575 ;|INC r |***V0-|Increment |r=r+1 |
2576 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2577 ;|INC xx |------|Increment |xx=xx+1 |
2578 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2579 ;|INC ss |------|Increment |ss=ss+1 |
2580 ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
2581 ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
2582 ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
2583 ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
2584 ;|JP [HL] |------|Unconditional Jump |PC=[HL] |
2585 ;|JP [xx] |------|Unconditional Jump |PC=[xx] |
2586 ;|JP nn |------|Unconditional Jump |PC=nn |
2587 ;|JP cc,nn |------|Conditional Jump |If cc JP |
2588 ;|JR e |------|Unconditional Jump |PC=PC+e |
2589 ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
2590 ;|LD dst,src|------|Load |dst=src |
2591 ;|LD A,i |**0*0-|Load |A=i (i=I,R)|
2592 ;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
2593 ;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
2594 ;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
2595 ;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
2596 ;|NEG |***V1*|Negate |A=-A |
2597 ;|NOP |------|No Operation | |
2598 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
2599 ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
2600 ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
2601 ;|OUT [C],r |------|Output |[C]=r |
2602 ;|OUT [n],A |------|Output |[n]=A |
2603 ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
2604 ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
2605 ;|POP xx |------|Pop |xx=[SP]+ |
2606 ;|POP qq |------|Pop |qq=[SP]+ |
2607 ;|PUSH xx |------|Push |-[SP]=xx |
2608 ;|PUSH qq |------|Push |-[SP]=qq |
2609 ;|RES b,m |------|Reset bit |m=m&{~2^b} |
2610 ;|RET |------|Return |PC=[SP]+ |
2611 ;|RET cc |------|Conditional Return |If cc RET |
2612 ;|RETI |------|Return from Interrupt|PC=[SP]+ |
2613 ;|RETN |------|Return from NMI |PC=[SP]+ |
2614 ;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
2615 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2616 ;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
2617 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
2618 ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
2619 ;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
2620 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2621 ;|RRC m |**0P0*|Rotate Right Circular|m=->m |
2622 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2623 ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
2624 ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
2625 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
2626 ;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY |
2627 ;|SCF |--0-01|Set Carry Flag |CY=1 |
2628 ;|SET b,m |------|Set bit |m=mv{2^b} |
2629 ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
2630 ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
2631 ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
2632 ;|SUB s |***V1*|Subtract |A=A-s |
2633 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
2634 ;|----------+------+--------------------------------------------|
2645 ;------------------------------------------------;
2646 ; Move single bit between two registers
2648 ; bmov dstreg,dstbit,srcreg.srcbit
2656 ;------------------------------------------------;
2657 ; Load table value from flash indexed by source reg.
2659 ; ldpmx dstreg,tablebase,indexreg
2661 ; (6 words, 8 cycles)
2672 .macro do_z80_flags_HP
2674 bmov z_flags, ZFL_P, temp, AVR_V
2675 bmov z_flags, ZFL_H, temp, AVR_H
2679 .macro do_z80_flags_set_N
2681 ori z_flags, (1<<ZFL_N) ; Negation auf 1
2685 .macro do_z80_flags_set_HN
2687 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
2691 .macro do_z80_flags_clear_N
2693 andi z_flags,~(1<<ZFL_N)
2697 .macro do_z80_flags_op_rotate
2698 ; must not change avr carry flag!
2700 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
2702 andi z_flags, ~( (1<<ZFL_C) )
2706 .macro do_z80_flags_op_and
2708 ori z_flags,(1<<ZFL_H)
2710 ori z_flags,(1<<ZFL_H)
2714 .macro do_z80_flags_op_or
2723 ;----------------------------------------------------------------
2724 ;|Mnemonic |SZHPNC|Description |Notes |
2725 ;----------------------------------------------------------------
2726 ;|INC r |***V0-|Increment |r=r+1 |
2727 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2728 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2729 ;|----------|SZHP C|---------- 8080 ----------------------------|
2730 ;|INC r |**-P0-|Increment |r=r+1 |
2731 ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 |
2738 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2739 ldpmx temp2, sz53p_tab, opl
2744 ;----------------------------------------------------------------
2745 ;|Mnemonic |SZHPNC|Description |Notes |
2746 ;----------------------------------------------------------------
2747 ;|DEC r |***V1-|Decrement |s=s-1 |
2748 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2749 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2750 ;|----------|SZHP C|---------- 8080 ----------------------------|
2751 ;|DEC r |**-P -|Increment |r=r+1 |
2752 ;|DEC [HL] |**-P -|Increment |[HL]=[HL]+1 |
2758 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2759 ldpmx temp2, sz53p_tab, opl
2766 ;----------------------------------------------------------------
2767 ;|Mnemonic |SZHPNC|Description |Notes |
2768 ;----------------------------------------------------------------
2769 ;|INC xx |------|Increment |xx=xx+1 |
2770 ;|INC ss |------|Increment |ss=ss+1 |
2780 ;----------------------------------------------------------------
2781 ;|Mnemonic |SZHPNC|Description |Notes |
2782 ;----------------------------------------------------------------
2783 ;|DEC xx |------|Decrement |xx=xx-1 |
2784 ;|DEC ss |------|Decrement |ss=ss-1 |
2792 ;----------------------------------------------------------------
2793 ;|Mnemonic |SZHPNC|Description |Notes |
2794 ;----------------------------------------------------------------
2795 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
2796 ;|----------|SZHP C|---------- 8080 ----------------------------|
2797 ;|RLCA |---- *|Rotate Left Circular |A=A<- |
2801 ;Rotate Left Cyclical. All bits move 1 to the
2802 ;left, the msb becomes c and lsb.
2803 do_z80_flags_op_rotate
2807 ori z_flags, (1<<ZFL_C)
2811 ;----------------------------------------------------------------
2812 ;|Mnemonic |SZHPNC|Description |Notes |
2813 ;----------------------------------------------------------------
2814 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2815 ;|----------|SZHP C|---------- 8080 ----------------------------|
2816 ;|RRCA |---- *|Rotate Right Circular|A=->A |
2820 ;Rotate Right Cyclical. All bits move 1 to the
2821 ;right, the lsb becomes c and msb.
2822 do_z80_flags_op_rotate
2826 ori z_flags, (1<<ZFL_C)
2830 ;----------------------------------------------------------------
2831 ;|Mnemonic |SZHPNC|Description |Notes |
2832 ;----------------------------------------------------------------
2833 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2834 ;|----------|SZHP C|---------- 8080 ----------------------------|
2835 ;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} |
2839 ;Rotate Right. All bits move 1 to the right, the lsb
2840 ;becomes c, c becomes msb.
2841 clc ; get z80 carry to avr carry
2844 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
2845 bmov z_flags,ZFL_C, opl,0 ; Bit 0 --> CY
2849 ;----------------------------------------------------------------
2850 ;|Mnemonic |SZHPNC|Description |Notes |
2851 ;----------------------------------------------------------------
2852 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2853 ;|----------|SZHP C|---------- 8080 ----------------------------|
2854 ;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- |
2858 ;Rotate Left. All bits move 1 to the left, the msb
2859 ;becomes c, c becomes lsb.
2863 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
2864 bmov z_flags,ZFL_C, opl,7 ; Bit 7 --> CY
2868 ;----------------------------------------------------------------
2869 ;|Mnemonic |SZHPNC|Description |Notes |
2870 ;----------------------------------------------------------------
2871 ;|ADD A,s |***V0*|Add |A=A+s |
2872 ;|----------|SZHP C|---------- 8080 ----------------------------|
2873 ;|ADD A,s |***P *|Add |A=A+s |
2879 ldpmx z_flags,sz53p_tab,opl ;S,Z,P flag
2880 bmov z_flags,ZFL_C, temp,AVR_C
2884 ;----------------------------------------------------------------
2885 ;|Mnemonic |SZHPNC|Description |Notes |
2886 ;----------------------------------------------------------------
2887 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
2888 ;|----------|SZHP C|---------- 8080 ----------------------------|
2889 ;|ADC A,s |***P *|Add with Carry |A=A+s+CY |
2898 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
2899 bmov z_flags,ZFL_C, temp,AVR_C
2903 ;----------------------------------------------------------------
2904 ;|Mnemonic |SZHPNC|Description |Notes |
2905 ;----------------------------------------------------------------
2906 ;|SUB s |***V1*|Subtract |A=A-s |
2907 ;|CP s |***V1*|Compare |A-s |
2908 ;|----------|SZHP C|---------- 8080 ----------------------------|
2909 ;|SUB s |***P *|Subtract |A=A-s |
2910 ;|CP s |***P *|Compare |A-s |
2918 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
2919 bmov z_flags,ZFL_C, temp,AVR_C
2924 ;----------------------------------------------------------------
2925 ;|Mnemonic |SZHPNC|Description |Notes |
2926 ;----------------------------------------------------------------
2927 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
2928 ;|----------|SZHP C|---------- 8080 ----------------------------|
2929 ;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY |
2940 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
2941 bmov z_flags,ZFL_C, temp,AVR_C
2946 ;----------------------------------------------------------------
2947 ;|Mnemonic |SZHPNC|Description |Notes |
2948 ;----------------------------------------------------------------
2949 ;|AND s |**1P00|Logical AND |A=A&s |
2950 ;|----------|SZHP C|---------- 8080 ----------------------------|
2951 ;|AND s |**-P 0|Logical AND |A=A&s |
2956 ldpmx z_flags,sz53p_tab,opl ;S,Z,P,N,C
2961 ;----------------------------------------------------------------
2962 ;|Mnemonic |SZHPNC|Description |Notes |
2963 ;----------------------------------------------------------------
2964 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
2965 ;|----------|SZHP C|---------- 8080 ----------------------------|
2966 ;|OR s |**-P00|Logical inclusive OR |A=Avs |
2971 ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
2975 ;----------------------------------------------------------------
2976 ;|Mnemonic |SZHPNC|Description |Notes |
2977 ;----------------------------------------------------------------
2978 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
2979 ;|----------|SZHP C|---------- 8080 ----------------------------|
2980 ;|XOR s |**-P 0|Logical Exclusive OR |A=Axs |
2985 ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
2989 ;----------------------------------------------------------------
2990 ;|Mnemonic |SZHPNC|Description |Notes |
2991 ;----------------------------------------------------------------
2992 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
2993 ;|----------|SZHP C|---------- 8080 ----------------------------|
2994 ;|ADD HL,ss |---- *|Add |HL=HL+ss |
3001 bmov z_flags,ZFL_H, temp,AVR_H
3002 bmov z_flags,ZFL_C, temp,AVR_C
3003 do_z80_flags_clear_N
3006 ;----------------------------------------------------------------
3007 ;|Mnemonic |SZHPNC|Description |Notes |
3008 ;----------------------------------------------------------------
3009 ;|LD dst,src|------|Load |dst=src |
3012 do_op_sthl: ;store hl to mem loc in opl:h
3029 ;----------------------------------------------------------------
3030 ;|Mnemonic |SZHPNC|Description |Notes |
3031 ;----------------------------------------------------------------
3032 ;|LD dst,src|------|Load |dst=src |
3048 ;----------------------------------------------------------------
3049 ;|Mnemonic |SZHPNC|Description |Notes |
3050 ;----------------------------------------------------------------
3051 ;|LD dst,src|------|Load |dst=src |
3061 ;----------------------------------------------------------------
3062 ;|Mnemonic |SZHPNC|Description |Notes |
3063 ;----------------------------------------------------------------
3064 ;|DAA |***P-*|Decimal Adjust Acc. | |
3065 ;|----------|SZHP C|---------- 8080 ----------------------------|
3069 ; Description (http://www.z80.info/z80syntx.htm#DAA):
3070 ; This instruction conditionally adjusts the accumulator for BCD addition
3071 ; and subtraction operations. For addition (ADD, ADC, INC) or subtraction
3072 ; (SUB, SBC, DEC, NEC), the following table indicates the operation performed:
3074 ; -------------------------------------------------------------------------------
3075 ; | | C Flag | HEX value in | H Flag | HEX value in | Number | C flag|
3076 ; | Operation| Before | upper digit | Before | lower digit | added | After |
3077 ; | | DAA | (bit 7-4) | DAA | (bit 3-0) | to byte | DAA |
3078 ; |-----------------------------------------------------------------------------|
3079 ; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3080 ; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
3081 ; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
3082 ; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
3083 ; | | 0 | 9-F | 0 | A-F | 66 | 1 |
3084 ; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
3085 ; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
3086 ; | | 1 | 0-2 | 0 | A-F | 66 | 1 |
3087 ; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
3088 ; |-----------------------------------------------------------------------------|
3089 ; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3090 ; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
3091 ; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
3092 ; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
3093 ; |-----------------------------------------------------------------------------|
3096 ; C: See instruction.
3098 ; P/V: Set if Acc. is even parity after operation, reset otherwise.
3099 ; H: See instruction.
3100 ; Z: Set if Acc. is Zero after operation, reset otherwise.
3101 ; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise.
3107 ldi oph,0 ; what to add
3108 sbrc z_flags,ZFL_H ; if H-Flag
3111 andi temp,0x0f ; ... or lower digit > 9
3117 sbrc z_flags,(1<<ZFL_C)
3126 ori z_flags,(1<<ZFL_C); set C
3128 sbrs z_flags,ZFL_N ; if sub-op
3129 rjmp op_da_add ; then
3132 op_da_add: ; else add-op
3145 ori z_flags,(1<<ZFL_C)
3146 andi z_flags,(1<<ZFL_N)|(1<<ZFL_C) ; preserve C,N
3147 ldpmx temp2, sz53p_tab, opl ; get S,Z,P
3149 bmov z_flags,ZFL_H, temp,AVR_H ; H (?)
3154 sbrc z_flags,ZFL_N ; if add-op
3155 rjmp do_op_da_sub ; then
3159 cpi temp,0x0a ; if lower digit > 9
3161 ori temp2,0x06 ; add 6 to lower digit
3163 sbrc z_flags,ZFL_H ; ... or H-Flag
3173 do_op_da_c: ; else sub-op
3174 sbrc z_flags,ZFL_C ;
3176 andi z_flags, ~( (1<<ZFL_S) | (1<<ZFL_Z) | (1<<ZFL_H) )
3179 bst temp,AVR_Z ;Z-Flag
3181 bst temp,AVR_N ;S-Flag
3183 sbrc temp2,5 ;C-Flag, set if 0x06 added
3184 ori z_flags,(1<<ZFL_C) ;
3188 do_op_da_sub: ;TODO:
3193 ;----------------------------------------------------------------
3194 ;|Mnemonic |SZHPNC|Description |Notes |
3195 ;----------------------------------------------------------------
3196 ;|SCF |--0-01|Set Carry Flag |CY=1 |
3197 ;|----------|SZHP C|---------- 8080 ----------------------------|
3201 andi z_flags,~((1<<ZFL_H)|(1<<ZFL_N))
3202 ori z_flags,(1<<ZFL_C)
3205 ;----------------------------------------------------------------
3206 ;|Mnemonic |SZHPNC|Description |Notes |
3207 ;----------------------------------------------------------------
3208 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
3209 ;|----------|SZHP C|---------- 8080 ----------------------------|
3210 ;|SCF |---- 1|Set Carry Flag |CY=1 |
3214 do_z80_flags_clear_N
3219 ;----------------------------------------------------------------
3220 ;|Mnemonic |SZHPNC|Description |Notes |
3221 ;----------------------------------------------------------------
3222 ;|CPL |--1-1-|Complement |A=~A |
3223 ;|----------|SZHP C|---------- 8080 ----------------------------|
3224 ;|CPL |---- -|Complement |A=~A |
3233 ;----------------------------------------------------------------
3234 ;|Mnemonic |SZHPNC|Description |Notes |
3235 ;----------------------------------------------------------------
3236 ;|PUSH xx |------|Push |-[SP]=xx |
3237 ;|PUSH qq |------|Push |-[SP]=qq |
3287 .db ", SP is now ",0
3298 ;----------------------------------------------------------------
3299 ;|Mnemonic |SZHPNC|Description |Notes |
3300 ;----------------------------------------------------------------
3301 ;|POP xx |------|Pop |xx=[SP]+ |
3302 ;|POP qq |------|Pop |qq=[SP]+ |
3328 .db "Stack pop: val ",0
3344 ;----------------------------------------------------------------
3345 ;|Mnemonic |SZHPNC|Description |Notes |
3346 ;----------------------------------------------------------------
3347 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
3348 ;|EX DE,HL |------|Exchange |DE<->HL |
3360 ;----------------------------------------------------------------
3361 ;|Mnemonic |SZHPNC|Description |Notes |
3362 ;----------------------------------------------------------------
3364 ; TODO: Implement IFF1, IFF2
3368 ;----------------------------------------------------------------
3369 ;|Mnemonic |SZHPNC|Description |Notes |
3370 ;----------------------------------------------------------------
3372 ; TODO: Implement IFF1, IFF2
3376 ;----------------------------------------------------------------
3377 ;|Mnemonic |SZHPNC|Description |Notes |
3378 ;----------------------------------------------------------------
3379 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3380 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3381 ;|RET cc |------|Conditional Return |If cc RET |
3391 ;----------------------------------------------------------------
3392 ;|Mnemonic |SZHPNC|Description |Notes |
3393 ;----------------------------------------------------------------
3394 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3395 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3396 ;|RET cc |------|Conditional Return |If cc RET |
3406 ;----------------------------------------------------------------
3407 ;|Mnemonic |SZHPNC|Description |Notes |
3408 ;----------------------------------------------------------------
3409 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3410 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3411 ;|RET cc |------|Conditional Return |If cc RET |
3421 ;----------------------------------------------------------------
3422 ;|Mnemonic |SZHPNC|Description |Notes |
3423 ;----------------------------------------------------------------
3424 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3425 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3426 ;|RET cc |------|Conditional Return |If cc RET |
3436 ;----------------------------------------------------------------
3437 ;|Mnemonic |SZHPNC|Description |Notes |
3438 ;----------------------------------------------------------------
3439 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3440 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3441 ;|RET cc |------|Conditional Return |If cc RET |
3451 ;----------------------------------------------------------------
3452 ;|Mnemonic |SZHPNC|Description |Notes |
3453 ;----------------------------------------------------------------
3454 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3455 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3456 ;|RET cc |------|Conditional Return |If cc RET |
3466 ;----------------------------------------------------------------
3467 ;|Mnemonic |SZHPNC|Description |Notes |
3468 ;----------------------------------------------------------------
3469 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3470 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3471 ;|RET cc |------|Conditional Return |If cc RET |
3474 do_op_ifp: ;sign positive, aka s=0
3481 ;----------------------------------------------------------------
3482 ;|Mnemonic |SZHPNC|Description |Notes |
3483 ;----------------------------------------------------------------
3484 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3485 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3486 ;|RET cc |------|Conditional Return |If cc RET |
3489 do_op_ifm: ;sign negative, aka s=1
3496 ;----------------------------------------------------------------
3497 ;|Mnemonic |SZHPNC|Description |Notes |
3498 ;----------------------------------------------------------------
3499 ;|OUT [n],A |------|Output |[n]=A |
3502 ;Interface with peripherials goes here :)
3503 do_op_outa: ; out (opl),a
3506 .db 13,"Port write: ",0
3521 ;----------------------------------------------------------------
3522 ;|Mnemonic |SZHPNC|Description |Notes |
3523 ;----------------------------------------------------------------
3524 ;|IN A,[n] |------|Input |A=[n] |
3527 do_op_in: ; in a,(opl)
3530 .db 13,"Port read: (",0
3548 ;----------------------------------------------------------------
3573 ;----------------------------------------------------------------
3576 .db "Invalid opcode @ PC=",0,0
3582 ;----------------------------------------------------------------
3586 ;----------------------------------------------------------------
3587 ; Lookup table, stolen from z80ex, Z80 emulation library.
3588 ; http://z80ex.sourceforge.net/
3590 ; The S, Z, 5 and 3 bits and the parity of the lookup value
3592 .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3593 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3594 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3595 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3596 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3597 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3598 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3599 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3600 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3601 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3602 .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3603 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3604 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3605 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3606 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3607 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3608 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3609 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3610 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3611 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3612 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3613 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3614 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3615 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3616 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3617 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3618 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3619 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3620 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3621 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3622 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3623 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3626 ; ----------------------- Opcode decoding -------------------------
3628 ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
3629 ; operations: fetch, do something, store.
3630 ; The table is made of 256 words. These 16-bit words consist of
3631 ; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store
3632 ; operation (bit 5-9).
3635 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
3636 .dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
3637 .dw (FETCH_A | OP_NOP | STORE_MBC ) ; 02 LD (BC),A
3638 .dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
3639 .dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
3640 .dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
3641 .dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
3642 .dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
3643 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
3644 .dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
3645 .dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
3646 .dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
3647 .dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
3648 .dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
3649 .dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
3650 .dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
3651 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
3652 .dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn
3653 .dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A
3654 .dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
3655 .dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D
3656 .dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D
3657 .dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n
3658 .dw (FETCH_A | OP_RL | STORE_A ) ; 17 RLA
3659 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 18 oo JR o (Z80)
3660 .dw (FETCH_DE | OP_ADDHL | STORE_HL ) ; 19 ADD HL,DE
3661 .dw (FETCH_MDE | OP_NOP | STORE_A ) ; 1A LD A,(DE)
3662 .dw (FETCH_DE | OP_DEC16 | STORE_DE ) ; 1B DEC DE
3663 .dw (FETCH_E | OP_INC | STORE_E ) ; 1C INC E
3664 .dw (FETCH_E | OP_DEC | STORE_E ) ; 1D DEC E
3665 .dw (FETCH_DIR8 | OP_NOP | STORE_E ) ; 1E nn LD E,n
3666 .dw (FETCH_A | OP_RR | STORE_A ) ; 1F RRA
3667 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 20 oo JR NZ,o (Z80)
3668 .dw (FETCH_DIR16| OP_NOP | STORE_HL ) ; 21 nn nn LD HL,nn
3669 .dw (FETCH_DIR16| OP_STHL | STORE_NOP) ; 22 nn nn LD (nn),HL
3670 .dw (FETCH_HL | OP_INC16 | STORE_HL ) ; 23 INC HL
3671 .dw (FETCH_H | OP_INC | STORE_H ) ; 24 INC H
3672 .dw (FETCH_H | OP_DEC | STORE_H ) ; 25 DEC H
3673 .dw (FETCH_DIR8 | OP_NOP | STORE_H ) ; 26 nn LD H,n
3674 .dw (FETCH_A | OP_DA | STORE_A ) ; 27 DAA
3675 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 28 oo JR Z,o (Z80)
3676 .dw (FETCH_HL | OP_ADDHL | STORE_HL ) ; 29 ADD HL,HL
3677 .dw (FETCH_DIR16| OP_RMEM16 | STORE_HL ) ; 2A nn nn LD HL,(nn)
3678 .dw (FETCH_HL | OP_DEC16 | STORE_HL ) ; 2B DEC HL
3679 .dw (FETCH_L | OP_INC | STORE_L ) ; 2C INC L
3680 .dw (FETCH_L | OP_DEC | STORE_L ) ; 2D DEC L
3681 .dw (FETCH_DIR8 | OP_NOP | STORE_L ) ; 2E nn LD L,n
3682 .dw (FETCH_A | OP_CPL | STORE_A ) ; 2F CPL
3683 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 30 oo JR NC,o (Z80)
3684 .dw (FETCH_DIR16| OP_NOP | STORE_SP ) ; 31 nn nn LD SP,nn
3685 .dw (FETCH_DIR16| OP_NOP | STORE_AM ) ; 32 nn nn LD (nn),A
3686 .dw (FETCH_SP | OP_INC16 | STORE_SP ) ; 33 INC SP
3687 .dw (FETCH_MHL | OP_INC | STORE_MHL) ; 34 INC (HL)
3688 .dw (FETCH_MHL | OP_DEC | STORE_MHL) ; 35 DEC (HL)
3689 .dw (FETCH_DIR8 | OP_NOP | STORE_MHL) ; 36 nn LD (HL),n
3690 .dw (FETCH_NOP | OP_SCF | STORE_NOP) ; 37 SCF
3691 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 38 oo JR C,o (Z80)
3692 .dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
3693 .dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
3694 .dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
3695 .dw (FETCH_A | OP_INC | STORE_A ) ; 3C INC A
3696 .dw (FETCH_A | OP_DEC | STORE_A ) ; 3D DEC A
3697 .dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
3698 .dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
3699 .dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r
3700 .dw (FETCH_C | OP_NOP | STORE_B ) ; 41 LD B,r
3701 .dw (FETCH_D | OP_NOP | STORE_B ) ; 42 LD B,r
3702 .dw (FETCH_E | OP_NOP | STORE_B ) ; 43 LD B,r
3703 .dw (FETCH_H | OP_NOP | STORE_B ) ; 44 LD B,r
3704 .dw (FETCH_L | OP_NOP | STORE_B ) ; 45 LD B,r
3705 .dw (FETCH_MHL | OP_NOP | STORE_B ) ; 46 LD B,r
3706 .dw (FETCH_A | OP_NOP | STORE_B ) ; 47 LD B,r
3707 .dw (FETCH_B | OP_NOP | STORE_C ) ; 48 LD C,r
3708 .dw (FETCH_C | OP_NOP | STORE_C ) ; 49 LD C,r
3709 .dw (FETCH_D | OP_NOP | STORE_C ) ; 4A LD C,r
3710 .dw (FETCH_E | OP_NOP | STORE_C ) ; 4B LD C,r
3711 .dw (FETCH_H | OP_NOP | STORE_C ) ; 4C LD C,r
3712 .dw (FETCH_L | OP_NOP | STORE_C ) ; 4D LD C,r
3713 .dw (FETCH_MHL | OP_NOP | STORE_C ) ; 4E LD C,r
3714 .dw (FETCH_A | OP_NOP | STORE_C ) ; 4F LD C,r
3715 .dw (FETCH_B | OP_NOP | STORE_D ) ; 50 LD D,r
3716 .dw (FETCH_C | OP_NOP | STORE_D ) ; 51 LD D,r
3717 .dw (FETCH_D | OP_NOP | STORE_D ) ; 52 LD D,r
3718 .dw (FETCH_E | OP_NOP | STORE_D ) ; 53 LD D,r
3719 .dw (FETCH_H | OP_NOP | STORE_D ) ; 54 LD D,r
3720 .dw (FETCH_L | OP_NOP | STORE_D ) ; 55 LD D,r
3721 .dw (FETCH_MHL | OP_NOP | STORE_D ) ; 56 LD D,r
3722 .dw (FETCH_A | OP_NOP | STORE_D ) ; 57 LD D,r
3723 .dw (FETCH_B | OP_NOP | STORE_E ) ; 58 LD E,r
3724 .dw (FETCH_C | OP_NOP | STORE_E ) ; 59 LD E,r
3725 .dw (FETCH_D | OP_NOP | STORE_E ) ; 5A LD E,r
3726 .dw (FETCH_E | OP_NOP | STORE_E ) ; 5B LD E,r
3727 .dw (FETCH_H | OP_NOP | STORE_E ) ; 5C LD E,r
3728 .dw (FETCH_L | OP_NOP | STORE_E ) ; 5D LD E,r
3729 .dw (FETCH_MHL | OP_NOP | STORE_E ) ; 5E LD E,r
3730 .dw (FETCH_A | OP_NOP | STORE_E ) ; 5F LD E,r
3731 .dw (FETCH_B | OP_NOP | STORE_H ) ; 60 LD H,r
3732 .dw (FETCH_C | OP_NOP | STORE_H ) ; 61 LD H,r
3733 .dw (FETCH_D | OP_NOP | STORE_H ) ; 62 LD H,r
3734 .dw (FETCH_E | OP_NOP | STORE_H ) ; 63 LD H,r
3735 .dw (FETCH_H | OP_NOP | STORE_H ) ; 64 LD H,r
3736 .dw (FETCH_L | OP_NOP | STORE_H ) ; 65 LD H,r
3737 .dw (FETCH_MHL | OP_NOP | STORE_H ) ; 66 LD H,r
3738 .dw (FETCH_A | OP_NOP | STORE_H ) ; 67 LD H,r
3739 .dw (FETCH_B | OP_NOP | STORE_L ) ; 68 LD L,r
3740 .dw (FETCH_C | OP_NOP | STORE_L ) ; 69 LD L,r
3741 .dw (FETCH_D | OP_NOP | STORE_L ) ; 6A LD L,r
3742 .dw (FETCH_E | OP_NOP | STORE_L ) ; 6B LD L,r
3743 .dw (FETCH_H | OP_NOP | STORE_L ) ; 6C LD L,r
3744 .dw (FETCH_L | OP_NOP | STORE_L ) ; 6D LD L,r
3745 .dw (FETCH_MHL | OP_NOP | STORE_L ) ; 6E LD L,r
3746 .dw (FETCH_A | OP_NOP | STORE_L ) ; 6F LD L,r
3747 .dw (FETCH_B | OP_NOP | STORE_MHL) ; 70 LD (HL),r
3748 .dw (FETCH_C | OP_NOP | STORE_MHL) ; 71 LD (HL),r
3749 .dw (FETCH_D | OP_NOP | STORE_MHL) ; 72 LD (HL),r
3750 .dw (FETCH_E | OP_NOP | STORE_MHL) ; 73 LD (HL),r
3751 .dw (FETCH_H | OP_NOP | STORE_MHL) ; 74 LD (HL),r
3752 .dw (FETCH_L | OP_NOP | STORE_MHL) ; 75 LD (HL),r
3753 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 76 HALT
3754 .dw (FETCH_A | OP_NOP | STORE_MHL) ; 77 LD (HL),r
3755 .dw (FETCH_B | OP_NOP | STORE_A ) ; 78 LD A,r
3756 .dw (FETCH_C | OP_NOP | STORE_A ) ; 79 LD A,r
3757 .dw (FETCH_D | OP_NOP | STORE_A ) ; 7A LD A,r
3758 .dw (FETCH_E | OP_NOP | STORE_A ) ; 7B LD A,r
3759 .dw (FETCH_H | OP_NOP | STORE_A ) ; 7C LD A,r
3760 .dw (FETCH_L | OP_NOP | STORE_A ) ; 7D LD A,r
3761 .dw (FETCH_MHL | OP_NOP | STORE_A ) ; 7E LD A,r
3762 .dw (FETCH_A | OP_NOP | STORE_A ) ; 7F LD A,r
3763 .dw (FETCH_B | OP_ADDA | STORE_A ) ; 80 ADD A,r
3764 .dw (FETCH_C | OP_ADDA | STORE_A ) ; 81 ADD A,r
3765 .dw (FETCH_D | OP_ADDA | STORE_A ) ; 82 ADD A,r
3766 .dw (FETCH_E | OP_ADDA | STORE_A ) ; 83 ADD A,r
3767 .dw (FETCH_H | OP_ADDA | STORE_A ) ; 84 ADD A,r
3768 .dw (FETCH_L | OP_ADDA | STORE_A ) ; 85 ADD A,r
3769 .dw (FETCH_MHL | OP_ADDA | STORE_A ) ; 86 ADD A,r
3770 .dw (FETCH_A | OP_ADDA | STORE_A ) ; 87 ADD A,r
3771 .dw (FETCH_B | OP_ADCA | STORE_A ) ; 88 ADC A,r
3772 .dw (FETCH_C | OP_ADCA | STORE_A ) ; 89 ADC A,r
3773 .dw (FETCH_D | OP_ADCA | STORE_A ) ; 8A ADC A,r
3774 .dw (FETCH_E | OP_ADCA | STORE_A ) ; 8B ADC A,r
3775 .dw (FETCH_H | OP_ADCA | STORE_A ) ; 8C ADC A,r
3776 .dw (FETCH_L | OP_ADCA | STORE_A ) ; 8D ADC A,r
3777 .dw (FETCH_MHL | OP_ADCA | STORE_A ) ; 8E ADC A,r
3778 .dw (FETCH_A | OP_ADCA | STORE_A ) ; 8F ADC A,r
3779 .dw (FETCH_B | OP_SUBFA | STORE_A ) ; 90 SUB A,r
3780 .dw (FETCH_C | OP_SUBFA | STORE_A ) ; 91 SUB A,r
3781 .dw (FETCH_D | OP_SUBFA | STORE_A ) ; 92 SUB A,r
3782 .dw (FETCH_E | OP_SUBFA | STORE_A ) ; 93 SUB A,r
3783 .dw (FETCH_H | OP_SUBFA | STORE_A ) ; 94 SUB A,r
3784 .dw (FETCH_L | OP_SUBFA | STORE_A ) ; 95 SUB A,r
3785 .dw (FETCH_MHL | OP_SUBFA | STORE_A ) ; 96 SUB A,r
3786 .dw (FETCH_A | OP_SUBFA | STORE_A ) ; 97 SUB A,r
3787 .dw (FETCH_B | OP_SBCFA | STORE_A ) ; 98 SBC A,r
3788 .dw (FETCH_C | OP_SBCFA | STORE_A ) ; 99 SBC A,r
3789 .dw (FETCH_D | OP_SBCFA | STORE_A ) ; 9A SBC A,r
3790 .dw (FETCH_E | OP_SBCFA | STORE_A ) ; 9B SBC A,r
3791 .dw (FETCH_H | OP_SBCFA | STORE_A ) ; 9C SBC A,r
3792 .dw (FETCH_L | OP_SBCFA | STORE_A ) ; 9D SBC A,r
3793 .dw (FETCH_MHL | OP_SBCFA | STORE_A ) ; 9E SBC A,r
3794 .dw (FETCH_A | OP_SBCFA | STORE_A ) ; 9F SBC A,r
3795 .dw (FETCH_B | OP_ANDA | STORE_A ) ; A0 AND A,r
3796 .dw (FETCH_C | OP_ANDA | STORE_A ) ; A1 AND A,r
3797 .dw (FETCH_D | OP_ANDA | STORE_A ) ; A2 AND A,r
3798 .dw (FETCH_E | OP_ANDA | STORE_A ) ; A3 AND A,r
3799 .dw (FETCH_H | OP_ANDA | STORE_A ) ; A4 AND A,r
3800 .dw (FETCH_L | OP_ANDA | STORE_A ) ; A5 AND A,r
3801 .dw (FETCH_MHL | OP_ANDA | STORE_A ) ; A6 AND A,r
3802 .dw (FETCH_A | OP_ANDA | STORE_A ) ; A7 AND A,r
3803 .dw (FETCH_B | OP_XORA | STORE_A ) ; A8 XOR A,r
3804 .dw (FETCH_C | OP_XORA | STORE_A ) ; A9 XOR A,r
3805 .dw (FETCH_D | OP_XORA | STORE_A ) ; AA XOR A,r
3806 .dw (FETCH_E | OP_XORA | STORE_A ) ; AB XOR A,r
3807 .dw (FETCH_H | OP_XORA | STORE_A ) ; AC XOR A,r
3808 .dw (FETCH_L | OP_XORA | STORE_A ) ; AD XOR A,r
3809 .dw (FETCH_MHL | OP_XORA | STORE_A ) ; AE XOR A,r
3810 .dw (FETCH_A | OP_XORA | STORE_A ) ; AF XOR A,r
3811 .dw (FETCH_B | OP_ORA | STORE_A ) ; B0 OR A,r
3812 .dw (FETCH_C | OP_ORA | STORE_A ) ; B1 OR A,r
3813 .dw (FETCH_D | OP_ORA | STORE_A ) ; B2 OR A,r
3814 .dw (FETCH_E | OP_ORA | STORE_A ) ; B3 OR A,r
3815 .dw (FETCH_H | OP_ORA | STORE_A ) ; B4 OR A,r
3816 .dw (FETCH_L | OP_ORA | STORE_A ) ; B5 OR A,r
3817 .dw (FETCH_MHL | OP_ORA | STORE_A ) ; B6 OR A,r
3818 .dw (FETCH_A | OP_ORA | STORE_A ) ; B7 OR A,r
3819 .dw (FETCH_B | OP_SUBFA | STORE_NOP) ; B8 CP A,r
3820 .dw (FETCH_C | OP_SUBFA | STORE_NOP) ; B9 CP A,r
3821 .dw (FETCH_D | OP_SUBFA | STORE_NOP) ; BA CP A,r
3822 .dw (FETCH_E | OP_SUBFA | STORE_NOP) ; BB CP A,r
3823 .dw (FETCH_H | OP_SUBFA | STORE_NOP) ; BC CP A,r
3824 .dw (FETCH_L | OP_SUBFA | STORE_NOP) ; BD CP A,r
3825 .dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; BE CP A,r
3826 .dw (FETCH_A | OP_SUBFA | STORE_NOP) ; BF CP A,r
3827 .dw (FETCH_NOP | OP_IFNZ | STORE_RET) ; C0 RET NZ
3828 .dw (FETCH_NOP | OP_POP16 | STORE_BC ) ; C1 POP BC
3829 .dw (FETCH_DIR16| OP_IFNZ | STORE_PC ) ; C2 nn nn JP NZ,nn
3830 .dw (FETCH_DIR16| OP_NOP | STORE_PC ) ; C3 nn nn JP nn
3831 .dw (FETCH_DIR16| OP_IFNZ | STORE_CALL) ; C4 nn nn CALL NZ,nn
3832 .dw (FETCH_BC | OP_PUSH16 | STORE_NOP) ; C5 PUSH BC
3833 .dw (FETCH_DIR8 | OP_ADDA | STORE_A ) ; C6 nn ADD A,n
3834 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; C7 RST 0
3835 .dw (FETCH_NOP | OP_IFZ | STORE_RET) ; C8 RET Z
3836 .dw (FETCH_NOP | OP_NOP | STORE_RET) ; C9 RET
3837 .dw (FETCH_DIR16| OP_IFZ | STORE_PC ) ; CA nn nn JP Z,nn
3838 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; CB (Z80 specific)
3839 .dw (FETCH_DIR16| OP_IFZ | STORE_CALL) ; CC nn nn CALL Z,nn
3840 .dw (FETCH_DIR16| OP_NOP | STORE_CALL) ; CD nn nn CALL nn
3841 .dw (FETCH_DIR8 | OP_ADCA | STORE_A ) ; CE nn ADC A,n
3842 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; CF RST 8H
3843 .dw (FETCH_NOP | OP_IFNC | STORE_RET) ; D0 RET NC
3844 .dw (FETCH_NOP | OP_POP16 | STORE_DE ) ; D1 POP DE
3845 .dw (FETCH_DIR16| OP_IFNC | STORE_PC ) ; D2 nn nn JP NC,nn
3846 .dw (FETCH_DIR8 | OP_OUTA | STORE_NOP) ; D3 nn OUT (n),A
3847 .dw (FETCH_DIR16| OP_IFNC | STORE_CALL) ; D4 nn nn CALL NC,nn
3848 .dw (FETCH_DE | OP_PUSH16 | STORE_NOP) ; D5 PUSH DE
3849 .dw (FETCH_DIR8 | OP_SUBFA | STORE_A ) ; D6 nn SUB n
3850 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H
3851 .dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C
3852 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
3853 .dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn
3854 .dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
3855 .dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn
3856 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; DD (Z80)
3857 .dw (FETCH_DIR8 | OP_SBCFA | STORE_A ) ; DE nn SBC A,n
3858 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; DF RST 18H
3859 .dw (FETCH_NOP | OP_IFPO | STORE_RET) ; E0 RET PO
3860 .dw (FETCH_NOP | OP_POP16 | STORE_HL ) ; E1 POP HL
3861 .dw (FETCH_DIR16| OP_IFPO | STORE_PC ) ; E2 nn nn JP PO,nn
3862 .dw (FETCH_MSP | OP_EXHL | STORE_MSP) ; E3 EX (SP),HL
3863 .dw (FETCH_DIR16| OP_IFPO | STORE_CALL) ; E4 nn nn CALL PO,nn
3864 .dw (FETCH_HL | OP_PUSH16 | STORE_NOP) ; E5 PUSH HL
3865 .dw (FETCH_DIR8 | OP_ANDA | STORE_A ) ; E6 nn AND n
3866 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; E7 RST 20H
3867 .dw (FETCH_NOP | OP_IFPE | STORE_RET) ; E8 RET PE
3868 .dw (FETCH_HL | OP_NOP | STORE_PC ) ; E9 JP (HL)
3869 .dw (FETCH_DIR16| OP_IFPE | STORE_PC ) ; EA nn nn JP PE,nn
3870 .dw (FETCH_DE | OP_EXHL | STORE_DE ) ; EB EX DE,HL
3871 .dw (FETCH_DIR16| OP_IFPE | STORE_CALL) ; EC nn nn CALL PE,nn
3872 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; ED (Z80 specific)
3873 .dw (FETCH_DIR8 | OP_XORA | STORE_A ) ; EE nn XOR n
3874 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; EF RST 28H
3875 .dw (FETCH_NOP | OP_IFP | STORE_RET) ; F0 RET P
3876 .dw (FETCH_NOP | OP_POP16 | STORE_AF ) ; F1 POP AF
3877 .dw (FETCH_DIR16| OP_IFP | STORE_PC ) ; F2 nn nn JP P,nn
3878 .dw (FETCH_NOP | OP_DI | STORE_NOP) ; F3 DI
3879 .dw (FETCH_DIR16| OP_IFP | STORE_CALL) ; F4 nn nn CALL P,nn
3880 .dw (FETCH_AF | OP_PUSH16 | STORE_NOP) ; F5 PUSH AF
3881 .dw (FETCH_DIR8 | OP_ORA | STORE_A ) ; F6 nn OR n
3882 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; F7 RST 30H
3883 .dw (FETCH_NOP | OP_IFM | STORE_RET) ; F8 RET M
3884 .dw (FETCH_HL | OP_NOP | STORE_SP ) ; F9 LD SP,HL
3885 .dw (FETCH_DIR16| OP_IFM | STORE_PC ) ; FA nn nn JP M,nn
3886 .dw (FETCH_NOP | OP_EI | STORE_NOP) ; FB EI
3887 .dw (FETCH_DIR16| OP_IFM | STORE_CALL) ; FC nn nn CALL M,nn
3888 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific)
3889 .dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; FE nn CP n
3890 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H
3892 ; vim:set ts=8 noet nowrap