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"
32 #ifndef DRAM_DQ_ORDER /* If this is set to 1, the portbits */
33 #define DRAM_DQ_ORDER 0 /* for DRAM D1 and WE are swapped. */
38 #define F_CPU 20000000 /* system clock in Hz; defaults to 20MHz */
41 #define BAUD 38400 /* console baud rate */
45 #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) /* clever rounding */
47 #define RXBUFSIZE 64 /* USART recieve buffer size. Must be power of 2 */
49 #define REFR_RATE 64000 /* dram refresh rate in cycles/s. */
50 /* Most drams need 1/15.6µs. */
51 #define REFR_PRE 8 /* timer prescale factor */
52 #define REFR_CS 0x02 /* timer clock select for 1/8 */
53 #define REFR_CNT F_CPU / REFR_RATE / REFR_PRE
56 #if defined __ATmega8__
57 .equ refr_vect = OC2addr
59 .equ refr_vect = OC2Aaddr
62 #define DRAM_WORD_ACCESS 1 /* experimental */
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
186 ; This is the base z80 port address for clock access
187 #define TIMERPORT 0x40
188 #define TIMER_CTL TIMERPORT
189 #define TIMER_MSECS TIMERPORT+1
190 #define TIMER_SECS TIMER_MSECS+2
192 #define starttimercmd 1
193 #define quitTimerCmd 2
194 #define printTimerCmd 15
207 ;Sector buffer for 512 byte reads/writes from/to SD-card
215 rjmp start ; reset vector
217 rjmp refrint ; tim2cmpa
218 .org OC1Aaddr ; Timer/Counter1 Compare Match A
219 rjmp sysclockint ; 1ms system timer
221 rjmp rxint ; USART receive int.
225 .org INT_VECTORS_SIZE
228 ldi temp,low(RAMEND) ; top of memory
229 out SPL,temp ; init stack pointer
230 ldi temp,high(RAMEND) ; top of memory
231 out SPH,temp ; init stack pointer
235 #if defined __ATmega8__
238 ldi temp,(1<<WDCE) | (1<<WDE)
242 ldi temp,(1<<PUD) ;disable pullups
247 ldi temp,(1<<WDCE) | (1<<WDE)
251 ldi temp,(1<<PUD) ;disable pullups
256 ldi temp,PB_OUTPUT_MASK
258 ldi temp,PD_OUTPUT_MASK
260 ldi temp,PC_OUTPUT_MASK
272 sts rxcount,_0 ; reset receive buffer
277 #if defined __ATmega8__
278 ldi temp, (1<<TXEN) | (1<<RXEN) | (1<<RXCIE)
280 ldi temp, (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0)
282 ldi temp, HIGH(UBRR_VAL)
284 ldi temp, LOW(UBRR_VAL)
287 ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
289 ldi temp, (1<<UCSZ01) | (1<<UCSZ00)
291 ldi temp, HIGH(UBRR_VAL)
293 ldi temp, LOW(UBRR_VAL)
297 ;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
300 ldi temp,REFR_CNT*2 ; 2 cycles per int
302 ldi temp,(1<<WGM21) | REFR_CS ;CTC, clk/REFR_PRE
307 ldi temp,REFR_CNT ;=312 cycles
311 ldi temp, REFR_CS ;clk/REFR_PRE
318 ; Init clock/timer system
320 ldi zl,low(timer_base)
321 ldi zh,high(timer_base)
328 ; Init timer 1 as 1 ms system clock tick.
331 ldi temp,high(F_CPU/1000)
333 ldi temp,low(F_CPU/1000)
335 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
341 ldi temp,high(F_CPU/1000)
343 ldi temp,low(F_CPU/1000)
345 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
361 .db "CPM on an AVR, v1.0",13,0,0
365 .db "Initing mmc...",13,0
371 .db "Testing RAM: fill...",0,0
393 .db "reread...",13,0,0
425 ;Fill ram with cbs, which (for now) will trigger an invalid opcode error.
437 ;Load initial sector from MMC (512 bytes)
442 ;Save to Z80 RAM (only 128 bytes because that's retro)
444 ldi zh,high(sectbuff)
455 cpi zl,low(sectbuff+128)
457 cpi zh,high(sectbuff+128)
470 .db 13,"Ok, CPU is live!",13,0,0
499 ; *** Stage 1: Fetch next opcode
522 ; *** Stage 2: Decode it using the ins_table.
523 ldi zh,high(inst_table*2)
544 ; *** Stage 3: Fetch operand. Use the fetch jumptable for this.
548 ldi zl,low(fetchjumps)
549 ldi zh,high(fetchjumps)
569 ; *** Stage 4: Execute operation :) Use the op jumptable for this.
594 ; *** Stage 5: Store operand. Use the store jumptable for this.
603 ldi zl,low(storejumps)
604 ldi zh,high(storejumps)
631 ; ----------------Virtual peripherial interface ------
633 ;The hw is modelled to make writing a CPM BIOS easier.
635 ;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise.
636 ;1 - Console input, aka UDR.
642 ;22 - Trigger - write 1 to read, 2 to write a sector using the above info.
643 ; This will automatically move track, sector and dma addr to the next sector.
645 ;Called with port in temp2. Should return value in temp.
652 cpi temp2,TIMER_MSECS
654 cpi temp2,TIMER_MSECS+6
662 ;Called with port in temp2 and value in temp.
681 cpi temp2,TIMER_MSECS+6
735 .db "Disk read: track ",0
753 ;First, convert track/sector to an LBA address (in 128byte blocks)
769 ;Now, see what has to be done.
777 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
782 ;Read 512-byte sector
786 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
788 ldi zh,high(sectbuff)
813 brne dskDoItReadMemLoop
817 ;The write routines is a bit naive: it'll read the 512-byte sector the 128byte CPM-sector
818 ;resides in into memory, will overwrite the needed 128 byte with the Z80s memory buffer
819 ;and will then write it back to disk. In theory, this would mean that every 512 bytes
820 ;written will take 4 write cycles, while theoretically the writes could be deferred so we
821 ;would only have to do one write cycle.
826 .db "Disk write: track ",0
847 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
852 ;Read 512-byte sector
860 ;Copy the data from the Z80 DMA buffer in external memory to the right place in the
862 ;Now, move the correct portion of the sector from AVR ram to Z80 ram
864 ldi zh,high(sectbuff)
889 brne dskDoItWriteMemLoop
894 ;Convert from 128-byte LBA blocks to 512-byte LBA blocks
899 ;Write the sector back.
906 ; ----------------- MMC/SD routines ------------------
941 ;Wait till the mmc answers with the response in temp2, or till a timeout happens.
948 brne mmcWaitResploopEnd
961 .db ": Error: MMC resp timeout!",13,0
968 ;Init start: send 80 clocks with cs disabled
972 ldi temp2,10 ; exactly 80 clocks
1010 ldi temp,0xff ;return byte
1013 ldi temp2,0 ;Error Code 0
1014 rcall mmcWaitResp ;Test on CMD0 is OK
1016 sbi P_MMC_CS,mmc_cs ;disable /CS
1020 ;Read OCR till card is ready
1021 ldi temp2,20 ;repeat counter
1025 cbi P_MMC_CS,mmc_cs ;enable /CS
1026 ldi temp,0xff ;dummy
1038 ; ldi temp,0x95 ;crc
1044 rcall mmcWaitResp ;wait until mmc-card send a byte <> 0xFF
1045 ;the first answer must be 0x01 (Idle-Mode)
1047 breq mmcInitOcrLoopDone ;second answer is 0x00 (Idle-Mode leave) CMD1 is OK
1049 sbi P_MMC_CS,mmc_cs ;disable /CS
1051 ; rcall mmcByteNoSend ;unnecessary
1059 brne mmcInitOcrLoop ;repeat
1066 sbi P_MMC_CS,mmc_cs ;disable /CS
1073 ;Call this with adrh:adrl = sector number
1074 ;16bit lba address means a max reach of 32M.
1081 ldi temp,0x51 ;cmd (read sector)
1096 ldi temp,0xff ;return byte
1107 ;Read sector to AVR RAM
1108 ldi zl,low(sectbuff)
1109 ldi zh,high(sectbuff)
1113 cpi zl,low(sectbuff+512)
1115 cpi zh,high(sectbuff+512)
1129 ;Call this with adrh:adrl = sector number
1130 ;16bit lba address means a max reach of 32M.
1138 ldi temp,0x58 ;cmd (write sector)
1153 ldi temp,0xff ;return byte
1164 ;Write sector from AVR RAM
1165 ldi zl,low(sectbuff)
1166 ldi zh,high(sectbuff)
1170 cpi zl,low(sectbuff+512)
1172 cpi zh,high(sectbuff+512)
1179 ;Status. Ignored for now.
1182 ;Wait till the mmc has written everything
1195 ;Set up wdt to time out after 1 sec.
1198 #if defined __ATmega8__
1201 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1206 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1213 ; ------------------ DRAM routines -------------
1215 ; DRAM_SETADDR val, low_and_mask, low_or_mask, high_and_mask, high_or_mask
1230 ori temp, @4 | (1<<mmc_cs)
1235 ;Loads the byte on address adrh:adrl into temp.
1236 ;must not alter adrh:adrl
1240 DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8), (1<<ram_oe)
1242 DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
1245 in temp,P_DQ-2 ; PIN
1251 in temp2,P_DQ-2 ; PIN
1261 #if DRAM_WORD_ACCESS
1276 DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
1278 DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
1281 in temp,P_DQ-2 ; PIN
1286 in temp2,P_DQ-2 ; PIN
1294 DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
1297 in temp,P_DQ-2 ; PIN
1302 in temp2,P_DQ-2 ; PIN
1315 ;Writes the byte in temp to adrh:adrl
1316 ;must not alter adrh:adrl
1320 ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1324 andi temp,RAM_DQ_MASK & ~(1<<ram_w)
1325 ori temp,(1<<ram_cas)
1328 DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
1330 DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
1337 andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
1338 ori temp2,(1<<ram_cas)
1344 ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1350 #if DRAM_WORD_ACCESS
1365 ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1369 andi temp,RAM_DQ_MASK & ~(1<<ram_w)
1370 ori temp,(1<<ram_cas)
1373 DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
1375 DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
1382 andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
1383 ori temp2,(1<<ram_cas)
1392 andi temp,RAM_DQ_MASK & ~(1<<ram_w)
1393 ori temp,(1<<ram_cas)
1396 DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
1403 andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
1404 ori temp2,(1<<ram_cas)
1410 ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1417 ; ****************************************************************************
1419 ; refresh interupt; exec 2 cbr cycles
1422 cbi P_CAS,ram_cas ;2 1| 1|
1424 cbi P_RAS,ram_ras ;2 |0 1|
1428 sbi P_RAS,ram_ras ;2 |0 |0
1431 cbi P_RAS,ram_ras ;2 |0 1|
1433 sbi P_CAS,ram_cas ;2 |0 |0
1435 sbi P_RAS,ram_ras ;2 1| |0
1437 reti ;4 --> 21 cycles
1439 ; ****************************************************************************
1441 ; ------------- system timer 10ms ---------------
1451 ; don't change order here, clock put/get depends on it.
1452 cntms_out: ; register for ms
1454 utime_io: ; register for uptime.
1461 .equ timer_size = timer_top - timer_base
1463 .equ clkofs = cnt_1ms-cntms_out
1464 .equ timerofs = cnt_1ms-timer_ms
1485 ldi zl,high(1000) ;doesn't change flags
1518 sts delay_timer,temp
1520 lds temp,delay_timer
1529 subi temp2,TIMER_MSECS
1530 brcs clkget_end ;Port number in range?
1531 ldi zl,low(cntms_out)
1532 ldi zh,high(cntms_out)
1533 breq clkget_copy ;lowest byte requestet, latch clock
1535 brsh clkget_end ;Port number to high?
1560 subi temp2,TIMERPORT
1561 brcs clkput_end ;Port number in range?
1566 cpi temp,starttimercmd
1568 cpi temp,quitTimerCmd
1570 cpi temp,printTimerCmd
1584 ldi zl,low(cntms_out)
1585 ldi zh,high(cntms_out)
1586 breq clkput_copy ;lowest byte requestet, latch clock
1588 brsh clkput_end ;Port number to high?
1613 ldi zl,low(timer_ms)
1614 ldi zh,high(timer_ms)
1634 ldi zl,low(timer_ms)
1635 ldi zh,high(timer_ms)
1637 ; put ms on stack (16 bit)
1648 subi adrl,low(-1000)
1649 sbci adrh,high(-1000)
1661 ldd temp2,z+timerofs
1675 .db 13,"Timer running. Elapsed: ",0
1699 ldi zh,high(cnt_1ms)
1734 ; --------------- Debugging stuff ---------------
1736 ;Print a unsigned lonng value to the uart
1737 ; oph:opl:temp2:temp = value
1744 clr adrl ;adrl = stack level
1746 ultoa1: ldi insdech, 32 ;adrh = oph:temp % 10
1747 clr adrh ;oph:temp /= 10
1759 cpi adrh, 10 ;adrh is a numeral digit '0'-'9'
1763 cp temp,_0 ;Repeat until oph:temp gets zero
1770 ultoa5: cpi adrl,3 ; at least 3 digits (ms)
1776 ultoa6: pop temp ;Flush stacked digits
1787 ;Prints the lower nibble of temp in hex to the uart
1803 ;Prints temp in hex to the uart
1811 ;Prints the zero-terminated string following the call statement. WARNING: Destroys temp.
1842 ; --------------- AVR HW <-> Z80 periph stuff ------------------
1844 .equ memReadByte = dram_read
1845 .equ memWriteByte = dram_write
1846 #if DRAM_WORD_ACCESS
1847 .equ memReadWord = dram_read_w
1848 .equ memWriteWord = dram_write_w
1851 ; --------------------------------------------------------------
1855 #define RXBUFMASK RXBUFSIZE-1
1869 ; Save received character in a circular buffer. Do nothing if buffer overflows.
1882 lds zh,rxcount ;if rxcount < RXBUFSIZE
1883 cpi zh,RXBUFSIZE ; (room for at least 1 char?)
1886 sts rxcount,zh ; rxcount++
1888 ldi zl,low(rxfifo) ;
1893 sts rxidx_w,zh ; rxidx_w = ++rxidx_w % RXBUFSIZE
1894 ldi zh,high(rxfifo) ;
1897 st z,temp ; rxfifo[rxidx_w] = char
1907 ;Fetches a char from the buffer to temp. If none available, waits till one is.
1910 lds temp,rxcount ; Number of characters in buffer
1930 ld temp,z ;don't forget to get the char
1937 ;Sends a char from temp to the uart.
1939 #if defined __ATmega8__
1955 ; ------------ Fetch phase stuff -----------------
1957 .equ FETCH_NOP = (0<<0)
1958 .equ FETCH_A = (1<<0)
1959 .equ FETCH_B = (2<<0)
1960 .equ FETCH_C = (3<<0)
1961 .equ FETCH_D = (4<<0)
1962 .equ FETCH_E = (5<<0)
1963 .equ FETCH_H = (6<<0)
1964 .equ FETCH_L = (7<<0)
1965 .equ FETCH_AF = (8<<0)
1966 .equ FETCH_BC = (9<<0)
1967 .equ FETCH_DE = (10<<0)
1968 .equ FETCH_HL = (11<<0)
1969 .equ FETCH_SP = (12<<0)
1970 .equ FETCH_MBC = (13<<0)
1971 .equ FETCH_MDE = (14<<0)
1972 .equ FETCH_MHL = (15<<0)
1973 .equ FETCH_MSP = (16<<0)
1974 .equ FETCH_DIR8 = (17<<0)
1975 .equ FETCH_DIR16= (18<<0)
1976 .equ FETCH_RST = (19<<0)
1979 ;Jump table for fetch routines. Make sure to keep this in sync with the .equs!
2080 #if DRAM_WORD_ACCESS
2102 #if DRAM_WORD_ACCESS
2127 ; ------------ Store phase stuff -----------------
2129 .equ STORE_NOP = (0<<5)
2130 .equ STORE_A = (1<<5)
2131 .equ STORE_B = (2<<5)
2132 .equ STORE_C = (3<<5)
2133 .equ STORE_D = (4<<5)
2134 .equ STORE_E = (5<<5)
2135 .equ STORE_H = (6<<5)
2136 .equ STORE_L = (7<<5)
2137 .equ STORE_AF = (8<<5)
2138 .equ STORE_BC = (9<<5)
2139 .equ STORE_DE = (10<<5)
2140 .equ STORE_HL = (11<<5)
2141 .equ STORE_SP = (12<<5)
2142 .equ STORE_PC = (13<<5)
2143 .equ STORE_MBC = (14<<5)
2144 .equ STORE_MDE = (15<<5)
2145 .equ STORE_MHL = (16<<5)
2146 .equ STORE_MSP = (17<<5)
2147 .equ STORE_RET = (18<<5)
2148 .equ STORE_CALL = (19<<5)
2149 .equ STORE_AM = (20<<5)
2151 ;Jump table for store routines. Make sure to keep this in sync with the .equs!
2250 #if DRAM_WORD_ACCESS
2291 ; ------------ Operation phase stuff -----------------
2294 .equ OP_NOP = (0<<10)
2295 .equ OP_INC = (1<<10)
2296 .equ OP_DEC = (2<<10)
2297 .equ OP_INC16 = (3<<10)
2298 .equ OP_DEC16 = (4<<10)
2299 .equ OP_RLC = (5<<10)
2300 .equ OP_RRC = (6<<10)
2301 .equ OP_RR = (7<<10)
2302 .equ OP_RL = (8<<10)
2303 .equ OP_ADDA = (9<<10)
2304 .equ OP_ADCA = (10<<10)
2305 .equ OP_SUBFA = (11<<10)
2306 .equ OP_SBCFA = (12<<10)
2307 .equ OP_ANDA = (13<<10)
2308 .equ OP_ORA = (14<<10)
2309 .equ OP_XORA = (15<<10)
2310 .equ OP_ADDHL = (16<<10)
2311 .equ OP_STHL = (17<<10) ;store HL in fetched address
2312 .equ OP_RMEM16 = (18<<10) ;read mem at fetched address
2313 .equ OP_RMEM8 = (19<<10) ;read mem at fetched address
2314 .equ OP_DA = (20<<10)
2315 .equ OP_SCF = (21<<10)
2316 .equ OP_CPL = (22<<10)
2317 .equ OP_CCF = (23<<10)
2318 .equ OP_POP16 = (24<<10)
2319 .equ OP_PUSH16 = (25<<10)
2320 .equ OP_IFNZ = (26<<10)
2321 .equ OP_IFZ = (27<<10)
2322 .equ OP_IFNC = (28<<10)
2323 .equ OP_IFC = (29<<10)
2324 .equ OP_IFPO = (30<<10)
2325 .equ OP_IFPE = (31<<10)
2326 .equ OP_IFP = (32<<10)
2327 .equ OP_IFM = (33<<10)
2328 .equ OP_OUTA = (34<<10)
2329 .equ OP_IN = (35<<10)
2330 .equ OP_EXHL = (36<<10)
2331 .equ OP_DI = (37<<10)
2332 .equ OP_EI = (38<<10)
2333 .equ OP_INV = (39<<10)
2378 ;How the flags are supposed to work:
2379 ;7 ZFL_S - Sign flag (=MSBit of result)
2380 ;6 ZFL_Z - Zero flag. Is 1 when the result is 0
2381 ;4 ZFL_H - Half-carry (carry from bit 3 to 4)
2382 ;2 ZFL_P - Parity/2-complement Overflow
2383 ;1 ZFL_N - Subtract - set if last op was a subtract
2386 ;I sure hope I got the mapping between flags and instructions correct...
2388 ;----------------------------------------------------------------
2392 ;| ZZZZZZZ 88888 000 |
2398 ;| ZZZZZZZ 88888 000 |
2400 ;| Z80 MICROPROCESSOR Instruction Set Summary |
2402 ;----------------------------------------------------------------
2403 ;----------------------------------------------------------------
2404 ;|Mnemonic |SZHPNC|Description |Notes |
2405 ;|----------+------+---------------------+----------------------|
2406 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
2407 ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
2408 ;|ADD A,s |***V0*|Add |A=A+s |
2409 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
2410 ;|ADD IX,pp |--?-0*|Add |IX=IX+pp |
2411 ;|ADD IY,rr |--?-0*|Add |IY=IY+rr |
2412 ;|AND s |**1P00|Logical AND |A=A&s |
2413 ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
2414 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
2415 ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
2416 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
2417 ;|CP s |***V1*|Compare |A-s |
2418 ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
2419 ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
2420 ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
2421 ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
2422 ;|CPL |--1-1-|Complement |A=~A |
2423 ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
2424 ;|DEC s |***V1-|Decrement |s=s-1 |
2425 ;|DEC xx |------|Decrement |xx=xx-1 |
2426 ;|DEC ss |------|Decrement |ss=ss-1 |
2427 ;|DI |------|Disable Interrupts | |
2428 ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
2429 ;|EI |------|Enable Interrupts | |
2430 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
2431 ;|EX [SP],xx|------|Exchange |[SP]<->xx |
2432 ;|EX AF,AF' |------|Exchange |AF<->AF' |
2433 ;|EX DE,HL |------|Exchange |DE<->HL |
2434 ;|EXX |------|Exchange |qq<->qq' (except AF)|
2435 ;|HALT |------|Halt | |
2436 ;|IM n |------|Interrupt Mode | (n=0,1,2)|
2437 ;|IN A,[n] |------|Input |A=[n] |
2438 ;|IN r,[C] |***P0-|Input |r=[C] |
2439 ;|INC r |***V0-|Increment |r=r+1 |
2440 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2441 ;|INC xx |------|Increment |xx=xx+1 |
2442 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2443 ;|INC ss |------|Increment |ss=ss+1 |
2444 ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
2445 ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
2446 ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
2447 ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
2448 ;|JP [HL] |------|Unconditional Jump |PC=[HL] |
2449 ;|JP [xx] |------|Unconditional Jump |PC=[xx] |
2450 ;|JP nn |------|Unconditional Jump |PC=nn |
2451 ;|JP cc,nn |------|Conditional Jump |If cc JP |
2452 ;|JR e |------|Unconditional Jump |PC=PC+e |
2453 ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
2454 ;|LD dst,src|------|Load |dst=src |
2455 ;|LD A,i |**0*0-|Load |A=i (i=I,R)|
2456 ;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
2457 ;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
2458 ;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
2459 ;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
2460 ;|NEG |***V1*|Negate |A=-A |
2461 ;|NOP |------|No Operation | |
2462 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
2463 ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
2464 ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
2465 ;|OUT [C],r |------|Output |[C]=r |
2466 ;|OUT [n],A |------|Output |[n]=A |
2467 ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
2468 ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
2469 ;|POP xx |------|Pop |xx=[SP]+ |
2470 ;|POP qq |------|Pop |qq=[SP]+ |
2471 ;|PUSH xx |------|Push |-[SP]=xx |
2472 ;|PUSH qq |------|Push |-[SP]=qq |
2473 ;|RES b,m |------|Reset bit |m=m&{~2^b} |
2474 ;|RET |------|Return |PC=[SP]+ |
2475 ;|RET cc |------|Conditional Return |If cc RET |
2476 ;|RETI |------|Return from Interrupt|PC=[SP]+ |
2477 ;|RETN |------|Return from NMI |PC=[SP]+ |
2478 ;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
2479 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2480 ;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
2481 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
2482 ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
2483 ;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
2484 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2485 ;|RRC m |**0P0*|Rotate Right Circular|m=->m |
2486 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2487 ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
2488 ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
2489 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
2490 ;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY |
2491 ;|SCF |--0-01|Set Carry Flag |CY=1 |
2492 ;|SET b,m |------|Set bit |m=mv{2^b} |
2493 ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
2494 ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
2495 ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
2496 ;|SUB s |***V1*|Subtract |A=A-s |
2497 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
2498 ;|----------+------+--------------------------------------------|
2499 ;| F |-*01? |Flag unaffected/affected/reset/set/unknown |
2500 ;| S |S |Sign flag (Bit 7) |
2501 ;| Z | Z |Zero flag (Bit 6) |
2502 ;| HC | H |Half Carry flag (Bit 4) |
2503 ;| P/V | P |Parity/Overflow flag (Bit 2, V=overflow) |
2504 ;| N | N |Add/Subtract flag (Bit 1) |
2505 ;| CY | C|Carry flag (Bit 0) |
2506 ;|-----------------+--------------------------------------------|
2507 ;| n |Immediate addressing |
2508 ;| nn |Immediate extended addressing |
2509 ;| e |Relative addressing (PC=PC+2+offset) |
2510 ;| [nn] |Extended addressing |
2511 ;| [xx+d] |Indexed addressing |
2512 ;| r |Register addressing |
2513 ;| [rr] |Register indirect addressing |
2514 ;| |Implied addressing |
2515 ;| b |Bit addressing |
2516 ;| p |Modified page zero addressing (see RST) |
2517 ;|-----------------+--------------------------------------------|
2518 ;|DEFB n(,...) |Define Byte(s) |
2519 ;|DEFB 'str'(,...) |Define Byte ASCII string(s) |
2520 ;|DEFS nn |Define Storage Block |
2521 ;|DEFW nn(,...) |Define Word(s) |
2522 ;|-----------------+--------------------------------------------|
2523 ;| A B C D E |Registers (8-bit) |
2524 ;| AF BC DE HL |Register pairs (16-bit) |
2525 ;| F |Flag register (8-bit) |
2526 ;| I |Interrupt page address register (8-bit) |
2527 ;| IX IY |Index registers (16-bit) |
2528 ;| PC |Program Counter register (16-bit) |
2529 ;| R |Memory Refresh register |
2530 ;| SP |Stack Pointer register (16-bit) |
2531 ;|-----------------+--------------------------------------------|
2532 ;| b |One bit (0 to 7) |
2533 ;| cc |Condition (C,M,NC,NZ,P,PE,PO,Z) |
2534 ;| d |One-byte expression (-128 to +127) |
2535 ;| dst |Destination s, ss, [BC], [DE], [HL], [nn] |
2536 ;| e |One-byte expression (-126 to +129) |
2537 ;| m |Any register r, [HL] or [xx+d] |
2538 ;| n |One-byte expression (0 to 255) |
2539 ;| nn |Two-byte expression (0 to 65535) |
2540 ;| pp |Register pair BC, DE, IX or SP |
2541 ;| qq |Register pair AF, BC, DE or HL |
2542 ;| qq' |Alternative register pair AF, BC, DE or HL |
2543 ;| r |Register A, B, C, D, E, H or L |
2544 ;| rr |Register pair BC, DE, IY or SP |
2545 ;| s |Any register r, value n, [HL] or [xx+d] |
2546 ;| src |Source s, ss, [BC], [DE], [HL], nn, [nn] |
2547 ;| ss |Register pair BC, DE, HL or SP |
2548 ;| xx |Index register IX or IY |
2549 ;|-----------------+--------------------------------------------|
2550 ;| + - * / ^ |Add/subtract/multiply/divide/exponent |
2551 ;| & ~ v x |Logical AND/NOT/inclusive OR/exclusive OR |
2552 ;| <- -> |Rotate left/right |
2553 ;| [ ] |Indirect addressing |
2554 ;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement|
2555 ;| { } |Combination of operands |
2556 ;| # |Also BC=BC-1,DE=DE-1 |
2557 ;| ## |Only lower 4 bits of accumulator A used |
2558 ;----------------------------------------------------------------
2569 ;------------------------------------------------;
2570 ; Move single bit between two registers
2572 ; bmov dstreg,dstbit,srcreg.srcbit
2580 ;------------------------------------------------;
2581 ; Load table value from flash indexed by source reg.
2583 ; ldpmx dstreg,tablebase,indexreg
2585 ; (6 words, 8 cycles)
2588 ldi zh,high(@1*2) ; table must be page aligned
2593 .macro do_z80_flags_HP
2595 bmov z_flags, ZFL_P, temp, AVR_V
2596 bmov z_flags, ZFL_H, temp, AVR_H
2600 .macro do_z80_flags_set_N
2602 ori z_flags, (1<<ZFL_N) ; Negation auf 1
2606 .macro do_z80_flags_set_HN
2608 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
2612 .macro do_z80_flags_clear_N
2614 andi z_flags,~(1<<ZFL_N)
2618 .macro do_z80_flags_op_rotate
2619 ; must not change avr carry flag!
2621 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
2623 andi z_flags, ~( (1<<ZFL_C) )
2627 .macro do_z80_flags_op_and
2629 ori z_flags,(1<<ZFL_H)
2631 ori z_flags,(1<<ZFL_H)
2635 .macro do_z80_flags_op_or
2644 ;----------------------------------------------------------------
2645 ;|Mnemonic |SZHPNC|Description |Notes |
2646 ;----------------------------------------------------------------
2647 ;|INC r |***V0-|Increment |r=r+1 |
2648 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2649 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2650 ;|----------|SZHP C|---------- 8080 ----------------------------|
2651 ;|INC r |**-P0-|Increment |r=r+1 |
2652 ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 |
2659 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2660 ldpmx temp2, sz53p_tab, opl
2665 ;----------------------------------------------------------------
2666 ;|Mnemonic |SZHPNC|Description |Notes |
2667 ;----------------------------------------------------------------
2668 ;|DEC r |***V1-|Decrement |s=s-1 |
2669 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2670 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2671 ;|----------|SZHP C|---------- 8080 ----------------------------|
2672 ;|DEC r |**-P -|Increment |r=r+1 |
2673 ;|DEC [HL] |**-P -|Increment |[HL]=[HL]+1 |
2679 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2680 ldpmx temp2, sz53p_tab, opl
2687 ;----------------------------------------------------------------
2688 ;|Mnemonic |SZHPNC|Description |Notes |
2689 ;----------------------------------------------------------------
2690 ;|INC xx |------|Increment |xx=xx+1 |
2691 ;|INC ss |------|Increment |ss=ss+1 |
2698 ;----------------------------------------------------------------
2699 ;|Mnemonic |SZHPNC|Description |Notes |
2700 ;----------------------------------------------------------------
2701 ;|DEC xx |------|Decrement |xx=xx-1 |
2702 ;|DEC ss |------|Decrement |ss=ss-1 |
2710 ;----------------------------------------------------------------
2711 ;|Mnemonic |SZHPNC|Description |Notes |
2712 ;----------------------------------------------------------------
2713 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
2714 ;|----------|SZHP C|---------- 8080 ----------------------------|
2715 ;|RLCA |---- *|Rotate Left Circular |A=A<- |
2719 ;Rotate Left Cyclical. All bits move 1 to the
2720 ;left, the msb becomes c and lsb.
2721 do_z80_flags_op_rotate
2725 ori z_flags, (1<<ZFL_C)
2729 ;----------------------------------------------------------------
2730 ;|Mnemonic |SZHPNC|Description |Notes |
2731 ;----------------------------------------------------------------
2732 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2733 ;|----------|SZHP C|---------- 8080 ----------------------------|
2734 ;|RRCA |---- *|Rotate Right Circular|A=->A |
2738 ;Rotate Right Cyclical. All bits move 1 to the
2739 ;right, the lsb becomes c and msb.
2740 do_z80_flags_op_rotate
2744 ori z_flags, (1<<ZFL_C)
2748 ;----------------------------------------------------------------
2749 ;|Mnemonic |SZHPNC|Description |Notes |
2750 ;----------------------------------------------------------------
2751 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2752 ;|----------|SZHP C|---------- 8080 ----------------------------|
2753 ;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} |
2757 ;Rotate Right. All bits move 1 to the right, the lsb
2758 ;becomes c, c becomes msb.
2759 clc ; get z80 carry to avr carry
2762 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
2763 bmov z_flags,ZFL_C, opl,0 ; Bit 0 --> CY
2767 ;----------------------------------------------------------------
2768 ;|Mnemonic |SZHPNC|Description |Notes |
2769 ;----------------------------------------------------------------
2770 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2771 ;|----------|SZHP C|---------- 8080 ----------------------------|
2772 ;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- |
2776 ;Rotate Left. All bits move 1 to the left, the msb
2777 ;becomes c, c becomes lsb.
2781 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
2782 bmov z_flags,ZFL_C, opl,7 ; Bit 7 --> CY
2786 ;----------------------------------------------------------------
2787 ;|Mnemonic |SZHPNC|Description |Notes |
2788 ;----------------------------------------------------------------
2789 ;|ADD A,s |***V0*|Add |A=A+s |
2790 ;|----------|SZHP C|---------- 8080 ----------------------------|
2791 ;|ADD A,s |***P *|Add |A=A+s |
2797 ldpmx z_flags,sz53p_tab,opl ;S,Z,P flag
2798 bmov z_flags,ZFL_C, temp,AVR_C
2802 ;----------------------------------------------------------------
2803 ;|Mnemonic |SZHPNC|Description |Notes |
2804 ;----------------------------------------------------------------
2805 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
2806 ;|----------|SZHP C|---------- 8080 ----------------------------|
2807 ;|ADC A,s |***P *|Add with Carry |A=A+s+CY |
2816 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
2817 bmov z_flags,ZFL_C, temp,AVR_C
2821 ;----------------------------------------------------------------
2822 ;|Mnemonic |SZHPNC|Description |Notes |
2823 ;----------------------------------------------------------------
2824 ;|SUB s |***V1*|Subtract |A=A-s |
2825 ;|CP s |***V1*|Compare |A-s |
2826 ;|----------|SZHP C|---------- 8080 ----------------------------|
2827 ;|SUB s |***P *|Subtract |A=A-s |
2828 ;|CP s |***P *|Compare |A-s |
2836 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
2837 bmov z_flags,ZFL_C, temp,AVR_C
2842 ;----------------------------------------------------------------
2843 ;|Mnemonic |SZHPNC|Description |Notes |
2844 ;----------------------------------------------------------------
2845 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
2846 ;|----------|SZHP C|---------- 8080 ----------------------------|
2847 ;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY |
2858 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
2859 bmov z_flags,ZFL_C, temp,AVR_C
2864 ;----------------------------------------------------------------
2865 ;|Mnemonic |SZHPNC|Description |Notes |
2866 ;----------------------------------------------------------------
2867 ;|AND s |**1P00|Logical AND |A=A&s |
2868 ;|----------|SZHP C|---------- 8080 ----------------------------|
2869 ;|AND s |**-P 0|Logical AND |A=A&s |
2874 ldpmx z_flags,sz53p_tab,opl ;S,Z,P,N,C
2879 ;----------------------------------------------------------------
2880 ;|Mnemonic |SZHPNC|Description |Notes |
2881 ;----------------------------------------------------------------
2882 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
2883 ;|----------|SZHP C|---------- 8080 ----------------------------|
2884 ;|OR s |**-P00|Logical inclusive OR |A=Avs |
2889 ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
2893 ;----------------------------------------------------------------
2894 ;|Mnemonic |SZHPNC|Description |Notes |
2895 ;----------------------------------------------------------------
2896 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
2897 ;|----------|SZHP C|---------- 8080 ----------------------------|
2898 ;|XOR s |**-P 0|Logical Exclusive OR |A=Axs |
2903 ldpmx z_flags,sz53p_tab,opl ;S,Z,H,P,N,C
2907 ;----------------------------------------------------------------
2908 ;|Mnemonic |SZHPNC|Description |Notes |
2909 ;----------------------------------------------------------------
2910 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
2911 ;|----------|SZHP C|---------- 8080 ----------------------------|
2912 ;|ADD HL,ss |---- *|Add |HL=HL+ss |
2919 bmov z_flags,ZFL_H, temp,AVR_H
2920 bmov z_flags,ZFL_C, temp,AVR_C
2921 do_z80_flags_clear_N
2924 ;----------------------------------------------------------------
2925 ;|Mnemonic |SZHPNC|Description |Notes |
2926 ;----------------------------------------------------------------
2927 ;|LD dst,src|------|Load |dst=src |
2930 do_op_sthl: ;store hl to mem loc in opl:h
2932 #if DRAM_WORD_ACCESS
2945 ;----------------------------------------------------------------
2946 ;|Mnemonic |SZHPNC|Description |Notes |
2947 ;----------------------------------------------------------------
2948 ;|LD dst,src|------|Load |dst=src |
2953 #if DRAM_WORD_ACCESS
2965 ;----------------------------------------------------------------
2966 ;|Mnemonic |SZHPNC|Description |Notes |
2967 ;----------------------------------------------------------------
2968 ;|LD dst,src|------|Load |dst=src |
2977 ;----------------------------------------------------------------
2978 ;|Mnemonic |SZHPNC|Description |Notes |
2979 ;----------------------------------------------------------------
2980 ;|DAA |***P-*|Decimal Adjust Acc. | |
2981 ;|----------|SZHP C|---------- 8080 ----------------------------|
2985 ; Description (http://www.z80.info/z80syntx.htm#DAA):
2986 ; This instruction conditionally adjusts the accumulator for BCD addition
2987 ; and subtraction operations. For addition (ADD, ADC, INC) or subtraction
2988 ; (SUB, SBC, DEC, NEC), the following table indicates the operation performed:
2990 ; -------------------------------------------------------------------------------
2991 ; | | C Flag | HEX value in | H Flag | HEX value in | Number | C flag|
2992 ; | Operation| Before | upper digit | Before | lower digit | added | After |
2993 ; | | DAA | (bit 7-4) | DAA | (bit 3-0) | to byte | DAA |
2994 ; |-----------------------------------------------------------------------------|
2995 ; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
2996 ; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
2997 ; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
2998 ; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
2999 ; | | 0 | 9-F | 0 | A-F | 66 | 1 |
3000 ; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
3001 ; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
3002 ; | | 1 | 0-2 | 0 | A-F | 66 | 1 |
3003 ; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
3004 ; |-----------------------------------------------------------------------------|
3005 ; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3006 ; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
3007 ; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
3008 ; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
3009 ; |-----------------------------------------------------------------------------|
3012 ; C: See instruction.
3014 ; P/V: Set if Acc. is even parity after operation, reset otherwise.
3015 ; H: See instruction.
3016 ; Z: Set if Acc. is Zero after operation, reset otherwise.
3017 ; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise.
3023 ldi oph,0 ; what to add
3024 sbrc z_flags,ZFL_H ; if H-Flag
3027 andi temp,0x0f ; ... or lower digit > 9
3033 sbrc z_flags,(1<<ZFL_C)
3042 ori z_flags,(1<<ZFL_C); set C
3044 sbrs z_flags,ZFL_N ; if sub-op
3045 rjmp op_da_add ; then
3048 op_da_add: ; else add-op
3061 ori z_flags,(1<<ZFL_C)
3062 andi z_flags,(1<<ZFL_N)|(1<<ZFL_C) ; preserve C,N
3063 ldpmx temp2, sz53p_tab, opl ; get S,Z,P
3065 bmov z_flags,ZFL_H, temp,AVR_H ; H (?)
3070 sbrc z_flags,ZFL_N ; if add-op
3071 rjmp do_op_da_sub ; then
3075 cpi temp,0x0a ; if lower digit > 9
3077 ori temp2,0x06 ; add 6 to lower digit
3079 sbrc z_flags,ZFL_H ; ... or H-Flag
3089 do_op_da_c: ; else sub-op
3090 sbrc z_flags,ZFL_C ;
3092 andi z_flags, ~( (1<<ZFL_S) | (1<<ZFL_Z) | (1<<ZFL_H) )
3095 bst temp,AVR_Z ;Z-Flag
3097 bst temp,AVR_N ;S-Flag
3099 sbrc temp2,5 ;C-Flag, set if 0x06 added
3100 ori z_flags,(1<<ZFL_C) ;
3104 do_op_da_sub: ;TODO:
3109 ;----------------------------------------------------------------
3110 ;|Mnemonic |SZHPNC|Description |Notes |
3111 ;----------------------------------------------------------------
3112 ;|SCF |--0-01|Set Carry Flag |CY=1 |
3113 ;|----------|SZHP C|---------- 8080 ----------------------------|
3117 andi z_flags,~((1<<ZFL_H)|(1<<ZFL_N))
3118 ori z_flags,(1<<ZFL_C)
3121 ;----------------------------------------------------------------
3122 ;|Mnemonic |SZHPNC|Description |Notes |
3123 ;----------------------------------------------------------------
3124 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
3125 ;|----------|SZHP C|---------- 8080 ----------------------------|
3126 ;|SCF |---- 1|Set Carry Flag |CY=1 |
3130 do_z80_flags_clear_N
3135 ;----------------------------------------------------------------
3136 ;|Mnemonic |SZHPNC|Description |Notes |
3137 ;----------------------------------------------------------------
3138 ;|CPL |--1-1-|Complement |A=~A |
3139 ;|----------|SZHP C|---------- 8080 ----------------------------|
3140 ;|CPL |---- -|Complement |A=~A |
3149 ;----------------------------------------------------------------
3150 ;|Mnemonic |SZHPNC|Description |Notes |
3151 ;----------------------------------------------------------------
3152 ;|PUSH xx |------|Push |-[SP]=xx |
3153 ;|PUSH qq |------|Push |-[SP]=qq |
3161 #if DRAM_WORD_ACCESS
3180 .db ", SP is now ",0
3191 ;----------------------------------------------------------------
3192 ;|Mnemonic |SZHPNC|Description |Notes |
3193 ;----------------------------------------------------------------
3194 ;|POP xx |------|Pop |xx=[SP]+ |
3195 ;|POP qq |------|Pop |qq=[SP]+ |
3200 #if DRAM_WORD_ACCESS
3217 .db "Stack pop: val ",0
3233 ;----------------------------------------------------------------
3234 ;|Mnemonic |SZHPNC|Description |Notes |
3235 ;----------------------------------------------------------------
3236 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
3237 ;|EX DE,HL |------|Exchange |DE<->HL |
3249 ;----------------------------------------------------------------
3250 ;|Mnemonic |SZHPNC|Description |Notes |
3251 ;----------------------------------------------------------------
3253 ; TODO: Implement IFF1, IFF2
3257 ;----------------------------------------------------------------
3258 ;|Mnemonic |SZHPNC|Description |Notes |
3259 ;----------------------------------------------------------------
3261 ; TODO: Implement IFF1, IFF2
3265 ;----------------------------------------------------------------
3266 ;|Mnemonic |SZHPNC|Description |Notes |
3267 ;----------------------------------------------------------------
3268 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3269 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3270 ;|RET cc |------|Conditional Return |If cc RET |
3280 ;----------------------------------------------------------------
3281 ;|Mnemonic |SZHPNC|Description |Notes |
3282 ;----------------------------------------------------------------
3283 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3284 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3285 ;|RET cc |------|Conditional Return |If cc RET |
3295 ;----------------------------------------------------------------
3296 ;|Mnemonic |SZHPNC|Description |Notes |
3297 ;----------------------------------------------------------------
3298 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3299 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3300 ;|RET cc |------|Conditional Return |If cc RET |
3310 ;----------------------------------------------------------------
3311 ;|Mnemonic |SZHPNC|Description |Notes |
3312 ;----------------------------------------------------------------
3313 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3314 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3315 ;|RET cc |------|Conditional Return |If cc RET |
3325 ;----------------------------------------------------------------
3326 ;|Mnemonic |SZHPNC|Description |Notes |
3327 ;----------------------------------------------------------------
3328 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3329 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3330 ;|RET cc |------|Conditional Return |If cc RET |
3340 ;----------------------------------------------------------------
3341 ;|Mnemonic |SZHPNC|Description |Notes |
3342 ;----------------------------------------------------------------
3343 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3344 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3345 ;|RET cc |------|Conditional Return |If cc RET |
3355 ;----------------------------------------------------------------
3356 ;|Mnemonic |SZHPNC|Description |Notes |
3357 ;----------------------------------------------------------------
3358 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3359 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3360 ;|RET cc |------|Conditional Return |If cc RET |
3363 do_op_ifp: ;sign positive, aka s=0
3370 ;----------------------------------------------------------------
3371 ;|Mnemonic |SZHPNC|Description |Notes |
3372 ;----------------------------------------------------------------
3373 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3374 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3375 ;|RET cc |------|Conditional Return |If cc RET |
3378 do_op_ifm: ;sign negative, aka s=1
3385 ;----------------------------------------------------------------
3386 ;|Mnemonic |SZHPNC|Description |Notes |
3387 ;----------------------------------------------------------------
3388 ;|OUT [n],A |------|Output |[n]=A |
3391 ;Interface with peripherials goes here :)
3392 do_op_outa: ; out (opl),a
3395 .db 13,"Port write: ",0
3410 ;----------------------------------------------------------------
3411 ;|Mnemonic |SZHPNC|Description |Notes |
3412 ;----------------------------------------------------------------
3413 ;|IN A,[n] |------|Input |A=[n] |
3416 do_op_in: ; in a,(opl)
3419 .db 13,"Port read: (",0
3438 ;----------------------------------------------------------------
3441 .db "Invalid opcode @ PC=",0,0
3447 ;----------------------------------------------------------------
3451 ;----------------------------------------------------------------
3452 ; Lookup table, stolen from z80ex, Z80 emulation library.
3453 ; http://z80ex.sourceforge.net/
3455 ; The S, Z, 5 and 3 bits and the parity of the lookup value
3456 .org (PC+255) & 0xff00
3458 .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3459 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3460 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3461 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3462 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3463 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3464 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3465 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3466 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3467 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3468 .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3469 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3470 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3471 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3472 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3473 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3474 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3475 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3476 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3477 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3478 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3479 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3480 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3481 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3482 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3483 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3484 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3485 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3486 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3487 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3488 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3489 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3492 ; ----------------------- Opcode decoding -------------------------
3494 ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
3495 ; operations: fetch, do something, store.
3496 ; The table is made of 256 words. These 16-bit words consist of
3497 ; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store
3498 ; operation (bit 5-9).
3500 .org (PC+255) & 0xff00
3502 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
3503 .dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
3504 .dw (FETCH_A | OP_NOP | STORE_MBC) ; 02 LD (BC),A
3505 .dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
3506 .dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
3507 .dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
3508 .dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
3509 .dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
3510 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
3511 .dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
3512 .dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
3513 .dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
3514 .dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
3515 .dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
3516 .dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
3517 .dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
3518 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
3519 .dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn
3520 .dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A
3521 .dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
3522 .dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D
3523 .dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D
3524 .dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n
3525 .dw (FETCH_A | OP_RL | STORE_A ) ; 17 RLA
3526 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 18 oo JR o (Z80)
3527 .dw (FETCH_DE | OP_ADDHL | STORE_HL ) ; 19 ADD HL,DE
3528 .dw (FETCH_MDE | OP_NOP | STORE_A ) ; 1A LD A,(DE)
3529 .dw (FETCH_DE | OP_DEC16 | STORE_DE ) ; 1B DEC DE
3530 .dw (FETCH_E | OP_INC | STORE_E ) ; 1C INC E
3531 .dw (FETCH_E | OP_DEC | STORE_E ) ; 1D DEC E
3532 .dw (FETCH_DIR8 | OP_NOP | STORE_E ) ; 1E nn LD E,n
3533 .dw (FETCH_A | OP_RR | STORE_A ) ; 1F RRA
3534 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 20 oo JR NZ,o (Z80)
3535 .dw (FETCH_DIR16| OP_NOP | STORE_HL ) ; 21 nn nn LD HL,nn
3536 .dw (FETCH_DIR16| OP_STHL | STORE_NOP) ; 22 nn nn LD (nn),HL
3537 .dw (FETCH_HL | OP_INC16 | STORE_HL ) ; 23 INC HL
3538 .dw (FETCH_H | OP_INC | STORE_H ) ; 24 INC H
3539 .dw (FETCH_H | OP_DEC | STORE_H ) ; 25 DEC H
3540 .dw (FETCH_DIR8 | OP_NOP | STORE_H ) ; 26 nn LD H,n
3541 .dw (FETCH_A | OP_DA | STORE_A ) ; 27 DAA
3542 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 28 oo JR Z,o (Z80)
3543 .dw (FETCH_HL | OP_ADDHL | STORE_HL ) ; 29 ADD HL,HL
3544 .dw (FETCH_DIR16| OP_RMEM16 | STORE_HL ) ; 2A nn nn LD HL,(nn)
3545 .dw (FETCH_HL | OP_DEC16 | STORE_HL ) ; 2B DEC HL
3546 .dw (FETCH_L | OP_INC | STORE_L ) ; 2C INC L
3547 .dw (FETCH_L | OP_DEC | STORE_L ) ; 2D DEC L
3548 .dw (FETCH_DIR8 | OP_NOP | STORE_L ) ; 2E nn LD L,n
3549 .dw (FETCH_A | OP_CPL | STORE_A ) ; 2F CPL
3550 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 30 oo JR NC,o (Z80)
3551 .dw (FETCH_DIR16| OP_NOP | STORE_SP ) ; 31 nn nn LD SP,nn
3552 .dw (FETCH_DIR16| OP_NOP | STORE_AM ) ; 32 nn nn LD (nn),A
3553 .dw (FETCH_SP | OP_INC16 | STORE_SP ) ; 33 INC SP
3554 .dw (FETCH_MHL | OP_INC | STORE_MHL) ; 34 INC (HL)
3555 .dw (FETCH_MHL | OP_DEC | STORE_MHL) ; 35 DEC (HL)
3556 .dw (FETCH_DIR8 | OP_NOP | STORE_MHL) ; 36 nn LD (HL),n
3557 .dw (FETCH_NOP | OP_SCF | STORE_NOP) ; 37 SCF
3558 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 38 oo JR C,o (Z80)
3559 .dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
3560 .dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
3561 .dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
3562 .dw (FETCH_A | OP_INC | STORE_A ) ; 3C INC A
3563 .dw (FETCH_A | OP_DEC | STORE_A ) ; 3D DEC A
3564 .dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
3565 .dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
3566 .dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r
3567 .dw (FETCH_C | OP_NOP | STORE_B ) ; 41 LD B,r
3568 .dw (FETCH_D | OP_NOP | STORE_B ) ; 42 LD B,r
3569 .dw (FETCH_E | OP_NOP | STORE_B ) ; 43 LD B,r
3570 .dw (FETCH_H | OP_NOP | STORE_B ) ; 44 LD B,r
3571 .dw (FETCH_L | OP_NOP | STORE_B ) ; 45 LD B,r
3572 .dw (FETCH_MHL | OP_NOP | STORE_B ) ; 46 LD B,r
3573 .dw (FETCH_A | OP_NOP | STORE_B ) ; 47 LD B,r
3574 .dw (FETCH_B | OP_NOP | STORE_C ) ; 48 LD C,r
3575 .dw (FETCH_C | OP_NOP | STORE_C ) ; 49 LD C,r
3576 .dw (FETCH_D | OP_NOP | STORE_C ) ; 4A LD C,r
3577 .dw (FETCH_E | OP_NOP | STORE_C ) ; 4B LD C,r
3578 .dw (FETCH_H | OP_NOP | STORE_C ) ; 4C LD C,r
3579 .dw (FETCH_L | OP_NOP | STORE_C ) ; 4D LD C,r
3580 .dw (FETCH_MHL | OP_NOP | STORE_C ) ; 4E LD C,r
3581 .dw (FETCH_A | OP_NOP | STORE_C ) ; 4F LD C,r
3582 .dw (FETCH_B | OP_NOP | STORE_D ) ; 50 LD D,r
3583 .dw (FETCH_C | OP_NOP | STORE_D ) ; 51 LD D,r
3584 .dw (FETCH_D | OP_NOP | STORE_D ) ; 52 LD D,r
3585 .dw (FETCH_E | OP_NOP | STORE_D ) ; 53 LD D,r
3586 .dw (FETCH_H | OP_NOP | STORE_D ) ; 54 LD D,r
3587 .dw (FETCH_L | OP_NOP | STORE_D ) ; 55 LD D,r
3588 .dw (FETCH_MHL | OP_NOP | STORE_D ) ; 56 LD D,r
3589 .dw (FETCH_A | OP_NOP | STORE_D ) ; 57 LD D,r
3590 .dw (FETCH_B | OP_NOP | STORE_E ) ; 58 LD E,r
3591 .dw (FETCH_C | OP_NOP | STORE_E ) ; 59 LD E,r
3592 .dw (FETCH_D | OP_NOP | STORE_E ) ; 5A LD E,r
3593 .dw (FETCH_E | OP_NOP | STORE_E ) ; 5B LD E,r
3594 .dw (FETCH_H | OP_NOP | STORE_E ) ; 5C LD E,r
3595 .dw (FETCH_L | OP_NOP | STORE_E ) ; 5D LD E,r
3596 .dw (FETCH_MHL | OP_NOP | STORE_E ) ; 5E LD E,r
3597 .dw (FETCH_A | OP_NOP | STORE_E ) ; 5F LD E,r
3598 .dw (FETCH_B | OP_NOP | STORE_H ) ; 60 LD H,r
3599 .dw (FETCH_C | OP_NOP | STORE_H ) ; 61 LD H,r
3600 .dw (FETCH_D | OP_NOP | STORE_H ) ; 62 LD H,r
3601 .dw (FETCH_E | OP_NOP | STORE_H ) ; 63 LD H,r
3602 .dw (FETCH_H | OP_NOP | STORE_H ) ; 64 LD H,r
3603 .dw (FETCH_L | OP_NOP | STORE_H ) ; 65 LD H,r
3604 .dw (FETCH_MHL | OP_NOP | STORE_H ) ; 66 LD H,r
3605 .dw (FETCH_A | OP_NOP | STORE_H ) ; 67 LD H,r
3606 .dw (FETCH_B | OP_NOP | STORE_L ) ; 68 LD L,r
3607 .dw (FETCH_C | OP_NOP | STORE_L ) ; 69 LD L,r
3608 .dw (FETCH_D | OP_NOP | STORE_L ) ; 6A LD L,r
3609 .dw (FETCH_E | OP_NOP | STORE_L ) ; 6B LD L,r
3610 .dw (FETCH_H | OP_NOP | STORE_L ) ; 6C LD L,r
3611 .dw (FETCH_L | OP_NOP | STORE_L ) ; 6D LD L,r
3612 .dw (FETCH_MHL | OP_NOP | STORE_L ) ; 6E LD L,r
3613 .dw (FETCH_A | OP_NOP | STORE_L ) ; 6F LD L,r
3614 .dw (FETCH_B | OP_NOP | STORE_MHL) ; 70 LD (HL),r
3615 .dw (FETCH_C | OP_NOP | STORE_MHL) ; 71 LD (HL),r
3616 .dw (FETCH_D | OP_NOP | STORE_MHL) ; 72 LD (HL),r
3617 .dw (FETCH_E | OP_NOP | STORE_MHL) ; 73 LD (HL),r
3618 .dw (FETCH_H | OP_NOP | STORE_MHL) ; 74 LD (HL),r
3619 .dw (FETCH_L | OP_NOP | STORE_MHL) ; 75 LD (HL),r
3620 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 76 HALT
3621 .dw (FETCH_A | OP_NOP | STORE_MHL) ; 77 LD (HL),r
3622 .dw (FETCH_B | OP_NOP | STORE_A ) ; 78 LD A,r
3623 .dw (FETCH_C | OP_NOP | STORE_A ) ; 79 LD A,r
3624 .dw (FETCH_D | OP_NOP | STORE_A ) ; 7A LD A,r
3625 .dw (FETCH_E | OP_NOP | STORE_A ) ; 7B LD A,r
3626 .dw (FETCH_H | OP_NOP | STORE_A ) ; 7C LD A,r
3627 .dw (FETCH_L | OP_NOP | STORE_A ) ; 7D LD A,r
3628 .dw (FETCH_MHL | OP_NOP | STORE_A ) ; 7E LD A,r
3629 .dw (FETCH_A | OP_NOP | STORE_A ) ; 7F LD A,r
3630 .dw (FETCH_B | OP_ADDA | STORE_A ) ; 80 ADD A,r
3631 .dw (FETCH_C | OP_ADDA | STORE_A ) ; 81 ADD A,r
3632 .dw (FETCH_D | OP_ADDA | STORE_A ) ; 82 ADD A,r
3633 .dw (FETCH_E | OP_ADDA | STORE_A ) ; 83 ADD A,r
3634 .dw (FETCH_H | OP_ADDA | STORE_A ) ; 84 ADD A,r
3635 .dw (FETCH_L | OP_ADDA | STORE_A ) ; 85 ADD A,r
3636 .dw (FETCH_MHL | OP_ADDA | STORE_A ) ; 86 ADD A,r
3637 .dw (FETCH_A | OP_ADDA | STORE_A ) ; 87 ADD A,r
3638 .dw (FETCH_B | OP_ADCA | STORE_A ) ; 88 ADC A,r
3639 .dw (FETCH_C | OP_ADCA | STORE_A ) ; 89 ADC A,r
3640 .dw (FETCH_D | OP_ADCA | STORE_A ) ; 8A ADC A,r
3641 .dw (FETCH_E | OP_ADCA | STORE_A ) ; 8B ADC A,r
3642 .dw (FETCH_H | OP_ADCA | STORE_A ) ; 8C ADC A,r
3643 .dw (FETCH_L | OP_ADCA | STORE_A ) ; 8D ADC A,r
3644 .dw (FETCH_MHL | OP_ADCA | STORE_A ) ; 8E ADC A,r
3645 .dw (FETCH_A | OP_ADCA | STORE_A ) ; 8F ADC A,r
3646 .dw (FETCH_B | OP_SUBFA | STORE_A ) ; 90 SUB A,r
3647 .dw (FETCH_C | OP_SUBFA | STORE_A ) ; 91 SUB A,r
3648 .dw (FETCH_D | OP_SUBFA | STORE_A ) ; 92 SUB A,r
3649 .dw (FETCH_E | OP_SUBFA | STORE_A ) ; 93 SUB A,r
3650 .dw (FETCH_H | OP_SUBFA | STORE_A ) ; 94 SUB A,r
3651 .dw (FETCH_L | OP_SUBFA | STORE_A ) ; 95 SUB A,r
3652 .dw (FETCH_MHL | OP_SUBFA | STORE_A ) ; 96 SUB A,r
3653 .dw (FETCH_A | OP_SUBFA | STORE_A ) ; 97 SUB A,r
3654 .dw (FETCH_B | OP_SBCFA | STORE_A ) ; 98 SBC A,r
3655 .dw (FETCH_C | OP_SBCFA | STORE_A ) ; 99 SBC A,r
3656 .dw (FETCH_D | OP_SBCFA | STORE_A ) ; 9A SBC A,r
3657 .dw (FETCH_E | OP_SBCFA | STORE_A ) ; 9B SBC A,r
3658 .dw (FETCH_H | OP_SBCFA | STORE_A ) ; 9C SBC A,r
3659 .dw (FETCH_L | OP_SBCFA | STORE_A ) ; 9D SBC A,r
3660 .dw (FETCH_MHL | OP_SBCFA | STORE_A ) ; 9E SBC A,r
3661 .dw (FETCH_A | OP_SBCFA | STORE_A ) ; 9F SBC A,r
3662 .dw (FETCH_B | OP_ANDA | STORE_A ) ; A0 AND A,r
3663 .dw (FETCH_C | OP_ANDA | STORE_A ) ; A1 AND A,r
3664 .dw (FETCH_D | OP_ANDA | STORE_A ) ; A2 AND A,r
3665 .dw (FETCH_E | OP_ANDA | STORE_A ) ; A3 AND A,r
3666 .dw (FETCH_H | OP_ANDA | STORE_A ) ; A4 AND A,r
3667 .dw (FETCH_L | OP_ANDA | STORE_A ) ; A5 AND A,r
3668 .dw (FETCH_MHL | OP_ANDA | STORE_A ) ; A6 AND A,r
3669 .dw (FETCH_A | OP_ANDA | STORE_A ) ; A7 AND A,r
3670 .dw (FETCH_B | OP_XORA | STORE_A ) ; A8 XOR A,r
3671 .dw (FETCH_C | OP_XORA | STORE_A ) ; A9 XOR A,r
3672 .dw (FETCH_D | OP_XORA | STORE_A ) ; AA XOR A,r
3673 .dw (FETCH_E | OP_XORA | STORE_A ) ; AB XOR A,r
3674 .dw (FETCH_H | OP_XORA | STORE_A ) ; AC XOR A,r
3675 .dw (FETCH_L | OP_XORA | STORE_A ) ; AD XOR A,r
3676 .dw (FETCH_MHL | OP_XORA | STORE_A ) ; AE XOR A,r
3677 .dw (FETCH_A | OP_XORA | STORE_A ) ; AF XOR A,r
3678 .dw (FETCH_B | OP_ORA | STORE_A ) ; B0 OR A,r
3679 .dw (FETCH_C | OP_ORA | STORE_A ) ; B1 OR A,r
3680 .dw (FETCH_D | OP_ORA | STORE_A ) ; B2 OR A,r
3681 .dw (FETCH_E | OP_ORA | STORE_A ) ; B3 OR A,r
3682 .dw (FETCH_H | OP_ORA | STORE_A ) ; B4 OR A,r
3683 .dw (FETCH_L | OP_ORA | STORE_A ) ; B5 OR A,r
3684 .dw (FETCH_MHL | OP_ORA | STORE_A ) ; B6 OR A,r
3685 .dw (FETCH_A | OP_ORA | STORE_A ) ; B7 OR A,r
3686 .dw (FETCH_B | OP_SUBFA | STORE_NOP) ; B8 CP A,r
3687 .dw (FETCH_C | OP_SUBFA | STORE_NOP) ; B9 CP A,r
3688 .dw (FETCH_D | OP_SUBFA | STORE_NOP) ; BA CP A,r
3689 .dw (FETCH_E | OP_SUBFA | STORE_NOP) ; BB CP A,r
3690 .dw (FETCH_H | OP_SUBFA | STORE_NOP) ; BC CP A,r
3691 .dw (FETCH_L | OP_SUBFA | STORE_NOP) ; BD CP A,r
3692 .dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; BE CP A,r
3693 .dw (FETCH_A | OP_SUBFA | STORE_NOP) ; BF CP A,r
3694 .dw (FETCH_NOP | OP_IFNZ | STORE_RET) ; C0 RET NZ
3695 .dw (FETCH_NOP | OP_POP16 | STORE_BC ) ; C1 POP BC
3696 .dw (FETCH_DIR16| OP_IFNZ | STORE_PC ) ; C2 nn nn JP NZ,nn
3697 .dw (FETCH_DIR16| OP_NOP | STORE_PC ) ; C3 nn nn JP nn
3698 .dw (FETCH_DIR16| OP_IFNZ | STORE_CALL) ; C4 nn nn CALL NZ,nn
3699 .dw (FETCH_BC | OP_PUSH16 | STORE_NOP) ; C5 PUSH BC
3700 .dw (FETCH_DIR8 | OP_ADDA | STORE_A ) ; C6 nn ADD A,n
3701 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; C7 RST 0
3702 .dw (FETCH_NOP | OP_IFZ | STORE_RET) ; C8 RET Z
3703 .dw (FETCH_NOP | OP_NOP | STORE_RET) ; C9 RET
3704 .dw (FETCH_DIR16| OP_IFZ | STORE_PC ) ; CA nn nn JP Z,nn
3705 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; CB (Z80 specific)
3706 .dw (FETCH_DIR16| OP_IFZ | STORE_CALL) ; CC nn nn CALL Z,nn
3707 .dw (FETCH_DIR16| OP_NOP | STORE_CALL) ; CD nn nn CALL nn
3708 .dw (FETCH_DIR8 | OP_ADCA | STORE_A ) ; CE nn ADC A,n
3709 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; CF RST 8H
3710 .dw (FETCH_NOP | OP_IFNC | STORE_RET) ; D0 RET NC
3711 .dw (FETCH_NOP | OP_POP16 | STORE_DE ) ; D1 POP DE
3712 .dw (FETCH_DIR16| OP_IFNC | STORE_PC ) ; D2 nn nn JP NC,nn
3713 .dw (FETCH_DIR8 | OP_OUTA | STORE_NOP) ; D3 nn OUT (n),A
3714 .dw (FETCH_DIR16| OP_IFNC | STORE_CALL) ; D4 nn nn CALL NC,nn
3715 .dw (FETCH_DE | OP_PUSH16 | STORE_NOP) ; D5 PUSH DE
3716 .dw (FETCH_DIR8 | OP_SUBFA | STORE_A ) ; D6 nn SUB n
3717 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H
3718 .dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C
3719 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
3720 .dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn
3721 .dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
3722 .dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn
3723 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; DD (Z80)
3724 .dw (FETCH_DIR8 | OP_SBCFA | STORE_A ) ; DE nn SBC A,n
3725 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; DF RST 18H
3726 .dw (FETCH_NOP | OP_IFPO | STORE_RET) ; E0 RET PO
3727 .dw (FETCH_NOP | OP_POP16 | STORE_HL ) ; E1 POP HL
3728 .dw (FETCH_DIR16| OP_IFPO | STORE_PC ) ; E2 nn nn JP PO,nn
3729 .dw (FETCH_MSP | OP_EXHL | STORE_MSP) ; E3 EX (SP),HL
3730 .dw (FETCH_DIR16| OP_IFPO | STORE_CALL) ; E4 nn nn CALL PO,nn
3731 .dw (FETCH_HL | OP_PUSH16 | STORE_NOP) ; E5 PUSH HL
3732 .dw (FETCH_DIR8 | OP_ANDA | STORE_A ) ; E6 nn AND n
3733 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; E7 RST 20H
3734 .dw (FETCH_NOP | OP_IFPE | STORE_RET) ; E8 RET PE
3735 .dw (FETCH_HL | OP_NOP | STORE_PC ) ; E9 JP (HL)
3736 .dw (FETCH_DIR16| OP_IFPE | STORE_PC ) ; EA nn nn JP PE,nn
3737 .dw (FETCH_DE | OP_EXHL | STORE_DE ) ; EB EX DE,HL
3738 .dw (FETCH_DIR16| OP_IFPE | STORE_CALL) ; EC nn nn CALL PE,nn
3739 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; ED (Z80 specific)
3740 .dw (FETCH_DIR8 | OP_XORA | STORE_A ) ; EE nn XOR n
3741 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; EF RST 28H
3742 .dw (FETCH_NOP | OP_IFP | STORE_RET) ; F0 RET P
3743 .dw (FETCH_NOP | OP_POP16 | STORE_AF ) ; F1 POP AF
3744 .dw (FETCH_DIR16| OP_IFP | STORE_PC ) ; F2 nn nn JP P,nn
3745 .dw (FETCH_NOP | OP_DI | STORE_NOP) ; F3 DI
3746 .dw (FETCH_DIR16| OP_IFP | STORE_CALL) ; F4 nn nn CALL P,nn
3747 .dw (FETCH_AF | OP_PUSH16 | STORE_NOP) ; F5 PUSH AF
3748 .dw (FETCH_DIR8 | OP_ORA | STORE_A ) ; F6 nn OR n
3749 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; F7 RST 30H
3750 .dw (FETCH_NOP | OP_IFM | STORE_RET) ; F8 RET M
3751 .dw (FETCH_HL | OP_NOP | STORE_SP ) ; F9 LD SP,HL
3752 .dw (FETCH_DIR16| OP_IFM | STORE_PC ) ; FA nn nn JP M,nn
3753 .dw (FETCH_NOP | OP_EI | STORE_NOP) ; FB EI
3754 .dw (FETCH_DIR16| OP_IFM | STORE_CALL) ; FC nn nn CALL M,nn
3755 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific)
3756 .dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; FE nn CP n
3757 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H
3759 ; vim:set ts=8 noet nowrap