home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 2
/
FFMCD02.bin
/
new
/
misc
/
emu
/
z80
/
std_instr.i
< prev
next >
Wrap
Text File
|
1993-12-21
|
37KB
|
2,397 lines
** The non-implementation-dependent Z80 instructions
** -----------------------------------------------------------------------
** The address register named Work points to a longword called Workspace,
** which is used for fast temporary storage and byte swaps.
** In order for the parity test to work, bits 8-15 of the tested register
** must be zero. The V flag (bit 1 of d6) must be clear before executing
** the macro.
** -----------------------------------------------------------------------
** Following opcodes exactly follow Zaks' "Programming the Z80".
**
** n = 8-bit number
** nn = 16-bit number
** e = 8-bit relative jump offset
** d = 8-bit displacement
** pq = 16-bit address
** p = 8-bit address
**
** Label notation: Underscore used for SPACE, comma and +
**
** 1 (one) used for ( and )
** =======================================================================
IFD VERBOSE
LIST
** Compiling the std_instr.i file.
NOLIST
ENDC
adc_A_r MACRO
Adc_A_\1
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB) ;BCD_A=A
move.b \1,Z80_BCD_B(TableB) ;BCD_B=r
move.w d6,Z80_BCD_C(TableB) ;BCD_C=carry
move.w #OP_ADC,Z80_BCD_OP(TableB) ;BCD_OP=adc
ENDC
lsr.w #1,d6 ;carry to X
ori #4,CCR ;set Z
addx.b \1,A
putsr d6
next
ENDM
do_r adc_A_r
** --
Adc_A_H move.w HL,(Work)
move.b (Work),d7
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b d7,Z80_BCD_B(TableB)
move.w d6,Z80_BCD_C(TableB)
move.w #OP_ADC,Z80_BCD_OP(TableB)
ENDC
lsr.w #1,d6
ori #4,CCR
addx.b d7,A
putsr d6
next
** --
Adc_A_n getRPC
getz d7,d7
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b d7,Z80_BCD_B(TableB)
move.w d6,Z80_BCD_C(TableB)
move.w #OP_ADC,Z80_BCD_OP(TableB)
ENDC
lsr.w #1,d6
ori #4,CCR
addx.b d7,A
putsr d6
skip 1
next
** --
Adc_A_1HL1 getz HL,d7
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b d7,Z80_BCD_B(TableB)
move.w d6,Z80_BCD_C(TableB)
move.w #OP_ADC,Z80_BCD_OP(TableB)
ENDC
lsr.w #1,d6
ori #4,CCR
addx.b d7,A
putsr d6
next
** --
adc_A_1xy1 MACRO
Adc_A_1I\1_d1 opcode_2_bytes
index \1
getz d7,d7
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b d7,Z80_BCD_B(TableB)
move.w d6,Z80_BCD_C(TableB)
move.w #OP_ADC,Z80_BCD_OP(TableB)
ENDC
lsr.w #1,d6
ori #4,CCR
addx.b d7,A
putsr d6
skip 2
next
ENDM
do_xy adc_A_1xy1
** --
adc_HL_ss MACRO
Adc_HL_\1\2 opcode_2_bytes
join \1,\2
lsr.w #1,d6
ori #4,CCR
addx.w d7,HL
putsr d6
skip 1
next
ENDM
do_ss adc_HL_ss
** --
Adc_HL_HL opcode_2_bytes
lsr.w #1,d6
ori #4,CCR
addx.w HL,HL
putsr d6
skip 1
next
** --
Adc_HL_SP opcode_2_bytes
move.w ZSP,d7
lsr.w #1,d6
ori #4,CCR
addx.w d7,HL
putsr d6
skip 1
next
** --
add_A_r MACRO
Add_A_\1
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b \1,Z80_BCD_B(TableB)
clr.w Z80_BCD_OP(TableB)
ENDC
add.b \1,A
putsr d6
next
ENDM
do_r add_A_r
** --
Add_A_H move.w HL,(Work)
move.b (Work),d7
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b d7,Z80_BCD_B(TableB)
clr.w Z80_BCD_OP(TableB)
ENDC
add.b d7,A
putsr d6
next
** --
Add_A_n getRPC
getz d7,d7
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b d7,Z80_BCD_B(TableB)
clr.w Z80_BCD_OP(TableB)
ENDC
add.b d7,A
putsr d6
skip 1
next
** --
Add_A_1HL1 getz HL,d7
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b d7,Z80_BCD_B(TableB)
clr.w Z80_BCD_OP(TableB)
ENDC
add.b d7,A
putsr d6
next
** --
add_A_1xy1 MACRO
Add_A_1I\1_d1 opcode_2_bytes
index \1
getz d7,d7
IFD BCDFLAGS
move.b A,Z80_BCD_A(TableB)
move.b d7,Z80_BCD_B(TableB)
clr.w Z80_BCD_OP(TableB)
ENDC
add.b d7,A
putsr d6
skip 2
next
ENDM
do_xy add_A_1xy1
** --
add_HL_ss MACRO
Add_HL_\1\2 join \1,\2
and.w #%1110,d6
add.w d7,HL
bcc.s .cc
or.w #1,d6
.cc next
ENDM
do_ss add_HL_ss
** --
Add_HL_HL and.w #%1110,d6
add.w HL,HL
bcc.s .cc
or.w #1,d6
.cc next
** --
Add_HL_SP and.w #%1110,d6
add.w ZSP,HL
bcc.s .cc
or.w #1,d6
.cc next
** --
add_xy_ss MACRO
Add_I\1_\2\3 opcode_2_bytes
join \2,\3
and.w #%1110,d6
add.w Z80_I\1(TableB),d7
bcc.s .cc
or.w #1,d6
.cc move.w d7,Z80_I\1(TableB)
skip 1
next
ENDM
add_xy_xy MACRO
Add_I\1_I\1 opcode_2_bytes
and.w #%1110,d6
move.w Z80_I\1(TableB),d7
add.w d7,d7
bcc.s .cc
or.w #1,d6
.cc move.w d7,Z80_I\1(TableB)
skip 1
next
ENDM
add_xy_SP MACRO
Add_I\1_SP opcode_2_bytes
and.w #%1110,d6
move.w Z80_I\1(TableB),d7
add.w ZSP,d7
bcc.s .cc
or.w #1,d6
.cc move.w d7,Z80_I\1(TableB)
skip 1
next
ENDM
addxy_xy MACRO
add_xy_ss \1,B,C
add_xy_ss \1,D,E
add_xy_xy \1
add_xy_SP \1
ENDM
do_xy addxy_xy
** --
and_r MACRO
And_\1 and.b \1,A ;V is cleared
putsr d6
parity A
next
ENDM
do_r and_r
** --
And_H move.w HL,(Work)
and.b (Work),A
putsr d6
parity A
next
** --
And_n getRPC
and.b (Z0,d7.w),A
putsr d6
parity A
skip 1
next
** --
And_1HL1 and.b (Z0,HL.w),A
putsr d6
parity A
next
** --
and_1xy1 MACRO
And_1I\1_d1 opcode_2_bytes
index \1
and.b (Z0,d7.w),A
putsr d6
parity A
skip 2
next
ENDM
do_xy and_1xy1
** --
bit_b_r MACRO
Bit_\1_\2 opcode_2_bytes
or.w #%0100,d6
btst #\1,\2
beq.s .z
and.w #%1011,d6
.z skip 1
next
ENDM
bit_b_H MACRO
Bit_\1_H opcode_2_bytes
or.w #%0100,d6
btst #8+\1,HL
beq.s .z
and.w #%1011,d6
.z skip 1
next
ENDM
bit_b_HL MACRO
Bit_\1_1HL1 opcode_2_bytes
or.w #%0100,d6
btst #\1,(Z0,HL.w)
beq.s .z
and.w #%1011,d6
.z skip 1
next
ENDM
bit_b_1xy1 MACRO
Bit_\1_1I\2_d1 opcode_3_bytes
index \2
or.w #%0100,d6
btst #\1,(Z0,d7.w)
beq.s .z
and.w #%1011,d6
.z skip 3
next
ENDM
bit_b MACRO
bit_b_r \1,A
bit_b_r \1,B
bit_b_r \1,C
bit_b_r \1,D
bit_b_r \1,E
bit_b_r \1,L
bit_b_H \1
bit_b_HL \1
bit_b_1xy1 \1,X
bit_b_1xy1 \1,Y
ENDM
bit_b 0
bit_b 1
bit_b 2
bit_b 3
bit_b 4
bit_b 5
bit_b 6
bit_b 7
** --
call_cc_pq MACRO
Call_\1_pq skip 2
getsr
b\2.s 101$ ; 'exit' label in testreq macro
getRPC
move.w d7,(Work)
decw ZSP
putz (Work),ZSP
decw ZSP
putz d7,ZSP,2 ;2nd use
decw d7
getz d7,(Work)
decw d7
getz d7,1(Work)
move.w (Work),d7
makePPC
testreq
ENDM
call_cc_pq NZ,eq
call_cc_pq Z,ne
call_cc_pq NC,cs
call_cc_pq C,cc
call_cc_pq PO,vs
call_cc_pq PE,vc
call_cc_pq P,mi
call_cc_pq M,pl
** --
Call_pq getRPC
addq.w #2,d7
move.w d7,(Work)
decw ZSP
putz (Work),ZSP
decw ZSP
putz d7,ZSP,2 ;2nd use
decw d7
getz d7,(Work)
decw d7
getz d7,1(Work)
move.w (Work),d7
makePPC
testreq
** --
Ccf eori.w #1,d6
next
** --
cp_r MACRO
Cp_\1 cmp.b \1,A
putsr d6
next
ENDM
do_r cp_r
** --
Cp_H move.w HL,(Work)
cmp.b (Work),A
putsr d6
next
** --
Cp_n getRPC
cmp.b (Z0,d7.w),A
putsr d6
skip 1
next
** --
Cp_1HL1 cmp.b (Z0,HL.w),A
putsr d6
next
** --
cp_1xy1 MACRO
Cp_1I\1_d1 opcode_2_bytes
index \1
cmp.b (Z0,d7.w),A
putsr d6
skip 2
next
ENDM
do_xy cp_1xy1
** --
Cpd opcode_2_bytes
cmp.b (Z0,HL.w),A
putsr d7
eor.w d7,d6 ;Join old carry and
and.w #1,d6 ; new sign and zero
eor.w d7,d6
or.w #%0010,d6 ;V set if BC not zero
decw HL ;dec HL
decb C
beq.s .Cz
bcc.s .BCnz ;if carry, decrement B
decb B
bra.s .BCnz ;C<>0, so BC<>0
.Cz tst.b B
bne.s .BCnz
and.w #%1101,d6 ;V reset if BC zero
.BCnz skip 1
next
** --
Cpi opcode_2_bytes
cmp.b (Z0,HL.w),A
putsr d7
eor.w d7,d6 ;Join old carry and
and.w #1,d6 ; new sign and zero
eor.w d7,d6
or.w #%0010,d6 ;V set if BC not zero
incw HL ;dec HL
decb C
beq.s .Cz
bcc.s .BCnz ;if carry, decrement B
decb B
bra.s .BCnz ;C<>0, so BC<>0
.Cz tst.b B
bne.s .BCnz
and.w #%1101,d6 ;V reset if BC zero
.BCnz skip 1
next
** --
Cpdr opcode_2_bytes
move.b B,(Work)
move.w (Work),B
move.b C,B ;use B (word) as counter
.loop cmp.b (Z0,HL.w),A
putsr d7
beq.s .eq
decw HL ;dec pointer
decw B ;dec counter
bne.s .loop
.BCz and.w #%1101,d7 ;BC zero, so reset V
.end eor.w d7,d6 ;join old carry
and.w #1,d6 ; with new N, Z & V
eor.w d7,d6
move.b B,C ;BC=counter
lsr.w #8,B ;restore B, zeroing bits 15-8
skip 1
next
.eq decw HL ;one last dec pointer
decw B ; and dec counter
beq.