diff options
| -rw-r--r-- | Makefile | 12 | ||||
| -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.asm | 196 | ||||
| -rw-r--r-- | main.s | 200 | ||||
| -rw-r--r-- | opcodes.s.m4 (renamed from opcodes.asm.m4) | 274 | ||||
| -rw-r--r-- | ports.asm | 1188 | ||||
| -rw-r--r-- | ports.s | 1188 |
9 files changed, 1627 insertions, 1613 deletions
@@ -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 @@ -1,6 +1,8 @@ ;; Parting out the big math/logic routines from the ;; instruction dispatch table. +.text + alu_add: ;; ADD instruction ;; ADD d1,d0 @@ -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 - @@ -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: @@ -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: |
