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/>.
25 #elif defined atmega168
26 .include "m168def.inc"
27 #elif defined atmega328P
28 .include "m328Pdef.inc"
40 #define F_CPU 20000000 /* system clock in Hz; defaults to 20MHz */
43 #define BAUD 38400 /* console baud rate */
47 #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) /* clever rounding */
49 #define RXBUFSIZE 64 /* USART recieve buffer size. Must be power of 2 */
50 #define TXBUFSIZE 64 /* USART transmit buffer size. Must be power of 2 */
52 #define DRAM_WAITSTATES 1 /* Number of additional clock cycles for dram read access */
53 #define REFR_RATE 64000 /* dram refresh rate in cycles/s. */
54 /* Most drams need 1/15.6µs. */
55 #define REFR_PRE 8 /* timer prescale factor */
56 #define REFR_CS 0x02 /* timer clock select for 1/8 */
57 #define REFR_CNT F_CPU / REFR_RATE / REFR_PRE
61 #define DRAM_WORD_ACCESS 0 /* experimental */
63 #define EM_Z80 0 /* we don't have any z80 instructions yet */
92 .equ RAM_AH_MASK = (1<<ram_a8)|(1<<ram_a7)|(1<<ram_a6)|(1<<ram_a5)
93 .equ PD_OUTPUT_MASK = (1<<mmc_cs) | (1<<ram_oe) | RAM_AH_MASK
111 .equ RAM_AL_MASK = (1<<ram_a4)|(1<<ram_a3)|(1<<ram_a2)|(1<<ram_a1)|(1<<ram_a0)
112 .equ PB_OUTPUT_MASK = (1<<ram_ras) | RAM_AL_MASK
125 .equ RAM_DQ_MASK = (1<<ram_d3)|(1<<ram_d2)|(1<<ram_d1)|(1<<ram_d0)
126 .equ PC_OUTPUT_MASK = (1<<ram_cas)|(1<<ram_w)
129 ;Flag bits in z_flags
137 ;Register definitions
171 #if defined __ATmega8__
180 .equ hostact = 7 ;host active flag
181 .equ hostwrt = 6 ;host written flag
182 .equ rsflag = 5 ;read sector flag
183 .equ readop = 4 ;1 if read operation
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
197 #if defined __ATmega8__
212 .equ OC2Aaddr= OC2addr
225 ;----------------------------------------
235 ;----------------------------------------
247 ;----------------------------------------
249 ; dram_wait number_of_cycles
264 rjmp start ; reset vector
266 rjmp refrint ; tim2cmpa
267 .org OC1Aaddr ; Timer/Counter1 Compare Match A
268 rjmp sysclockint ; 1ms system timer
270 rjmp rxint ; USART receive int.
272 rjmp txint ; USART transmit int.
274 .org INT_VECTORS_SIZE
277 ldi temp,low(RAMEND) ; top of memory
278 out SPL,temp ; init stack pointer
279 ldi temp,high(RAMEND) ; top of memory
280 out SPH,temp ; init stack pointer
288 ldi temp,(1<<WDCE) | (1<<WDE)
295 ldi zl,low(SRAM_START)
296 ldi zh,high(SRAM_START)
297 ldi temp2,high(ramtop)
305 ldi temp,(1<<PUD) ;disable pullups
308 out PORTD,temp ;all pins high
311 out DDRD,temp ; all outputs
323 ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
326 ldi temp, (1<<URSEL) | (1<<UCSZ01) | (1<<UCSZ00)
328 ldi temp, (1<<UCSZ01) | (1<<UCSZ00)
331 ldi temp, HIGH(UBRR_VAL)
333 ldi temp, LOW(UBRR_VAL)
336 ; Init clock/timer system
338 ; Init timer 1 as 1 ms system clock tick.
340 ldi temp,high(F_CPU/1000)
342 ldi temp,low(F_CPU/1000)
344 ldi temp,(1<<WGM12) | (1<<CS10) ;CTC, clk/1
350 ;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
352 ldi temp,REFR_CNT*2 ; 2 cycles per int
355 ori temp,(1<<WGM21) ;CTC mode
358 ori temp,REFR_CS ;clk/REFR_PRE
361 ori temp, (1<<OCIE2A)
374 .db "CPM on an AVR, v1.0",13,0,0
378 .db "Initing mmc...",13,0
384 .db "Testing RAM: fill...",0,0
406 .db "reread...",13,0,0
438 ;Fill ram with cbs, which (for now) will trigger an invalid opcode error.
450 ;Load initial sector from MMC (512 bytes)
457 ;Save to Z80 RAM (only 128 bytes because that's retro)
466 cpi zl,low(hostbuf+128)
468 cpi zh,high(hostbuf+128)
470 rcall dsk_boot ;init (de)blocking buffer
481 .db 13,"Ok, CPU is live!",13,0,0
510 ; *** Stage 1: Fetch next opcode
533 ; *** Stage 2: Decode it using the ins_table.
534 ldi zh,high(inst_table*2)
555 ; *** Stage 3: Fetch operand. Use the fetch jumptable for this.
559 ldi zl,low(fetchjumps)
560 ldi zh,high(fetchjumps)
580 ; *** Stage 4: Execute operation :) Use the op jumptable for this.
596 .db ",post:oph:l=",0,0
605 ; *** Stage 5: Store operand. Use the store jumptable for this.
614 ldi zl,low(storejumps)
615 ldi zh,high(storejumps)
642 ; ----------------Virtual peripherial interface ------
644 ;The hw is modelled to make writing a CPM BIOS easier.
646 ;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise.
647 ;1 - Console input, aka UDR.
650 ;16,17 - Track select
654 ;22 - Trigger - write to read, to write a sector using the above info;
655 ; , write to allocated/dirctory/unallocated
664 ;*****************************************************
665 ;* CP/M to host disk constants *
666 ;*****************************************************
667 .equ blksize = 1024 ;CP/M allocation size
668 .equ hostsize = 512 ;host disk sector size
669 ; .equ hostspt = 20 ;host disk sectors/trk
670 .equ hostblk = hostsize/128 ;CP/M sects/host buff
671 ; .equ CPMSPT = hostblk*hostspt;CP/M sectors/track
673 .equ SECMSK = hostblk-1 ;sector mask
674 .equ SECSHF = log2(hostblk) ;sector shift
676 ;*****************************************************
677 ;* BDOS constants on entry to write *
678 ;*****************************************************
679 .equ WRALL = 0 ;write to allocated
680 .equ WRDIR = 1 ;write to directory
681 .equ WRUAL = 2 ;write to unallocated
682 .equ WRTMSK= 3 ;write type mask
687 seekdsk: .byte 1 ;seek disk number
688 seektrk: .byte 2 ;seek track number
689 seeksec: .byte 1 ;seek sector number
691 hostdsk: .byte 1 ;host disk number
692 hostlba: .byte 2 ;host track number
694 unacnt: .byte 1 ;unalloc rec cnt
695 unadsk: .byte 1 ;last unalloc disk
696 unatrk: .byte 2 ;last unalloc track
697 unasec: .byte 1 ;last unalloc sector
699 erflag: .byte 1 ;error reporting
700 wrtype: .byte 1 ;write operation type
701 dmaadr: .byte 2 ;last dma address
702 hostbuf: .byte hostsize;host buffer (from/to SD-card)
707 ;Called with port in temp2. Should return value in temp.
714 cpi temp2,TIMER_MSECS
716 cpi temp2,TIMER_MSECS+6
724 ;Called with port in temp2 and value in temp.
746 cpi temp2,TIMER_MSECS+6
800 ;See what has to be done.
811 .db "DISK I/O: Invalid Function code: ",0
816 cbi flags,hostact ;host buffer inactive
817 sts unacnt,_0 ;clear unalloc count
821 sbis flags,hostwrt ;check for pending write
822 cbi flags,hostact ;clear host active flag
839 .db "Disk read: track ",0
859 sbi flags,readop ;read operation
860 sbi flags,rsflag ;must read data
861 ldi temp,WRUAL ;write type
862 sts wrtype,temp ;treat as unalloc
863 rjmp dsk_rwoper ;to perform the read
867 ;write the selected CP/M sector
870 sts wrtype,temp ;save write type
871 cbi flags,readop ;not a read operation
878 .db "Disk write: track ",0,0
902 cpi temp,WRUAL ;write unallocated?
903 brne dsk_chkuna ;check for unalloc
905 ; write to unallocated, set parameters
906 ldi temp,blksize/128 ;next unalloc recs
908 lds temp,seekdsk ;disk to seek
909 sts unadsk,temp ;unadsk = sekdsk
911 sts unatrk,temp ;unatrk = sectrk
913 sts unatrk+1,temp ;unatrk = sectrk
915 sts unasec,temp ;unasec = seksec
918 ;check for write to unallocated sector
919 lds temp,unacnt ;any unalloc remain?
921 breq dsk_alloc ;skip if not
923 ; more unallocated records remain
924 dec temp ;unacnt = unacnt-1
926 lds temp,seekdsk ;same disk?
928 cp temp,temp2 ;seekdsk = unadsk?
929 brne dsk_alloc ;skip if not
936 cp temp,temp3 ;seektrk = unatrk?
938 brne dsk_alloc ;skip if not
940 ; tracks are the same
941 lds temp,seeksec ;same sector?
943 cp temp,temp2 ;seeksec = unasec?
944 brne dsk_alloc ;skip if not
946 ; match, move to next sector for future ref
947 inc temp2 ;unasec = unasec+1
949 cpi temp2,CPMSPT ;end of track? (count CP/M sectors)
950 brlo dsk_noovf ;skip if no overflow
952 ; overflow to next track
953 sts unasec,_0 ;unasec = 0
956 subi temp, low(-1) ;unatrk = unatrk+1
962 cbi flags,rsflag ;rsflag = 0
963 rjmp dsk_rwoper ;to perform the write
966 ;not an unallocated record, requires pre-read
967 sts unacnt,_0 ;unacnt = 0
968 sbi flags,rsflag ;rsflag = 1
970 ;*****************************************************
971 ;* Common code for READ and WRITE follows *
972 ;*****************************************************
975 ;enter here to perform the read/write
976 sts erflag,_0 ;no errors (yet)
978 ;Convert track/sector to an LBA address (in 128byte blocks)
983 lds temp4,seektrk+1 ;
989 add xh,r0 ;xh:xl := sec + trk * SectorsPerTrack
993 andi temp,SECMSK ;mask buffer number
994 push temp ;save for later
996 ;Convert from CP/M LBA blocks to host LBA blocks
1003 ;xh:xl = host block to seek
1004 ; active host sector?
1005 sbis flags,hostact ;host active?
1006 rjmp dsk_filhst ;fill host if not
1008 ; host buffer active, same as seek buffer?
1010 lds temp3,hostdsk ;same disk?
1011 cp temp,temp3 ;seekdsk = hostdsk?
1014 ; same disk, same block?
1022 ;proper disk, but not correct sector
1023 sbic flags,hostwrt ;host written?
1024 rcall dsk_writehost ;clear host buff
1027 ;may have to fill the host buffer
1033 sbic flags,rsflag ;need to read?
1034 rcall dsk_readhost ;yes, if 1
1035 cbi flags,hostwrt ;no pending write
1038 sbi flags,hostact ;host buffer active now
1040 ;copy data to or from buffer
1042 ldi zh,high(hostbuf)
1044 pop temp2 ;get buffer number (which part of hostbuf)
1046 add zl,r0 ;offset in hostbuf
1053 .db "; host buf adr: ",0,0
1063 ldi temp3,128 ;length of move
1064 sbic flags,readop ;which way?
1065 rjmp dsk_rmove ;skip if read
1067 ; mark write operation
1068 sbi flags,hostwrt ;hostwrt = 1
1084 ; data has been moved to/from host buffer
1085 lds temp,wrtype ;write type
1086 cpi temp,WRDIR ;to directory?
1094 ret ;no further processing
1096 ; clear host buffer for directory write
1102 rcall dsk_writehost ;clear host buff
1103 cbi flags,hostwrt ;buffer written
1108 ;*****************************************************
1109 ;* WRITEhost performs the physical write to *
1110 ;* the host disk, READhost reads the physical *
1112 ;*****************************************************
1115 ;hostdsk = host disk #, hostlba = host block #.
1116 ;Write "hostsize" bytes from hostbuf and return
1117 ;error flag in erflag.
1118 ;Return erflag non-zero if error
1137 ;hostdsk = host disk #, hostlba = host block #.
1138 ;Read "hostsiz" bytes into hostbuf and return
1139 ;error flag in erflag.
1158 ;***************************************************************************
1160 ; ----------------- MMC/SD routines ------------------
1189 ;Wait till the mmc answers with the response in temp2, or till a timeout happens.
1196 brne mmcWaitResploopEnd
1200 rjmp mmcWaitResploop
1209 .db ": Error: MMC resp timeout!",13,0
1216 ;Init start: send 80 clocks with cs disabled
1220 ldi temp2,10 ; exactly 80 clocks
1242 ldi temp,0xff ;dummy
1244 ldi temp,0xff ;dummy
1258 ldi temp,0xff ;return byte
1261 ldi temp2,0 ;Error Code 0
1262 rcall mmcWaitResp ;Test on CMD0 is OK
1264 sbi P_MMC_CS,mmc_cs ;disable /CS
1268 ;Read OCR till card is ready
1269 ldi temp2,20 ;repeat counter
1273 cbi P_MMC_CS,mmc_cs ;enable /CS
1274 ldi temp,0xff ;dummy
1286 ; ldi temp,0x95 ;crc
1292 rcall mmcWaitResp ;wait until mmc-card send a byte <> 0xFF
1293 ;the first answer must be 0x01 (Idle-Mode)
1295 breq mmcInitOcrLoopDone ;second answer is 0x00 (Idle-Mode leave) CMD1 is OK
1297 sbi P_MMC_CS,mmc_cs ;disable /CS
1299 ; rcall mmcByteNoSend ;unnecessary
1307 brne mmcInitOcrLoop ;repeat
1314 sbi P_MMC_CS,mmc_cs ;disable /CS
1321 ;Call this with yh:yl:xh:xl = sector number
1329 ldi temp,0x51 ;cmd (read sector)
1331 lsl xl ;convert to byte address (*512)
1344 ldi temp,0xff ;return byte
1355 ;Read sector to AVR RAM
1357 ldi zh,high(hostbuf)
1361 cpi zl,low(hostbuf+512)
1363 cpi zh,high(hostbuf+512)
1377 ;Call this with yh:yl:xh:xl = sector number
1386 ldi temp,0x58 ;cmd (write sector)
1388 lsl xl ;convert to byte address (*512)
1401 ldi temp,0xff ;return byte
1412 ;Write sector from AVR RAM
1414 ldi zh,high(hostbuf)
1418 cpi zl,low(hostbuf+512)
1420 cpi zh,high(hostbuf+512)
1427 ;Status. Ignored for now.
1430 ;Wait till the mmc has written everything
1443 ;Set up wdt to time out after 1 sec.
1448 ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0)
1453 ; ------------------ DRAM routines -------------
1455 ; DRAM_SETADDR val, low_and_mask, low_or_mask, high_and_mask, high_or_mask
1470 ori temp, @4 | (1<<mmc_cs)
1474 ;Loads the byte on address xh:xl into temp.
1475 ;must not alter xh:xl
1479 DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8), (1<<ram_oe)
1481 DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
1484 dram_wait DRAM_WAITSTATES ;
1485 in temp,P_DQ-2 ; PIN
1491 dram_wait DRAM_WAITSTATES ;
1492 in temp2,P_DQ-2 ; PIN
1502 #if DRAM_WORD_ACCESS
1517 DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
1519 DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
1523 in temp,P_DQ-2 ; PIN
1529 in temp2,P_DQ-2 ; PIN
1537 DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
1541 in temp,P_DQ-2 ; PIN
1547 in temp2,P_DQ-2 ; PIN
1560 ;Writes the byte in temp to xh:xl
1561 ;must not alter xh:xl
1565 ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1569 andi temp,RAM_DQ_MASK & ~(1<<ram_w)
1570 ori temp,(1<<ram_cas)
1572 DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
1574 DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
1581 andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
1582 ori temp2,(1<<ram_cas)
1588 ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1594 #if DRAM_WORD_ACCESS
1609 ldi temp2,RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1613 andi temp,RAM_DQ_MASK & ~(1<<ram_w)
1614 ori temp,(1<<ram_cas)
1617 DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
1619 DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
1626 andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
1627 ori temp2,(1<<ram_cas)
1636 andi temp,RAM_DQ_MASK & ~(1<<ram_w)
1637 ori temp,(1<<ram_cas)
1640 DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
1647 andi temp2,RAM_DQ_MASK & ~(1<<ram_w)
1648 ori temp2,(1<<ram_cas)
1654 ldi temp,~RAM_DQ_MASK | (1<<ram_w) | (1<<ram_cas)
1661 ; ****************************************************************************
1663 ; refresh interupt; exec 2 cbr cycles
1666 cbi P_CAS,ram_cas ;2 1| 1|
1668 cbi P_RAS,ram_ras ;2 |0 1|
1672 sbi P_RAS,ram_ras ;2 |0 |0
1674 dram_wait DRAM_WAITSTATES-1 ;
1676 cbi P_RAS,ram_ras ;2 |0 1|
1678 sbi P_CAS,ram_cas ;2 |0 |0
1680 sbi P_RAS,ram_ras ;2 1| |0
1682 reti ;4 --> 21 cycles
1685 ; ------------- system timer 1ms ---------------
1695 ; don't change order here, clock put/get depends on it.
1696 cntms_out: ; register for ms
1698 utime_io: ; register for uptime.
1705 .equ timer_size = timer_top - timer_base
1707 .equ clkofs = cnt_1ms-cntms_out
1708 .equ timerofs = cnt_1ms-timer_ms
1729 ldi zl,high(1000) ;doesn't change flags
1762 sts delay_timer,temp
1764 lds temp,delay_timer
1773 subi temp2,TIMER_MSECS
1774 brcs clkget_end ;Port number in range?
1775 ldi zl,low(cntms_out)
1776 ldi zh,high(cntms_out)
1777 breq clkget_copy ;lowest byte requestet, latch clock
1779 brsh clkget_end ;Port number to high?
1804 subi temp2,TIMERPORT
1805 brcs clkput_end ;Port number in range?
1810 cpi temp,starttimercmd
1812 cpi temp,quitTimerCmd
1814 cpi temp,printTimerCmd
1828 ldi zl,low(cntms_out)
1829 ldi zh,high(cntms_out)
1830 breq clkput_copy ;lowest byte requestet, latch clock
1832 brsh clkput_end ;Port number to high?
1857 ldi zl,low(timer_ms)
1858 ldi zh,high(timer_ms)
1876 ldi zl,low(timer_ms)
1877 ldi zh,high(timer_ms)
1879 ; put ms on stack (16 bit)
1901 ldd temp2,z+timerofs
1905 ldd temp3,z+timerofs
1910 ldd temp4,z+timerofs
1915 .db 13,"Timer running. Elapsed: ",0
1935 ldi zh,high(cnt_1ms)
1968 ; --------------- Debugging stuff ---------------
1970 ;Print a unsigned lonng value to the uart
1971 ; temp4:temp3:temp2:temp = value
1978 clr yl ;yl = stack level
1980 ultoa1: ldi z_flags, 32 ;yh = temp4:temp % 10
1981 clr yh ;temp4:temp /= 10
1993 cpi yh, 10 ;yh is a numeral digit '0'-'9'
1997 cp temp,_0 ;Repeat until temp4:temp gets zero
2004 ultoa5: cpi yl,3 ; at least 3 digits (ms)
2010 ultoa6: pop temp ;Flush stacked digits
2021 ;Prints the lower nibble of temp in hex to the uart
2037 ;Prints temp in hex to the uart
2045 ;Prints the zero-terminated string following the call statement.
2085 ; --------------- AVR HW <-> Z80 periph stuff ------------------
2087 .equ memReadByte = dram_read
2088 .equ memWriteByte = dram_write
2089 #if DRAM_WORD_ACCESS
2090 .equ memReadWord = dram_read_w
2091 .equ memWriteWord = dram_write_w
2094 ; --------------------------------------------------------------
2098 #define RXBUFMASK RXBUFSIZE-1
2099 #define TXBUFMASK TXBUFSIZE-1
2121 ; Save received character in a circular buffer. Do nothing if buffer overflows.
2130 lds zh,rxcount ;if rxcount < RXBUFSIZE
2131 cpi zh,RXBUFSIZE ; (room for at least 1 char?)
2134 sts rxcount,zh ; rxcount++
2136 ldi zl,low(rxfifo) ;
2141 sts rxidx_w,zh ; rxidx_w = ++rxidx_w % RXBUFSIZE
2142 ldi zh,high(rxfifo) ;
2145 st z,temp ; rxfifo[rxidx_w] = char
2155 ;Fetches a char from the buffer to temp. If none available, waits till one is.
2158 lds temp,rxcount ; Number of characters in buffer
2178 ld temp,z ;don't forget to get the char
2187 lds temp,txcount ;if txcount != 0
2192 sts txcount,temp ; --txcount
2195 ldi zl,low(txfifo) ;
2196 ldi zh,high(txfifo) ;
2202 andi temp,TXBUFMASK ;
2212 ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
2221 ;Sends a char from temp to the uart.
2227 lds temp,txcount ;do {
2228 cpi temp,TXBUFSIZE ;
2229 brsh putc_l ;} while (txcount >= TXBUFSIZE)
2231 ldi zl,low(txfifo) ;
2232 ldi zh,high(txfifo) ;
2238 andi temp,TXBUFMASK ;
2239 sts txidx_w,temp ; txidx_w = ++txidx_w % TXBUFSIZE
2241 st z,temp ; txfifo[txidx_w] = char
2246 ldi zl, (1<<UDRIE0) | (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
2253 ; ------------ Fetch phase stuff -----------------
2255 .equ FETCH_NOP = (0<<0)
2256 .equ FETCH_A = (1<<0)
2257 .equ FETCH_B = (2<<0)
2258 .equ FETCH_C = (3<<0)
2259 .equ FETCH_D = (4<<0)
2260 .equ FETCH_E = (5<<0)
2261 .equ FETCH_H = (6<<0)
2262 .equ FETCH_L = (7<<0)
2263 .equ FETCH_AF = (8<<0)
2264 .equ FETCH_BC = (9<<0)
2265 .equ FETCH_DE = (10<<0)
2266 .equ FETCH_HL = (11<<0)
2267 .equ FETCH_SP = (12<<0)
2268 .equ FETCH_MBC = (13<<0)
2269 .equ FETCH_MDE = (14<<0)
2270 .equ FETCH_MHL = (15<<0)
2271 .equ FETCH_MSP = (16<<0)
2272 .equ FETCH_DIR8 = (17<<0)
2273 .equ FETCH_DIR16= (18<<0)
2274 .equ FETCH_RST = (19<<0)
2277 ;Jump table for fetch routines. Make sure to keep this in sync with the .equs!
2372 #if DRAM_WORD_ACCESS
2393 #if DRAM_WORD_ACCESS
2418 ; ------------ Store phase stuff -----------------
2420 .equ STORE_NOP = (0<<5)
2421 .equ STORE_A = (1<<5)
2422 .equ STORE_B = (2<<5)
2423 .equ STORE_C = (3<<5)
2424 .equ STORE_D = (4<<5)
2425 .equ STORE_E = (5<<5)
2426 .equ STORE_H = (6<<5)
2427 .equ STORE_L = (7<<5)
2428 .equ STORE_AF = (8<<5)
2429 .equ STORE_BC = (9<<5)
2430 .equ STORE_DE = (10<<5)
2431 .equ STORE_HL = (11<<5)
2432 .equ STORE_SP = (12<<5)
2433 .equ STORE_PC = (13<<5)
2434 .equ STORE_MBC = (14<<5)
2435 .equ STORE_MDE = (15<<5)
2436 .equ STORE_MHL = (16<<5)
2437 .equ STORE_MSP = (17<<5)
2438 .equ STORE_RET = (18<<5)
2439 .equ STORE_CALL = (19<<5)
2440 .equ STORE_AM = (20<<5)
2442 ;Jump table for store routines. Make sure to keep this in sync with the .equs!
2538 #if DRAM_WORD_ACCESS
2579 ; ------------ Operation phase stuff -----------------
2582 .equ OP_NOP = (0<<10)
2583 .equ OP_INC = (1<<10)
2584 .equ OP_DEC = (2<<10)
2585 .equ OP_INC16 = (3<<10)
2586 .equ OP_DEC16 = (4<<10)
2587 .equ OP_RLC = (5<<10)
2588 .equ OP_RRC = (6<<10)
2589 .equ OP_RR = (7<<10)
2590 .equ OP_RL = (8<<10)
2591 .equ OP_ADDA = (9<<10)
2592 .equ OP_ADCA = (10<<10)
2593 .equ OP_SUBFA = (11<<10)
2594 .equ OP_SBCFA = (12<<10)
2595 .equ OP_ANDA = (13<<10)
2596 .equ OP_ORA = (14<<10)
2597 .equ OP_XORA = (15<<10)
2598 .equ OP_ADDHL = (16<<10)
2599 .equ OP_STHL = (17<<10) ;store HL in fetched address
2600 .equ OP_RMEM16 = (18<<10) ;read mem at fetched address
2601 .equ OP_RMEM8 = (19<<10) ;read mem at fetched address
2602 .equ OP_DA = (20<<10)
2603 .equ OP_SCF = (21<<10)
2604 .equ OP_CPL = (22<<10)
2605 .equ OP_CCF = (23<<10)
2606 .equ OP_POP16 = (24<<10)
2607 .equ OP_PUSH16 = (25<<10)
2608 .equ OP_IFNZ = (26<<10)
2609 .equ OP_IFZ = (27<<10)
2610 .equ OP_IFNC = (28<<10)
2611 .equ OP_IFC = (29<<10)
2612 .equ OP_IFPO = (30<<10)
2613 .equ OP_IFPE = (31<<10)
2614 .equ OP_IFP = (32<<10)
2615 .equ OP_IFM = (33<<10)
2616 .equ OP_OUTA = (34<<10)
2617 .equ OP_IN = (35<<10)
2618 .equ OP_EXHL = (36<<10)
2619 .equ OP_DI = (37<<10)
2620 .equ OP_EI = (38<<10)
2621 .equ OP_INV = (39<<10)
2622 .equ OP_CPFA = (40<<10)
2623 .equ OP_INCA = (41<<10)
2624 .equ OP_DECA = (42<<10)
2672 ;How the flags are supposed to work:
2673 ;7 ZFL_S - Sign flag (=MSBit of result)
2674 ;6 ZFL_Z - Zero flag. Is 1 when the result is 0
2675 ;4 ZFL_H - Half-carry (carry from bit 3 to 4)
2676 ;2 ZFL_P - Parity/2-complement Overflow
2677 ;1 ZFL_N - Subtract - set if last op was a subtract
2680 ;I sure hope I got the mapping between flags and instructions correct...
2682 ;----------------------------------------------------------------
2686 ;| ZZZZZZZ 88888 000 |
2692 ;| ZZZZZZZ 88888 000 |
2694 ;| Z80 MICROPROCESSOR Instruction Set Summary |
2696 ;----------------------------------------------------------------
2697 ;----------------------------------------------------------------
2698 ;|Mnemonic |SZHPNC|Description |Notes |
2699 ;|----------+------+---------------------+----------------------|
2700 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
2701 ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
2702 ;|ADD A,s |***V0*|Add |A=A+s |
2703 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
2704 ;|ADD IX,pp |--?-0*|Add |IX=IX+pp |
2705 ;|ADD IY,rr |--?-0*|Add |IY=IY+rr |
2706 ;|AND s |**1P00|Logical AND |A=A&s |
2707 ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
2708 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
2709 ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
2710 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
2711 ;|CP s |***V1*|Compare |A-s |
2712 ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
2713 ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
2714 ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
2715 ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
2716 ;|CPL |--1-1-|Complement |A=~A |
2717 ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
2718 ;|DEC s |***V1-|Decrement |s=s-1 |
2719 ;|DEC xx |------|Decrement |xx=xx-1 |
2720 ;|DEC ss |------|Decrement |ss=ss-1 |
2721 ;|DI |------|Disable Interrupts | |
2722 ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
2723 ;|EI |------|Enable Interrupts | |
2724 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
2725 ;|EX [SP],xx|------|Exchange |[SP]<->xx |
2726 ;|EX AF,AF' |------|Exchange |AF<->AF' |
2727 ;|EX DE,HL |------|Exchange |DE<->HL |
2728 ;|EXX |------|Exchange |qq<->qq' (except AF)|
2729 ;|HALT |------|Halt | |
2730 ;|IM n |------|Interrupt Mode | (n=0,1,2)|
2731 ;|IN A,[n] |------|Input |A=[n] |
2732 ;|IN r,[C] |***P0-|Input |r=[C] |
2733 ;|INC r |***V0-|Increment |r=r+1 |
2734 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2735 ;|INC xx |------|Increment |xx=xx+1 |
2736 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2737 ;|INC ss |------|Increment |ss=ss+1 |
2738 ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
2739 ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
2740 ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
2741 ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
2742 ;|JP [HL] |------|Unconditional Jump |PC=[HL] |
2743 ;|JP [xx] |------|Unconditional Jump |PC=[xx] |
2744 ;|JP nn |------|Unconditional Jump |PC=nn |
2745 ;|JP cc,nn |------|Conditional Jump |If cc JP |
2746 ;|JR e |------|Unconditional Jump |PC=PC+e |
2747 ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
2748 ;|LD dst,src|------|Load |dst=src |
2749 ;|LD A,i |**0*0-|Load |A=i (i=I,R)|
2750 ;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
2751 ;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
2752 ;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
2753 ;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
2754 ;|NEG |***V1*|Negate |A=-A |
2755 ;|NOP |------|No Operation | |
2756 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
2757 ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
2758 ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
2759 ;|OUT [C],r |------|Output |[C]=r |
2760 ;|OUT [n],A |------|Output |[n]=A |
2761 ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
2762 ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
2763 ;|POP xx |------|Pop |xx=[SP]+ |
2764 ;|POP qq |------|Pop |qq=[SP]+ |
2765 ;|PUSH xx |------|Push |-[SP]=xx |
2766 ;|PUSH qq |------|Push |-[SP]=qq |
2767 ;|RES b,m |------|Reset bit |m=m&{~2^b} |
2768 ;|RET |------|Return |PC=[SP]+ |
2769 ;|RET cc |------|Conditional Return |If cc RET |
2770 ;|RETI |------|Return from Interrupt|PC=[SP]+ |
2771 ;|RETN |------|Return from NMI |PC=[SP]+ |
2772 ;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
2773 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
2774 ;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
2775 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
2776 ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
2777 ;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
2778 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
2779 ;|RRC m |**0P0*|Rotate Right Circular|m=->m |
2780 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
2781 ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
2782 ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
2783 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
2784 ;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY |
2785 ;|SCF |--0-01|Set Carry Flag |CY=1 |
2786 ;|SET b,m |------|Set bit |m=mv{2^b} |
2787 ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
2788 ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
2789 ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
2790 ;|SUB s |***V1*|Subtract |A=A-s |
2791 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
2792 ;|----------+------+--------------------------------------------|
2793 ;| F |-*01? |Flag unaffected/affected/reset/set/unknown |
2794 ;| S |S |Sign flag (Bit 7) |
2795 ;| Z | Z |Zero flag (Bit 6) |
2796 ;| HC | H |Half Carry flag (Bit 4) |
2797 ;| P/V | P |Parity/Overflow flag (Bit 2, V=overflow) |
2798 ;| N | N |Add/Subtract flag (Bit 1) |
2799 ;| CY | C|Carry flag (Bit 0) |
2800 ;|-----------------+--------------------------------------------|
2801 ;| n |Immediate addressing |
2802 ;| nn |Immediate extended addressing |
2803 ;| e |Relative addressing (PC=PC+2+offset) |
2804 ;| [nn] |Extended addressing |
2805 ;| [xx+d] |Indexed addressing |
2806 ;| r |Register addressing |
2807 ;| [rr] |Register indirect addressing |
2808 ;| |Implied addressing |
2809 ;| b |Bit addressing |
2810 ;| p |Modified page zero addressing (see RST) |
2811 ;|-----------------+--------------------------------------------|
2812 ;|DEFB n(,...) |Define Byte(s) |
2813 ;|DEFB 'str'(,...) |Define Byte ASCII string(s) |
2814 ;|DEFS nn |Define Storage Block |
2815 ;|DEFW nn(,...) |Define Word(s) |
2816 ;|-----------------+--------------------------------------------|
2817 ;| A B C D E |Registers (8-bit) |
2818 ;| AF BC DE HL |Register pairs (16-bit) |
2819 ;| F |Flag register (8-bit) |
2820 ;| I |Interrupt page address register (8-bit) |
2821 ;| IX IY |Index registers (16-bit) |
2822 ;| PC |Program Counter register (16-bit) |
2823 ;| R |Memory Refresh register |
2824 ;| SP |Stack Pointer register (16-bit) |
2825 ;|-----------------+--------------------------------------------|
2826 ;| b |One bit (0 to 7) |
2827 ;| cc |Condition (C,M,NC,NZ,P,PE,PO,Z) |
2828 ;| d |One-byte expression (-128 to +127) |
2829 ;| dst |Destination s, ss, [BC], [DE], [HL], [nn] |
2830 ;| e |One-byte expression (-126 to +129) |
2831 ;| m |Any register r, [HL] or [xx+d] |
2832 ;| n |One-byte expression (0 to 255) |
2833 ;| nn |Two-byte expression (0 to 65535) |
2834 ;| pp |Register pair BC, DE, IX or SP |
2835 ;| qq |Register pair AF, BC, DE or HL |
2836 ;| qq' |Alternative register pair AF, BC, DE or HL |
2837 ;| r |Register A, B, C, D, E, H or L |
2838 ;| rr |Register pair BC, DE, IY or SP |
2839 ;| s |Any register r, value n, [HL] or [xx+d] |
2840 ;| src |Source s, ss, [BC], [DE], [HL], nn, [nn] |
2841 ;| ss |Register pair BC, DE, HL or SP |
2842 ;| xx |Index register IX or IY |
2843 ;|-----------------+--------------------------------------------|
2844 ;| + - * / ^ |Add/subtract/multiply/divide/exponent |
2845 ;| & ~ v x |Logical AND/NOT/inclusive OR/exclusive OR |
2846 ;| <- -> |Rotate left/right |
2847 ;| [ ] |Indirect addressing |
2848 ;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement|
2849 ;| { } |Combination of operands |
2850 ;| # |Also BC=BC-1,DE=DE-1 |
2851 ;| ## |Only lower 4 bits of accumulator A used |
2852 ;----------------------------------------------------------------
2863 ;------------------------------------------------;
2864 ; Move single bit between two registers
2866 ; bmov dstreg,dstbit,srcreg.srcbit
2874 ;------------------------------------------------;
2875 ; Load table value from flash indexed by source reg.
2877 ; ldpmx dstreg,tablebase,indexreg
2879 ; (6 words, 8 cycles)
2882 ldi zh,high(@1*2) ; table must be page aligned
2886 .macro do_z80_flags_HP
2888 bmov z_flags, ZFL_P, temp, AVR_V
2889 bmov z_flags, ZFL_H, temp, AVR_H
2893 .macro do_z80_flags_set_N
2895 ori z_flags, (1<<ZFL_N) ; Negation auf 1
2899 .macro do_z80_flags_set_HN
2901 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
2905 .macro do_z80_flags_clear_N
2907 andi z_flags,~(1<<ZFL_N)
2911 .macro do_z80_flags_op_rotate
2912 ; must not change avr carry flag!
2914 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
2916 andi z_flags, ~( (1<<ZFL_C) )
2920 .macro do_z80_flags_op_and
2922 ori z_flags,(1<<ZFL_H)
2924 ori z_flags,(1<<ZFL_H)
2928 .macro do_z80_flags_op_or
2937 ;----------------------------------------------------------------
2938 ;|Mnemonic |SZHPNC|Description |Notes |
2939 ;----------------------------------------------------------------
2940 ;|INC r |***V0-|Increment |r=r+1 |
2941 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2942 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2943 ;|----------|SZHP C|---------- 8080 ----------------------------|
2944 ;|INC r |**-P0-|Increment |r=r+1 |
2945 ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 |
2953 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2954 ldpmx temp2, sz53p_tab, opl
2964 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2965 ldpmx temp2, sz53p_tab, z_a
2970 ;----------------------------------------------------------------
2971 ;|Mnemonic |SZHPNC|Description |Notes |
2972 ;----------------------------------------------------------------
2973 ;|DEC r |***V1-|Decrement |s=s-1 |
2974 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
2975 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
2976 ;|----------|SZHP C|---------- 8080 ----------------------------|
2977 ;|DEC r |**-P -|Increment |r=r+1 |
2978 ;|DEC [HL] |**-P -|Increment |[HL]=[HL]+1 |
2986 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2987 ldpmx temp2, sz53p_tab, opl
2998 andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
2999 ldpmx temp2, sz53p_tab, z_a
3005 ;----------------------------------------------------------------
3006 ;|Mnemonic |SZHPNC|Description |Notes |
3007 ;----------------------------------------------------------------
3008 ;|INC xx |------|Increment |xx=xx+1 |
3009 ;|INC ss |------|Increment |ss=ss+1 |
3017 ;----------------------------------------------------------------
3018 ;|Mnemonic |SZHPNC|Description |Notes |
3019 ;----------------------------------------------------------------
3020 ;|DEC xx |------|Decrement |xx=xx-1 |
3021 ;|DEC ss |------|Decrement |ss=ss-1 |
3029 ;----------------------------------------------------------------
3030 ;|Mnemonic |SZHPNC|Description |Notes |
3031 ;----------------------------------------------------------------
3032 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
3033 ;|----------|SZHP C|---------- 8080 ----------------------------|
3034 ;|RLCA |---- *|Rotate Left Circular |A=A<- |
3038 ;Rotate Left Cyclical. All bits move 1 to the
3039 ;left, the msb becomes c and lsb.
3040 do_z80_flags_op_rotate
3044 ori z_flags, (1<<ZFL_C)
3048 ;----------------------------------------------------------------
3049 ;|Mnemonic |SZHPNC|Description |Notes |
3050 ;----------------------------------------------------------------
3051 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
3052 ;|----------|SZHP C|---------- 8080 ----------------------------|
3053 ;|RRCA |---- *|Rotate Right Circular|A=->A |
3057 ;Rotate Right Cyclical. All bits move 1 to the
3058 ;right, the lsb becomes c and msb.
3059 do_z80_flags_op_rotate
3063 ori z_flags, (1<<ZFL_C)
3067 ;----------------------------------------------------------------
3068 ;|Mnemonic |SZHPNC|Description |Notes |
3069 ;----------------------------------------------------------------
3070 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
3071 ;|----------|SZHP C|---------- 8080 ----------------------------|
3072 ;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} |
3076 ;Rotate Right. All bits move 1 to the right, the lsb
3077 ;becomes c, c becomes msb.
3078 clc ; get z80 carry to avr carry
3081 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
3082 bmov z_flags,ZFL_C, opl,0 ; Bit 0 --> CY
3086 ;----------------------------------------------------------------
3087 ;|Mnemonic |SZHPNC|Description |Notes |
3088 ;----------------------------------------------------------------
3089 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
3090 ;|----------|SZHP C|---------- 8080 ----------------------------|
3091 ;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- |
3095 ;Rotate Left. All bits move 1 to the left, the msb
3096 ;becomes c, c becomes lsb.
3100 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
3101 bmov z_flags,ZFL_C, opl,7 ; Bit 7 --> CY
3105 ;----------------------------------------------------------------
3106 ;|Mnemonic |SZHPNC|Description |Notes |
3107 ;----------------------------------------------------------------
3108 ;|ADD A,s |***V0*|Add |A=A+s |
3109 ;|----------|SZHP C|---------- 8080 ----------------------------|
3110 ;|ADD A,s |***P *|Add |A=A+s |
3116 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P flag
3117 bmov z_flags,ZFL_C, temp,AVR_C
3121 ;----------------------------------------------------------------
3122 ;|Mnemonic |SZHPNC|Description |Notes |
3123 ;----------------------------------------------------------------
3124 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
3125 ;|----------|SZHP C|---------- 8080 ----------------------------|
3126 ;|ADC A,s |***P *|Add with Carry |A=A+s+CY |
3135 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
3136 bmov z_flags,ZFL_C, temp,AVR_C
3140 ;----------------------------------------------------------------
3141 ;|Mnemonic |SZHPNC|Description |Notes |
3142 ;----------------------------------------------------------------
3143 ;|SUB s |***V1*|Subtract |A=A-s |
3144 ;|----------|SZHP C|---------- 8080 ----------------------------|
3145 ;|SUB s |***P *|Subtract |A=A-s |
3151 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
3152 bmov z_flags,ZFL_C, temp,AVR_C
3157 ;----------------------------------------------------------------
3158 ;|Mnemonic |SZHPNC|Description |Notes |
3159 ;----------------------------------------------------------------
3160 ;|CP s |***V1*|Compare |A-s |
3161 ;|----------|SZHP C|---------- 8080 ----------------------------|
3162 ;|CP s |***P *|Compare |A-s |
3170 ldpmx z_flags,sz53p_tab,opl ;S,Z,P
3171 bmov z_flags,ZFL_C, temp,AVR_C
3176 ;----------------------------------------------------------------
3177 ;|Mnemonic |SZHPNC|Description |Notes |
3178 ;----------------------------------------------------------------
3179 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
3180 ;|----------|SZHP C|---------- 8080 ----------------------------|
3181 ;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY |
3190 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
3191 bmov z_flags,ZFL_C, temp,AVR_C
3196 ;----------------------------------------------------------------
3197 ;|Mnemonic |SZHPNC|Description |Notes |
3198 ;----------------------------------------------------------------
3199 ;|AND s |**1P00|Logical AND |A=A&s |
3200 ;|----------|SZHP C|---------- 8080 ----------------------------|
3201 ;|AND s |**-P 0|Logical AND |A=A&s |
3206 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P,N,C
3211 ;----------------------------------------------------------------
3212 ;|Mnemonic |SZHPNC|Description |Notes |
3213 ;----------------------------------------------------------------
3214 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
3215 ;|----------|SZHP C|---------- 8080 ----------------------------|
3216 ;|OR s |**-P00|Logical inclusive OR |A=Avs |
3221 ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
3225 ;----------------------------------------------------------------
3226 ;|Mnemonic |SZHPNC|Description |Notes |
3227 ;----------------------------------------------------------------
3228 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
3229 ;|----------|SZHP C|---------- 8080 ----------------------------|
3230 ;|XOR s |**-P 0|Logical Exclusive OR |A=Axs |
3235 ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
3239 ;----------------------------------------------------------------
3240 ;|Mnemonic |SZHPNC|Description |Notes |
3241 ;----------------------------------------------------------------
3242 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
3243 ;|----------|SZHP C|---------- 8080 ----------------------------|
3244 ;|ADD HL,ss |---- *|Add |HL=HL+ss |
3251 bmov z_flags,ZFL_H, temp,AVR_H
3252 bmov z_flags,ZFL_C, temp,AVR_C
3253 do_z80_flags_clear_N
3256 ;----------------------------------------------------------------
3257 ;|Mnemonic |SZHPNC|Description |Notes |
3258 ;----------------------------------------------------------------
3259 ;|LD dst,src|------|Load |dst=src |
3262 do_op_sthl: ;store hl to mem loc in opl:h
3264 #if DRAM_WORD_ACCESS
3276 ;----------------------------------------------------------------
3277 ;|Mnemonic |SZHPNC|Description |Notes |
3278 ;----------------------------------------------------------------
3279 ;|LD dst,src|------|Load |dst=src |
3284 #if DRAM_WORD_ACCESS
3296 ;----------------------------------------------------------------
3297 ;|Mnemonic |SZHPNC|Description |Notes |
3298 ;----------------------------------------------------------------
3299 ;|LD dst,src|------|Load |dst=src |
3308 ;----------------------------------------------------------------
3309 ;|Mnemonic |SZHPNC|Description |Notes |
3310 ;----------------------------------------------------------------
3311 ;|DAA |***P-*|Decimal Adjust Acc. | |
3312 ;|----------|SZHP C|---------- 8080 ----------------------------|
3316 ; Description (http://www.z80.info/z80syntx.htm#DAA):
3317 ; This instruction conditionally adjusts the accumulator for BCD addition
3318 ; and subtraction operations. For addition (ADD, ADC, INC) or subtraction
3319 ; (SUB, SBC, DEC, NEC), the following table indicates the operation performed:
3321 ; -------------------------------------------------------------------------------
3322 ; | | C Flag | HEX value in | H Flag | HEX value in | Number | C flag|
3323 ; | Operation| Before | upper digit | Before | lower digit | added | After |
3324 ; | | DAA | (bit 7-4) | DAA | (bit 3-0) | to byte | DAA |
3325 ; |-----------------------------------------------------------------------------|
3326 ; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3327 ; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
3328 ; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
3329 ; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
3330 ; | | 0 | 9-F | 0 | A-F | 66 | 1 |
3331 ; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
3332 ; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
3333 ; | | 1 | 0-2 | 0 | A-F | 66 | 1 |
3334 ; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
3335 ; |-----------------------------------------------------------------------------|
3336 ; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
3337 ; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
3338 ; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
3339 ; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
3340 ; |-----------------------------------------------------------------------------|
3343 ; C: See instruction.
3345 ; P/V: Set if Acc. is even parity after operation, reset otherwise.
3346 ; H: See instruction.
3347 ; Z: Set if Acc. is Zero after operation, reset otherwise.
3348 ; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise.
3354 ldi oph,0 ; what to add
3355 sbrc z_flags,ZFL_H ; if H-Flag
3358 andi temp,0x0f ; ... or lower digit > 9
3364 sbrc z_flags,(1<<ZFL_C)
3373 ori z_flags,(1<<ZFL_C); set C
3375 sbrs z_flags,ZFL_N ; if sub-op
3376 rjmp op_da_add ; then
3379 op_da_add: ; else add-op
3392 ori z_flags,(1<<ZFL_C)
3393 andi z_flags,(1<<ZFL_N)|(1<<ZFL_C) ; preserve C,N
3394 ldpmx temp2, sz53p_tab, opl ; get S,Z,P
3396 bmov z_flags,ZFL_H, temp,AVR_H ; H (?)
3401 sbrc z_flags,ZFL_N ; if add-op
3402 rjmp do_op_da_sub ; then
3406 cpi temp,0x0a ; if lower digit > 9
3408 ori temp2,0x06 ; add 6 to lower digit
3410 sbrc z_flags,ZFL_H ; ... or H-Flag
3420 do_op_da_c: ; else sub-op
3421 sbrc z_flags,ZFL_C ;
3423 andi z_flags, ~( (1<<ZFL_S) | (1<<ZFL_Z) | (1<<ZFL_H) )
3426 bst temp,AVR_Z ;Z-Flag
3428 bst temp,AVR_N ;S-Flag
3430 sbrc temp2,5 ;C-Flag, set if 0x06 added
3431 ori z_flags,(1<<ZFL_C) ;
3435 do_op_da_sub: ;TODO:
3440 ;----------------------------------------------------------------
3441 ;|Mnemonic |SZHPNC|Description |Notes |
3442 ;----------------------------------------------------------------
3443 ;|SCF |--0-01|Set Carry Flag |CY=1 |
3444 ;|----------|SZHP C|---------- 8080 ----------------------------|
3448 andi z_flags,~((1<<ZFL_H)|(1<<ZFL_N))
3449 ori z_flags,(1<<ZFL_C)
3452 ;----------------------------------------------------------------
3453 ;|Mnemonic |SZHPNC|Description |Notes |
3454 ;----------------------------------------------------------------
3455 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
3456 ;|----------|SZHP C|---------- 8080 ----------------------------|
3457 ;|SCF |---- 1|Set Carry Flag |CY=1 |
3461 do_z80_flags_clear_N
3466 ;----------------------------------------------------------------
3467 ;|Mnemonic |SZHPNC|Description |Notes |
3468 ;----------------------------------------------------------------
3469 ;|CPL |--1-1-|Complement |A=~A |
3470 ;|----------|SZHP C|---------- 8080 ----------------------------|
3471 ;|CPL |---- -|Complement |A=~A |
3480 ;----------------------------------------------------------------
3481 ;|Mnemonic |SZHPNC|Description |Notes |
3482 ;----------------------------------------------------------------
3483 ;|PUSH xx |------|Push |-[SP]=xx |
3484 ;|PUSH qq |------|Push |-[SP]=qq |
3492 #if DRAM_WORD_ACCESS
3511 .db ", SP is now ",0
3522 ;----------------------------------------------------------------
3523 ;|Mnemonic |SZHPNC|Description |Notes |
3524 ;----------------------------------------------------------------
3525 ;|POP xx |------|Pop |xx=[SP]+ |
3526 ;|POP qq |------|Pop |qq=[SP]+ |
3531 #if DRAM_WORD_ACCESS
3549 .db "Stack pop: val ",0
3565 ;----------------------------------------------------------------
3566 ;|Mnemonic |SZHPNC|Description |Notes |
3567 ;----------------------------------------------------------------
3568 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
3569 ;|EX DE,HL |------|Exchange |DE<->HL |
3581 ;----------------------------------------------------------------
3582 ;|Mnemonic |SZHPNC|Description |Notes |
3583 ;----------------------------------------------------------------
3585 ; TODO: Implement IFF1, IFF2
3589 ;----------------------------------------------------------------
3590 ;|Mnemonic |SZHPNC|Description |Notes |
3591 ;----------------------------------------------------------------
3593 ; TODO: Implement IFF1, IFF2
3597 ;----------------------------------------------------------------
3598 ;|Mnemonic |SZHPNC|Description |Notes |
3599 ;----------------------------------------------------------------
3600 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3601 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3602 ;|RET cc |------|Conditional Return |If cc RET |
3612 ;----------------------------------------------------------------
3613 ;|Mnemonic |SZHPNC|Description |Notes |
3614 ;----------------------------------------------------------------
3615 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3616 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3617 ;|RET cc |------|Conditional Return |If cc RET |
3627 ;----------------------------------------------------------------
3628 ;|Mnemonic |SZHPNC|Description |Notes |
3629 ;----------------------------------------------------------------
3630 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3631 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3632 ;|RET cc |------|Conditional Return |If cc RET |
3642 ;----------------------------------------------------------------
3643 ;|Mnemonic |SZHPNC|Description |Notes |
3644 ;----------------------------------------------------------------
3645 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3646 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3647 ;|RET cc |------|Conditional Return |If cc RET |
3657 ;----------------------------------------------------------------
3658 ;|Mnemonic |SZHPNC|Description |Notes |
3659 ;----------------------------------------------------------------
3660 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3661 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3662 ;|RET cc |------|Conditional Return |If cc RET |
3672 ;----------------------------------------------------------------
3673 ;|Mnemonic |SZHPNC|Description |Notes |
3674 ;----------------------------------------------------------------
3675 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3676 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3677 ;|RET cc |------|Conditional Return |If cc RET |
3687 ;----------------------------------------------------------------
3688 ;|Mnemonic |SZHPNC|Description |Notes |
3689 ;----------------------------------------------------------------
3690 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3691 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3692 ;|RET cc |------|Conditional Return |If cc RET |
3695 do_op_ifp: ;sign positive, aka s=0
3702 ;----------------------------------------------------------------
3703 ;|Mnemonic |SZHPNC|Description |Notes |
3704 ;----------------------------------------------------------------
3705 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
3706 ;|JP cc,nn |------|Conditional Jump |If cc JP |
3707 ;|RET cc |------|Conditional Return |If cc RET |
3710 do_op_ifm: ;sign negative, aka s=1
3717 ;----------------------------------------------------------------
3718 ;|Mnemonic |SZHPNC|Description |Notes |
3719 ;----------------------------------------------------------------
3720 ;|OUT [n],A |------|Output |[n]=A |
3723 ;Interface with peripherials goes here :)
3724 do_op_outa: ; out (opl),a
3727 .db 13,"Port write: ",0
3742 ;----------------------------------------------------------------
3743 ;|Mnemonic |SZHPNC|Description |Notes |
3744 ;----------------------------------------------------------------
3745 ;|IN A,[n] |------|Input |A=[n] |
3748 do_op_in: ; in a,(opl)
3751 .db 13,"Port read: (",0
3770 ;----------------------------------------------------------------
3773 .db "Invalid opcode @ PC=",0,0
3779 ;----------------------------------------------------------------
3783 ;----------------------------------------------------------------
3784 ; Lookup table, stolen from z80ex, Z80 emulation library.
3785 ; http://z80ex.sourceforge.net/
3787 ; The S, Z, 5 and 3 bits and the parity of the lookup value
3788 .org (PC+255) & 0xff00
3790 .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3791 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3792 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3793 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3794 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3795 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3796 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3797 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3798 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
3799 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
3800 .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00
3801 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
3802 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
3803 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
3804 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
3805 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
3806 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3807 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3808 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3809 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3810 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3811 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3812 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3813 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3814 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
3815 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
3816 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
3817 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
3818 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
3819 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
3820 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
3821 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
3824 ; ----------------------- Opcode decoding -------------------------
3826 ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
3827 ; operations: fetch, do something, store.
3828 ; The table is made of 256 words. These 16-bit words consist of
3829 ; the fetch operation (bit 0-4), the processing operation (bit 10-16) and the store
3830 ; operation (bit 5-9).
3831 .org (PC+255) & 0xff00
3833 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 00 NOP
3834 .dw (FETCH_DIR16| OP_NOP | STORE_BC ) ; 01 nn nn LD BC,nn
3835 .dw (FETCH_A | OP_NOP | STORE_MBC) ; 02 LD (BC),A
3836 .dw (FETCH_BC | OP_INC16 | STORE_BC ) ; 03 INC BC
3837 .dw (FETCH_B | OP_INC | STORE_B ) ; 04 INC B
3838 .dw (FETCH_B | OP_DEC | STORE_B ) ; 05 DEC B
3839 .dw (FETCH_DIR8 | OP_NOP | STORE_B ) ; 06 nn LD B,n
3840 .dw (FETCH_A | OP_RLC | STORE_A ) ; 07 RLCA
3841 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 08 EX AF,AF' (Z80)
3842 .dw (FETCH_BC | OP_ADDHL | STORE_HL ) ; 09 ADD HL,BC
3843 .dw (FETCH_MBC | OP_NOP | STORE_A ) ; 0A LD A,(BC)
3844 .dw (FETCH_BC | OP_DEC16 | STORE_BC ) ; 0B DEC BC
3845 .dw (FETCH_C | OP_INC | STORE_C ) ; 0C INC C
3846 .dw (FETCH_C | OP_DEC | STORE_C ) ; 0D DEC C
3847 .dw (FETCH_DIR8 | OP_NOP | STORE_C ) ; 0E nn LD C,n
3848 .dw (FETCH_A | OP_RRC | STORE_A ) ; 0F RRCA
3849 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 10 oo DJNZ o (Z80)
3850 .dw (FETCH_DIR16| OP_NOP | STORE_DE ) ; 11 nn nn LD DE,nn
3851 .dw (FETCH_A | OP_NOP | STORE_MDE) ; 12 LD (DE),A
3852 .dw (FETCH_DE | OP_INC16 | STORE_DE ) ; 13 INC DE
3853 .dw (FETCH_D | OP_INC | STORE_D ) ; 14 INC D
3854 .dw (FETCH_D | OP_DEC | STORE_D ) ; 15 DEC D
3855 .dw (FETCH_DIR8 | OP_NOP | STORE_D ) ; 16 nn LD D,n
3856 .dw (FETCH_A | OP_RL | STORE_A ) ; 17 RLA
3857 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 18 oo JR o (Z80)
3858 .dw (FETCH_DE | OP_ADDHL | STORE_HL ) ; 19 ADD HL,DE
3859 .dw (FETCH_MDE | OP_NOP | STORE_A ) ; 1A LD A,(DE)
3860 .dw (FETCH_DE | OP_DEC16 | STORE_DE ) ; 1B DEC DE
3861 .dw (FETCH_E | OP_INC | STORE_E ) ; 1C INC E
3862 .dw (FETCH_E | OP_DEC | STORE_E ) ; 1D DEC E
3863 .dw (FETCH_DIR8 | OP_NOP | STORE_E ) ; 1E nn LD E,n
3864 .dw (FETCH_A | OP_RR | STORE_A ) ; 1F RRA
3865 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 20 oo JR NZ,o (Z80)
3866 .dw (FETCH_DIR16| OP_NOP | STORE_HL ) ; 21 nn nn LD HL,nn
3867 .dw (FETCH_DIR16| OP_STHL | STORE_NOP) ; 22 nn nn LD (nn),HL
3868 .dw (FETCH_HL | OP_INC16 | STORE_HL ) ; 23 INC HL
3869 .dw (FETCH_H | OP_INC | STORE_H ) ; 24 INC H
3870 .dw (FETCH_H | OP_DEC | STORE_H ) ; 25 DEC H
3871 .dw (FETCH_DIR8 | OP_NOP | STORE_H ) ; 26 nn LD H,n
3872 .dw (FETCH_A | OP_DA | STORE_A ) ; 27 DAA
3873 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 28 oo JR Z,o (Z80)
3874 .dw (FETCH_HL | OP_ADDHL | STORE_HL ) ; 29 ADD HL,HL
3875 .dw (FETCH_DIR16| OP_RMEM16 | STORE_HL ) ; 2A nn nn LD HL,(nn)
3876 .dw (FETCH_HL | OP_DEC16 | STORE_HL ) ; 2B DEC HL
3877 .dw (FETCH_L | OP_INC | STORE_L ) ; 2C INC L
3878 .dw (FETCH_L | OP_DEC | STORE_L ) ; 2D DEC L
3879 .dw (FETCH_DIR8 | OP_NOP | STORE_L ) ; 2E nn LD L,n
3880 .dw (FETCH_NOP | OP_CPL | STORE_NOP) ; 2F CPL
3881 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 30 oo JR NC,o (Z80)
3882 .dw (FETCH_DIR16| OP_NOP | STORE_SP ) ; 31 nn nn LD SP,nn
3883 .dw (FETCH_DIR16| OP_NOP | STORE_AM ) ; 32 nn nn LD (nn),A
3884 .dw (FETCH_SP | OP_INC16 | STORE_SP ) ; 33 INC SP
3885 .dw (FETCH_MHL | OP_INC | STORE_MHL) ; 34 INC (HL)
3886 .dw (FETCH_MHL | OP_DEC | STORE_MHL) ; 35 DEC (HL)
3887 .dw (FETCH_DIR8 | OP_NOP | STORE_MHL) ; 36 nn LD (HL),n
3888 .dw (FETCH_NOP | OP_SCF | STORE_NOP) ; 37 SCF
3889 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; 38 oo JR C,o (Z80)
3890 .dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
3891 .dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
3892 .dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
3893 .dw (FETCH_NOP | OP_INCA | STORE_NOP) ; 3C INC A
3894 .dw (FETCH_NOP | OP_DECA | STORE_NOP) ; 3D DEC A
3895 .dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
3896 .dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
3897 .dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r
3898 .dw (FETCH_C | OP_NOP | STORE_B ) ; 41 LD B,r
3899 .dw (FETCH_D | OP_NOP | STORE_B ) ; 42 LD B,r
3900 .dw (FETCH_E | OP_NOP | STORE_B ) ; 43 LD B,r
3901 .dw (FETCH_H | OP_NOP | STORE_B ) ; 44 LD B,r
3902 .dw (FETCH_L | OP_NOP | STORE_B ) ; 45 LD B,r
3903 .dw (FETCH_MHL | OP_NOP | STORE_B ) ; 46 LD B,r
3904 .dw (FETCH_A | OP_NOP | STORE_B ) ; 47 LD B,r
3905 .dw (FETCH_B | OP_NOP | STORE_C ) ; 48 LD C,r
3906 .dw (FETCH_C | OP_NOP | STORE_C ) ; 49 LD C,r
3907 .dw (FETCH_D | OP_NOP | STORE_C ) ; 4A LD C,r
3908 .dw (FETCH_E | OP_NOP | STORE_C ) ; 4B LD C,r
3909 .dw (FETCH_H | OP_NOP | STORE_C ) ; 4C LD C,r
3910 .dw (FETCH_L | OP_NOP | STORE_C ) ; 4D LD C,r
3911 .dw (FETCH_MHL | OP_NOP | STORE_C ) ; 4E LD C,r
3912 .dw (FETCH_A | OP_NOP | STORE_C ) ; 4F LD C,r
3913 .dw (FETCH_B | OP_NOP | STORE_D ) ; 50 LD D,r
3914 .dw (FETCH_C | OP_NOP | STORE_D ) ; 51 LD D,r
3915 .dw (FETCH_D | OP_NOP | STORE_D ) ; 52 LD D,r
3916 .dw (FETCH_E | OP_NOP | STORE_D ) ; 53 LD D,r
3917 .dw (FETCH_H | OP_NOP | STORE_D ) ; 54 LD D,r
3918 .dw (FETCH_L | OP_NOP | STORE_D ) ; 55 LD D,r
3919 .dw (FETCH_MHL | OP_NOP | STORE_D ) ; 56 LD D,r
3920 .dw (FETCH_A | OP_NOP | STORE_D ) ; 57 LD D,r
3921 .dw (FETCH_B | OP_NOP | STORE_E ) ; 58 LD E,r
3922 .dw (FETCH_C | OP_NOP | STORE_E ) ; 59 LD E,r
3923 .dw (FETCH_D | OP_NOP | STORE_E ) ; 5A LD E,r
3924 .dw (FETCH_E | OP_NOP | STORE_E ) ; 5B LD E,r
3925 .dw (FETCH_H | OP_NOP | STORE_E ) ; 5C LD E,r
3926 .dw (FETCH_L | OP_NOP | STORE_E ) ; 5D LD E,r
3927 .dw (FETCH_MHL | OP_NOP | STORE_E ) ; 5E LD E,r
3928 .dw (FETCH_A | OP_NOP | STORE_E ) ; 5F LD E,r
3929 .dw (FETCH_B | OP_NOP | STORE_H ) ; 60 LD H,r
3930 .dw (FETCH_C | OP_NOP | STORE_H ) ; 61 LD H,r
3931 .dw (FETCH_D | OP_NOP | STORE_H ) ; 62 LD H,r
3932 .dw (FETCH_E | OP_NOP | STORE_H ) ; 63 LD H,r
3933 .dw (FETCH_H | OP_NOP | STORE_H ) ; 64 LD H,r
3934 .dw (FETCH_L | OP_NOP | STORE_H ) ; 65 LD H,r
3935 .dw (FETCH_MHL | OP_NOP | STORE_H ) ; 66 LD H,r
3936 .dw (FETCH_A | OP_NOP | STORE_H ) ; 67 LD H,r
3937 .dw (FETCH_B | OP_NOP | STORE_L ) ; 68 LD L,r
3938 .dw (FETCH_C | OP_NOP | STORE_L ) ; 69 LD L,r
3939 .dw (FETCH_D | OP_NOP | STORE_L ) ; 6A LD L,r
3940 .dw (FETCH_E | OP_NOP | STORE_L ) ; 6B LD L,r
3941 .dw (FETCH_H | OP_NOP | STORE_L ) ; 6C LD L,r
3942 .dw (FETCH_L | OP_NOP | STORE_L ) ; 6D LD L,r
3943 .dw (FETCH_MHL | OP_NOP | STORE_L ) ; 6E LD L,r
3944 .dw (FETCH_A | OP_NOP | STORE_L ) ; 6F LD L,r
3945 .dw (FETCH_B | OP_NOP | STORE_MHL) ; 70 LD (HL),r
3946 .dw (FETCH_C | OP_NOP | STORE_MHL) ; 71 LD (HL),r
3947 .dw (FETCH_D | OP_NOP | STORE_MHL) ; 72 LD (HL),r
3948 .dw (FETCH_E | OP_NOP | STORE_MHL) ; 73 LD (HL),r
3949 .dw (FETCH_H | OP_NOP | STORE_MHL) ; 74 LD (HL),r
3950 .dw (FETCH_L | OP_NOP | STORE_MHL) ; 75 LD (HL),r
3951 .dw (FETCH_NOP | OP_NOP | STORE_NOP) ; 76 HALT
3952 .dw (FETCH_A | OP_NOP | STORE_MHL) ; 77 LD (HL),r
3953 .dw (FETCH_B | OP_NOP | STORE_A ) ; 78 LD A,r
3954 .dw (FETCH_C | OP_NOP | STORE_A ) ; 79 LD A,r
3955 .dw (FETCH_D | OP_NOP | STORE_A ) ; 7A LD A,r
3956 .dw (FETCH_E | OP_NOP | STORE_A ) ; 7B LD A,r
3957 .dw (FETCH_H | OP_NOP | STORE_A ) ; 7C LD A,r
3958 .dw (FETCH_L | OP_NOP | STORE_A ) ; 7D LD A,r
3959 .dw (FETCH_MHL | OP_NOP | STORE_A ) ; 7E LD A,r
3960 .dw (FETCH_A | OP_NOP | STORE_A ) ; 7F LD A,r
3961 .dw (FETCH_B | OP_ADDA | STORE_NOP) ; 80 ADD A,r
3962 .dw (FETCH_C | OP_ADDA | STORE_NOP) ; 81 ADD A,r
3963 .dw (FETCH_D | OP_ADDA | STORE_NOP) ; 82 ADD A,r
3964 .dw (FETCH_E | OP_ADDA | STORE_NOP) ; 83 ADD A,r
3965 .dw (FETCH_H | OP_ADDA | STORE_NOP) ; 84 ADD A,r
3966 .dw (FETCH_L | OP_ADDA | STORE_NOP) ; 85 ADD A,r
3967 .dw (FETCH_MHL | OP_ADDA | STORE_NOP) ; 86 ADD A,r
3968 .dw (FETCH_A | OP_ADDA | STORE_NOP) ; 87 ADD A,r
3969 .dw (FETCH_B | OP_ADCA | STORE_NOP) ; 88 ADC A,r
3970 .dw (FETCH_C | OP_ADCA | STORE_NOP) ; 89 ADC A,r
3971 .dw (FETCH_D | OP_ADCA | STORE_NOP) ; 8A ADC A,r
3972 .dw (FETCH_E | OP_ADCA | STORE_NOP) ; 8B ADC A,r
3973 .dw (FETCH_H | OP_ADCA | STORE_NOP) ; 8C ADC A,r
3974 .dw (FETCH_L | OP_ADCA | STORE_NOP) ; 8D ADC A,r
3975 .dw (FETCH_MHL | OP_ADCA | STORE_NOP) ; 8E ADC A,r
3976 .dw (FETCH_A | OP_ADCA | STORE_NOP) ; 8F ADC A,r
3977 .dw (FETCH_B | OP_SUBFA | STORE_NOP) ; 90 SUB A,r
3978 .dw (FETCH_C | OP_SUBFA | STORE_NOP) ; 91 SUB A,r
3979 .dw (FETCH_D | OP_SUBFA | STORE_NOP) ; 92 SUB A,r
3980 .dw (FETCH_E | OP_SUBFA | STORE_NOP) ; 93 SUB A,r
3981 .dw (FETCH_H | OP_SUBFA | STORE_NOP) ; 94 SUB A,r
3982 .dw (FETCH_L | OP_SUBFA | STORE_NOP) ; 95 SUB A,r
3983 .dw (FETCH_MHL | OP_SUBFA | STORE_NOP) ; 96 SUB A,r
3984 .dw (FETCH_A | OP_SUBFA | STORE_NOP) ; 97 SUB A,r
3985 .dw (FETCH_B | OP_SBCFA | STORE_NOP) ; 98 SBC A,r
3986 .dw (FETCH_C | OP_SBCFA | STORE_NOP) ; 99 SBC A,r
3987 .dw (FETCH_D | OP_SBCFA | STORE_NOP) ; 9A SBC A,r
3988 .dw (FETCH_E | OP_SBCFA | STORE_NOP) ; 9B SBC A,r
3989 .dw (FETCH_H | OP_SBCFA | STORE_NOP) ; 9C SBC A,r
3990 .dw (FETCH_L | OP_SBCFA | STORE_NOP) ; 9D SBC A,r
3991 .dw (FETCH_MHL | OP_SBCFA | STORE_NOP) ; 9E SBC A,r
3992 .dw (FETCH_A | OP_SBCFA | STORE_NOP) ; 9F SBC A,r
3993 .dw (FETCH_B | OP_ANDA | STORE_NOP) ; A0 AND A,r
3994 .dw (FETCH_C | OP_ANDA | STORE_NOP) ; A1 AND A,r
3995 .dw (FETCH_D | OP_ANDA | STORE_NOP) ; A2 AND A,r
3996 .dw (FETCH_E | OP_ANDA | STORE_NOP) ; A3 AND A,r
3997 .dw (FETCH_H | OP_ANDA | STORE_NOP) ; A4 AND A,r
3998 .dw (FETCH_L | OP_ANDA | STORE_NOP) ; A5 AND A,r
3999 .dw (FETCH_MHL | OP_ANDA | STORE_NOP) ; A6 AND A,r
4000 .dw (FETCH_A | OP_ANDA | STORE_NOP) ; A7 AND A,r
4001 .dw (FETCH_B | OP_XORA | STORE_NOP) ; A8 XOR A,r
4002 .dw (FETCH_C | OP_XORA | STORE_NOP) ; A9 XOR A,r
4003 .dw (FETCH_D | OP_XORA | STORE_NOP) ; AA XOR A,r
4004 .dw (FETCH_E | OP_XORA | STORE_NOP) ; AB XOR A,r
4005 .dw (FETCH_H | OP_XORA | STORE_NOP) ; AC XOR A,r
4006 .dw (FETCH_L | OP_XORA | STORE_NOP) ; AD XOR A,r
4007 .dw (FETCH_MHL | OP_XORA | STORE_NOP) ; AE XOR A,r
4008 .dw (FETCH_A | OP_XORA | STORE_NOP) ; AF XOR A,r
4009 .dw (FETCH_B | OP_ORA | STORE_NOP) ; B0 OR A,r
4010 .dw (FETCH_C | OP_ORA | STORE_NOP) ; B1 OR A,r
4011 .dw (FETCH_D | OP_ORA | STORE_NOP) ; B2 OR A,r
4012 .dw (FETCH_E | OP_ORA | STORE_NOP) ; B3 OR A,r
4013 .dw (FETCH_H | OP_ORA | STORE_NOP) ; B4 OR A,r
4014 .dw (FETCH_L | OP_ORA | STORE_NOP) ; B5 OR A,r
4015 .dw (FETCH_MHL | OP_ORA | STORE_NOP) ; B6 OR A,r
4016 .dw (FETCH_A | OP_ORA | STORE_NOP) ; B7 OR A,r
4017 .dw (FETCH_B | OP_CPFA | STORE_NOP) ; B8 CP A,r
4018 .dw (FETCH_C | OP_CPFA | STORE_NOP) ; B9 CP A,r
4019 .dw (FETCH_D | OP_CPFA | STORE_NOP) ; BA CP A,r
4020 .dw (FETCH_E | OP_CPFA | STORE_NOP) ; BB CP A,r
4021 .dw (FETCH_H | OP_CPFA | STORE_NOP) ; BC CP A,r
4022 .dw (FETCH_L | OP_CPFA | STORE_NOP) ; BD CP A,r
4023 .dw (FETCH_MHL | OP_CPFA | STORE_NOP) ; BE CP A,r
4024 .dw (FETCH_A | OP_CPFA | STORE_NOP) ; BF CP A,r
4025 .dw (FETCH_NOP | OP_IFNZ | STORE_RET) ; C0 RET NZ
4026 .dw (FETCH_NOP | OP_POP16 | STORE_BC ) ; C1 POP BC
4027 .dw (FETCH_DIR16| OP_IFNZ | STORE_PC ) ; C2 nn nn JP NZ,nn
4028 .dw (FETCH_DIR16| OP_NOP | STORE_PC ) ; C3 nn nn JP nn
4029 .dw (FETCH_DIR16| OP_IFNZ | STORE_CALL) ; C4 nn nn CALL NZ,nn
4030 .dw (FETCH_BC | OP_PUSH16 | STORE_NOP) ; C5 PUSH BC
4031 .dw (FETCH_DIR8 | OP_ADDA | STORE_NOP) ; C6 nn ADD A,n
4032 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; C7 RST 0
4033 .dw (FETCH_NOP | OP_IFZ | STORE_RET) ; C8 RET Z
4034 .dw (FETCH_NOP | OP_NOP | STORE_RET) ; C9 RET
4035 .dw (FETCH_DIR16| OP_IFZ | STORE_PC ) ; CA nn nn JP Z,nn
4036 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; CB (Z80 specific)
4037 .dw (FETCH_DIR16| OP_IFZ | STORE_CALL) ; CC nn nn CALL Z,nn
4038 .dw (FETCH_DIR16| OP_NOP | STORE_CALL) ; CD nn nn CALL nn
4039 .dw (FETCH_DIR8 | OP_ADCA | STORE_NOP) ; CE nn ADC A,n
4040 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; CF RST 8H
4041 .dw (FETCH_NOP | OP_IFNC | STORE_RET) ; D0 RET NC
4042 .dw (FETCH_NOP | OP_POP16 | STORE_DE ) ; D1 POP DE
4043 .dw (FETCH_DIR16| OP_IFNC | STORE_PC ) ; D2 nn nn JP NC,nn
4044 .dw (FETCH_DIR8 | OP_OUTA | STORE_NOP) ; D3 nn OUT (n),A
4045 .dw (FETCH_DIR16| OP_IFNC | STORE_CALL) ; D4 nn nn CALL NC,nn
4046 .dw (FETCH_DE | OP_PUSH16 | STORE_NOP) ; D5 PUSH DE
4047 .dw (FETCH_DIR8 | OP_SUBFA | STORE_NOP) ; D6 nn SUB n
4048 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; D7 RST 10H
4049 .dw (FETCH_NOP | OP_IFC | STORE_RET) ; D8 RET C
4050 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; D9 EXX (Z80)
4051 .dw (FETCH_DIR16| OP_IFC | STORE_PC ) ; DA nn nn JP C,nn
4052 .dw (FETCH_DIR8 | OP_IN | STORE_A ) ; DB nn IN A,(n)
4053 .dw (FETCH_DIR16| OP_IFC | STORE_CALL) ; DC nn nn CALL C,nn
4054 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; DD (Z80)
4055 .dw (FETCH_DIR8 | OP_SBCFA | STORE_NOP) ; DE nn SBC A,n
4056 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; DF RST 18H
4057 .dw (FETCH_NOP | OP_IFPO | STORE_RET) ; E0 RET PO
4058 .dw (FETCH_NOP | OP_POP16 | STORE_HL ) ; E1 POP HL
4059 .dw (FETCH_DIR16| OP_IFPO | STORE_PC ) ; E2 nn nn JP PO,nn
4060 .dw (FETCH_MSP | OP_EXHL | STORE_MSP) ; E3 EX (SP),HL
4061 .dw (FETCH_DIR16| OP_IFPO | STORE_CALL) ; E4 nn nn CALL PO,nn
4062 .dw (FETCH_HL | OP_PUSH16 | STORE_NOP) ; E5 PUSH HL
4063 .dw (FETCH_DIR8 | OP_ANDA | STORE_NOP) ; E6 nn AND n
4064 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; E7 RST 20H
4065 .dw (FETCH_NOP | OP_IFPE | STORE_RET) ; E8 RET PE
4066 .dw (FETCH_HL | OP_NOP | STORE_PC ) ; E9 JP (HL)
4067 .dw (FETCH_DIR16| OP_IFPE | STORE_PC ) ; EA nn nn JP PE,nn
4068 .dw (FETCH_DE | OP_EXHL | STORE_DE ) ; EB EX DE,HL
4069 .dw (FETCH_DIR16| OP_IFPE | STORE_CALL) ; EC nn nn CALL PE,nn
4070 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; ED (Z80 specific)
4071 .dw (FETCH_DIR8 | OP_XORA | STORE_NOP) ; EE nn XOR n
4072 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; EF RST 28H
4073 .dw (FETCH_NOP | OP_IFP | STORE_RET) ; F0 RET P
4074 .dw (FETCH_NOP | OP_POP16 | STORE_AF ) ; F1 POP AF
4075 .dw (FETCH_DIR16| OP_IFP | STORE_PC ) ; F2 nn nn JP P,nn
4076 .dw (FETCH_NOP | OP_DI | STORE_NOP) ; F3 DI
4077 .dw (FETCH_DIR16| OP_IFP | STORE_CALL) ; F4 nn nn CALL P,nn
4078 .dw (FETCH_AF | OP_PUSH16 | STORE_NOP) ; F5 PUSH AF
4079 .dw (FETCH_DIR8 | OP_ORA | STORE_NOP) ; F6 nn OR n
4080 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; F7 RST 30H
4081 .dw (FETCH_NOP | OP_IFM | STORE_RET) ; F8 RET M
4082 .dw (FETCH_HL | OP_NOP | STORE_SP ) ; F9 LD SP,HL
4083 .dw (FETCH_DIR16| OP_IFM | STORE_PC ) ; FA nn nn JP M,nn
4084 .dw (FETCH_NOP | OP_EI | STORE_NOP) ; FB EI
4085 .dw (FETCH_DIR16| OP_IFM | STORE_CALL) ; FC nn nn CALL M,nn
4086 .dw (FETCH_NOP | OP_INV | STORE_NOP) ; FD (Z80 specific)
4087 .dw (FETCH_DIR8 | OP_CPFA | STORE_NOP) ; FE nn CP n
4088 .dw (FETCH_RST | OP_NOP | STORE_CALL) ; FF RST 38H
4090 ; vim:set ts=8 noet nowrap