2 ; This is part of the Z80-CP/M emulator written by Sprite_tm.
5 ; Copyright (C) 2010 Sprite_tm
6 ; Copyright (C) 2010 Leo C.
7 ; Copyright (C) 2010 Horst S.
9 ; This file is part of avrcpm.
11 ; avrcpm is free software: you can redistribute it and/or modify it
12 ; under the terms of the GNU General Public License as published by
13 ; the Free Software Foundation, either version 3 of the License, or
14 ; (at your option) any later version.
16 ; avrcpm is distributed in the hope that it will be useful,
17 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ; GNU General Public License for more details.
21 ; You should have received a copy of the GNU General Public License
22 ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
40 ldi z_pcl,low (IPLADDR)
41 ldi z_pch,high(IPLADDR)
45 printstring "Ok, CPU is live!"
48 ;----------------------------------------------------------
50 ;.db (low)do_store (low)do_op (hihg)do_op (low)do_fetch
52 ;das kommt auf den stapel
53 ; main da solls zum schluss weitergehen
54 ;do_store wohin damit beenden mit RET
55 ;do_op was tun beenden mit RET
57 ;das wird direkt angesprungen
58 ;do_fetch woher beenden mit RET
64 cpi z_pch,DBG_TRACE_BOTTOM
66 cpi z_pch,DBG_TRACE_TOP
73 cpi z_pch,DBG_TRACE_BOTTOM
75 cpi z_pch,DBG_TRACE_TOP
91 ;hier kommt die Interruptbehandlung rein
93 ldi zl,low(main) ;da will ich wieder hin.
97 mem_read_s z_pc ;temp=memReadByte(z_pc)
99 ldi zl,low(todo_table*2) ;zhl=todo_table
100 ldi zh,high(todo_table*2) ;
106 ldi temp2,high(store_ops) ;
107 lpm temp,Z+ ;do_store
111 .if high(opjumps) != high(opjumps)
112 ldi temp2,high(opjumps)
119 ldi zh,high(fetch_ops)
124 ;-----------------------------------------------------
125 ; Generate jump to target and position in table
129 .ifndef opjmp_table_pos_
130 .set opjmp_table_page_ = high(PC)
131 .set opjmp_table_pos_ = PC
133 .equ @0 = low(opjmp_table_pos_)
134 .set opjmp_table_pos_ = opjmp_table_pos_ + 1
135 .if high(opjmp_table_pos_) != opjmp_table_page_
136 .warning "Table 'opjump' crosses page boarder."
137 .message "Program will not work, unless the opjump table is relocated."
142 ;--------------------------------------------------
143 ; Generate a table entry for one instruction
145 ; instr fetch, op, store
148 .ifndef inst_table_odd_
149 .set inst_table_odd_ = 0
153 .db inst_table_next_, low(@2), @1, low(@0)
154 .set inst_table_odd_ = 0
156 .set inst_table_next_ = low(@0)
158 .set inst_table_odd_ = 1
162 ;-----------------------------------
171 ;-----------------------------------
175 ldi zh,high(store_ops) ;
180 ;-----------------------------------
187 ;-----------------------------------
195 ; ------------ Fetch phase stuff -----------------
197 .org (PC+255) & 0xff00 ; wichtig !!!fetch und store muessen in einer page liegen
280 mem_read_ds opl, z_pc
285 mem_read_ds opl, z_pc
287 mem_read_ds oph, z_pc
299 ; ------------ Store phase stuff -----------------
301 .org (PC+255) & 0xff00 ; wichtig !!!fetch und store muessen in einer page liegen
397 printstring "Stack pop "
400 printstring ", SP is now "
417 printstring "Stack push "
420 printstring ", SP is now "
434 ; ------------ Operation phase stuff -----------------
436 ;.org (PC+255) & 0xff00
484 ;----------------------------------------------------------------
488 ;| ZZZZZZZ 88888 000 |
494 ;| ZZZZZZZ 88888 000 |
496 ;| Z80 MICROPROCESSOR Instruction Set Summary |
498 ;----------------------------------------------------------------
499 ;----------------------------------------------------------------
500 ;|Mnemonic |SZHPNC|Description |Notes |
501 ;|----------+------+---------------------+----------------------|
502 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
503 ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
504 ;|ADD A,s |***V0*|Add |A=A+s |
505 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
506 ;|ADD IX,pp |--?-0*|Add |IX=IX+pp |
507 ;|ADD IY,rr |--?-0*|Add |IY=IY+rr |
508 ;|AND s |**1P00|Logical AND |A=A&s |
509 ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
510 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
511 ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
512 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
513 ;|CP s |***V1*|Compare |A-s |
514 ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
515 ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
516 ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
517 ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
518 ;|CPL |--1-1-|Complement |A=~A |
519 ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
520 ;|DEC s |***V1-|Decrement |s=s-1 |
521 ;|DEC xx |------|Decrement |xx=xx-1 |
522 ;|DEC ss |------|Decrement |ss=ss-1 |
523 ;|DI |------|Disable Interrupts | |
524 ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
525 ;|EI |------|Enable Interrupts | |
526 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
527 ;|EX [SP],xx|------|Exchange |[SP]<->xx |
528 ;|EX AF,AF' |------|Exchange |AF<->AF' |
529 ;|EX DE,HL |------|Exchange |DE<->HL |
530 ;|EXX |------|Exchange |qq<->qq' (except AF)|
531 ;|HALT |------|Halt | |
532 ;|IM n |------|Interrupt Mode | (n=0,1,2)|
533 ;|IN A,[n] |------|Input |A=[n] |
534 ;|IN r,[C] |***P0-|Input |r=[C] |
535 ;|INC r |***V0-|Increment |r=r+1 |
536 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
537 ;|INC xx |------|Increment |xx=xx+1 |
538 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
539 ;|INC ss |------|Increment |ss=ss+1 |
540 ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
541 ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
542 ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
543 ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
544 ;|JP [HL] |------|Unconditional Jump |PC=[HL] |
545 ;|JP [xx] |------|Unconditional Jump |PC=[xx] |
546 ;|JP nn |------|Unconditional Jump |PC=nn |
547 ;|JP cc,nn |------|Conditional Jump |If cc JP |
548 ;|JR e |------|Unconditional Jump |PC=PC+e |
549 ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
550 ;|LD dst,src|------|Load |dst=src |
551 ;|LD A,i |**0*0-|Load |A=i (i=I,R)|
552 ;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
553 ;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
554 ;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
555 ;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
556 ;|NEG |***V1*|Negate |A=-A |
557 ;|NOP |------|No Operation | |
558 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
559 ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
560 ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
561 ;|OUT [C],r |------|Output |[C]=r |
562 ;|OUT [n],A |------|Output |[n]=A |
563 ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
564 ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
565 ;|POP xx |------|Pop |xx=[SP]+ |
566 ;|POP qq |------|Pop |qq=[SP]+ |
567 ;|PUSH xx |------|Push |-[SP]=xx |
568 ;|PUSH qq |------|Push |-[SP]=qq |
569 ;|RES b,m |------|Reset bit |m=m&{~2^b} |
570 ;|RET |------|Return |PC=[SP]+ |
571 ;|RET cc |------|Conditional Return |If cc RET |
572 ;|RETI |------|Return from Interrupt|PC=[SP]+ |
573 ;|RETN |------|Return from NMI |PC=[SP]+ |
574 ;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
575 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
576 ;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
577 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
578 ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
579 ;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
580 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
581 ;|RRC m |**0P0*|Rotate Right Circular|m=->m |
582 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
583 ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
584 ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
585 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
586 ;|SBC HL,ss |**?V1*|Subtract with Carry |HL=HL-ss-CY |
587 ;|SCF |--0-01|Set Carry Flag |CY=1 |
588 ;|SET b,m |------|Set bit |m=mv{2^b} |
589 ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
590 ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
591 ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
592 ;|SUB s |***V1*|Subtract |A=A-s |
593 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
594 ;|----------+------+--------------------------------------------|
595 ;| F |-*01? |Flag unaffected/affected/reset/set/unknown |
596 ;| S |S |Sign flag (Bit 7) |
597 ;| Z | Z |Zero flag (Bit 6) |
598 ;| HC | H |Half Carry flag (Bit 4) |
599 ;| P/V | P |Parity/Overflow flag (Bit 2, V=overflow) |
600 ;| N | N |Add/Subtract flag (Bit 1) |
601 ;| CY | C|Carry flag (Bit 0) |
602 ;|-----------------+--------------------------------------------|
603 ;| n |Immediate addressing |
604 ;| nn |Immediate extended addressing |
605 ;| e |Relative addressing (PC=PC+2+offset) |
606 ;| [nn] |Extended addressing |
607 ;| [xx+d] |Indexed addressing |
608 ;| r |Register addressing |
609 ;| [rr] |Register indirect addressing |
610 ;| |Implied addressing |
611 ;| b |Bit addressing |
612 ;| p |Modified page zero addressing (see RST) |
613 ;|-----------------+--------------------------------------------|
614 ;|DEFB n(,...) |Define Byte(s) |
615 ;|DEFB 'str'(,...) |Define Byte ASCII string(s) |
616 ;|DEFS nn |Define Storage Block |
617 ;|DEFW nn(,...) |Define Word(s) |
618 ;|-----------------+--------------------------------------------|
619 ;| A B C D E |Registers (8-bit) |
620 ;| AF BC DE HL |Register pairs (16-bit) |
621 ;| F |Flag register (8-bit) |
622 ;| I |Interrupt page address register (8-bit) |
623 ;| IX IY |Index registers (16-bit) |
624 ;| PC |Program Counter register (16-bit) |
625 ;| R |Memory Refresh register |
626 ;| SP |Stack Pointer register (16-bit) |
627 ;|-----------------+--------------------------------------------|
628 ;| b |One bit (0 to 7) |
629 ;| cc |Condition (C,M,NC,NZ,P,PE,PO,Z) |
630 ;| d |One-byte expression (-128 to +127) |
631 ;| dst |Destination s, ss, [BC], [DE], [HL], [nn] |
632 ;| e |One-byte expression (-126 to +129) |
633 ;| m |Any register r, [HL] or [xx+d] |
634 ;| n |One-byte expression (0 to 255) |
635 ;| nn |Two-byte expression (0 to 65535) |
636 ;| pp |Register pair BC, DE, IX or SP |
637 ;| qq |Register pair AF, BC, DE or HL |
638 ;| qq' |Alternative register pair AF, BC, DE or HL |
639 ;| r |Register A, B, C, D, E, H or L |
640 ;| rr |Register pair BC, DE, IY or SP |
641 ;| s |Any register r, value n, [HL] or [xx+d] |
642 ;| src |Source s, ss, [BC], [DE], [HL], nn, [nn] |
643 ;| ss |Register pair BC, DE, HL or SP |
644 ;| xx |Index register IX or IY |
645 ;|-----------------+--------------------------------------------|
646 ;| + - * / ^ |Add/subtract/multiply/divide/exponent |
647 ;| & ~ v x |Logical AND/NOT/inclusive OR/exclusive OR |
648 ;| <- -> |Rotate left/right |
649 ;| [ ] |Indirect addressing |
650 ;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement|
651 ;| { } |Combination of operands |
652 ;| # |Also BC=BC-1,DE=DE-1 |
653 ;| ## |Only lower 4 bits of accumulator A used |
654 ;----------------------------------------------------------------
656 ;How the flags are supposed to work:
657 ;7 ZFL_S - Sign flag (=MSBit of result)
658 ;6 ZFL_Z - Zero flag. Is 1 when the result is 0
659 ;4 ZFL_H - Half-carry (carry from bit 3 to 4)
660 ;2 ZFL_P - Parity/2-complement Overflow
661 ;1 ZFL_N - Subtract - set if last op was a subtract
664 ;I sure hope I got the mapping between flags and instructions correct...
681 ;------------------------------------------------;
682 ; Load table value from flash indexed by source reg.
684 ;ldpmx dstreg,tablebase,indexreg
686 ; (6 words, 8 cycles)
689 ldi zh,high(@1*2) ; table must be page aligned
694 .macro do_z80_flags_V
696 bmov z_flags, ZFL_P, temp, AVR_V
700 .macro do_z80_flags_set_N
702 ori z_flags, (1<<ZFL_N) ; Negation auf 1
706 .macro do_z80_flags_set_HN
708 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
712 .macro do_z80_flags_clear_N
714 andi z_flags,~(1<<ZFL_N)
718 .macro do_z80_flags_clear_HN
720 andi z_flags,~((1<<ZFL_H)|(1<<ZFL_N))
725 .macro do_z80_flags_copy_HC
727 bmov z_flags, ZFL_H, z_flags, ZFL_H
731 .macro do_z80_flags_op_rotate
732 ; must not change avr carry flag!
734 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
736 andi z_flags, ~( (1<<ZFL_C) )
740 .macro do_z80_flags_op_and
742 ori z_flags,(1<<ZFL_H)
746 .macro do_z80_flags_op_or
753 ;----------------------------------------------------------------
758 printstring "Invalid opcode! "
766 ;----------------------------------------------------------------
767 ;|Mnemonic |SZHPNC|Description |Notes |
768 ;----------------------------------------------------------------
769 ;|OUT [n],A |------|Output |[n]=A |
772 ;Interface with peripherials goes here :)
773 do_op_outa: ; out (opl),a
776 printstring "Port write: "
789 ;----------------------------------------------------------------
790 ;|Mnemonic |SZHPNC|Description |Notes |
791 ;----------------------------------------------------------------
792 ;|IN A,[n] |------|Input |A=[n] |
795 do_op_in: ; in a,(opl)
798 printstring "Port read: ("
814 ;----------------------------------------------------------------
815 ;|Mnemonic |SZHPNC|Description |Notes |
816 ;----------------------------------------------------------------
817 ;|INC r |***V0-|Increment |r=r+1 |
818 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
819 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
820 ;|----------|SZHP C|---------- 8080 ----------------------------|
821 ;|INC r |**-P0-|Increment |r=r+1 |
822 ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 |
829 andi z_flags,(1<<ZFL_C) ; preserve C-flag
830 ldpmx temp2, sz53p_tab, opl
832 bmov z_flags, ZFL_H, temp, AVR_H
840 andi z_flags,(1<<ZFL_C) ; preserve C-flag
841 ldpmx temp2, sz53p_tab, z_a
843 bmov z_flags, ZFL_H, temp, AVR_H
847 ;----------------------------------------------------------------
848 ;|Mnemonic |SZHPNC|Description |Notes |
849 ;----------------------------------------------------------------
850 ;|DEC r |***V1-|Decrement |s=s-1 |
851 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
852 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
853 ;|----------|SZHP C|---------- 8080 ----------------------------|
854 ;|DEC r |**-P -|Increment |r=r+1 |
855 ;|DEC [HL] |**-P -|Increment |[HL]=[HL]+1 |
861 andi z_flags,(1<<ZFL_C) ; preserve C-flag
862 ldpmx temp2, sz53p_tab, opl
864 bmov z_flags, ZFL_H, temp, AVR_H
873 andi z_flags,(1<<ZFL_C) ; preserve C-flag
874 ldpmx temp2, sz53p_tab, z_a
876 bmov z_flags, ZFL_H, temp, AVR_H
881 ;----------------------------------------------------------------
882 ;|Mnemonic |SZHPNC|Description |Notes |
883 ;----------------------------------------------------------------
884 ;|INC xx |------|Increment |xx=xx+1 |
885 ;|INC ss |------|Increment |ss=ss+1 |
893 ;----------------------------------------------------------------
894 ;|Mnemonic |SZHPNC|Description |Notes |
895 ;----------------------------------------------------------------
896 ;|DEC xx |------|Decrement |xx=xx-1 |
897 ;|DEC ss |------|Decrement |ss=ss-1 |
905 ;----------------------------------------------------------------
906 ;|Mnemonic |SZHPNC|Description |Notes |
907 ;----------------------------------------------------------------
908 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
909 ;|----------|SZHP C|---------- 8080 ----------------------------|
910 ;|RLCA |---- *|Rotate Left Circular |A=A<- |
914 ;Rotate Left Cyclical. All bits move 1 to the
915 ;left, the msb becomes c and lsb.
916 do_z80_flags_op_rotate
921 ori z_flags, (1<<ZFL_C)
925 ;----------------------------------------------------------------
926 ;|Mnemonic |SZHPNC|Description |Notes |
927 ;----------------------------------------------------------------
928 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
929 ;|----------|SZHP C|---------- 8080 ----------------------------|
930 ;|RRCA |---- *|Rotate Right Circular|A=->A |
934 ;Rotate Right Cyclical. All bits move 1 to the
935 ;right, the lsb becomes c and msb.
936 do_z80_flags_op_rotate
941 ori z_flags, (1<<ZFL_C)
945 ;----------------------------------------------------------------
946 ;|Mnemonic |SZHPNC|Description |Notes |
947 ;----------------------------------------------------------------
948 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
949 ;|----------|SZHP C|---------- 8080 ----------------------------|
950 ;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} |
954 ;Rotate Right. All bits move 1 to the right, the lsb
955 ;becomes c, c becomes msb.
956 clc ; get z80 carry to avr carry
959 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
960 bmov z_flags,ZFL_C, z_a,0 ; Bit 0 --> CY
964 ;----------------------------------------------------------------
965 ;|Mnemonic |SZHPNC|Description |Notes |
966 ;----------------------------------------------------------------
967 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
968 ;|----------|SZHP C|---------- 8080 ----------------------------|
969 ;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- |
973 ;Rotate Left. All bits move 1 to the left, the msb
974 ;becomes c, c becomes lsb.
978 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
979 bmov z_flags,ZFL_C, z_a,7 ; Bit 7 --> CY
983 ;----------------------------------------------------------------
984 ;|Mnemonic |SZHPNC|Description |Notes |
985 ;----------------------------------------------------------------
986 ;|ADD A,s |***V0*|Add |A=A+s |
987 ;|----------|SZHP C|---------- 8080 ----------------------------|
988 ;|ADD A,s |***P *|Add |A=A+s |
994 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P flag
995 bmov z_flags,ZFL_C, temp,AVR_C
996 bmov z_flags,ZFL_H, temp,AVR_H
1000 ;----------------------------------------------------------------
1001 ;|Mnemonic |SZHPNC|Description |Notes |
1002 ;----------------------------------------------------------------
1003 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
1004 ;|----------|SZHP C|---------- 8080 ----------------------------|
1005 ;|ADC A,s |***P *|Add with Carry |A=A+s+CY |
1014 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1015 bmov z_flags,ZFL_C, temp,AVR_C
1016 bmov z_flags,ZFL_H, temp,AVR_H
1020 ;----------------------------------------------------------------
1021 ;|Mnemonic |SZHPNC|Description |Notes |
1022 ;----------------------------------------------------------------
1023 ;|SUB s |***V1*|Subtract |A=A-s |
1024 ;|----------|SZHP C|---------- 8080 ----------------------------|
1025 ;|SUB s |***P *|Subtract |A=A-s |
1031 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1032 bmov z_flags,ZFL_C, temp,AVR_C
1033 bmov z_flags,ZFL_H, temp,AVR_H
1038 ;----------------------------------------------------------------
1039 ;|Mnemonic |SZHPNC|Description |Notes |
1040 ;----------------------------------------------------------------
1041 ;|CP s |***V1*|Compare |A-s |
1042 ;|----------|SZHP C|---------- 8080 ----------------------------|
1043 ;|CP s |***P *|Compare |A-s |
1050 ldpmx z_flags,sz53p_tab,temp2 ;S,Z,P
1051 bmov z_flags,ZFL_C, temp,AVR_C
1052 bmov z_flags,ZFL_H, temp,AVR_H
1057 ;----------------------------------------------------------------
1058 ;|Mnemonic |SZHPNC|Description |Notes |
1059 ;----------------------------------------------------------------
1060 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
1061 ;|----------|SZHP C|---------- 8080 ----------------------------|
1062 ;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY |
1071 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1072 bmov z_flags,ZFL_C, temp,AVR_C
1073 bmov z_flags,ZFL_H, temp,AVR_H
1078 ;----------------------------------------------------------------
1079 ;|Mnemonic |SZHPNC|Description |Notes |
1080 ;----------------------------------------------------------------
1081 ;|AND s |**1P00|Logical AND |A=A&s |
1082 ;|----------|SZHP C|---------- 8080 ----------------------------|
1083 ;|AND s |**-P 0|Logical AND |A=A&s |
1088 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P,N,C
1093 ;----------------------------------------------------------------
1094 ;|Mnemonic |SZHPNC|Description |Notes |
1095 ;----------------------------------------------------------------
1096 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
1097 ;|----------|SZHP C|---------- 8080 ----------------------------|
1098 ;|OR s |**-P00|Logical inclusive OR |A=Avs |
1103 ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
1107 ;----------------------------------------------------------------
1108 ;|Mnemonic |SZHPNC|Description |Notes |
1109 ;----------------------------------------------------------------
1110 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
1111 ;|----------|SZHP C|---------- 8080 ----------------------------|
1112 ;|XOR s |**-P 0|Logical Exclusive OR |A=Axs |
1117 ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
1121 ;----------------------------------------------------------------
1122 ;|Mnemonic |SZHPNC|Description |Notes |
1123 ;----------------------------------------------------------------
1124 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
1125 ;|----------|SZHP C|---------- 8080 ----------------------------|
1126 ;|ADD HL,ss |---- *|Add |HL=HL+ss |
1135 bmov z_flags,ZFL_H, temp,AVR_H
1136 bmov z_flags,ZFL_C, temp,AVR_C
1137 do_z80_flags_clear_N
1140 ;----------------------------------------------------------------
1141 ;|Mnemonic |SZHPNC|Description |Notes |
1142 ;----------------------------------------------------------------
1143 ;|LD dst,src|------|Load |dst=src |
1146 do_op_sthl: ;store hl to mem loc in opl:h
1155 ;----------------------------------------------------------------
1156 ;|Mnemonic |SZHPNC|Description |Notes |
1157 ;----------------------------------------------------------------
1158 ;|LD dst,src|------|Load |dst=src |
1168 ;----------------------------------------------------------------
1169 ;|Mnemonic |SZHPNC|Description |Notes |
1170 ;----------------------------------------------------------------
1171 ;|LD dst,src|------|Load |dst=src |
1178 ;----------------------------------------------------------------
1179 ;|Mnemonic |SZHPNC|Description |Notes |
1180 ;----------------------------------------------------------------
1181 ;|DAA |***P-*|Decimal Adjust Acc. | |
1182 ;|----------|SZHP C|---------- 8080 ----------------------------|
1186 ; Description (http://www.z80.info/z80syntx.htm#DAA):
1187 ; This instruction conditionally adjusts the accumulator for BCD addition
1188 ; and subtraction operations. For addition (ADD, ADC, INC) or subtraction
1189 ; (SUB, SBC, DEC, NEC), the following table indicates the operation performed:
1191 ; -------------------------------------------------------------------
1192 ; | |C Flag |HEX value in|H Flag |HEX val in | Number |C flag |
1193 ; | Oper |Before |upper digit |Before |lower digit| added |After |
1194 ; | |DAA |(bit 7-4) |DAA |(bit 3-0) | to A |DAA |
1195 ; |-------+-------+------------+-------+-----------+--------+-------|
1196 ; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
1197 ; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
1198 ; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
1199 ; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
1200 ; | | 0 | 9-F | 0 | A-F | 66 | 1 |
1201 ; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
1202 ; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
1203 ; | | 1 | 0-2 | 0 | A-F | 66 | 1 |
1204 ; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
1205 ; |-------+-------+------------+-------+-----------+--------+-------|
1206 ; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
1207 ; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
1208 ; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
1209 ; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
1210 ; -------------------------------------------------------------------
1212 ; The H flag is affected as follows:
1214 ; ---------------------
1215 ; | N | H | low |H' |
1217 ; |---+---+-------+---|
1218 ; | 0 | * | 0-9 | 0 |
1219 ; | 0 | * | a-f | 1 |
1221 ; | 1 | 1 | 6-f | 0 |
1222 ; | 1 | 1 | 0-5 | 1 |
1223 ; ---------------------
1227 ; P/V: Set if Acc. is even parity after operation, reset otherwise.
1228 ; Z: Set if Acc. is Zero after operation, reset otherwise.
1229 ; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise.
1236 sbrc z_flags,ZFL_N ;if add-op
1237 rjmp op_da_sub ;then
1241 ldi temp2,0 ; new C and H flag
1242 sbrc z_flags,ZFL_H ; |
1243 rjmp op_da_a01 ; if (H flag ...
1246 cpi temp,0x0a ; or (lower nibble >= 0x0A))
1249 ldi oph,0x06 ; add 6 to lower nibble
1252 ori temp2,(1<<ZFL_H) ; set new H flag
1255 ori temp2,(1<<ZFL_C) ; set new H flag
1257 sbrc z_flags,ZFL_C ; |
1258 rjmp op_da_a12 ; if (C flag ...
1259 cpi opl,0xA0 ; |... or upper nibble >= 0xA0)
1262 ldi oph,0x60 ; add 6 to lower nibble
1264 ori temp2,(1<<ZFL_C) ; set new C flag
1266 ldpmx z_flags, sz53p_tab, opl ; get S,Z,P flag
1267 or z_flags,temp2 ; merge new C and H flag
1272 op_da_sub: ;else (sub-op)
1273 rcall do_op_inv ; TODO: !
1280 ldi temp2,0 ;new C and H flag
1281 ldi oph,0 ;oph: what to add
1283 sbrc z_flags,ZFL_N ;if add-op
1284 rjmp op_da_sub ;then
1288 cpi temp,0x0a ; if (lower nibble >= 0x0A)
1290 ori oph,0x06 ; add 6
1291 ori temp2,(1<<ZFL_H) ; set new H flag
1293 sbrc z_flags,ZFL_C ; |
1294 rjmp op_da_a02 ; if (C flag ...
1295 cpi opl,0x90 ; |... or upper nibble >= 0x90)
1298 ori oph,0x60 ; add 0x60
1299 ori temp2,(1<<ZFL_C) ; set new C flag
1302 op_da_a10: ; else (lower nibble is 0x09 or lower)
1303 sbrc z_flags,ZFL_C ; |
1304 rjmp op_da_a12 ; if (C flag ...
1305 cpi opl,0xA0 ; |... or upper nibble >= 0xA0)
1308 ori oph,0x60 ; add 0x60
1309 ori temp2,(1<<ZFL_C) ; set new C flag
1311 sbrs z_flags,ZFL_H ; if (H flag)
1313 ori oph,0x06 ; add 0x06
1316 cpi temp,0x06 ; if (lower nibble >= 0x0A)
1318 ori temp2,(1<<ZFL_H) ; set new H flag
1323 ldpmx z_flags, sz53p_tab, opl ; get S,Z,P flag
1324 or z_flags,temp2 ; merge new C and H flag
1327 op_da_sub: ;else (sub-op)
1328 rcall do_op_inv ; TODO: !
1333 ;----------------------------------------------------------------
1334 ;|Mnemonic |SZHPNC|Description |Notes |
1335 ;----------------------------------------------------------------
1336 ;|SCF |--0-01|Set Carry Flag |CY=1 |
1337 ;|----------|SZHP C|---------- 8080 ----------------------------|
1341 do_z80_flags_clear_HN
1342 ori z_flags,(1<<ZFL_C)
1345 ;----------------------------------------------------------------
1346 ;|Mnemonic |SZHPNC|Description |Notes |
1347 ;----------------------------------------------------------------
1348 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY, HC=previous CY|
1349 ;|----------|SZHP C|---------- 8080 ----------------------------|
1350 ;|CCF |---- 1|Set Carry Flag |CY=1 |
1353 do_z80_flags_clear_N
1354 do_z80_flags_copy_HC
1359 ;----------------------------------------------------------------
1360 ;|Mnemonic |SZHPNC|Description |Notes |
1361 ;----------------------------------------------------------------
1362 ;|CPL |--1-1-|Complement |A=~A |
1363 ;|----------|SZHP C|---------- 8080 ----------------------------|
1364 ;|CPL |---- -|Complement |A=~A |
1373 ;----------------------------------------------------------------
1374 ;|Mnemonic |SZHPNC|Description |Notes |
1375 ;----------------------------------------------------------------
1376 ;|PUSH xx |------|Push |-[SP]=xx |
1377 ;|PUSH qq |------|Push |-[SP]=qq |
1390 printstring "Stack push "
1393 printstring ", SP is now "
1401 ;----------------------------------------------------------------
1402 ;|Mnemonic |SZHPNC|Description |Notes |
1403 ;----------------------------------------------------------------
1404 ;|POP xx |------|Pop |xx=[SP]+ |
1405 ;|POP qq |------|Pop |qq=[SP]+ |
1418 printstring "Stack pop "
1421 printstring ", SP is now "
1428 ;----------------------------------------------------------------
1429 ;|Mnemonic |SZHPNC|Description |Notes |
1430 ;----------------------------------------------------------------
1431 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
1432 ;|EX DE,HL |------|Exchange |DE<->HL |
1433 ;-----------------------------Z80--------------------------------
1443 ;----------------------------------------------------------------
1444 ;|Mnemonic |SZHPNC|Description |Notes |
1445 ;----------------------------------------------------------------
1447 ; TODO: Implement IFF1, IFF2
1451 ;----------------------------------------------------------------
1452 ;|Mnemonic |SZHPNC|Description |Notes |
1453 ;----------------------------------------------------------------
1455 ; TODO: Implement IFF1, IFF2
1459 ;----------------------------------------------------------------
1460 ;|Mnemonic |SZHPNC|Description |Notes |
1461 ;----------------------------------------------------------------
1462 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1463 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1464 ;|RET cc |------|Conditional Return |If cc RET |
1471 pop temp ; direkt zuruech zu main
1474 ;----------------------------------------------------------------
1475 ;|Mnemonic |SZHPNC|Description |Notes |
1476 ;----------------------------------------------------------------
1477 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1478 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1479 ;|RET cc |------|Conditional Return |If cc RET |
1486 pop temp ; direkt zuruech zu main
1489 ;----------------------------------------------------------------
1490 ;|Mnemonic |SZHPNC|Description |Notes |
1491 ;----------------------------------------------------------------
1492 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1493 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1494 ;|RET cc |------|Conditional Return |If cc RET |
1501 pop temp ; direkt zuruech zu main
1504 ;----------------------------------------------------------------
1505 ;|Mnemonic |SZHPNC|Description |Notes |
1506 ;----------------------------------------------------------------
1507 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1508 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1509 ;|RET cc |------|Conditional Return |If cc RET |
1516 pop temp ; direkt zuruech zu main
1519 ;----------------------------------------------------------------
1520 ;|Mnemonic |SZHPNC|Description |Notes |
1521 ;----------------------------------------------------------------
1522 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1523 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1524 ;|RET cc |------|Conditional Return |If cc RET |
1531 pop temp ; direkt zuruech zu main
1534 ;----------------------------------------------------------------
1535 ;|Mnemonic |SZHPNC|Description |Notes |
1536 ;----------------------------------------------------------------
1537 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1538 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1539 ;|RET cc |------|Conditional Return |If cc RET |
1546 pop temp ; direkt zuruech zu main
1549 ;----------------------------------------------------------------
1550 ;|Mnemonic |SZHPNC|Description |Notes |
1551 ;----------------------------------------------------------------
1552 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1553 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1554 ;|RET cc |------|Conditional Return |If cc RET |
1557 do_op_ifp: ;sign positive, aka s=0
1561 pop temp ; direkt zuruech zu main
1564 ;----------------------------------------------------------------
1565 ;|Mnemonic |SZHPNC|Description |Notes |
1566 ;----------------------------------------------------------------
1567 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1568 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1569 ;|RET cc |------|Conditional Return |If cc RET |
1572 do_op_ifm: ;sign negative, aka s=1
1576 pop temp ; direkt zuruech zu main
1580 ; ----------------------- Opcode decoding -------------------------
1582 ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
1583 ; operations: fetch, do something, store.
1584 ; The table is made of 256 words.
1586 ;.org (PC+255) & 0xff00
1588 instr do_fetch_nop, op_nop, do_store_nop ;00 ;NOP
1589 instr do_fetch_DIR16, op_nop, do_store_BC ;01 nn nn ;LD BC,nn
1590 instr do_fetch_nop, op_nop, do_store_MBC ;02 ;LD (BC),A
1591 instr do_fetch_BC, op_INC16, do_store_BC ;03 ;INC BC
1592 instr do_fetch_B, op_INC, do_store_B ;04 ;INC B
1593 instr do_fetch_B, op_DEC, do_store_B ;05 ;DEC B
1594 instr do_fetch_DIR8, op_nop, do_store_B ;06 ;LD B,n
1595 instr do_fetch_nop, op_RLCA, do_store_nop ;07 ;RLCA
1596 instr do_fetch_nop, op_INV, do_store_nop ;08 ;EX AF,AF'
1597 instr do_fetch_BC, op_ADDHL, do_store_HL ;09 ;ADD HL,BC
1598 instr do_fetch_MBC, op_nop, do_store_nop ;0A ;LD A,(BC)
1599 instr do_fetch_BC, op_DEC16, do_store_BC ;0B ;DEC BC
1600 instr do_fetch_C, op_INC, do_store_C ;0C ;INC C
1601 instr do_fetch_C, op_DEC, do_store_C ;0D ;DEC C
1602 instr do_fetch_DIR8, op_nop, do_store_C ;0E nn ;LD C,n
1603 instr do_fetch_nop, op_RRCA, do_store_nop ;0F ;RRCA
1604 instr do_fetch_nop, op_INV, do_store_nop ;10 oo ;DJNZ o
1605 instr do_fetch_DIR16, op_nop, do_store_DE ;11 nn nn ;LD DE,nn
1606 instr do_fetch_nop, op_nop, do_store_MDE ;12 ;LD (DE),A
1607 instr do_fetch_DE, op_INC16, do_store_DE ;13 ;INC DE
1608 instr do_fetch_D, op_INC, do_store_D ;14 ;INC D
1609 instr do_fetch_D, op_DEC, do_store_D ;15 ;DEC D
1610 instr do_fetch_DIR8, op_nop, do_store_D ;16 nn ;LD D,n
1611 instr do_fetch_nop, op_RLA, do_store_nop ;17 ;RLA
1612 instr do_fetch_nop, op_INV, do_store_nop ;18 oo ;JR o
1613 instr do_fetch_DE, op_ADDHL, do_store_HL ;19 ;ADD HL,DE
1614 instr do_fetch_MDE, op_nop, do_store_nop ;1A ;LD A,(DE)
1615 instr do_fetch_DE, op_DEC16, do_store_DE ;1B ;DEC DE
1616 instr do_fetch_E, op_INC, do_store_E ;1C ;INC E
1617 instr do_fetch_E, op_DEC, do_store_E ;1D ;DEC E
1618 instr do_fetch_DIR8, op_nop, do_store_E ;1E nn ;LD E,n
1619 instr do_fetch_nop, op_RRA, do_store_nop ;1F ;RRA
1620 instr do_fetch_nop, op_INV, do_store_nop ;20 oo ;JR NZ,o
1621 instr do_fetch_DIR16, op_nop, do_store_HL ;21 nn nn ;LD HL,nn
1622 instr do_fetch_DIR16, op_STHL, do_store_nop ;22 nn nn ;LD (nn),HL
1623 instr do_fetch_HL, op_INC16, do_store_HL ;23 ;INC HL
1624 instr do_fetch_H, op_INC, do_store_H ;24 ;INC H
1625 instr do_fetch_H, op_DEC, do_store_H ;25 ;DEC H
1626 instr do_fetch_DIR8, op_nop, do_store_H ;26 nn ;LD H,n
1627 instr do_fetch_A, op_DA, do_store_A ;27 ;DAA
1628 instr do_fetch_nop, op_INV, do_store_nop ;28 oo ;JR Z,o
1629 instr do_fetch_HL, op_ADDHL, do_store_HL ;29 ;ADD HL,HL
1630 instr do_fetch_DIR16, op_RMEM16, do_store_HL ;2A nn nn ;LD HL,(nn)
1631 instr do_fetch_HL, op_DEC16, do_store_HL ;2B ;DEC HL
1632 instr do_fetch_L, op_INC, do_store_L ;2C ;INC L
1633 instr do_fetch_L, op_DEC, do_store_L ;2D ;DEC L
1634 instr do_fetch_DIR8, op_nop, do_store_L ;2E nn ;LD L,n
1635 instr do_fetch_nop, op_CPL, do_store_nop ;2F ;CPL
1636 instr do_fetch_nop, op_INV, do_store_nop ;30 oo ;JR NC,o
1637 instr do_fetch_DIR16, op_nop, do_store_SP ;31 nn nn ;LD SP,nn
1638 instr do_fetch_DIR16, op_nop, do_store_AM ;32 nn nn ;LD (nn),A
1639 instr do_fetch_SP, op_INC16, do_store_SP ;33 ;INC SP
1640 instr do_fetch_MHL, op_INC, do_store_MHL ;34 ;INC (HL)
1641 instr do_fetch_MHL, op_DEC, do_store_MHL ;35 ;DEC (HL)
1642 instr do_fetch_DIR8, op_nop, do_store_MHL ;36 nn ;LD (HL),n
1643 instr do_fetch_nop, op_SCF, do_store_nop ;37 ;SCF
1644 instr do_fetch_nop, op_INV, do_store_nop ;38 oo ;JR C,o
1645 instr do_fetch_SP, op_ADDHL, do_store_HL ;39 ;ADD HL,SP
1646 instr do_fetch_DIR16, op_RMEM8, do_store_A ;3A nn nn ;LD A,(nn)
1647 instr do_fetch_SP, op_DEC16, do_store_SP ;3B ;DEC SP
1648 instr do_fetch_nop, op_INCA, do_store_nop ;3C ;INC A
1649 instr do_fetch_nop, op_DECA, do_store_nop ;3D ;DEC A
1650 instr do_fetch_DIR8, op_nop, do_store_A ;3E nn ;LD A,n
1651 instr do_fetch_nop, op_CCF, do_store_nop ;3F ;CCF (Complement Carry Flag, gvd)
1652 instr do_fetch_nop, op_nop, do_store_nop ;40 ;LD B,B
1653 instr do_fetch_C, op_nop, do_store_B ;41 ;LD B,C
1654 instr do_fetch_D, op_nop, do_store_B ;42 ;LD B,D
1655 instr do_fetch_E, op_nop, do_store_B ;43 ;LD B,E
1656 instr do_fetch_H, op_nop, do_store_B ;44 ;LD B,H
1657 instr do_fetch_L, op_nop, do_store_B ;45 ;LD B,L
1658 instr do_fetch_MHL, op_nop, do_store_B ;46 ;LD B,(HL)
1659 instr do_fetch_A, op_nop, do_store_B ;47 ;LD B,A
1660 instr do_fetch_B, op_nop, do_store_C ;48 ;LD C,B
1661 instr do_fetch_nop, op_nop, do_store_nop ;49 ;LD C,C
1662 instr do_fetch_D, op_nop, do_store_C ;4A ;LD C,D
1663 instr do_fetch_E, op_nop, do_store_C ;4B ;LD C,E
1664 instr do_fetch_H, op_nop, do_store_C ;4C ;LD C,H
1665 instr do_fetch_L, op_nop, do_store_C ;4D ;LD C,L
1666 instr do_fetch_MHL, op_nop, do_store_C ;4E ;LD C,(HL)
1667 instr do_fetch_A, op_nop, do_store_C ;4F ;LD C,A
1668 instr do_fetch_B, op_nop, do_store_D ;50 ;LD D,B
1669 instr do_fetch_C, op_nop, do_store_D ;51 ;LD D,C
1670 instr do_fetch_nop, op_nop, do_store_nop ;52 ;LD D,D
1671 instr do_fetch_E, op_nop, do_store_D ;53 ;LD D,E
1672 instr do_fetch_H, op_nop, do_store_D ;54 ;LD D,H
1673 instr do_fetch_L, op_nop, do_store_D ;55 ;LD D,L
1674 instr do_fetch_MHL, op_nop, do_store_D ;56 ;LD D,(HL)
1675 instr do_fetch_A, op_nop, do_store_D ;57 ;LD D,A
1676 instr do_fetch_B, op_nop, do_store_E ;58 ;LD E,B
1677 instr do_fetch_C, op_nop, do_store_E ;59 ;LD E,C
1678 instr do_fetch_D, op_nop, do_store_E ;5A ;LD E,D
1679 instr do_fetch_nop, op_nop, do_store_nop ;5B ;LD E,E
1680 instr do_fetch_H, op_nop, do_store_E ;5C ;LD E,H
1681 instr do_fetch_L, op_nop, do_store_E ;5D ;LD E,L
1682 instr do_fetch_MHL, op_nop, do_store_E ;5E ;LD E,(HL)
1683 instr do_fetch_A, op_nop, do_store_E ;5F ;LD E,A
1684 instr do_fetch_B, op_nop, do_store_H ;60 ;LD H,B
1685 instr do_fetch_C, op_nop, do_store_H ;61 ;LD H,C
1686 instr do_fetch_D, op_nop, do_store_H ;62 ;LD H,D
1687 instr do_fetch_E, op_nop, do_store_H ;63 ;LD H,E
1688 instr do_fetch_nop, op_nop, do_store_nop ;64 ;LD H,H
1689 instr do_fetch_L, op_nop, do_store_H ;65 ;LD H,L
1690 instr do_fetch_MHL, op_nop, do_store_H ;66 ;LD H,(HL)
1691 instr do_fetch_A, op_nop, do_store_H ;67 ;LD H,A
1692 instr do_fetch_B, op_nop, do_store_L ;68 ;LD L,B
1693 instr do_fetch_C, op_nop, do_store_L ;69 ;LD L,C
1694 instr do_fetch_D, op_nop, do_store_L ;6A ;LD L,D
1695 instr do_fetch_E, op_nop, do_store_L ;6B ;LD L,E
1696 instr do_fetch_H, op_nop, do_store_L ;6C ;LD L,H
1697 instr do_fetch_nop, op_nop, do_store_nop ;6D ;LD L,L
1698 instr do_fetch_MHL, op_nop, do_store_L ;6E ;LD L,(HL)
1699 instr do_fetch_A, op_nop, do_store_L ;6F ;LD L,A
1700 instr do_fetch_B, op_nop, do_store_MHL ;70 ;LD (HL),B
1701 instr do_fetch_C, op_nop, do_store_MHL ;71 ;LD (HL),C
1702 instr do_fetch_D, op_nop, do_store_MHL ;72 ;LD (HL),D
1703 instr do_fetch_E, op_nop, do_store_MHL ;73 ;LD (HL),E
1704 instr do_fetch_H, op_nop, do_store_MHL ;74 ;LD (HL),H
1705 instr do_fetch_L, op_nop, do_store_MHL ;75 ;LD (HL),L
1706 instr do_fetch_nop, op_INV, do_store_nop ;76 ;HALT
1707 instr do_fetch_A, op_nop, do_store_MHL ;77 ;LD (HL),A
1708 instr do_fetch_B, op_nop, do_store_A ;78 ;LD A,B
1709 instr do_fetch_C, op_nop, do_store_A ;79 ;LD A,C
1710 instr do_fetch_D, op_nop, do_store_A ;7A ;LD A,D
1711 instr do_fetch_E, op_nop, do_store_A ;7B ;LD A,E
1712 instr do_fetch_H, op_nop, do_store_A ;7C ;LD A,H
1713 instr do_fetch_L, op_nop, do_store_A ;7D ;LD A,L
1714 instr do_fetch_MHL, op_nop, do_store_A ;7E ;LD A,(HL)
1715 instr do_fetch_nop, op_nop, do_store_nop ;7F ;LD A,A
1716 instr do_fetch_B, op_ADDA, do_store_nop ;80 ;ADD A,B
1717 instr do_fetch_C, op_ADDA, do_store_nop ;81 ;ADD A,C
1718 instr do_fetch_D, op_ADDA, do_store_nop ;82 ;ADD A,D
1719 instr do_fetch_E, op_ADDA, do_store_nop ;83 ;ADD A,E
1720 instr do_fetch_H, op_ADDA, do_store_nop ;84 ;ADD A,H
1721 instr do_fetch_L, op_ADDA, do_store_nop ;85 ;ADD A,L
1722 instr do_fetch_MHL, op_ADDA, do_store_nop ;86 ;ADD A,(HL)
1723 instr do_fetch_A, op_ADDA, do_store_nop ;87 ;ADD A,A
1724 instr do_fetch_B, op_ADCA, do_store_nop ;88 ;ADC A,B
1725 instr do_fetch_C, op_ADCA, do_store_nop ;89 ;ADC A,C
1726 instr do_fetch_D, op_ADCA, do_store_nop ;8A ;ADC A,D
1727 instr do_fetch_E, op_ADCA, do_store_nop ;8B ;ADC A,E
1728 instr do_fetch_H, op_ADCA, do_store_nop ;8C ;ADC A,H
1729 instr do_fetch_L, op_ADCA, do_store_nop ;8D ;ADC A,L
1730 instr do_fetch_MHL, op_ADCA, do_store_nop ;8E ;ADC A,(HL)
1731 instr do_fetch_A, op_ADCA, do_store_nop ;8F ;ADC A,A
1732 instr do_fetch_B, op_SUBFA, do_store_nop ;90 ;SUB A,B
1733 instr do_fetch_C, op_SUBFA, do_store_nop ;91 ;SUB A,C
1734 instr do_fetch_D, op_SUBFA, do_store_nop ;92 ;SUB A,D
1735 instr do_fetch_E, op_SUBFA, do_store_nop ;93 ;SUB A,E
1736 instr do_fetch_H, op_SUBFA, do_store_nop ;94 ;SUB A,H
1737 instr do_fetch_L, op_SUBFA, do_store_nop ;95 ;SUB A,L
1738 instr do_fetch_MHL, op_SUBFA, do_store_nop ;96 ;SUB A,(HL)
1739 instr do_fetch_A, op_SUBFA, do_store_nop ;97 ;SUB A,A
1740 instr do_fetch_B, op_SBCFA, do_store_nop ;98 ;SBC A,B
1741 instr do_fetch_C, op_SBCFA, do_store_nop ;99 ;SBC A,C
1742 instr do_fetch_D, op_SBCFA, do_store_nop ;9A ;SBC A,D
1743 instr do_fetch_E, op_SBCFA, do_store_nop ;9B ;SBC A,E
1744 instr do_fetch_H, op_SBCFA, do_store_nop ;9C ;SBC A,H
1745 instr do_fetch_L, op_SBCFA, do_store_nop ;9D ;SBC A,L
1746 instr do_fetch_MHL, op_SBCFA, do_store_nop ;9E ;SBC A,(HL)
1747 instr do_fetch_A, op_SBCFA, do_store_nop ;9F ;SBC A,A
1748 instr do_fetch_B, op_ANDA, do_store_nop ;A0 ;AND A,B
1749 instr do_fetch_C, op_ANDA, do_store_nop ;A1 ;AND A,C
1750 instr do_fetch_D, op_ANDA, do_store_nop ;A2 ;AND A,D
1751 instr do_fetch_E, op_ANDA, do_store_nop ;A3 ;AND A,E
1752 instr do_fetch_H, op_ANDA, do_store_nop ;A4 ;AND A,H
1753 instr do_fetch_L, op_ANDA, do_store_nop ;A5 ;AND A,L
1754 instr do_fetch_MHL, op_ANDA, do_store_nop ;A6 ;AND A,(HL)
1755 instr do_fetch_A, op_ANDA, do_store_nop ;A7 ;AND A,A
1756 instr do_fetch_B, op_XORA, do_store_nop ;A8 ;XOR A,B
1757 instr do_fetch_C, op_XORA, do_store_nop ;A9 ;XOR A,C
1758 instr do_fetch_D, op_XORA, do_store_nop ;AA ;XOR A,D
1759 instr do_fetch_E, op_XORA, do_store_nop ;AB ;XOR A,E
1760 instr do_fetch_H, op_XORA, do_store_nop ;AC ;XOR A,H
1761 instr do_fetch_L, op_XORA, do_store_nop ;AD ;XOR A,L
1762 instr do_fetch_MHL, op_XORA, do_store_nop ;AE ;XOR A,(HL)
1763 instr do_fetch_A, op_XORA, do_store_nop ;AF ;XOR A,A
1764 instr do_fetch_B, op_ORA, do_store_nop ;B0 ;OR A,B
1765 instr do_fetch_C, op_ORA, do_store_nop ;B1 ;OR A,C
1766 instr do_fetch_D, op_ORA, do_store_nop ;B2 ;OR A,D
1767 instr do_fetch_E, op_ORA, do_store_nop ;B3 ;OR A,E
1768 instr do_fetch_H, op_ORA, do_store_nop ;B4 ;OR A,H
1769 instr do_fetch_L, op_ORA, do_store_nop ;B5 ;OR A,L
1770 instr do_fetch_MHL, op_ORA, do_store_nop ;B6 ;OR A,(HL)
1771 instr do_fetch_A, op_ORA, do_store_nop ;B7 ;OR A,A
1772 instr do_fetch_B, op_CPFA, do_store_nop ;B8 ;CP A,B
1773 instr do_fetch_C, op_CPFA, do_store_nop ;B9 ;CP A,C
1774 instr do_fetch_D, op_CPFA, do_store_nop ;BA ;CP A,D
1775 instr do_fetch_E, op_CPFA, do_store_nop ;BB ;CP A,E
1776 instr do_fetch_H, op_CPFA, do_store_nop ;BC ;CP A,H
1777 instr do_fetch_L, op_CPFA, do_store_nop ;BD ;CP A,L
1778 instr do_fetch_MHL, op_CPFA, do_store_nop ;BE ;CP A,(HL)
1779 instr do_fetch_A, op_CPFA, do_store_nop ;BF ;CP A,A
1780 instr do_fetch_nop, op_IFNZ, do_store_RET ;C0 ;RET NZ
1781 instr do_fetch_nop, op_POP16, do_store_BC ;C1 ;POP BC
1782 instr do_fetch_DIR16, op_IFNZ, do_store_PC ;C2 nn nn ;JP NZ,nn
1783 instr do_fetch_DIR16, op_nop, do_store_PC ;C3 nn nn ;JP nn
1784 instr do_fetch_DIR16, op_IFNZ, do_store_CALL ;C4 nn nn ;CALL NZ,nn
1785 instr do_fetch_BC, op_PUSH16, do_store_nop ;C5 ;PUSH BC
1786 instr do_fetch_DIR8, op_ADDA, do_store_nop ;C6 nn ;ADD A,n
1787 instr do_fetch_RST, op_nop, do_store_CALL ;C7 ;RST 0
1788 instr do_fetch_nop, op_IFZ, do_store_RET ;C8 ;RET Z
1789 instr do_fetch_nop, op_nop, do_store_RET ;C9 ;RET
1790 instr do_fetch_DIR16, op_IFZ, do_store_PC ;CA nn nn ;JP Z,nn
1791 instr do_fetch_nop, op_INV, do_store_nop ;CB ;(Z80 specific)
1792 instr do_fetch_DIR16, op_IFZ, do_store_CALL ;CC nn nn ;CALL Z,nn
1793 instr do_fetch_DIR16, op_nop, do_store_CALL ;CD nn nn ;CALL nn
1794 instr do_fetch_DIR8, op_ADCA, do_store_nop ;CE nn ;ADC A,n
1795 instr do_fetch_RST, op_nop, do_store_CALL ;CF ;RST 8H
1796 instr do_fetch_nop, op_IFNC, do_store_RET ;D0 ;RET NC
1797 instr do_fetch_nop, op_POP16, do_store_DE ;D1 ;POP DE
1798 instr do_fetch_DIR16, op_IFNC, do_store_PC ;D2 nn nn ;JP NC,nn
1799 instr do_fetch_DIR8, op_OUTA, do_store_nop ;D3 nn ;OUT (n),A
1800 instr do_fetch_DIR16, op_IFNC, do_store_CALL ;D4 nn nn ;CALL NC,nn
1801 instr do_fetch_DE, op_PUSH16, do_store_nop ;D5 ;PUSH DE
1802 instr do_fetch_DIR8, op_SUBFA, do_store_nop ;D6 nn ;SUB n
1803 instr do_fetch_RST, op_nop, do_store_CALL ;D7 ;RST 10H
1804 instr do_fetch_nop, op_IFC, do_store_RET ;D8 ;RET C
1805 instr do_fetch_nop, op_nop, do_store_nop ;D9 ;EXX
1806 instr do_fetch_DIR16, op_IFC, do_store_PC ;DA nn nn ;JP C,nn
1807 instr do_fetch_DIR8, op_IN, do_store_A ;DB nn ;IN A,(n)
1808 instr do_fetch_DIR16, op_IFC, do_store_CALL ;DC nn nn ;CALL C,nn
1809 instr do_fetch_nop, op_INV, do_store_nop ;DD ;(Z80 specific)
1810 instr do_fetch_DIR8, op_SBCFA, do_store_nop ;DE nn ;SBC A,n
1811 instr do_fetch_RST, op_nop, do_store_CALL ;DF ;RST 18H
1812 instr do_fetch_nop, op_IFPO, do_store_RET ;E0 ;RET PO
1813 instr do_fetch_nop, op_POP16, do_store_HL ;E1 ;POP HL
1814 instr do_fetch_DIR16, op_IFPO, do_store_PC ;E2 nn nn ;JP PO,nn
1815 instr do_fetch_MSP, op_EXHL, do_store_MSP ;E3 ;EX (SP),HL
1816 instr do_fetch_DIR16, op_IFPO, do_store_CALL ;E4 nn nn ;CALL PO,nn
1817 instr do_fetch_HL, op_PUSH16, do_store_nop ;E5 ;PUSH HL
1818 instr do_fetch_DIR8, op_ANDA, do_store_nop ;E6 nn ;AND n
1819 instr do_fetch_RST, op_nop, do_store_CALL ;E7 ;RST 20H
1820 instr do_fetch_nop, op_IFPE, do_store_RET ;E8 ;RET PE
1821 instr do_fetch_HL, op_nop, do_store_PC ;E9 ;JP HL
1822 instr do_fetch_DIR16, op_IFPE, do_store_PC ;EA nn nn ;JP PE,nn
1823 instr do_fetch_DE, op_EXHL, do_store_DE ;EB ;EX DE,HL
1824 instr do_fetch_DIR16, op_IFPE, do_store_CALL ;EC nn nn ;CALL PE,nn
1825 instr do_fetch_nop, op_INV, do_store_nop ;ED ;(Z80 specific)
1826 instr do_fetch_DIR8, op_XORA, do_store_nop ;EE nn ;XOR n
1827 instr do_fetch_RST, op_nop, do_store_CALL ;EF ;RST 28H
1828 instr do_fetch_nop, op_IFP, do_store_RET ;F0 ;RET P
1829 instr do_fetch_nop, op_POP16, do_store_AF ;F1 ;POP AF
1830 instr do_fetch_DIR16, op_IFP, do_store_PC ;F2 nn nn ;JP P,nn
1831 instr do_fetch_nop, op_DI, do_store_nop ;F3 ;DI
1832 instr do_fetch_DIR16, op_IFP, do_store_CALL ;F4 nn nn ;CALL P,nn
1833 instr do_fetch_AF, op_PUSH16, do_store_nop ;F5 ;PUSH AF
1834 instr do_fetch_DIR8, op_ORA, do_store_nop ;F6 nn ;OR n
1835 instr do_fetch_RST, op_nop, do_store_CALL ;F7 ;RST 30H
1836 instr do_fetch_nop, op_IFM, do_store_RET ;F8 ;RET M
1837 instr do_fetch_HL, op_nop, do_store_SP ;F9 ;LD SP,HL
1838 instr do_fetch_DIR16, op_IFM, do_store_PC ;FA nn nn ;JP M,nn
1839 instr do_fetch_nop, op_EI, do_store_nop ;FB ;EI
1840 instr do_fetch_DIR16, op_IFM, do_store_CALL ;FC nn nn ;CALL M,nn
1841 instr do_fetch_nop, op_INV, do_store_nop ;FD ;(Z80 specific)
1842 instr do_fetch_DIR8, op_CPFA, do_store_nop ;FE nn ;CP n
1843 instr do_fetch_RST, op_nop, do_store_CALL ;FF ;RST 38H
1846 ;----------------------------------------------------------------
1847 ; Lookup table, stolen from z80ex, Z80 emulation library.
1848 ; http://z80ex.sourceforge.net/
1850 ; The S, Z, 5 and 3 bits and the parity of the lookup value
1852 .org (PC+255) & 0xff00
1854 .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
1855 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
1856 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
1857 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
1858 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
1859 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
1860 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
1861 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
1862 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
1863 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
1864 .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00
1865 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
1866 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
1867 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
1868 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
1869 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
1870 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
1871 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
1872 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
1873 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
1874 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
1875 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
1876 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
1877 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
1878 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
1879 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
1880 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
1881 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
1882 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
1883 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
1884 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
1885 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
1887 ; vim:set ts=8 noet nowrap