home *** CD-ROM | disk | FTP | other *** search
- ** Definitions for coding of Z80 instruction routines.
- ** (Macros and register aliases.)
-
- ** =====================================================================
-
- ** Registers:
-
- ** D0 00 A' 00 A A0 TableBase/Work
- ** D1 00 B' 00 B A1 Pseudo-PC
- ** D2 00 C' 00 C A2 Z80 SP (high word is garbage)
- ** D3 00 D' 00 D A3 Z80 address zero
- ** D4 00 E' 00 E A4 CacheBase
- ** D5 scratch H L A5 FlagsBase
- ** D6 scratch saveCCR A6 InstructionBase
- ** D7 --- scratch --- A7 User Stack Pointer
-
- ** Aliases:
-
- A EQUR d0
- B EQUR d1
- C EQUR d2
- D EQUR d3
- E EQUR d4
- L EQUR d5 ;To indicate byte access
- HL EQUR d5 ;To indicate word access
-
- TableB EQUR a0 ;pointer to TableBase
- Work EQUR a0 ;pointer to the Z80_Workspace longword
- PPC EQUR a1 ;Pseudo-PC
- ZSP EQUR a2 ;Z80 Stack Pointer (only lower word used)
- Z0 EQUR a3 ;pointer to Z80 address zero
- CacheB EQUR a4 ;pointer to CacheBase (corresponding to Z0)
- FlagsB EQUR a5 ;pointer to FlagsBase (corresponding to Z0)
- InstrB EQUR a6 ;pointer to InstructionBase
-
- ** The memory handler refers to most of the base pointers, by their
- ** aliases. The only address registers that can be used as scratch pads
- ** are PPC and ZSP, so I'd like them to remain in a1 and a2. If they are
- ** moved, changes must be done in the memory handler.
-
- ** Remember: if you change this, you must also change the labels
- ** in the Z80_RegStorage table in Z80_struct.i.
-
- ** ======================================================================
-
- IFD VERBOSE
- LIST
- ** Compiling the Z80_coding.i file.
- NOLIST
- ENDC
-
- ** Macros and local labels:
- **
- ** Make sure any labels within a macro are truly unique, especially
- ** if the macro might be repeated between global labels.
- ** Let local labels be on the form "<number>$", where <number>
- ** is > 100 in "utility" macros. Local labels in instruction routines
- ** (or macros defining such routines) that are on that form should have
- ** <number> less than 100.
- ** If a macro could be called more than once between global labels, and
- ** the macro must contain local labels, those labels must be unique for
- ** each macro call (between global labels), but may not be global since
- ** that would undefine any other local labels. Standard local labels
- ** (<number>$) can't be auto-generated, since the macro 'parameter' \@
- ** expands to "_<number>" (plain stupid, if you ask me).
- ** My solution (while I can't use Devpac-style local labels here),
- ** is to use an extra parameter (the last) to specify a "usage number"
- ** to be joined with the local label numbers, i.e. "<number>\3$".
- ** This is certainly ugly, but it will work.
-
- ** Reserved digit sequences:
- ** 100-110 testreq
- ** (111-119)... putz (i.e. anything beginning with 111 to 119.)
- ** 200-210 opcode_2_bytes
- ** 300-310 opcode_3_bytes
-
-
- ** End of instruction, execute next.
- next MACRO
- move.w (PPC)+,d7
- jmp (InstrB,d7.w)
- ENDM
- ** ----
-
- ** Test for requests. Has a built-in "next" function.
- ** May only occur once in an instruction routine.
- testreq MACRO
- move.w Z80_Request(TableB),d7
- bne.s 102$ ;skip if no request
- 101$ move.w (PPC)+,d7
- 102$ jmp (InstrB,d7.w)
- ENDM
- ;101$ is supposed to be a known entry point used to
- ;exit to next instruction without testing requests.
- ;Most jumps/calls use this "feature".
- ** ----
-
- ** Read from z80 memory. Address is a register.
- getz MACRO ;address,value
- move.b (Z0,\1.w),\2
- ENDM
- ** ----
-
- ** Write a byte to memory, marking the cache pointer 'changed'.
- ** Address is a register. Memory flags are not checked here. See putz.
- IFD UPDATECACHE
- writemem MACRO ;value,address
- move.b \1,(Z0,\2.w)
- add.w \2,CacheB
- clr.w (CacheB,\2.w)
- sub.w \2,CacheB
- ENDM
- ELSE
- writemem MACRO ;value,address
- move.b \1,(Z0,\2.w) ;write to z80 memory
- ENDM
- IFD VERBOSE
- LIST
- ** Writemem does not mark the cache pointer.
- NOLIST
- ENDC
- ENDC ;IFD UPDATECACHE
- ** ----
-
- ** Write to z80 memory. Address is a register.
- IFND Z80_MEMCHECK
- putz MACRO ;value,address
- writemem <\1>,<\2>
- ENDM
- ELSE
- ** As above, but do address exception testing.
- ** May occur several times in a single instruction routine,
- ** therefore, calls beyond the first must specify a "usage number"
- ** (preferably a single digit).
- putz MACRO ;value,address[,use]
- tst.b (FlagsB,\2.w)
- beq.s 111\3$
- move.w \2,-(sp)
- move.b \1,-(sp)
- jsr memhandler(InstrB)
- addq.l #4,sp
- bra.s 112\3$
- 111\3$ writemem <\1>,<\2>
- 112\3$
- ENDM
-
- ;If the handler is called, the write part is skipped. If
- ;the value should be written, the handler will do it.
- ;When the memory handler is reached, the stack should
- ;look like this:
- ; sp+6 word address
- ; byte padding (caused by move.b to stack)
- ; sp+4 byte value
- ; sp-> long return address
-
- WRITE_ADDR = 6 ;the offsets used by memhandler
- WRITE_VAL = 4
-
- ENDC ;IFND Z80_MEMCHECK
- ** ----
-
- ** Word-sized Increment
- incw MACRO ;dest
- addq.w #1,\1
- ENDM
- ** ----
-
- ** Word-sized decrement
- decw MACRO ;dest
- subq.w #1,\1
- ENDM
- ** ----
-
- ** Byte-sized increment
- incb MACRO ;dest
- addq.b #1,\1
- ENDM
- ** ----
-
- ** Byte-sized decrement
- decb MACRO ;dest
- subq.b #1,\1
- ENDM
- ** ----
-
- ** Move PPC 'count' words forward. (Max 4)
- skip MACRO ;count
- addq.l #2*(\1),PPC
- ENDM
- ** ----
-
- ** Calculate the real 16-bit Z80 PC (result in d7).
- getRPC MACRO
- move.l PPC,d7
- sub.l CacheB,d7
- lsr.l #1,d7
- ENDM
- ** ----
-
- ** Make new PPC from the Real PC in d7.
- ** PPC=CacheB+2*(extended d7.w)
- makePPC MACRO
- lea (CacheB,d7.w),PPC
- add.w d7,PPC
- ENDM
- ** ----
-
- ** Test parity. Bits 8-15 must be zero.
- parity MACRO ;register
- or.b Z80_Parity(TableB,\1.w),d6
- ENDM
- ** ----
-
- ** Store the status register / condition code register.
- ;Move from SR is privileged on 68010 and higher. On those,
- ;use Move from CCR (which doesn't exist on 68000).
- IFNE PROCESSOR<68010
-
- putsr MACRO ;dest
- move SR,\1
- ENDM
- IFD VERBOSE
- LIST
- ** putsr uses Move from SR.
- NOLIST
- ENDC
-
- ELSE
-
- putsr MACRO ;dest
- move CCR,\1
- ENDM
- IFD VERBOSE
- LIST
- ** putsr uses Move from CCR.
- NOLIST
- ENDC
-
- ENDC ;IFND CCR_VERSION
- ** ----
-
- ** Load the condition code register from d6.
- getsr MACRO
- move d6,CCR
- ENDM
- ** ----
-
- ** Make a word of two bytes. Result in d7.
- join MACRO ;High,Low
- move.b \1,(Work)
- move.w (Work),d7
- move.b \2,d7
- ENDM
- ** ----
-
- ** Index register + offset to d7. Offset is always the third byte.
- ** The PPC has been increased by one.
- index MACRO ;X or Y
- getRPC
- incw d7
- getz d7,d7
- ext.w d7
- add.w Z80_I\1(TableB),d7
- ENDM
- ** ----
-
- ** Execute macro/instruction with all r but H as parameter.
- do_r MACRO ;instruction
- \1 A
- \1 B
- \1 C
- \1 D
- \1 E
- \1 L
- ENDM
- ** ----
-
- ** Execute macro/instruction with B,C and D,E as parameters.
- do_ss MACRO ;instruction
- \1 B,C
- \1 D,E
- ENDM
- ** ----
-
- ** Execute macro/instruction with X and Y as parameter
- do_xy MACRO ;instruction
- \1 X
- \1 Y
- ENDM
- ** ----
-
- ** Test multi-byte opcodes for modified code.
- ** Only negative cache values are allowed for the second and third
- ** bytes of the opcode.
-
-
- ** This tests the instructions on the form
- ** prefix (DD/CB)
- ** opcode
- ** [offset]
- ** [data]
-
- ;May only occur once in an instruction routine
-
- IFD MODIFIEDCODE
- opcode_2_bytes MACRO
- tst.w (PPC)
- bmi.s 201$
- jmp stale_ptr(InstrB)
- 201$
- ENDM
- ELSE
- opcode_2_bytes MACRO
- ;do nothing
- ENDM
- IFD VERBOSE
- LIST
- ** No tests for modified code in 2-byte opcodes are made.
- NOLIST
- ENDC
- ENDC ;IFD MODIFIEDCODE
-
-
- ** This tests the instructions on the form
- ** prefix (DD/FD)
- ** prefix (CB)
- ** offset
- ** opcode
-
- ;May only occur once in an instruction routine
-
- IFD MODIFIEDCODE
- opcode_3_bytes MACRO
- move.w (PPC),d7
- or.w 4(PPC),d7
- bmi.s 301$
- jmp stale_ptr(InstrB)
- 301$
- ENDM
- ELSE
- opcode_3_bytes MACRO
- ;do nothing
- ENDM
- IFD VERBOSE
- LIST
- ** No tests for modified code in 3-byte opcodes are made.
- NOLIST
- ENDC
- ENDC ;IFD MODIFIEDCODE
-
- ** =======================================================================
-