summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAstrid Smith2011-10-21 01:07:19 -0700
committerAstrid Smith2011-10-21 01:07:19 -0700
commit541bce94a4d73e754ce522758dd25ecddb818f04 (patch)
tree6bca458ce09cc2b9470410bae62b74a747733165
parentef89049eae1d7e2591bef44a3e8151131fb4bed2 (diff)
First stage of converting to be GAS-compliant
I (think I) have converted all the A68k directives to their GAS equivalents. Still remaining are all the inline expressions.
-rw-r--r--Makefile12
-rw-r--r--alu.s (renamed from alu.asm)2
-rw-r--r--flags.s (renamed from flags.asm)178
-rw-r--r--interrupts.s.m4 (renamed from interrupts.asm.m4)2
-rw-r--r--main.asm196
-rw-r--r--main.s200
-rw-r--r--opcodes.s.m4 (renamed from opcodes.asm.m4)274
-rw-r--r--ports.asm1188
-rw-r--r--ports.s1188
9 files changed, 1627 insertions, 1613 deletions
diff --git a/Makefile b/Makefile
index e89fa38..9da723e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,13 @@
-# these files are written as .asm
-ASM_FILES=alu.asm flags.asm ports.asm main.asm
+# these files are written as .s
+ASM_FILES=alu.s flags.s ports.s main.s
-# these files are written as .asm.m4 and then preprocessed to .asm
-M4_ASM_OUTPUT=opcodes.asm interrupts.asm
+# these files are written as .s.m4 and then preprocessed to .s
+M4_ASM_OUTPUT=opcodes.s interrupts.s
M4_ASM_INCLUDES=opcodes.inc.m4
# this is the set of file(s) which is fed to the assembler, and uses
# INCLUDE directives to include the rest of assembly source.
-ASM=main.asm
+ASM=main.s
C_HEADERS=global.h asm_vars.h
C_FILES=loader.c bankswap.c video.c misc.c debug.c
@@ -53,7 +53,7 @@ packager: packager.c
gcc $(CFLAGS) packager.c -o packager
# preprocess asm files using m4 as necessary
-%.asm: %.asm.m4
+%.s: %.s.m4
m4 $(M4_ASM_INCLUDES) $< > $@
# assemble z80 code
diff --git a/alu.asm b/alu.s
index ec0e137..22594bd 100644
--- a/alu.asm
+++ b/alu.s
@@ -1,6 +1,8 @@
;; Parting out the big math/logic routines from the
;; instruction dispatch table.
+.text
+
alu_add:
;; ADD instruction
;; ADD d1,d0
diff --git a/flags.asm b/flags.s
index 6282336..8fc2058 100644
--- a/flags.asm
+++ b/flags.s
@@ -1,48 +1,52 @@
;; Routine to set the given flags
- ;; Noted in \1 by a 1 bit
-F_SET MACRO ; 32 cycles, 8 bytes
- or.b \1,flag_byte-flag_storage(a3)
- or.b \1,flag_valid-flag_storage(a3)
- ENDM
+ ;; Noted in \mask by a 1 bit
+.macro F_SET mask ; 32 cycles, 8 bytes
+ or.b \mask,flag_byte-flag_storage(a3)
+ or.b \mask,flag_valid-flag_storage(a3)
+.endm
;; Clear the given flags
- ;; Noted in \1 (must be a reg) by a 1 bit
-F_CLEAR MACRO ; 36 cycles, 10 bytes
- or.b \1,flag_valid-flag_storage(a3)
- not.b \1
- and.b \1,flag_byte-flag_storage(a3)
- ENDM
+ ;; Noted in \mask (must be a reg) by a 1 bit
+.macro F_CLEAR mask ; 36 cycles, 10 bytes
+ or.b \mask,flag_valid-flag_storage(a3)
+ not.b \mask
+ and.b \mask,flag_byte-flag_storage(a3)
+.endm
;; Use this when an instruction uses the P/V bit as Parity.
;; Sets or clears the bit explicitly.
;;
- ;; Byte for which parity is calculated must be in \1. High
- ;; byte of \1.w must be zero, using d0 is suggested. (a0,d1
+ ;; Byte for which parity is calculated must be in \byte. High
+ ;; byte of \byte.w must be zero, using d0 is suggested. (a0,d1
;; destroyed)
-F_PAR MACRO
+.macro F_PAR byte
ori.b #%00000100,flag_valid-flag_storage(a3)
move.b flag_byte(pc),d1
andi.b #%11111011,d1
lea lut_parity(pc),a0
- or.b 0(a0,\1.w),d1
+ or.b 0(a0,\byte.w),d1
move.b d1,flag_byte-flag_storage(a3)
- ENDM
+.endm
;; Use this when an instruction uses the P/V bit as Overflow.
;; Leaves the bit itself implicit; simply marks it dirty.
-F_OVFL MACRO ; 20 cycles, 6 bytes
+.macro F_OVFL ; 20 cycles, 6 bytes
andi.b #%11111011,flag_valid-flag_storage(a3)
- ENDM
+.endm
;; Save the two operands from ADD \1,\2
-F_ADD_SAVE MACRO
- move.b \1,f_tmp_src_b-flag_storage(a3)
- move.b \2,f_tmp_dst_b-flag_storage(a3)
+.macro F_ADD_SAVE src dst
+ move.b \src,f_tmp_src_b-flag_storage(a3)
+ move.b \dst,f_tmp_dst_b-flag_storage(a3)
move.b #$01,f_tmp_byte-flag_storage(a3)
F_SET #%
- ENDM
+.endm
+
+
+
+.text
;; Normalize and return inverse of emulated Carry bit (loaded
;; into host zero flag)
@@ -203,39 +207,41 @@ flags_all:
bsr f_calc_carries
rts
- EVEN
+
+
+.data
flag_storage:
;; 0 if the flag is already valid
;; 2 if tmp_???b is valid
;; 3 if tmp_???w is valid
-f_tmp_byte: dc.b 0
+f_tmp_byte: .byte 0
;; 2 if P is 0
;; 3 if P is 1
;; 4 if P is uncalculated Parity
;; 5 if P is uncalculated oVerflow
-f_tmp_p_type: dc.b 0
+f_tmp_p_type: .byte 0
;; byte operands
-f_tmp_src_b: dc.b 0
-f_tmp_dst_b: dc.b 0
-f_tmp_result_b: dc.b 0
+f_tmp_src_b: .byte 0
+f_tmp_dst_b: .byte 0
+f_tmp_result_b: .byte 0
- EVEN
-f_tmp_src_w: dc.w 0
-f_tmp_dst_w: dc.w 0
-f_tmp_result_w: dc.w 0
+.even
+f_tmp_src_w: .word 0
+f_tmp_dst_w: .word 0
+f_tmp_result_w: .word 0
;; 000XNZVC
- EVEN
+.even
;; DO NOT REARRANGE THESE
-f_host_sr: dc.w 0
-f_host_ccr: dc.b 0 ;XXX make overlap somehow?
+f_host_sr: .word 0
+f_host_ccr: .byte 0 ;XXX make overlap somehow?
- EVEN
+.even
;; DO NOT REARRANGE THESE.
-flag_byte: dc.b 0 ; Byte of all flags
-flag_valid: dc.b 0 ; Validity mask -- 1 if valid.
+flag_byte: .byte 0 ; Byte of all flags
+flag_valid: .byte 0 ; Validity mask -- 1 if valid.
;; LUT for the CCR -> F mapping
@@ -247,38 +253,38 @@ lut_ccr:
;;
;; =CCR= == z80==
;; XNZVC SZ5H3PNC
- dc.b %00000000 ;; 00000 00000000
- dc.b %00000001 ;; 00001 00000001
- dc.b %00000100 ;; 00010 00000100
- dc.b %00000101 ;; 00011 00000101
- dc.b %01000000 ;; 00100 01000000
- dc.b %01000001 ;; 00101 01000001
- dc.b %01000100 ;; 00110 01000100
- dc.b %01000101 ;; 00111 01000101
- dc.b %10000000 ;; 01000 10000000
- dc.b %10000001 ;; 01001 10000001
- dc.b %10000100 ;; 01010 10000100
- dc.b %10000101 ;; 01011 10000101
- dc.b %11000000 ;; 01100 11000000
- dc.b %11000001 ;; 01101 11000001
- dc.b %11000100 ;; 01110 11000100
- dc.b %11000101 ;; 01111 11000101
- dc.b %00000000 ;; 10000 00000000
- dc.b %00000001 ;; 10001 00000001
- dc.b %00000100 ;; 10010 00000100
- dc.b %00000101 ;; 10011 00000101
- dc.b %01000000 ;; 10100 01000000
- dc.b %01000001 ;; 10101 01000001
- dc.b %01000100 ;; 10110 01000100
- dc.b %01000101 ;; 10111 01000101
- dc.b %10000000 ;; 11000 10000000
- dc.b %10000001 ;; 11001 10000001
- dc.b %10000100 ;; 11010 10000100
- dc.b %10000101 ;; 11011 10000101
- dc.b %11000000 ;; 11100 11000000
- dc.b %11000001 ;; 11101 11000001
- dc.b %11000100 ;; 11110 11000100
- dc.b %11000101 ;; 11111 11000101
+ .byte %00000000 ;; 00000 00000000
+ .byte %00000001 ;; 00001 00000001
+ .byte %00000100 ;; 00010 00000100
+ .byte %00000101 ;; 00011 00000101
+ .byte %01000000 ;; 00100 01000000
+ .byte %01000001 ;; 00101 01000001
+ .byte %01000100 ;; 00110 01000100
+ .byte %01000101 ;; 00111 01000101
+ .byte %10000000 ;; 01000 10000000
+ .byte %10000001 ;; 01001 10000001
+ .byte %10000100 ;; 01010 10000100
+ .byte %10000101 ;; 01011 10000101
+ .byte %11000000 ;; 01100 11000000
+ .byte %11000001 ;; 01101 11000001
+ .byte %11000100 ;; 01110 11000100
+ .byte %11000101 ;; 01111 11000101
+ .byte %00000000 ;; 10000 00000000
+ .byte %00000001 ;; 10001 00000001
+ .byte %00000100 ;; 10010 00000100
+ .byte %00000101 ;; 10011 00000101
+ .byte %01000000 ;; 10100 01000000
+ .byte %01000001 ;; 10101 01000001
+ .byte %01000100 ;; 10110 01000100
+ .byte %01000101 ;; 10111 01000101
+ .byte %10000000 ;; 11000 10000000
+ .byte %10000001 ;; 11001 10000001
+ .byte %10000100 ;; 11010 10000100
+ .byte %10000101 ;; 11011 10000101
+ .byte %11000000 ;; 11100 11000000
+ .byte %11000001 ;; 11101 11000001
+ .byte %11000100 ;; 11110 11000100
+ .byte %11000101 ;; 11111 11000101
;; 256-byte LUT for the Parity bit.
;; Keep this last so all storage references require only one
@@ -286,22 +292,22 @@ lut_ccr:
;;
;; This table taken from another z80 emulator
lut_parity:
- dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
- dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
- dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
- dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
- dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
- dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
- dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
- dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
- dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
- dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
- dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
- dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
- dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
- dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
- dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
- dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
+ .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
+ .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
+ .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
+ .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
+ .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
+ .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
+ .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
+ .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
+ .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
+ .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
+ .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
+ .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
+ .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
+ .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
+ .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0
+ .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4
;; To save space I might be able to overlay the Parity table
;; with the CCR table, or even interleave it in the opcodes.
diff --git a/interrupts.asm.m4 b/interrupts.s.m4
index 7b4e522..66b71d8 100644
--- a/interrupts.asm.m4
+++ b/interrupts.s.m4
@@ -1,5 +1,6 @@
;;; interrupt handling code, in -*- asm -*-
+.data
;; Current interrupt mode. IM 1 and friends will modify
;; this. It can be any of 0, 1, 2.
int_mode: dc.b 0
@@ -29,6 +30,7 @@ int0_opcode: dc.b 0
int0_return: dc.w 0 ; the destination address
+.text
;; This is the interrupt routine. It can come at any point
;; during an instruction, though routines that use a5 (e.g. by
;; calling C subroutines) will have to turn off or hold
diff --git a/main.asm b/main.asm
deleted file mode 100644
index 76b84fe..0000000
--- a/main.asm
+++ /dev/null
@@ -1,196 +0,0 @@
-;;; z80 emulator for 68k calculators
-
-;;; Astrid Smith
-;;; Project started: 2010-06-06
-;;; GPL
-
-;;; Yes, I use lots of big ascii art. With this much code, you need
-;;; something to catch your eye when scrolling through it. I suppose
-;;; I'll split it into different files later.
-
-;;; Registers used:
-;;;
-;;; A7 68000 stack pointer
-;;; A6/epc emulated PC
-;;; A5 instruction table base pointer
-;;; A4 emulated SP
-;;; A3 pointer to flag_storage
-;;; A2
-;;; A1
-;;; A0
-;;;
-;;; D0 current instruction, scratch for macros
-;;; D1 scratch for instructions
-;;; D2 further scratch
-;;;
-;;;
-;;; The following have their shadows in the top half of the register
-;;; D3/eaf = AF A is in the low byte, F in the high byte (yeah ... speed)
-;;; D4/ebc = BC B high, C low
-;;; D5/ede = DE D high, E low
-;;; D6/ehl = HL H high, L low
-;;;
-;;; IY is used more often so it's easier to get at. It can be slow
-;;; but I don't really care to go to the effort to make it so.
-;;; D7/eixy = IX (hi word), IY (low word)
-
-
-;;; emulated I and R are both in RAM
-
- xdef _ti89
-; xdef _ti92plus
- xdef __main
-; xdef _tigcc_native
- include "../tios.h"
-
- include "global.inc"
-
-__main:
- movem.l d0-d7/a0-a6,-(sp)
- bsr init_load
- bsr display_setup
-
- bsr emu_setup
- lea emu_plain_op,a5
-
- ;; ... aaaaand we're off!
- jsr emu_run
- bsr emu_teardown
-
- bsr display_teardown
- bsr unload
- movem.l (sp)+,d0-d7/a0-a6
- rts
-
- include "ports.asm"
- include "interrupts.asm"
- include "flags.asm"
- include "alu.asm"
-
-emu_setup:
- movea.l emu_op_00,a5
- lea emu_run,a2
- lea flag_storage,a3
- move.w #$4000,d1
- bsr deref
- move.l a0,epc
- move.l a0,esp
-
- rts
-
-emu_teardown:
- rts
-
-
-;; ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-;; _ __ ___ ___ _ __ ___ ___ _ __ _ _ |||||||||||||||||||||||||||
-;; | '_ ` _ \ / _ \ '_ ` _ \ / _ \| '__| | | | \\\\\\\\\\\\\\\\\\\\\\\\\\\
-;; | | | | | | __/ | | | | | (_) | | | |_| | |||||||||||||||||||||||||||
-;; |_| |_| |_|\___|_| |_| |_|\___/|_| \__, | ///////////////////////////
-;; of the virtual type |___/ |||||||||||||||||||||||||||
-;; =============================================JJJJJJJJJJJJJJJJJJJJJJJJJJJ
-
- ;; Take a virtual address in d1 and dereference it. Returns the
- ;; host address in a0. Destroys a0, d0.
-deref: ; 76 cycles + 18 cycles for bsr
- ; 20 bytes to inline, saves 34 cycles per call
- move.w d1,d0
- andi.w #$3FFF,d0
- movea.w d0,a0
- move.w d1,d0
- andi.w #$C000,d0 ; Can cut this out by pre-masking the table.
- rol.w #4,d0
- adda.l deref_table(pc,d0.w),a0
- rts
-
- EVEN
-deref_table:
-mem_page_0: dc.l 0 ; bank 0 / 0x0000
-mem_page_1: dc.l 0 ; bank 1 / 0x4000
-mem_page_2: dc.l 0 ; bank 2 / 0x8000
-mem_page_3: dc.l 0 ; bank 3 / 0xc000
-
- xdef mem_page_0
- xdef mem_page_1
- xdef mem_page_2
- xdef mem_page_3
-
-mem_page_loc_0: dc.b 0
-mem_page_loc_1: dc.b 0
-mem_page_loc_2: dc.b 0
-mem_page_loc_3: dc.b 0
-
- xdef mem_page_loc_0
- xdef mem_page_loc_1
- xdef mem_page_loc_2
- xdef mem_page_loc_3
-
-pages: dc.l 0
-
- xdef pages
-
- ;; Take a physical address in a0 and turn it into a virtual
- ;; address in d0
- ;; Destroys d0
-; XXX AFAICS, a1 is currently a scratch address register, so you can load deref_table in it, and then save some space:
-; But you may wish to use it for other purposes in the future, so you needn't integrate that immediately.
-
- ;; Guessing this is 300 cycles.
-underef:
- move.l d2,-(a7)
- lea deref_table(pc),a1
- move.l a0,d0
- clr.w d2
- sub.l (a1)+,d0
- bmi.s underef_not0
- cmpi.l #$4000,d0
- bmi.s underef_thatsit
-underef_not0:
- move.l a0,d0
- move.w #$4000,d2
- sub.l (a1)+,d0
- bmi.s underef_not1
- cmpi.l #$4000,d0
- bmi.s underef_thatsit
-underef_not1:
- move.l a0,d0
- move.w #$8000,d2
- sub.l (a1)+,d0
- bmi.s underef_not2
- cmpi.l #$4000,d0
- bmi.s underef_thatsit
-underef_not2:
- move.w #$c000,d2
- suba.l (a1)+,a0
- ;; if that fails too, well shit man!
- moveq #0,d0
-underef_thatsit:
- add.w d2,d0
- move.l (a7)+,d2
- rts
-
-
-;; =========================================================================
-;; instruction instruction instruction ================================
-;; _ _ _ _ ================================
-;; __| (_)___ _ __ __ _| |_ ___| |__ ================================
-;; / _` | / __| '_ \ / _` | __/ __| '_ \ ================================
-;; | (_| | \__ \ |_) | (_| | || (__| | | | ================================
-;; \__,_|_|___/ .__/ \__,_|\__\___|_| |_| ================================
-;; |_| =================================
-;; ========== ========================================================
-;; =========================================================================
-
- include "opcodes.asm"
-
-emu_run:
- ;; XXX: make this actually return
- DONE
- rts
-
-emu_op_undo_cb:
-emu_op_undo_dd:
-emu_op_undo_ed:
-emu_op_undo_fd:
- rts
-
diff --git a/main.s b/main.s
new file mode 100644
index 0000000..a45950a
--- /dev/null
+++ b/main.s
@@ -0,0 +1,200 @@
+||| -*- mode: gas; gas-comment-char: 124 -*-
+||| z80 emulator for 68k calculators
+
+||| Astrid Smith
+||| Project started: 2010-06-06
+||| GPL
+
+||| Yes, I use lots of big ascii art. With this much code, you need
+||| something to catch your eye when scrolling through it. I suppose
+||| I'll split it into different files later.
+
+||| Registers used:
+|||
+||| A7 68000 stack pointer
+||| A6/epc emulated PC
+||| A5 instruction table base pointer
+||| A4 emulated SP
+||| A3 pointer to flag_storage
+||| A2
+||| A1
+||| A0
+|||
+||| D0 current instruction, scratch for macros
+||| D1 scratch for instructions
+||| D2 further scratch
+|||
+|||
+||| The following have their shadows in the top half of the register
+||| D3/eaf = AF A is in the low byte, F in the high byte (yeah ... speed)
+||| D4/ebc = BC B high, C low
+||| D5/ede = DE D high, E low
+||| D6/ehl = HL H high, L low
+|||
+||| IY is used more often so it's easier to get at. It can be slow
+||| but I don't really care to go to the effort to make it so.
+||| D7/eixy = IX (hi word), IY (low word)
+
+
+||| emulated I and R are both in RAM
+
+.xdef _ti89
+|.xdef _ti92plus
+.xdef __main
+|.xdef _tigcc_native
+.include "../tios.h"
+
+.include "global.inc"
+
+__main:
+ movem.l d0-d7/a0-a6,-(sp)
+ bsr init_load
+ bsr display_setup
+
+ bsr emu_setup
+ lea emu_plain_op,a5
+
+ || ... aaaaand we're off!
+ jsr emu_run
+ bsr emu_teardown
+
+ bsr display_teardown
+ bsr unload
+ movem.l (sp)+,d0-d7/a0-a6
+ rts
+
+.include "ports.s"
+.include "interrupts.s"
+.include "flags.s"
+.include "alu.s"
+
+emu_setup:
+ movea.l emu_op_00,a5
+ lea emu_run,a2
+ lea flag_storage,a3
+ move.w #$4000,d1
+ bsr deref
+ move.l a0,epc
+ move.l a0,esp
+
+ rts
+
+emu_teardown:
+ rts
+
+
+|| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+|| _ __ ___ ___ _ __ ___ ___ _ __ _ _ |||||||||||||||||||||||||||
+|| | '_ ` _ \ / _ \ '_ ` _ \ / _ \| '__| | | | \\\\\\\\\\\\\\\\\\\\\\\\\\\
+|| | | | | | | __/ | | | | | (_) | | | |_| | |||||||||||||||||||||||||||
+|| |_| |_| |_|\___|_| |_| |_|\___/|_| \__, | ///////////////////////////
+|| of the virtual type |___/ |||||||||||||||||||||||||||
+|| =============================================JJJJJJJJJJJJJJJJJJJJJJJJJJJ
+
+ || Take a virtual address in d1 and dereference it. Returns the
+ || host address in a0. Destroys a0, d0.
+deref: | 76 cycles + 18 cycles for bsr
+ | 20 bytes to inline, saves 34 cycles per call
+ move.w d1,d0
+ andi.w #$3FFF,d0
+ movea.w d0,a0
+ move.w d1,d0
+ andi.w #$C000,d0 | Can cut this out by pre-masking the table.
+ rol.w #4,d0
+ adda.l deref_table(pc,d0.w),a0
+ rts
+
+.even
+.data
+deref_table:
+mem_page_0: .long 0 | bank 0 / 0x0000
+mem_page_1: .long 0 | bank 1 / 0x4000
+mem_page_2: .long 0 | bank 2 / 0x8000
+mem_page_3: .long 0 | bank 3 / 0xc000
+
+.xdef mem_page_0
+.xdef mem_page_1
+.xdef mem_page_2
+.xdef mem_page_3
+
+mem_page_loc_0: .byte 0
+mem_page_loc_1: .byte 0
+mem_page_loc_2: .byte 0
+mem_page_loc_3: .byte 0
+
+.xdef mem_page_loc_0
+.xdef mem_page_loc_1
+.xdef mem_page_loc_2
+.xdef mem_page_loc_3
+
+pages: .long 0
+
+.xdef pages
+
+.text
+
+ || Take a physical address in a0 and turn it into a virtual
+ || address in d0
+ || Destroys d0
+| XXX AFAICS, a1 is currently a scratch address register, so you can load deref_table in it, and then save some space:
+| But you may wish to use it for other purposes in the future, so you needn't integrate that immediately.
+
+ || Guessing this is 300 cycles.
+underef:
+ move.l d2,-(a7)
+ lea deref_table(pc),a1
+ move.l a0,d0
+ clr.w d2
+ sub.l (a1)+,d0
+ bmi.s underef_not0
+ cmpi.l #$4000,d0
+ bmi.s underef_thatsit
+underef_not0:
+ move.l a0,d0
+ move.w #$4000,d2
+ sub.l (a1)+,d0
+ bmi.s underef_not1
+ cmpi.l #$4000,d0
+ bmi.s underef_thatsit
+underef_not1:
+ move.l a0,d0
+ move.w #$8000,d2
+ sub.l (a1)+,d0
+ bmi.s underef_not2
+ cmpi.l #$4000,d0
+ bmi.s underef_thatsit
+underef_not2:
+ move.w #$c000,d2
+ suba.l (a1)+,a0
+ || if that fails too, well shit man!
+ moveq #0,d0
+underef_thatsit:
+ add.w d2,d0
+ move.l (a7)+,d2
+ rts
+
+
+|| =========================================================================
+|| instruction instruction instruction ================================
+|| _ _ _ _ ================================
+|| __| (_)___ _ __ __ _| |_ ___| |__ ================================
+|| / _` | / __| '_ \ / _` | __/ __| '_ \ ================================
+|| | (_| | \__ \ |_) | (_| | || (__| | | | ================================
+|| \__,_|_|___/ .__/ \__,_|\__\___|_| |_| ================================
+|| |_| =================================
+|| ========== ========================================================
+|| =========================================================================
+
+.include "opcodes.s"
+
+emu_run:
+ || XXX: make this actually return
+ DONE
+ rts
+
+emu_op_undo_cb:
+emu_op_undo_dd:
+emu_op_undo_ed:
+emu_op_undo_fd:
+ rts
+
diff --git a/opcodes.asm.m4 b/opcodes.s.m4
index c88f728..522b539 100644
--- a/opcodes.asm.m4
+++ b/opcodes.s.m4
@@ -13,120 +13,120 @@
;; == Memory Macros ================================================
- ;; Macro to read a byte from main memory at register \1. Puts
- ;; the byte read in \2.
-FETCHB MACRO ; 106 cycles, 8 bytes
- move.w \1,d1
+ ;; Macro to read a byte from main memory at register \addr. Puts
+ ;; the byte read in \dest.
+.macro FETCHB src dest ; 106 cycles, 8 bytes
+ move.w \addr,d1
jsr deref
- move.b (a0),\2
- ENDM
+ move.b (a0),\dest
+.endm
- ;; Macro to write a byte in \1 to main memory at \2
-PUTB MACRO ; 106 cycles, 8 bytes
- move.w \2,d1
+ ;; Macro to write a byte in \val to main memory at \addr
+.macro PUTB val addr ; 106 cycles, 8 bytes
+ move.w \addr,d1
jsr deref
- move.b \1,(a0)
- ENDM
+ move.b \val,(a0)
+.endm
- ;; Macro to read a word from main memory at register \1
- ;; (unaligned). Puts the word read in \2.
-FETCHW MACRO ; 140 cycles, 16 bytes
- move.w \1,d1
+ ;; Macro to read a word from main memory at register \addr
+ ;; (unaligned). Puts the word read in \dest.
+.macro FETCHW addr dest ; 140 cycles, 16 bytes
+ move.w \addr,d1
jsr deref
;; XXX SPEED
move.b (a0)+,d2
- move.b (a0),\2
- rol.w #8,\2
- move.b d2,\2
- ENDM
-
- ;; Macro to write a word in \1 to main memory at \2 (regs only)
-PUTW MACRO ; 140 cycles, 14 bytes
- move.w \2,d1
+ move.b (a0),\dest
+ rol.w #8,\dest
+ move.b d2,\dest
+.endm
+
+ ;; Macro to write a word in \val to main memory at \addr (regs only)
+.macro PUTW val addr ; 140 cycles, 14 bytes
+ move.w \addr,d1
jsr deref
- move.w \1,d0
+ move.w \val,d0
move.b d0,(a0)+
LOHI d0
move.b d0,(a0)
- ENDM
+.endm
- ;; Push the word in \1 (register) using stack register esp.
+ ;; Push the word in \val (register) using stack register esp.
;; Sadly, I can't trust the stack register to be aligned.
;; Destroys d2.
;; (SP-2) <- \1_l
;; (SP-1) <- \1_h
;; SP <- SP - 2
-PUSHW MACRO ; 42 cycles, 8 bytes
- move.w \1,d2
+.macro PUSHW val ; 42 cycles, 8 bytes
+ move.w \val,d2
LOHI d2 ;slow
move.b d2,-(esp) ; high byte
- move.b \1,-(esp) ; low byte
- ENDM
+ move.b \val,-(esp) ; low byte
+.endm
- ;; Pop the word at the top of stack esp into \1.
+ ;; Pop the word at the top of stack esp into \dest.
;; Destroys d0.
;; \1_h <- (SP+1)
;; \1_l <- (SP)
;; SP <- SP + 2
-POPW MACRO ; 60 cycles, 8 bytes
- move.b (esp)+,\1
- LOHI \1
- move.b (esp)+,\1 ; high byte
- HILO \1
- ENDM
+.macro POPW dest ; 60 cycles, 8 bytes
+ move.b (esp)+,\dest
+ LOHI \dest
+ move.b (esp)+,\dest ; high byte
+ HILO \dest
+.endm
;; == Immediate Memory Macros ==
- ;; Macro to read an immediate byte into \1.
-FETCHBI MACRO ; 8 cycles, 2 bytes
- move.b (epc)+,\1
- ENDM
+ ;; Macro to read an immediate byte into \dest.
+.macro FETCHBI dest ; 8 cycles, 2 bytes
+ move.b (epc)+,\dest
+.endm
- ;; Macro to read an immediate word (unaligned) into \1.
-FETCHWI MACRO ; 42 cycles, 8 bytes
+ ;; Macro to read an immediate word (unaligned) into \dest.
+.macro FETCHWI dest ; 42 cycles, 8 bytes
;; XXX SPEED
move.b (epc)+,d2
- move.b (epc)+,\1
- rol.w #8,\1
- move.b d2,\1
- ENDM
+ move.b (epc)+,\dest
+ rol.w #8,\dest
+ move.b d2,\dest
+.endm
;; == Common Opcode Macros =========================================
;; To align opcode routines.
-_align SET 0
+.set _align,0
-START MACRO
- ORG emu_plain_op+_align
-_align SET _align+$100 ; opcode routine length
+.macro start
+ .org emu_plain_op+_align
+.set _align,_align+$100 ; opcode routine length
jmp do_interrupt ; for interrupt routines
- ENDM
+.endm
-START_DD MACRO
- ORG emu_plain_op+_align+$40
- ENDM
+.macro START_DD
+ .org emu_plain_op+_align+$40
+.endm
-START_CB MACRO
- ORG emu_plain_op+_align+$42
- ENDM
+.macro START_CB
+ .org emu_plain_op+_align+$42
+.endm
-START_DDCB MACRO
- ORG emu_plain_op+_align+$44
- ENDM
+.macro START_DDCB
+ .org emu_plain_op+_align+$44
+.endm
-START_FD MACRO
- ORG emu_plain_op+_align+$46
- ENDM
+.macro START_FD
+ .org emu_plain_op+_align+$46
+.endm
-START_FDCB MACRO
- ORG emu_plain_op+_align+$48
- ENDM
+.macro START_FDCB
+ .org emu_plain_op+_align+$48
+.endm
-START_ED MACRO
- ORG emu_plain_op+_align+$4A
- ENDM
+.macro START_ED
+ .org emu_plain_op+_align+$4A
+.endm
;; LOHI/HILO are hideously slow for instructions used often.
;; Consider interleaving registers instead:
@@ -137,60 +137,60 @@ START_ED MACRO
;; 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
- ENDM
+.macro LOHI reg ; 22 cycles, 2 bytes
+ ror.w #8,\reg
+.endm
;; Then do your shit and finish with this
-HILO MACRO ; 22 cycles, 2 bytes
- rol.w #8,\1
- ENDM
+.macro HILO reg ; 22 cycles, 2 bytes
+ rol.w #8,\reg
+.endm
;; Rearrange a register: ABCD -> ACBD.
-WORD MACRO ; 52 cycles, 14 bytes
- move.l \1,-(sp)
- movep.w 0(sp),\1
- swap \1
- movep.w 1(sp),\1
+.macro WORD reg ; 52 cycles, 14 bytes
+ move.l \reg,-(sp)
+ movep.w 0(sp),\reg
+ swap \reg
+ movep.w 1(sp),\reg
addq #4,sp
- ENDM
+.endm
;; == Special Opcode Macros ========================================
;; Do an ADD \1,\2
-F_ADD_W MACRO ; ? cycles, ? bytes
+.macro F_ADD_W ; ? cycles, ? bytes
;; XXX
- ENDM
+.endm
;; Do an SUB \1,\2
-F_SUB_W MACRO ; ? cycles, ? bytes
+.macro F_SUB_W ; ? cycles, ? bytes
;; XXX
- ENDM
+.endm
;; INC and DEC macros
-F_INC_B MACRO ; 108 cycles, 34 bytes
+.macro F_INC_B reg ; 108 cycles, 34 bytes
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
+ move.b \reg,f_tmp_dst_b-flag_storage(a3)
+ addq #1,\reg
moveq #2,d0
F_CLEAR d0
F_OVFL
- ENDM
+.endm
-F_DEC_B MACRO ; 80 cycles, 26 bytes
+.macro F_DEC_B reg ; 80 cycles, 26 bytes
move.b #1,f_tmp_byte-flag_storage(a3)
st f_tmp_src_b-flag_storage(a3) ;; why did I do this?
- move.b \1,f_tmp_dst_b-flag_storage(a3)
- subq #1,\1
+ move.b \reg,f_tmp_dst_b-flag_storage(a3)
+ subq #1,\reg
F_SET #2
- ENDM
+.endm
-F_INC_W MACRO ; 4 cycles, 2 bytes
- addq.w #1,\1
+.macro F_INC_W regpr ; 4 cycles, 2 bytes
+ addq.w #1,\regpr
ENDM
-F_DEC_W MACRO ; 4 cycles, 2 bytes
- subq.w #1,\1
+.macro F_DEC_W regpr ; 4 cycles, 2 bytes
+ subq.w #1,\regpr
ENDM
;; I might be able to unify rotation flags or maybe use a
@@ -207,20 +207,20 @@ done:
;; overhead: 42 cycles /10 bytes
-DONE MACRO
+.macro DONE
clr.w d0 ; 4 cycles / 2 bytes
move.b (epc)+,d0 ; 8 cycles / 2 bytes
move.b d0,$4c00+32*(128/8)
rol.w #6,d0 ;18 cycles / 2 bytes
jmp 0(a5,d0.w) ;14 cycles / 4 bytes
- ENDM
+.endm
;; Timing correction for more precise emulation
;;
;; \1 is number of tstates the current instruction should take
;; \2 is number of cycles taken already
-TIME MACRO
- ENDM
+.macro TIME
+.endm
CNOP 0,32
@@ -2342,11 +2342,11 @@ OP_ED(7f,«»)
;; Do an ADD \2,\1
-F_ADD_B MACRO ; 14 bytes?
- move.b \2,d1
- move.b \1,d0
+.macro F_ADD_B src dest ; 14 bytes?
+ move.b \dest,d1
+ move.b \src,d0
jsr alu_add
- move.b d1,\2
+ move.b d1,\dest
ENDM
;; ADD A,B
@@ -2465,11 +2465,11 @@ OP_ED(87,«»)
;; Do an ADC \2,\1
-F_ADC_B MACRO ; S34
- move.b \2,d1
- move.b \1,d0
+.macro F_ADC_B src dest ; S34
+ move.b \dest,d1
+ move.b \src,d0
jsr alu_adc
- move.b d1,\2
+ move.b d1,\dest
ENDM
;; ADC A,B
@@ -2592,11 +2592,11 @@ OP_ED(8f,«»)
;; Do a SUB \2,\1
-F_SUB_B MACRO
- move.b \2,d1
- move.b \1,d0
+.macro F_SUB_B src dest
+ move.b \dest,d1
+ move.b \src,d0
jsr alu_sub
- move.b d1,\2
+ move.b d1,\dest
ENDM
;; SUB A,B
@@ -2714,12 +2714,12 @@ OP_ED(97,«»)
;; Do a SBC \2,\1
-F_SBC_B MACRO
- move.b \2,d1
- move.b \1,d0
+.macro F_SBC_B src dest
+ move.b \dest,d1
+ move.b \src,d0
jsr alu_sbc
- move.b d1,\2
- ENDM
+ move.b d1,\dest
+.endm
;; SBC A,B
OPCODE(98,«
@@ -2830,12 +2830,12 @@ OPCODE(9f,«
-F_AND_B MACRO
- move.b \2,d1
- move.b \1,d0
+.macro F_AND_B src dest
+ move.b \dest,d1
+ move.b \src,d0
jsr alu_and
- move.b d1,\2
- ENDM
+ move.b d1,\dest
+.endm
OP_DD(9f,«»)
OP_CB(9f,«»)
@@ -2953,11 +2953,11 @@ OPCODE(a7,«
-F_XOR_B MACRO
- move.b \2,d1
- move.b \1,d0
+.macro F_XOR_B src dest
+ move.b \dest,d1
+ move.b \src,d0
jsr alu_xor
- move.b d1,\2
+ move.b d1,\dest
ENDM
OP_DD(a7,«»)
@@ -3077,12 +3077,12 @@ OPCODE(af,«
-F_OR_B MACRO
- move.b \2,d1
- move.b \1,d0
+.macro F_OR_B src dest
+ move.b \dest,d1
+ move.b \src,d0
jsr alu_or
- move.b d1,\2
- ENDM
+ move.b d1,\dest
+.endm
OP_DD(af,«»)
OP_CB(af,«»)
@@ -3202,13 +3202,13 @@ OP_ED(b6,«»)
;; COMPARE instruction
;; Tests the argument against A
-F_CP_B MACRO
+.macro F_CP_B src dest
;; XXX deal with \2 or \1 being d1 or d0
- move.b \2,d1
- move.b \1,d0
+ move.b \dest,d1
+ move.b \src,d0
jsr alu_cp
;; no result to save
- ENDM
+.endm
OP_DD(b7,«»)
OP_CB(b7,«»)
diff --git a/ports.asm b/ports.asm
deleted file mode 100644
index 1a6b47e..0000000
--- a/ports.asm
+++ /dev/null
@@ -1,1188 +0,0 @@
- ;; Routines to process OUT and IN instructions. This is the
- ;; bit that's unique to TI calculators.
-
- ;; Port is in d0, byte is in d1
- ;; Destroys a0
-port_in:
- andi.w #$ff,d0
- add.w d0,d0
- add.w d0,d0
- movea.l lut_ports_in(pc,d0),a0
- jmp (a0)
- rts
-
-lut_ports_in:
- dc.l port_in_00
- dc.l port_in_01
- dc.l port_in_02
- dc.l port_in_03
- dc.l port_in_04
- dc.l port_in_05
- dc.l port_in_06
- dc.l port_in_07
- dc.l port_in_08
- dc.l port_in_09
- dc.l port_in_0a
- dc.l port_in_0b
- dc.l port_in_0c
- dc.l port_in_0d
- dc.l port_in_0e
- dc.l port_in_0f
- dc.l port_in_10
- dc.l port_in_11
- dc.l port_in_12
- dc.l port_in_13
- dc.l port_in_14
- dc.l port_in_15
- dc.l port_in_16
- dc.l port_in_17
- dc.l port_in_18
- dc.l port_in_19
- dc.l port_in_1a
- dc.l port_in_1b
- dc.l port_in_1c
- dc.l port_in_1d
- dc.l port_in_1e
- dc.l port_in_1f
- dc.l port_in_20
- dc.l port_in_21
- dc.l port_in_22
- dc.l port_in_23
- dc.l port_in_24
- dc.l port_in_25
- dc.l port_in_26
- dc.l port_in_27
- dc.l port_in_28
- dc.l port_in_29
- dc.l port_in_2a
- dc.l port_in_2b
- dc.l port_in_2c
- dc.l port_in_2d
- dc.l port_in_2e
- dc.l port_in_2f
- dc.l port_in_30
- dc.l port_in_31
- dc.l port_in_32
- dc.l port_in_33
- dc.l port_in_34
- dc.l port_in_35
- dc.l port_in_36
- dc.l port_in_37
- dc.l port_in_38
- dc.l port_in_39
- dc.l port_in_3a
- dc.l port_in_3b
- dc.l port_in_3c
- dc.l port_in_3d
- dc.l port_in_3e
- dc.l port_in_3f
- dc.l port_in_40
- dc.l port_in_41
- dc.l port_in_42
- dc.l port_in_43
- dc.l port_in_44
- dc.l port_in_45
- dc.l port_in_46
- dc.l port_in_47
- dc.l port_in_48
- dc.l port_in_49
- dc.l port_in_4a
- dc.l port_in_4b
- dc.l port_in_4c
- dc.l port_in_4d
- dc.l port_in_4e
- dc.l port_in_4f
- dc.l port_in_50
- dc.l port_in_51
- dc.l port_in_52
- dc.l port_in_53
- dc.l port_in_54
- dc.l port_in_55
- dc.l port_in_56
- dc.l port_in_57
- dc.l port_in_58
- dc.l port_in_59
- dc.l port_in_5a
- dc.l port_in_5b
- dc.l port_in_5c
- dc.l port_in_5d
- dc.l port_in_5e
- dc.l port_in_5f
- dc.l port_in_60
- dc.l port_in_61
- dc.l port_in_62
- dc.l port_in_63
- dc.l port_in_64
- dc.l port_in_65
- dc.l port_in_66
- dc.l port_in_67
- dc.l port_in_68
- dc.l port_in_69
- dc.l port_in_6a
- dc.l port_in_6b
- dc.l port_in_6c
- dc.l port_in_6d
- dc.l port_in_6e
- dc.l port_in_6f
- dc.l port_in_70
- dc.l port_in_71
- dc.l port_in_72
- dc.l port_in_73
- dc.l port_in_74
- dc.l port_in_75
- dc.l port_in_76
- dc.l port_in_77
- dc.l port_in_78
- dc.l port_in_79
- dc.l port_in_7a
- dc.l port_in_7b
- dc.l port_in_7c
- dc.l port_in_7d
- dc.l port_in_7e
- dc.l port_in_7f
- dc.l port_in_80
- dc.l port_in_81
- dc.l port_in_82
- dc.l port_in_83
- dc.l port_in_84
- dc.l port_in_85
- dc.l port_in_86
- dc.l port_in_87
- dc.l port_in_88
- dc.l port_in_89
- dc.l port_in_8a
- dc.l port_in_8b
- dc.l port_in_8c
- dc.l port_in_8d
- dc.l port_in_8e
- dc.l port_in_8f
- dc.l port_in_90
- dc.l port_in_91
- dc.l port_in_92
- dc.l port_in_93
- dc.l port_in_94
- dc.l port_in_95
- dc.l port_in_96
- dc.l port_in_97
- dc.l port_in_98
- dc.l port_in_99
- dc.l port_in_9a
- dc.l port_in_9b
- dc.l port_in_9c
- dc.l port_in_9d
- dc.l port_in_9e
- dc.l port_in_9f
- dc.l port_in_a0
- dc.l port_in_a1
- dc.l port_in_a2
- dc.l port_in_a3
- dc.l port_in_a4
- dc.l port_in_a5
- dc.l port_in_a6
- dc.l port_in_a7
- dc.l port_in_a8
- dc.l port_in_a9
- dc.l port_in_aa
- dc.l port_in_ab
- dc.l port_in_ac
- dc.l port_in_ad
- dc.l port_in_ae
- dc.l port_in_af
- dc.l port_in_b0
- dc.l port_in_b1
- dc.l port_in_b2
- dc.l port_in_b3
- dc.l port_in_b4
- dc.l port_in_b5
- dc.l port_in_b6
- dc.l port_in_b7
- dc.l port_in_b8
- dc.l port_in_b9
- dc.l port_in_ba
- dc.l port_in_bb
- dc.l port_in_bc
- dc.l port_in_bd
- dc.l port_in_be
- dc.l port_in_bf
- dc.l port_in_c0
- dc.l port_in_c1
- dc.l port_in_c2
- dc.l port_in_c3
- dc.l port_in_c4
- dc.l port_in_c5
- dc.l port_in_c6
- dc.l port_in_c7
- dc.l port_in_c8
- dc.l port_in_c9
- dc.l port_in_ca
- dc.l port_in_cb
- dc.l port_in_cc
- dc.l port_in_cd
- dc.l port_in_ce
- dc.l port_in_cf
- dc.l port_in_d0
- dc.l port_in_d1
- dc.l port_in_d2
- dc.l port_in_d3
- dc.l port_in_d4
- dc.l port_in_d5
- dc.l port_in_d6
- dc.l port_in_d7
- dc.l port_in_d8
- dc.l port_in_d9
- dc.l port_in_da
- dc.l port_in_db
- dc.l port_in_dc
- dc.l port_in_dd
- dc.l port_in_de
- dc.l port_in_df
- dc.l port_in_e0
- dc.l port_in_e1
- dc.l port_in_e2
- dc.l port_in_e3
- dc.l port_in_e4
- dc.l port_in_e5
- dc.l port_in_e6
- dc.l port_in_e7
- dc.l port_in_e8
- dc.l port_in_e9
- dc.l port_in_ea
- dc.l port_in_eb
- dc.l port_in_ec
- dc.l port_in_ed
- dc.l port_in_ee
- dc.l port_in_ef
- dc.l port_in_f0
- dc.l port_in_f1
- dc.l port_in_f2
- dc.l port_in_f3
- dc.l port_in_f4
- dc.l port_in_f5
- dc.l port_in_f6
- dc.l port_in_f7
- dc.l port_in_f8
- dc.l port_in_f9
- dc.l port_in_fa
- dc.l port_in_fb
- dc.l port_in_fc
- dc.l port_in_fd
- dc.l port_in_fe
- dc.l port_in_ff
-
-port_out:
- andi.w #$ff,d0
- ;; This is the fastest way to shift left 2 bits. :S
- add.w d0,d0
- add.w d0,d0
- movea.l lut_ports_out(pc,d0.w),a0
- jmp (a0)
-
-lut_ports_out:
- dc.l port_out_00
- dc.l port_out_01
- dc.l port_out_02
- dc.l port_out_03
- dc.l port_out_04
- dc.l port_out_05
- dc.l port_out_06
- dc.l port_out_07
- dc.l port_out_08
- dc.l port_out_09
- dc.l port_out_0a
- dc.l port_out_0b
- dc.l port_out_0c
- dc.l port_out_0d
- dc.l port_out_0e
- dc.l port_out_0f
- dc.l port_out_10
- dc.l port_out_11
- dc.l port_out_12
- dc.l port_out_13
- dc.l port_out_14
- dc.l port_out_15
- dc.l port_out_16
- dc.l port_out_17
- dc.l port_out_18
- dc.l port_out_19
- dc.l port_out_1a
- dc.l port_out_1b
- dc.l port_out_1c
- dc.l port_out_1d
- dc.l port_out_1e
- dc.l port_out_1f
- dc.l port_out_20
- dc.l port_out_21
- dc.l port_out_22
- dc.l port_out_23
- dc.l port_out_24
- dc.l port_out_25
- dc.l port_out_26
- dc.l port_out_27
- dc.l port_out_28
- dc.l port_out_29
- dc.l port_out_2a
- dc.l port_out_2b
- dc.l port_out_2c
- dc.l port_out_2d
- dc.l port_out_2e
- dc.l port_out_2f
- dc.l port_out_30
- dc.l port_out_31
- dc.l port_out_32
- dc.l port_out_33
- dc.l port_out_34
- dc.l port_out_35
- dc.l port_out_36
- dc.l port_out_37
- dc.l port_out_38
- dc.l port_out_39
- dc.l port_out_3a
- dc.l port_out_3b
- dc.l port_out_3c
- dc.l port_out_3d
- dc.l port_out_3e
- dc.l port_out_3f
- dc.l port_out_40
- dc.l port_out_41
- dc.l port_out_42
- dc.l port_out_43
- dc.l port_out_44
- dc.l port_out_45
- dc.l port_out_46
- dc.l port_out_47
- dc.l port_out_48
- dc.l port_out_49
- dc.l port_out_4a
- dc.l port_out_4b
- dc.l port_out_4c
- dc.l port_out_4d
- dc.l port_out_4e
- dc.l port_out_4f
- dc.l port_out_50
- dc.l port_out_51
- dc.l port_out_52
- dc.l port_out_53
- dc.l port_out_54
- dc.l port_out_55
- dc.l port_out_56
- dc.l port_out_57
- dc.l port_out_58
- dc.l port_out_59
- dc.l port_out_5a
- dc.l port_out_5b
- dc.l port_out_5c
- dc.l port_out_5d
- dc.l port_out_5e
- dc.l port_out_5f
- dc.l port_out_60
- dc.l port_out_61
- dc.l port_out_62
- dc.l port_out_63
- dc.l port_out_64
- dc.l port_out_65
- dc.l port_out_66
- dc.l port_out_67
- dc.l port_out_68
- dc.l port_out_69
- dc.l port_out_6a
- dc.l port_out_6b
- dc.l port_out_6c
- dc.l port_out_6d
- dc.l port_out_6e
- dc.l port_out_6f
- dc.l port_out_70
- dc.l port_out_71
- dc.l port_out_72
- dc.l port_out_73
- dc.l port_out_74
- dc.l port_out_75
- dc.l port_out_76
- dc.l port_out_77
- dc.l port_out_78
- dc.l port_out_79
- dc.l port_out_7a
- dc.l port_out_7b
- dc.l port_out_7c
- dc.l port_out_7d
- dc.l port_out_7e
- dc.l port_out_7f
- dc.l port_out_80
- dc.l port_out_81
- dc.l port_out_82
- dc.l port_out_83
- dc.l port_out_84
- dc.l port_out_85
- dc.l port_out_86
- dc.l port_out_87
- dc.l port_out_88
- dc.l port_out_89
- dc.l port_out_8a
- dc.l port_out_8b
- dc.l port_out_8c
- dc.l port_out_8d
- dc.l port_out_8e
- dc.l port_out_8f
- dc.l port_out_90
- dc.l port_out_91
- dc.l port_out_92
- dc.l port_out_93
- dc.l port_out_94
- dc.l port_out_95
- dc.l port_out_96
- dc.l port_out_97
- dc.l port_out_98
- dc.l port_out_99
- dc.l port_out_9a
- dc.l port_out_9b
- dc.l port_out_9c
- dc.l port_out_9d
- dc.l port_out_9e
- dc.l port_out_9f
- dc.l port_out_a0
- dc.l port_out_a1
- dc.l port_out_a2
- dc.l port_out_a3
- dc.l port_out_a4
- dc.l port_out_a5
- dc.l port_out_a6
- dc.l port_out_a7
- dc.l port_out_a8
- dc.l port_out_a9
- dc.l port_out_aa
- dc.l port_out_ab
- dc.l port_out_ac
- dc.l port_out_ad
- dc.l port_out_ae
- dc.l port_out_af
- dc.l port_out_b0
- dc.l port_out_b1
- dc.l port_out_b2
- dc.l port_out_b3
- dc.l port_out_b4
- dc.l port_out_b5
- dc.l port_out_b6
- dc.l port_out_b7
- dc.l port_out_b8
- dc.l port_out_b9
- dc.l port_out_ba
- dc.l port_out_bb
- dc.l port_out_bc
- dc.l port_out_bd
- dc.l port_out_be
- dc.l port_out_bf
- dc.l port_out_c0
- dc.l port_out_c1
- dc.l port_out_c2
- dc.l port_out_c3
- dc.l port_out_c4
- dc.l port_out_c5
- dc.l port_out_c6
- dc.l port_out_c7
- dc.l port_out_c8
- dc.l port_out_c9
- dc.l port_out_ca
- dc.l port_out_cb
- dc.l port_out_cc
- dc.l port_out_cd
- dc.l port_out_ce
- dc.l port_out_cf
- dc.l port_out_d0
- dc.l port_out_d1
- dc.l port_out_d2
- dc.l port_out_d3
- dc.l port_out_d4
- dc.l port_out_d5
- dc.l port_out_d6
- dc.l port_out_d7
- dc.l port_out_d8
- dc.l port_out_d9
- dc.l port_out_da
- dc.l port_out_db
- dc.l port_out_dc
- dc.l port_out_dd
- dc.l port_out_de
- dc.l port_out_df
- dc.l port_out_e0
- dc.l port_out_e1
- dc.l port_out_e2
- dc.l port_out_e3
- dc.l port_out_e4
- dc.l port_out_e5
- dc.l port_out_e6
- dc.l port_out_e7
- dc.l port_out_e8
- dc.l port_out_e9
- dc.l port_out_ea
- dc.l port_out_eb
- dc.l port_out_ec
- dc.l port_out_ed
- dc.l port_out_ee
- dc.l port_out_ef
- dc.l port_out_f0
- dc.l port_out_f1
- dc.l port_out_f2
- dc.l port_out_f3
- dc.l port_out_f4
- dc.l port_out_f5
- dc.l port_out_f6
- dc.l port_out_f7
- dc.l port_out_f8
- dc.l port_out_f9
- dc.l port_out_fa
- dc.l port_out_fb
- dc.l port_out_fc
- dc.l port_out_fd
- dc.l port_out_fe
- dc.l port_out_ff
-
-port_in_00:
-port_out_00:
- ;; Temporary test harness. Writing to this port writes a
- ;; character to the screen.
- SAVEREG
- andi.w #$ff,d1
- move.w d1,-(sp)
- jsr char_draw
- addq #2,sp
- RESTREG
- rts
-
-port_in_01:
-port_out_01:
-port_in_02:
-port_out_02:
-port_in_03:
-port_out_03:
-port_in_04:
-port_out_04:
- ;; Bank B paging, among other things
- SAVEREG
- move.b d1,-(a7)
- jsr bankswap_b_write
- addq #2,a7
- RESTREG
- rts
-
-port_in_05:
-port_out_05:
-port_in_06:
-port_out_06:
- ;; Bank A paging
- SAVEREG
- move.b d1,-(a7)
- jsr bankswap_a_write
- addq #2,a7
- RESTREG
- rts
-
-port_in_07:
-port_out_07:
-port_in_08:
-port_out_08:
-port_in_09:
-port_out_09:
-port_in_0a:
-port_out_0a:
-port_in_0b:
-port_out_0b:
-port_in_0c:
-port_out_0c:
-port_in_0d:
-port_out_0d:
-port_in_0e:
-port_out_0e:
-port_in_0f:
-port_out_0f:
-port_in_10:
- xref video_row
- xref video_increment
- xref video_enabled
- xref video_6bit
- xref video_busy
- xref video_cur_row
- xref video_cur_col
- xref video_write
- xref video_read
-
- ;; LCD status
- clr.b d1
- or.b video_increment,d1
- or.b video_row,d1
- or.b video_enabled,d1
- or.b video_6bit,d1
- or.b video_busy,d1
- rts
-
-port_out_10:
- ;; LCD command
- tst.b d1
- beq port_out_10_00
- subq.b #1,d1
- beq port_out_10_01
- subq.b #1,d1
- beq port_out_10_02
- subq.b #1,d1
- beq port_out_10_03
- subq.b #1,d1
- beq port_out_10_04
- subq.b #1,d1
- beq port_out_10_05
- subq.b #1,d1
- beq port_out_10_06
- subq.b #1,d1
- beq port_out_10_07
- addq.b #7,d1
- cmpi.b #$0b,d1 ; power supply enhancement
- ble port_out_10_undef
- cmpi.b #$13,d1 ; power supply level
- ble port_out_10_undef
- cmpi.b #$17,d1 ; undefined
- ble port_out_10_undef
- cmpi.b #$18,d1 ; cancel test mode
- beq port_out_10_undef
- cmpi.b #$1b,d1 ; undefined
- beq port_out_10_undef
- cmpi.b #$1f,d1 ; enter test mode
- ble port_out_10_undef
- cmpi.b #$3f,d1 ; set column
- ble port_out_10_set_col
- cmpi.b #$7f,d1 ; z-addressing
- ble port_out_10_undef ; XXX?
- cmpi.b #$df,d1 ; set row
- ble port_out_10_set_row
- ;; fallthrough: set contrast (unimplemented)
- rts
- ;; ...
-port_out_10_00: ; 6-bit mode
- move.b #$00,video_6bit
- rts
-port_out_10_01: ; 8-bit mode
- move.b #$40,video_6bit
- rts
-port_out_10_02: ; screen off
- move.b #$20,video_enabled
- rts
-port_out_10_03: ; screen on
- move.b #$00,video_enabled
- rts
-port_out_10_04: ; x--
- move.b #$01,video_row
- move.b #$00,video_increment
- rts
-port_out_10_05: ; x++
- move.b #$01,video_row
- move.b #$02,video_increment
- rts
-port_out_10_06: ; y--
- move.b #$00,video_row
- move.b #$00,video_increment
- rts
-port_out_10_07: ; y++
- move.b #$00,video_row
- move.b #$02,video_increment
- rts
-port_out_10_undef:
- rts
-port_out_10_set_col:
- sub.b #$20,d1
- move.b d1,video_cur_col
- rts
-port_out_10_set_row:
- sub.b #$80,d1
- move.b d1,video_cur_row
- rts
-
-
-port_in_11:
- ;; LCD data
- SAVEREG
- jsr video_read
- move.b d0,d1 ; return value
- RESTREG
- rts
-
-port_out_11:
- ;; LCD data
- SAVEREG
- move.b d1,-(a7)
- jsr video_write
- addq #2,a7
- RESTREG
- rts
-
-port_in_12:
-port_out_12:
-port_in_13:
-port_out_13:
-port_in_14:
-port_out_14:
-port_in_15:
-port_out_15:
-port_in_16:
-port_out_16:
-port_in_17:
-port_out_17:
-port_in_18:
-port_out_18:
-port_in_19:
-port_out_19:
-port_in_1a:
-port_out_1a:
-port_in_1b:
-port_out_1b:
-port_in_1c:
-port_out_1c:
-port_in_1d:
-port_out_1d:
-port_in_1e:
-port_out_1e:
-port_in_1f:
-port_out_1f:
-port_in_20:
-port_out_20:
-port_in_21:
-port_out_21:
-port_in_22:
-port_out_22:
-port_in_23:
-port_out_23:
-port_in_24:
-port_out_24:
-port_in_25:
-port_out_25:
-port_in_26:
-port_out_26:
-port_in_27:
-port_out_27:
-port_in_28:
-port_out_28:
-port_in_29:
-port_out_29:
-port_in_2a:
-port_out_2a:
-port_in_2b:
-port_out_2b:
-port_in_2c:
-port_out_2c:
-port_in_2d:
-port_out_2d:
-port_in_2e:
-port_out_2e:
-port_in_2f:
-port_out_2f:
-port_in_30:
-port_out_30:
-port_in_31:
-port_out_31:
-port_in_32:
-port_out_32:
-port_in_33:
-port_out_33:
-port_in_34:
-port_out_34:
-port_in_35:
-port_out_35:
-port_in_36:
-port_out_36:
-port_in_37:
-port_out_37:
-port_in_38:
-port_out_38:
-port_in_39:
-port_out_39:
-port_in_3a:
-port_out_3a:
-port_in_3b:
-port_out_3b:
-port_in_3c:
-port_out_3c:
-port_in_3d:
-port_out_3d:
-port_in_3e:
-port_out_3e:
-port_in_3f:
-port_out_3f:
-port_in_40:
-port_out_40:
-port_in_41:
-port_out_41:
-port_in_42:
-port_out_42:
-port_in_43:
-port_out_43:
-port_in_44:
-port_out_44:
-port_in_45:
-port_out_45:
-port_in_46:
-port_out_46:
-port_in_47:
-port_out_47:
-port_in_48:
-port_out_48:
-port_in_49:
-port_out_49:
-port_in_4a:
-port_out_4a:
-port_in_4b:
-port_out_4b:
-port_in_4c:
-port_out_4c:
-port_in_4d:
-port_out_4d:
-port_in_4e:
-port_out_4e:
-port_in_4f:
-port_out_4f:
-port_in_50:
-port_out_50:
-port_in_51:
-port_out_51:
-port_in_52:
-port_out_52:
-port_in_53:
-port_out_53:
-port_in_54:
-port_out_54:
-port_in_55:
-port_out_55:
-port_in_56:
-port_out_56:
-port_in_57:
-port_out_57:
-port_in_58:
-port_out_58:
-port_in_59:
-port_out_59:
-port_in_5a:
-port_out_5a:
-port_in_5b:
-port_out_5b:
-port_in_5c:
-port_out_5c:
-port_in_5d:
-port_out_5d:
-port_in_5e:
-port_out_5e:
-port_in_5f:
-port_out_5f:
-port_in_60:
-port_out_60:
-port_in_61:
-port_out_61:
-port_in_62:
-port_out_62:
-port_in_63:
-port_out_63:
-port_in_64:
-port_out_64:
-port_in_65:
-port_out_65:
-port_in_66:
-port_out_66:
-port_in_67:
-port_out_67:
-port_in_68:
-port_out_68:
-port_in_69:
-port_out_69:
-port_in_6a:
-port_out_6a:
-port_in_6b:
-port_out_6b:
-port_in_6c:
-port_out_6c:
-port_in_6d:
-port_out_6d:
-port_in_6e:
-port_out_6e:
-port_in_6f:
-port_out_6f:
-port_in_70:
-port_out_70:
-port_in_71:
-port_out_71:
-port_in_72:
-port_out_72:
-port_in_73:
-port_out_73:
-port_in_74:
-port_out_74:
-port_in_75:
-port_out_75:
-port_in_76:
-port_out_76:
-port_in_77:
-port_out_77:
-port_in_78:
-port_out_78:
-port_in_79:
-port_out_79:
-port_in_7a:
-port_out_7a:
-port_in_7b:
-port_out_7b:
-port_in_7c:
-port_out_7c:
-port_in_7d:
-port_out_7d:
-port_in_7e:
-port_out_7e:
-port_in_7f:
-port_out_7f:
-port_in_80:
-port_out_80:
-port_in_81:
-port_out_81:
-port_in_82:
-port_out_82:
-port_in_83:
-port_out_83:
-port_in_84:
-port_out_84:
-port_in_85:
-port_out_85:
-port_in_86:
-port_out_86:
-port_in_87:
-port_out_87:
-port_in_88:
-port_out_88:
-port_in_89:
-port_out_89:
-port_in_8a:
-port_out_8a:
-port_in_8b:
-port_out_8b:
-port_in_8c:
-port_out_8c:
-port_in_8d:
-port_out_8d:
-port_in_8e:
-port_out_8e:
-port_in_8f:
-port_out_8f:
-port_in_90:
-port_out_90:
-port_in_91:
-port_out_91:
-port_in_92:
-port_out_92:
-port_in_93:
-port_out_93:
-port_in_94:
-port_out_94:
-port_in_95:
-port_out_95:
-port_in_96:
-port_out_96:
-port_in_97:
-port_out_97:
-port_in_98:
-port_out_98:
-port_in_99:
-port_out_99:
-port_in_9a:
-port_out_9a:
-port_in_9b:
-port_out_9b:
-port_in_9c:
-port_out_9c:
-port_in_9d:
-port_out_9d:
-port_in_9e:
-port_out_9e:
-port_in_9f:
-port_out_9f:
-port_in_a0:
-port_out_a0:
-port_in_a1:
-port_out_a1:
-port_in_a2:
-port_out_a2:
-port_in_a3:
-port_out_a3:
-port_in_a4:
-port_out_a4:
-port_in_a5:
-port_out_a5:
-port_in_a6:
-port_out_a6:
-port_in_a7:
-port_out_a7:
-port_in_a8:
-port_out_a8:
-port_in_a9:
-port_out_a9:
-port_in_aa:
-port_out_aa:
-port_in_ab:
-port_out_ab:
-port_in_ac:
-port_out_ac:
-port_in_ad:
-port_out_ad:
-port_in_ae:
-port_out_ae:
-port_in_af:
-port_out_af:
-port_in_b0:
-port_out_b0:
-port_in_b1:
-port_out_b1:
-port_in_b2:
-port_out_b2:
-port_in_b3:
-port_out_b3:
-port_in_b4:
-port_out_b4:
-port_in_b5:
-port_out_b5:
-port_in_b6:
-port_out_b6:
-port_in_b7:
-port_out_b7:
-port_in_b8:
-port_out_b8:
-port_in_b9:
-port_out_b9:
-port_in_ba:
-port_out_ba:
-port_in_bb:
-port_out_bb:
-port_in_bc:
-port_out_bc:
-port_in_bd:
-port_out_bd:
-port_in_be:
-port_out_be:
-port_in_bf:
-port_out_bf:
-port_in_c0:
-port_out_c0:
-port_in_c1:
-port_out_c1:
-port_in_c2:
-port_out_c2:
-port_in_c3:
-port_out_c3:
-port_in_c4:
-port_out_c4:
-port_in_c5:
-port_out_c5:
-port_in_c6:
-port_out_c6:
-port_in_c7:
-port_out_c7:
-port_in_c8:
-port_out_c8:
-port_in_c9:
-port_out_c9:
-port_in_ca:
-port_out_ca:
-port_in_cb:
-port_out_cb:
-port_in_cc:
-port_out_cc:
-port_in_cd:
-port_out_cd:
-port_in_ce:
-port_out_ce:
-port_in_cf:
-port_out_cf:
-port_in_d0:
-port_out_d0:
-port_in_d1:
-port_out_d1:
-port_in_d2:
-port_out_d2:
-port_in_d3:
-port_out_d3:
-port_in_d4:
-port_out_d4:
-port_in_d5:
-port_out_d5:
-port_in_d6:
-port_out_d6:
-port_in_d7:
-port_out_d7:
-port_in_d8:
-port_out_d8:
-port_in_d9:
-port_out_d9:
-port_in_da:
-port_out_da:
-port_in_db:
-port_out_db:
-port_in_dc:
-port_out_dc:
-port_in_dd:
-port_out_dd:
-port_in_de:
-port_out_de:
-port_in_df:
-port_out_df:
-port_in_e0:
-port_out_e0:
-port_in_e1:
-port_out_e1:
-port_in_e2:
-port_out_e2:
-port_in_e3:
-port_out_e3:
-port_in_e4:
-port_out_e4:
-port_in_e5:
-port_out_e5:
-port_in_e6:
-port_out_e6:
-port_in_e7:
-port_out_e7:
-port_in_e8:
-port_out_e8:
-port_in_e9:
-port_out_e9:
-port_in_ea:
-port_out_ea:
-port_in_eb:
-port_out_eb:
-port_in_ec:
-port_out_ec:
-port_in_ed:
-port_out_ed:
-port_in_ee:
-port_out_ee:
-port_in_ef:
-port_out_ef:
-port_in_f0:
-port_out_f0:
-port_in_f1:
-port_out_f1:
-port_in_f2:
-port_out_f2:
-port_in_f3:
-port_out_f3:
-port_in_f4:
-port_out_f4:
-port_in_f5:
-port_out_f5:
-port_in_f6:
-port_out_f6:
-port_in_f7:
-port_out_f7:
-port_in_f8:
-port_out_f8:
-port_in_f9:
-port_out_f9:
-port_in_fa:
-port_out_fa:
-port_in_fb:
-port_out_fb:
-port_in_fc:
-port_out_fc:
-port_in_fd:
-port_out_fd:
-port_in_fe:
-port_out_fe:
-port_in_ff:
-port_out_ff:
diff --git a/ports.s b/ports.s
new file mode 100644
index 0000000..2c7a93e
--- /dev/null
+++ b/ports.s
@@ -0,0 +1,1188 @@
+ ;; Routines to process OUT and IN instructions. This is the
+ ;; bit that's unique to TI calculators.
+
+ ;; Port is in d0, byte is in d1
+ ;; Destroys a0
+port_in:
+ andi.w #$ff,d0
+ add.w d0,d0
+ add.w d0,d0
+ movea.l lut_ports_in(pc,d0),a0
+ jmp (a0)
+ rts
+
+lut_ports_in:
+ .int port_in_00
+ .int port_in_01
+ .int port_in_02
+ .int port_in_03
+ .int port_in_04
+ .int port_in_05
+ .int port_in_06
+ .int port_in_07
+ .int port_in_08
+ .int port_in_09
+ .int port_in_0a
+ .int port_in_0b
+ .int port_in_0c
+ .int port_in_0d
+ .int port_in_0e
+ .int port_in_0f
+ .int port_in_10
+ .int port_in_11
+ .int port_in_12
+ .int port_in_13
+ .int port_in_14
+ .int port_in_15
+ .int port_in_16
+ .int port_in_17
+ .int port_in_18
+ .int port_in_19
+ .int port_in_1a
+ .int port_in_1b
+ .int port_in_1c
+ .int port_in_1d
+ .int port_in_1e
+ .int port_in_1f
+ .int port_in_20
+ .int port_in_21
+ .int port_in_22
+ .int port_in_23
+ .int port_in_24
+ .int port_in_25
+ .int port_in_26
+ .int port_in_27
+ .int port_in_28
+ .int port_in_29
+ .int port_in_2a
+ .int port_in_2b
+ .int port_in_2c
+ .int port_in_2d
+ .int port_in_2e
+ .int port_in_2f
+ .int port_in_30
+ .int port_in_31
+ .int port_in_32
+ .int port_in_33
+ .int port_in_34
+ .int port_in_35
+ .int port_in_36
+ .int port_in_37
+ .int port_in_38
+ .int port_in_39
+ .int port_in_3a
+ .int port_in_3b
+ .int port_in_3c
+ .int port_in_3d
+ .int port_in_3e
+ .int port_in_3f
+ .int port_in_40
+ .int port_in_41
+ .int port_in_42
+ .int port_in_43
+ .int port_in_44
+ .int port_in_45
+ .int port_in_46
+ .int port_in_47
+ .int port_in_48
+ .int port_in_49
+ .int port_in_4a
+ .int port_in_4b
+ .int port_in_4c
+ .int port_in_4d
+ .int port_in_4e
+ .int port_in_4f
+ .int port_in_50
+ .int port_in_51
+ .int port_in_52
+ .int port_in_53
+ .int port_in_54
+ .int port_in_55
+ .int port_in_56
+ .int port_in_57
+ .int port_in_58
+ .int port_in_59
+ .int port_in_5a
+ .int port_in_5b
+ .int port_in_5c
+ .int port_in_5d
+ .int port_in_5e
+ .int port_in_5f
+ .int port_in_60
+ .int port_in_61
+ .int port_in_62
+ .int port_in_63
+ .int port_in_64
+ .int port_in_65
+ .int port_in_66
+ .int port_in_67
+ .int port_in_68
+ .int port_in_69
+ .int port_in_6a
+ .int port_in_6b
+ .int port_in_6c
+ .int port_in_6d
+ .int port_in_6e
+ .int port_in_6f
+ .int port_in_70
+ .int port_in_71
+ .int port_in_72
+ .int port_in_73
+ .int port_in_74
+ .int port_in_75
+ .int port_in_76
+ .int port_in_77
+ .int port_in_78
+ .int port_in_79
+ .int port_in_7a
+ .int port_in_7b
+ .int port_in_7c
+ .int port_in_7d
+ .int port_in_7e
+ .int port_in_7f
+ .int port_in_80
+ .int port_in_81
+ .int port_in_82
+ .int port_in_83
+ .int port_in_84
+ .int port_in_85
+ .int port_in_86
+ .int port_in_87
+ .int port_in_88
+ .int port_in_89
+ .int port_in_8a
+ .int port_in_8b
+ .int port_in_8c
+ .int port_in_8d
+ .int port_in_8e
+ .int port_in_8f
+ .int port_in_90
+ .int port_in_91
+ .int port_in_92
+ .int port_in_93
+ .int port_in_94
+ .int port_in_95
+ .int port_in_96
+ .int port_in_97
+ .int port_in_98
+ .int port_in_99
+ .int port_in_9a
+ .int port_in_9b
+ .int port_in_9c
+ .int port_in_9d
+ .int port_in_9e
+ .int port_in_9f
+ .int port_in_a0
+ .int port_in_a1
+ .int port_in_a2
+ .int port_in_a3
+ .int port_in_a4
+ .int port_in_a5
+ .int port_in_a6
+ .int port_in_a7
+ .int port_in_a8
+ .int port_in_a9
+ .int port_in_aa
+ .int port_in_ab
+ .int port_in_ac
+ .int port_in_ad
+ .int port_in_ae
+ .int port_in_af
+ .int port_in_b0
+ .int port_in_b1
+ .int port_in_b2
+ .int port_in_b3
+ .int port_in_b4
+ .int port_in_b5
+ .int port_in_b6
+ .int port_in_b7
+ .int port_in_b8
+ .int port_in_b9
+ .int port_in_ba
+ .int port_in_bb
+ .int port_in_bc
+ .int port_in_bd
+ .int port_in_be
+ .int port_in_bf
+ .int port_in_c0
+ .int port_in_c1
+ .int port_in_c2
+ .int port_in_c3
+ .int port_in_c4
+ .int port_in_c5
+ .int port_in_c6
+ .int port_in_c7
+ .int port_in_c8
+ .int port_in_c9
+ .int port_in_ca
+ .int port_in_cb
+ .int port_in_cc
+ .int port_in_cd
+ .int port_in_ce
+ .int port_in_cf
+ .int port_in_d0
+ .int port_in_d1
+ .int port_in_d2
+ .int port_in_d3
+ .int port_in_d4
+ .int port_in_d5
+ .int port_in_d6
+ .int port_in_d7
+ .int port_in_d8
+ .int port_in_d9
+ .int port_in_da
+ .int port_in_db
+ .int port_in_dc
+ .int port_in_dd
+ .int port_in_de
+ .int port_in_df
+ .int port_in_e0
+ .int port_in_e1
+ .int port_in_e2
+ .int port_in_e3
+ .int port_in_e4
+ .int port_in_e5
+ .int port_in_e6
+ .int port_in_e7
+ .int port_in_e8
+ .int port_in_e9
+ .int port_in_ea
+ .int port_in_eb
+ .int port_in_ec
+ .int port_in_ed
+ .int port_in_ee
+ .int port_in_ef
+ .int port_in_f0
+ .int port_in_f1
+ .int port_in_f2
+ .int port_in_f3
+ .int port_in_f4
+ .int port_in_f5
+ .int port_in_f6
+ .int port_in_f7
+ .int port_in_f8
+ .int port_in_f9
+ .int port_in_fa
+ .int port_in_fb
+ .int port_in_fc
+ .int port_in_fd
+ .int port_in_fe
+ .int port_in_ff
+
+port_out:
+ andi.w #$ff,d0
+ ;; This is the fastest way to shift left 2 bits. :S
+ add.w d0,d0
+ add.w d0,d0
+ movea.l lut_ports_out(pc,d0.w),a0
+ jmp (a0)
+
+lut_ports_out:
+ .int port_out_00
+ .int port_out_01
+ .int port_out_02
+ .int port_out_03
+ .int port_out_04
+ .int port_out_05
+ .int port_out_06
+ .int port_out_07
+ .int port_out_08
+ .int port_out_09
+ .int port_out_0a
+ .int port_out_0b
+ .int port_out_0c
+ .int port_out_0d
+ .int port_out_0e
+ .int port_out_0f
+ .int port_out_10
+ .int port_out_11
+ .int port_out_12
+ .int port_out_13
+ .int port_out_14
+ .int port_out_15
+ .int port_out_16
+ .int port_out_17
+ .int port_out_18
+ .int port_out_19
+ .int port_out_1a
+ .int port_out_1b
+ .int port_out_1c
+ .int port_out_1d
+ .int port_out_1e
+ .int port_out_1f
+ .int port_out_20
+ .int port_out_21
+ .int port_out_22
+ .int port_out_23
+ .int port_out_24
+ .int port_out_25
+ .int port_out_26
+ .int port_out_27
+ .int port_out_28
+ .int port_out_29
+ .int port_out_2a
+ .int port_out_2b
+ .int port_out_2c
+ .int port_out_2d
+ .int port_out_2e
+ .int port_out_2f
+ .int port_out_30
+ .int port_out_31
+ .int port_out_32
+ .int port_out_33
+ .int port_out_34
+ .int port_out_35
+ .int port_out_36
+ .int port_out_37
+ .int port_out_38
+ .int port_out_39
+ .int port_out_3a
+ .int port_out_3b
+ .int port_out_3c
+ .int port_out_3d
+ .int port_out_3e
+ .int port_out_3f
+ .int port_out_40
+ .int port_out_41
+ .int port_out_42
+ .int port_out_43
+ .int port_out_44
+ .int port_out_45
+ .int port_out_46
+ .int port_out_47
+ .int port_out_48
+ .int port_out_49
+ .int port_out_4a
+ .int port_out_4b
+ .int port_out_4c
+ .int port_out_4d
+ .int port_out_4e
+ .int port_out_4f
+ .int port_out_50
+ .int port_out_51
+ .int port_out_52
+ .int port_out_53
+ .int port_out_54
+ .int port_out_55
+ .int port_out_56
+ .int port_out_57
+ .int port_out_58
+ .int port_out_59
+ .int port_out_5a
+ .int port_out_5b
+ .int port_out_5c
+ .int port_out_5d
+ .int port_out_5e
+ .int port_out_5f
+ .int port_out_60
+ .int port_out_61
+ .int port_out_62
+ .int port_out_63
+ .int port_out_64
+ .int port_out_65
+ .int port_out_66
+ .int port_out_67
+ .int port_out_68
+ .int port_out_69
+ .int port_out_6a
+ .int port_out_6b
+ .int port_out_6c
+ .int port_out_6d
+ .int port_out_6e
+ .int port_out_6f
+ .int port_out_70
+ .int port_out_71
+ .int port_out_72
+ .int port_out_73
+ .int port_out_74
+ .int port_out_75
+ .int port_out_76
+ .int port_out_77
+ .int port_out_78
+ .int port_out_79
+ .int port_out_7a
+ .int port_out_7b
+ .int port_out_7c
+ .int port_out_7d
+ .int port_out_7e
+ .int port_out_7f
+ .int port_out_80
+ .int port_out_81
+ .int port_out_82
+ .int port_out_83
+ .int port_out_84
+ .int port_out_85
+ .int port_out_86
+ .int port_out_87
+ .int port_out_88
+ .int port_out_89
+ .int port_out_8a
+ .int port_out_8b
+ .int port_out_8c
+ .int port_out_8d
+ .int port_out_8e
+ .int port_out_8f
+ .int port_out_90
+ .int port_out_91
+ .int port_out_92
+ .int port_out_93
+ .int port_out_94
+ .int port_out_95
+ .int port_out_96
+ .int port_out_97
+ .int port_out_98
+ .int port_out_99
+ .int port_out_9a
+ .int port_out_9b
+ .int port_out_9c
+ .int port_out_9d
+ .int port_out_9e
+ .int port_out_9f
+ .int port_out_a0
+ .int port_out_a1
+ .int port_out_a2
+ .int port_out_a3
+ .int port_out_a4
+ .int port_out_a5
+ .int port_out_a6
+ .int port_out_a7
+ .int port_out_a8
+ .int port_out_a9
+ .int port_out_aa
+ .int port_out_ab
+ .int port_out_ac
+ .int port_out_ad
+ .int port_out_ae
+ .int port_out_af
+ .int port_out_b0
+ .int port_out_b1
+ .int port_out_b2
+ .int port_out_b3
+ .int port_out_b4
+ .int port_out_b5
+ .int port_out_b6
+ .int port_out_b7
+ .int port_out_b8
+ .int port_out_b9
+ .int port_out_ba
+ .int port_out_bb
+ .int port_out_bc
+ .int port_out_bd
+ .int port_out_be
+ .int port_out_bf
+ .int port_out_c0
+ .int port_out_c1
+ .int port_out_c2
+ .int port_out_c3
+ .int port_out_c4
+ .int port_out_c5
+ .int port_out_c6
+ .int port_out_c7
+ .int port_out_c8
+ .int port_out_c9
+ .int port_out_ca
+ .int port_out_cb
+ .int port_out_cc
+ .int port_out_cd
+ .int port_out_ce
+ .int port_out_cf
+ .int port_out_d0
+ .int port_out_d1
+ .int port_out_d2
+ .int port_out_d3
+ .int port_out_d4
+ .int port_out_d5
+ .int port_out_d6
+ .int port_out_d7
+ .int port_out_d8
+ .int port_out_d9
+ .int port_out_da
+ .int port_out_db
+ .int port_out_dc
+ .int port_out_dd
+ .int port_out_de
+ .int port_out_df
+ .int port_out_e0
+ .int port_out_e1
+ .int port_out_e2
+ .int port_out_e3
+ .int port_out_e4
+ .int port_out_e5
+ .int port_out_e6
+ .int port_out_e7
+ .int port_out_e8
+ .int port_out_e9
+ .int port_out_ea
+ .int port_out_eb
+ .int port_out_ec
+ .int port_out_ed
+ .int port_out_ee
+ .int port_out_ef
+ .int port_out_f0
+ .int port_out_f1
+ .int port_out_f2
+ .int port_out_f3
+ .int port_out_f4
+ .int port_out_f5
+ .int port_out_f6
+ .int port_out_f7
+ .int port_out_f8
+ .int port_out_f9
+ .int port_out_fa
+ .int port_out_fb
+ .int port_out_fc
+ .int port_out_fd
+ .int port_out_fe
+ .int port_out_ff
+
+port_in_00:
+port_out_00:
+ ;; Temporary test harness. Writing to this port writes a
+ ;; character to the screen.
+ SAVEREG
+ andi.w #$ff,d1
+ move.w d1,-(sp)
+ jsr char_draw
+ addq #2,sp
+ RESTREG
+ rts
+
+port_in_01:
+port_out_01:
+port_in_02:
+port_out_02:
+port_in_03:
+port_out_03:
+port_in_04:
+port_out_04:
+ ;; Bank B paging, among other things
+ SAVEREG
+ move.b d1,-(a7)
+ jsr bankswap_b_write
+ addq #2,a7
+ RESTREG
+ rts
+
+port_in_05:
+port_out_05:
+port_in_06:
+port_out_06:
+ ;; Bank A paging
+ SAVEREG
+ move.b d1,-(a7)
+ jsr bankswap_a_write
+ addq #2,a7
+ RESTREG
+ rts
+
+port_in_07:
+port_out_07:
+port_in_08:
+port_out_08:
+port_in_09:
+port_out_09:
+port_in_0a:
+port_out_0a:
+port_in_0b:
+port_out_0b:
+port_in_0c:
+port_out_0c:
+port_in_0d:
+port_out_0d:
+port_in_0e:
+port_out_0e:
+port_in_0f:
+port_out_0f:
+port_in_10:
+.xref video_row
+.xref video_increment
+.xref video_enabled
+.xref video_6bit
+.xref video_busy
+.xref video_cur_row
+.xref video_cur_col
+.xref video_write
+.xref video_read
+
+ ;; LCD status
+ clr.b d1
+ or.b video_increment,d1
+ or.b video_row,d1
+ or.b video_enabled,d1
+ or.b video_6bit,d1
+ or.b video_busy,d1
+ rts
+
+port_out_10:
+ ;; LCD command
+ tst.b d1
+ beq port_out_10_00
+ subq.b #1,d1
+ beq port_out_10_01
+ subq.b #1,d1
+ beq port_out_10_02
+ subq.b #1,d1
+ beq port_out_10_03
+ subq.b #1,d1
+ beq port_out_10_04
+ subq.b #1,d1
+ beq port_out_10_05
+ subq.b #1,d1
+ beq port_out_10_06
+ subq.b #1,d1
+ beq port_out_10_07
+ addq.b #7,d1
+ cmpi.b #$0b,d1 ; power supply enhancement
+ ble port_out_10_undef
+ cmpi.b #$13,d1 ; power supply level
+ ble port_out_10_undef
+ cmpi.b #$17,d1 ; undefined
+ ble port_out_10_undef
+ cmpi.b #$18,d1 ; cancel test mode
+ beq port_out_10_undef
+ cmpi.b #$1b,d1 ; undefined
+ beq port_out_10_undef
+ cmpi.b #$1f,d1 ; enter test mode
+ ble port_out_10_undef
+ cmpi.b #$3f,d1 ; set column
+ ble port_out_10_set_col
+ cmpi.b #$7f,d1 ; z-addressing
+ ble port_out_10_undef ; XXX?
+ cmpi.b #$df,d1 ; set row
+ ble port_out_10_set_row
+ ;; fallthrough: set contrast (unimplemented)
+ rts
+ ;; ...
+port_out_10_00: ; 6-bit mode
+ move.b #$00,video_6bit
+ rts
+port_out_10_01: ; 8-bit mode
+ move.b #$40,video_6bit
+ rts
+port_out_10_02: ; screen off
+ move.b #$20,video_enabled
+ rts
+port_out_10_03: ; screen on
+ move.b #$00,video_enabled
+ rts
+port_out_10_04: ; x--
+ move.b #$01,video_row
+ move.b #$00,video_increment
+ rts
+port_out_10_05: ; x++
+ move.b #$01,video_row
+ move.b #$02,video_increment
+ rts
+port_out_10_06: ; y--
+ move.b #$00,video_row
+ move.b #$00,video_increment
+ rts
+port_out_10_07: ; y++
+ move.b #$00,video_row
+ move.b #$02,video_increment
+ rts
+port_out_10_undef:
+ rts
+port_out_10_set_col:
+ sub.b #$20,d1
+ move.b d1,video_cur_col
+ rts
+port_out_10_set_row:
+ sub.b #$80,d1
+ move.b d1,video_cur_row
+ rts
+
+
+port_in_11:
+ ;; LCD data
+ SAVEREG
+ jsr video_read
+ move.b d0,d1 ; return value
+ RESTREG
+ rts
+
+port_out_11:
+ ;; LCD data
+ SAVEREG
+ move.b d1,-(a7)
+ jsr video_write
+ addq #2,a7
+ RESTREG
+ rts
+
+port_in_12:
+port_out_12:
+port_in_13:
+port_out_13:
+port_in_14:
+port_out_14:
+port_in_15:
+port_out_15:
+port_in_16:
+port_out_16:
+port_in_17:
+port_out_17:
+port_in_18:
+port_out_18:
+port_in_19:
+port_out_19:
+port_in_1a:
+port_out_1a:
+port_in_1b:
+port_out_1b:
+port_in_1c:
+port_out_1c:
+port_in_1d:
+port_out_1d:
+port_in_1e:
+port_out_1e:
+port_in_1f:
+port_out_1f:
+port_in_20:
+port_out_20:
+port_in_21:
+port_out_21:
+port_in_22:
+port_out_22:
+port_in_23:
+port_out_23:
+port_in_24:
+port_out_24:
+port_in_25:
+port_out_25:
+port_in_26:
+port_out_26:
+port_in_27:
+port_out_27:
+port_in_28:
+port_out_28:
+port_in_29:
+port_out_29:
+port_in_2a:
+port_out_2a:
+port_in_2b:
+port_out_2b:
+port_in_2c:
+port_out_2c:
+port_in_2d:
+port_out_2d:
+port_in_2e:
+port_out_2e:
+port_in_2f:
+port_out_2f:
+port_in_30:
+port_out_30:
+port_in_31:
+port_out_31:
+port_in_32:
+port_out_32:
+port_in_33:
+port_out_33:
+port_in_34:
+port_out_34:
+port_in_35:
+port_out_35:
+port_in_36:
+port_out_36:
+port_in_37:
+port_out_37:
+port_in_38:
+port_out_38:
+port_in_39:
+port_out_39:
+port_in_3a:
+port_out_3a:
+port_in_3b:
+port_out_3b:
+port_in_3c:
+port_out_3c:
+port_in_3d:
+port_out_3d:
+port_in_3e:
+port_out_3e:
+port_in_3f:
+port_out_3f:
+port_in_40:
+port_out_40:
+port_in_41:
+port_out_41:
+port_in_42:
+port_out_42:
+port_in_43:
+port_out_43:
+port_in_44:
+port_out_44:
+port_in_45:
+port_out_45:
+port_in_46:
+port_out_46:
+port_in_47:
+port_out_47:
+port_in_48:
+port_out_48:
+port_in_49:
+port_out_49:
+port_in_4a:
+port_out_4a:
+port_in_4b:
+port_out_4b:
+port_in_4c:
+port_out_4c:
+port_in_4d:
+port_out_4d:
+port_in_4e:
+port_out_4e:
+port_in_4f:
+port_out_4f:
+port_in_50:
+port_out_50:
+port_in_51:
+port_out_51:
+port_in_52:
+port_out_52:
+port_in_53:
+port_out_53:
+port_in_54:
+port_out_54:
+port_in_55:
+port_out_55:
+port_in_56:
+port_out_56:
+port_in_57:
+port_out_57:
+port_in_58:
+port_out_58:
+port_in_59:
+port_out_59:
+port_in_5a:
+port_out_5a:
+port_in_5b:
+port_out_5b:
+port_in_5c:
+port_out_5c:
+port_in_5d:
+port_out_5d:
+port_in_5e:
+port_out_5e:
+port_in_5f:
+port_out_5f:
+port_in_60:
+port_out_60:
+port_in_61:
+port_out_61:
+port_in_62:
+port_out_62:
+port_in_63:
+port_out_63:
+port_in_64:
+port_out_64:
+port_in_65:
+port_out_65:
+port_in_66:
+port_out_66:
+port_in_67:
+port_out_67:
+port_in_68:
+port_out_68:
+port_in_69:
+port_out_69:
+port_in_6a:
+port_out_6a:
+port_in_6b:
+port_out_6b:
+port_in_6c:
+port_out_6c:
+port_in_6d:
+port_out_6d:
+port_in_6e:
+port_out_6e:
+port_in_6f:
+port_out_6f:
+port_in_70:
+port_out_70:
+port_in_71:
+port_out_71:
+port_in_72:
+port_out_72:
+port_in_73:
+port_out_73:
+port_in_74:
+port_out_74:
+port_in_75:
+port_out_75:
+port_in_76:
+port_out_76:
+port_in_77:
+port_out_77:
+port_in_78:
+port_out_78:
+port_in_79:
+port_out_79:
+port_in_7a:
+port_out_7a:
+port_in_7b:
+port_out_7b:
+port_in_7c:
+port_out_7c:
+port_in_7d:
+port_out_7d:
+port_in_7e:
+port_out_7e:
+port_in_7f:
+port_out_7f:
+port_in_80:
+port_out_80:
+port_in_81:
+port_out_81:
+port_in_82:
+port_out_82:
+port_in_83:
+port_out_83:
+port_in_84:
+port_out_84:
+port_in_85:
+port_out_85:
+port_in_86:
+port_out_86:
+port_in_87:
+port_out_87:
+port_in_88:
+port_out_88:
+port_in_89:
+port_out_89:
+port_in_8a:
+port_out_8a:
+port_in_8b:
+port_out_8b:
+port_in_8c:
+port_out_8c:
+port_in_8d:
+port_out_8d:
+port_in_8e:
+port_out_8e:
+port_in_8f:
+port_out_8f:
+port_in_90:
+port_out_90:
+port_in_91:
+port_out_91:
+port_in_92:
+port_out_92:
+port_in_93:
+port_out_93:
+port_in_94:
+port_out_94:
+port_in_95:
+port_out_95:
+port_in_96:
+port_out_96:
+port_in_97:
+port_out_97:
+port_in_98:
+port_out_98:
+port_in_99:
+port_out_99:
+port_in_9a:
+port_out_9a:
+port_in_9b:
+port_out_9b:
+port_in_9c:
+port_out_9c:
+port_in_9d:
+port_out_9d:
+port_in_9e:
+port_out_9e:
+port_in_9f:
+port_out_9f:
+port_in_a0:
+port_out_a0:
+port_in_a1:
+port_out_a1:
+port_in_a2:
+port_out_a2:
+port_in_a3:
+port_out_a3:
+port_in_a4:
+port_out_a4:
+port_in_a5:
+port_out_a5:
+port_in_a6:
+port_out_a6:
+port_in_a7:
+port_out_a7:
+port_in_a8:
+port_out_a8:
+port_in_a9:
+port_out_a9:
+port_in_aa:
+port_out_aa:
+port_in_ab:
+port_out_ab:
+port_in_ac:
+port_out_ac:
+port_in_ad:
+port_out_ad:
+port_in_ae:
+port_out_ae:
+port_in_af:
+port_out_af:
+port_in_b0:
+port_out_b0:
+port_in_b1:
+port_out_b1:
+port_in_b2:
+port_out_b2:
+port_in_b3:
+port_out_b3:
+port_in_b4:
+port_out_b4:
+port_in_b5:
+port_out_b5:
+port_in_b6:
+port_out_b6:
+port_in_b7:
+port_out_b7:
+port_in_b8:
+port_out_b8:
+port_in_b9:
+port_out_b9:
+port_in_ba:
+port_out_ba:
+port_in_bb:
+port_out_bb:
+port_in_bc:
+port_out_bc:
+port_in_bd:
+port_out_bd:
+port_in_be:
+port_out_be:
+port_in_bf:
+port_out_bf:
+port_in_c0:
+port_out_c0:
+port_in_c1:
+port_out_c1:
+port_in_c2:
+port_out_c2:
+port_in_c3:
+port_out_c3:
+port_in_c4:
+port_out_c4:
+port_in_c5:
+port_out_c5:
+port_in_c6:
+port_out_c6:
+port_in_c7:
+port_out_c7:
+port_in_c8:
+port_out_c8:
+port_in_c9:
+port_out_c9:
+port_in_ca:
+port_out_ca:
+port_in_cb:
+port_out_cb:
+port_in_cc:
+port_out_cc:
+port_in_cd:
+port_out_cd:
+port_in_ce:
+port_out_ce:
+port_in_cf:
+port_out_cf:
+port_in_d0:
+port_out_d0:
+port_in_d1:
+port_out_d1:
+port_in_d2:
+port_out_d2:
+port_in_d3:
+port_out_d3:
+port_in_d4:
+port_out_d4:
+port_in_d5:
+port_out_d5:
+port_in_d6:
+port_out_d6:
+port_in_d7:
+port_out_d7:
+port_in_d8:
+port_out_d8:
+port_in_d9:
+port_out_d9:
+port_in_da:
+port_out_da:
+port_in_db:
+port_out_db:
+port_in_dc:
+port_out_dc:
+port_in_dd:
+port_out_dd:
+port_in_de:
+port_out_de:
+port_in_df:
+port_out_df:
+port_in_e0:
+port_out_e0:
+port_in_e1:
+port_out_e1:
+port_in_e2:
+port_out_e2:
+port_in_e3:
+port_out_e3:
+port_in_e4:
+port_out_e4:
+port_in_e5:
+port_out_e5:
+port_in_e6:
+port_out_e6:
+port_in_e7:
+port_out_e7:
+port_in_e8:
+port_out_e8:
+port_in_e9:
+port_out_e9:
+port_in_ea:
+port_out_ea:
+port_in_eb:
+port_out_eb:
+port_in_ec:
+port_out_ec:
+port_in_ed:
+port_out_ed:
+port_in_ee:
+port_out_ee:
+port_in_ef:
+port_out_ef:
+port_in_f0:
+port_out_f0:
+port_in_f1:
+port_out_f1:
+port_in_f2:
+port_out_f2:
+port_in_f3:
+port_out_f3:
+port_in_f4:
+port_out_f4:
+port_in_f5:
+port_out_f5:
+port_in_f6:
+port_out_f6:
+port_in_f7:
+port_out_f7:
+port_in_f8:
+port_out_f8:
+port_in_f9:
+port_out_f9:
+port_in_fa:
+port_out_fa:
+port_in_fb:
+port_out_fb:
+port_in_fc:
+port_out_fc:
+port_in_fd:
+port_out_fd:
+port_in_fe:
+port_out_fe:
+port_in_ff:
+port_out_ff: