summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.asm176
-rw-r--r--opcodes.asm173
2 files changed, 175 insertions, 174 deletions
diff --git a/main.asm b/main.asm
index 8bd0db3..531f6c5 100644
--- a/main.asm
+++ b/main.asm
@@ -47,177 +47,6 @@
xdef _tigcc_native
include "../tios.h"
- ;; == Memory Macros ================================================
-
- ;; Macro to read a byte from main memory at register \1. Puts
- ;; the byte read in \2.
-FETCHB MACRO
- move.w \1,d1
- bsr deref
- move.b (a0),\2
- ENDM
-
- ;; Macro to write a byte in \1 to main memory at \2
-PUTB MACRO
- move.w \2,d1
- bsr deref
- move.b \1,(a0)
- ENDM
-
- ;; Macro to read a word from main memory at register \1
- ;; (unaligned). Puts the word read in \2.
- ;;
- ;; <debrouxl> It decrements sp by 2, but stores the result at
- ;; sp, not at 1(sp). So you essentially get a "free" shift
- ;; left by 8 bits. Much faster than lsl.w / rol.w #8, at
- ;; least.
-FETCHW MACRO ; ?/16
- move.w \1,d1 ; 4/2
- bsr deref ; ?/4
- move.b (a0),-(sp) ; 18/4
- move.w (sp)+,\2 ; 8/2
- move.b (a0),\2 ; 14/4
- ENDM
-
- ;; Macro to write a word in \1 to main memory at \2 (regs only)
-PUTW MACRO ;
- move.w \2,d1
- bsr deref
- move.w \1,d0
- move.b d0,(a0)+
- LOHI d0
- move.b d0,(a0)
- ENDM
-
- ;; Push the word in \1 (register) using stack register a4.
- ;; Sadly, I can't trust the stack register to be aligned.
- ;; Destroys d0.
-
- ;; (SP-2) <- \1_l
- ;; (SP-1) <- \1_h
- ;; SP <- SP - 2
-PUSHW MACRO
- move.w \1,d0
- LOHI d0 ;slow
- move.b d0,-(a4) ; high byte
- move.b \1,-(a4) ; low byte
- ENDM
-
- ;; Pop the word at the top of stack a4 into \1.
- ;; Destroys d0.
-
- ;; \1_h <- (SP+1)
- ;; \1_l <- (SP)
- ;; SP <- SP + 2
-POPW MACRO
- move.b (a4)+,\1
- LOHI \1 ;slow
- move.b (a4)+,\1 ; high byte
- HILO \1 ;slow
- ENDM
-
- ;; == Immediate Memory Macros ==
-
- ;; Macro to read an immediate byte into \1.
-FETCHBI MACRO ; 8 cycles, 2 bytes
- move.b (a6)+,\1 ; 8/2
- ENDM
-
- ;; Macro to read an immediate word (unaligned) into \1.
-FETCHWI MACRO ; 28 cycles, 6 bytes
- ;; See FETCHW for an explanation of this trick.
- move.b (a6)+,-(sp) ; 12/2
- move.w (sp)+,\1 ; 8/2
- move.b (a6)+,\1 ; 8/2
- ENDM ; 28/6
-
- ;; == Common Opcode Macros =========================================
-
- ;; To align subroutines.
-_align SET 0
-
-START MACRO
- ORG emu_plain_op+_align
-_align SET _align+$20
- ENDM
-
- ;; LOHI/HILO are hideously slow for instructions used often.
- ;; Interleave registers instead:
- ;;
- ;; d4 = [B' B C' C]
- ;;
- ;; Thus access to B is fast (swap d4) while access to BC is
- ;; slow.
-
- ;; When you want to use the high reg of a pair, use this first
-LOHI MACRO ; 22 cycles, 2 bytes
- ror.w #8,\1 ; 22/2
- ENDM
-
- ;; Then do your shit and finish with this
-HILO MACRO ; 22 cycles, 2 bytes
- rol.w #8,\1
- ENDM
-
- ;; Rearrange a register: ABCD -> ACBD.
-WORD MACRO
- move.l \1,-(a7) ;12 cycles / 2 bytes
- movep.w 0(a7),\1 ;16 cycles / 4 bytes
- swap \1 ; 4 cycles / 2 bytes
- movep.w 1(a7),\1 ;16 cycles / 4 bytes
- addq #4,a7 ; 4 cycles / 2 bytes
- ;; overhead: 52 cycles /14 bytes
- ENDM
-
-
- ;; This is run at the end of every instruction routine.
-DONE MACRO
- clr.w d0 ; 4 cycles / 2 bytes
- move.b (a4)+,d0 ; 8 cycles / 2 bytes
- rol.w #5,d0 ;16 cycles / 2 bytes
- jmp 0(a5,d0.w) ;14 cycles / 4 bytes
- ;; overhead: 42 cycles /10 bytes
- ENDM
-
- ;; == Special Opcode Macros ========================================
-
- ;; Do an ADD \1,\2
-F_ADD_W MACRO
- ENDM
- ;; Do an SUB \1,\2
-F_SUB_W MACRO
- ENDM
-
- ;; INC and DEC macros
-F_INC_B MACRO
- move.b #1,f_tmp_byte-flag_storage(a3)
- move.b #1,f_tmp_src_b-flag_storage(a3)
- move.b \1,f_tmp_dst_b-flag_storage(a3)
- addq #1,\1
- moveq #2,d0
- F_CLEAR d0
- F_OVFL
- ENDM
-
-F_DEC_B MACRO
- move.b #1,f_tmp_byte-flag_storage(a3)
- st f_tmp_src_b-flag_storage(a3)
- move.b \1,f_tmp_dst_b-flag_storage(a3)
- subq #1,\1
- F_SET #2
- ENDM
-
-F_INC_W MACRO
- addq.w #1,\1
- ENDM
-
-F_DEC_W MACRO
- subq.w #1,\1
- ENDM
-
- ;; I might be able to unify rotation flags or maybe use a
- ;; lookup table
-
__main:
@@ -323,14 +152,13 @@ underef_thatsit:
;; ========== ========================================================
;; =========================================================================
+ include "opcodes.asm"
+
emu_run:
;; XXX: make this actually return
DONE
rts
- include "opcodes.asm"
-
-
emu_op_undo_cb:
emu_op_undo_dd:
emu_op_undo_ed:
diff --git a/opcodes.asm b/opcodes.asm
index ea94e80..2ae5c49 100644
--- a/opcodes.asm
+++ b/opcodes.asm
@@ -11,6 +11,179 @@
;;; http://z80.info/z80oplist.txt
+ ;; == Memory Macros ================================================
+
+ ;; Macro to read a byte from main memory at register \1. Puts
+ ;; the byte read in \2.
+FETCHB MACRO
+ move.w \1,d1
+ bsr deref
+ move.b (a0),\2
+ ENDM
+
+ ;; Macro to write a byte in \1 to main memory at \2
+PUTB MACRO
+ move.w \2,d1
+ bsr deref
+ move.b \1,(a0)
+ ENDM
+
+ ;; Macro to read a word from main memory at register \1
+ ;; (unaligned). Puts the word read in \2.
+ ;;
+ ;; <debrouxl> It decrements sp by 2, but stores the result at
+ ;; sp, not at 1(sp). So you essentially get a "free" shift
+ ;; left by 8 bits. Much faster than lsl.w / rol.w #8, at
+ ;; least.
+FETCHW MACRO ; ?/16
+ move.w \1,d1 ; 4/2
+ bsr deref ; ?/4
+ move.b (a0),-(sp) ; 18/4
+ move.w (sp)+,\2 ; 8/2
+ move.b (a0),\2 ; 14/4
+ ENDM
+
+ ;; Macro to write a word in \1 to main memory at \2 (regs only)
+PUTW MACRO ;
+ move.w \2,d1
+ bsr deref
+ move.w \1,d0
+ move.b d0,(a0)+
+ LOHI d0
+ move.b d0,(a0)
+ ENDM
+
+ ;; Push the word in \1 (register) using stack register a4.
+ ;; Sadly, I can't trust the stack register to be aligned.
+ ;; Destroys d0.
+
+ ;; (SP-2) <- \1_l
+ ;; (SP-1) <- \1_h
+ ;; SP <- SP - 2
+PUSHW MACRO
+ move.w \1,d0
+ LOHI d0 ;slow
+ move.b d0,-(a4) ; high byte
+ move.b \1,-(a4) ; low byte
+ ENDM
+
+ ;; Pop the word at the top of stack a4 into \1.
+ ;; Destroys d0.
+
+ ;; \1_h <- (SP+1)
+ ;; \1_l <- (SP)
+ ;; SP <- SP + 2
+POPW MACRO
+ move.b (a4)+,\1
+ LOHI \1 ;slow
+ move.b (a4)+,\1 ; high byte
+ HILO \1 ;slow
+ ENDM
+
+ ;; == Immediate Memory Macros ==
+
+ ;; Macro to read an immediate byte into \1.
+FETCHBI MACRO ; 8 cycles, 2 bytes
+ move.b (a6)+,\1 ; 8/2
+ ENDM
+
+ ;; Macro to read an immediate word (unaligned) into \1.
+FETCHWI MACRO ; 28 cycles, 6 bytes
+ ;; See FETCHW for an explanation of this trick.
+ move.b (a6)+,-(sp) ; 12/2
+ move.w (sp)+,\1 ; 8/2
+ move.b (a6)+,\1 ; 8/2
+ ENDM ; 28/6
+
+ ;; == Common Opcode Macros =========================================
+
+ ;; To align subroutines.
+_align SET 0
+
+START MACRO
+ ORG emu_plain_op+_align
+_align SET _align+$20
+ ENDM
+
+ ;; LOHI/HILO are hideously slow for instructions used often.
+ ;; Interleave registers instead:
+ ;;
+ ;; d4 = [B' B C' C]
+ ;;
+ ;; Thus access to B is fast (swap d4) while access to BC is
+ ;; slow.
+
+ ;; When you want to use the high reg of a pair, use this first
+LOHI MACRO ; 22 cycles, 2 bytes
+ ror.w #8,\1 ; 22/2
+ ENDM
+
+ ;; Then do your shit and finish with this
+HILO MACRO ; 22 cycles, 2 bytes
+ rol.w #8,\1
+ ENDM
+
+ ;; Rearrange a register: ABCD -> ACBD.
+WORD MACRO
+ move.l \1,-(a7) ;12 cycles / 2 bytes
+ movep.w 0(a7),\1 ;16 cycles / 4 bytes
+ swap \1 ; 4 cycles / 2 bytes
+ movep.w 1(a7),\1 ;16 cycles / 4 bytes
+ addq #4,a7 ; 4 cycles / 2 bytes
+ ;; overhead: 52 cycles /14 bytes
+ ENDM
+
+
+ ;; This is run at the end of every instruction routine.
+DONE MACRO
+ clr.w d0 ; 4 cycles / 2 bytes
+ move.b (a4)+,d0 ; 8 cycles / 2 bytes
+ rol.w #5,d0 ;16 cycles / 2 bytes
+ jmp 0(a5,d0.w) ;14 cycles / 4 bytes
+ ;; overhead: 42 cycles /10 bytes
+ ENDM
+
+ ;; == Special Opcode Macros ========================================
+
+ ;; Do an ADD \1,\2
+F_ADD_W MACRO
+ ENDM
+ ;; Do an SUB \1,\2
+F_SUB_W MACRO
+ ENDM
+
+ ;; INC and DEC macros
+F_INC_B MACRO
+ move.b #1,f_tmp_byte-flag_storage(a3)
+ move.b #1,f_tmp_src_b-flag_storage(a3)
+ move.b \1,f_tmp_dst_b-flag_storage(a3)
+ addq #1,\1
+ moveq #2,d0
+ F_CLEAR d0
+ F_OVFL
+ ENDM
+
+F_DEC_B MACRO
+ move.b #1,f_tmp_byte-flag_storage(a3)
+ st f_tmp_src_b-flag_storage(a3)
+ move.b \1,f_tmp_dst_b-flag_storage(a3)
+ subq #1,\1
+ F_SET #2
+ ENDM
+
+F_INC_W MACRO
+ addq.w #1,\1
+ ENDM
+
+F_DEC_W MACRO
+ subq.w #1,\1
+ ENDM
+
+ ;; I might be able to unify rotation flags or maybe use a
+ ;; lookup table
+
+
+
CNOP 0,32
emu_plain_op: ; Size(bytes) Time(cycles)