gsplus/src/engine_s.s
2015-11-05 14:23:46 -06:00

2482 lines
51 KiB
ArmAsm

/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 by GSport contributors
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
.code
.level 1.1
#include "defs.h"
#define ASM
/*
#define COUNT_GET_CALLS
*/
#if 0
# define CHECK_SIZE_CONSISTENCY
#endif
#define STACK_ENGINE_SIZE 512
#define STACK_SAVE_CMP_INDEX_REG -64
#define STACK_GET_MEM_B0_DIRECT_SAVELINK -68
#define STACK_SAVE_ARG0 -72
#define STACK_SAVE_INSTR -76
#define STACK_SRC_BANK -80
#define STACK_INST_TAB_PTR_DONT_USE_THIS -84
#if 0
#define STACK_BP_ARG0_SAVE -88
#define STACK_BP_ARG1_SAVE -92
#define STACK_BP_ARG2_SAVE -96
#define STACK_BP_ARG3_SAVE -100
#define STACK_BP_RP_SAVE -104
#define STACK_BP_SCRATCH4_SAVE -108
#endif
#define STACK_GET_MEMORY_SAVE_LINK -112
#define STACK_SET_MEMORY_SAVE_LINK -116
#define STACK_MEMORY16_SAVE1 -120
#define STACK_MEMORY16_SAVE2 -124
#define STACK_MEMORY16_SAVE3 -128
#define STACK_SAVE_CYCLES_WORD2 -132 /* Cycles = dword */
#define STACK_SAVE_CYCLES -136
#define STACK_SET_MEMORY24_SAVE1 -140
#define STACK_SET_MEMORY24_SAVE2 -144
#define STACK_SET_MEMORY24_SAVE3 -148
#define STACK_GET_MEMORY24_SAVE1 -152
#define STACK_GET_MEMORY24_SAVE2 -156
#define STACK_GET_MEMORY24_SAVE3 -160
/* #define STACK_SAVE_INIT_CYCLES -164 */
#define STACK_SAVE_DECIMAL16_A -168
#define STACK_SAVE_DECIMAL16_B -172
#define STACK_SAVE_INSTR_TMP1 -176
#define STACK_SAVE_DISPATCH_LINK -180
#define STACK_SAVE_OP_LINK -184
#define STACK_GET_MEMORY16_ADDR_LATCH -188
#define STACK_GET_MEMORY24_ADDR_LATCH -192
#define STACK_GET_MEM_B0_DIRECT_ARG0 -200
#define STACK_GET_MEM_B0_DIRECT_RET0 -204
#define STACK_SAVE_PUSH16_LINK -208
#define STACK_SAVE_PUSH16_ARG1 -212
#define STACK_SAVE_PULL16_LINK -216
#define STACK_SAVE_PULL16_RET0 -220
#define STACK_SAVE_PULL24_LINK -224
#define STACK_SAVE_PULL24_RET0 -228
#define STACK_SAVE_COP_ARG0 -232
#define STACK_SAVE_TMP_INST0 -236
#define STACK_SAVE_TMP_INST -240
#define STACK_SAVE_TMP_INST1 -244
#define STACK_SAVE_DISP_PIECES_LINK -248
#define STACK_SAVE_DISPATCH_SCRATCH1 -252
#if 0
#define STACK_BP_SCRATCH2_SAVE -256
#define STACK_BP_SCRATCH3_SAVE -260
#endif
#define CYCLES_PLUS_1 fadd,dbl fr_plus_1,fcycles,fcycles
#define CYCLES_PLUS_2 fadd,dbl fr_plus_2,fcycles,fcycles
#define CYCLES_PLUS_3 fadd,dbl fr_plus_3,fcycles,fcycles
#define CYCLES_PLUS_5 fadd,dbl fr_plus_3,fcycles,fcycles ! \
fadd,dbl fr_plus_2,fcycles,fcycles
#define CYCLES_MINUS_1 fsub,dbl fcycles,fr_plus_1,fcycles
#define CYCLES_MINUS_2 fsub,dbl fcycles,fr_plus_2,fcycles
#define CYCLES_FINISH fadd,dbl fcycles_stop,fr_plus_1,fcycles
#define FCYCLES_ROUND_1 fadd,dbl fcycles,fr_plus_x_m1,ftmp1
#define FCYCLES_ROUND_2 fcnvfxt,dbl,dbl ftmp1,ftmp1
#define FCYCLES_ROUND_3 fcnvxf,dbl,dbl ftmp1,fcycles
/* HACK: INC_KPC* and DEC_KPC2 should avoid overflow into kbank! */
#define INC_KPC_1 addi 1,kpc,kpc
#define INC_KPC_2 addi 2,kpc,kpc
#define INC_KPC_3 addi 3,kpc,kpc
#define INC_KPC_4 addi 4,kpc,kpc
#define DEC_KPC2 addi -2,kpc,kpc
#define get_mem_b0_8 get_memory_asm
#define get_mem_b0_16 get_memory16_asm
#define get_mem_b0_24 get_memory24_asm
#define get_mem_long_8 get_memory_asm
#define get_mem_long_16 get_memory16_asm
#define get_mem_long_24 get_memory24_asm
#define set_mem_long_8 set_memory_asm
#define set_mem_long_16 set_memory16_asm
#define set_mem_b0_8 set_memory_asm
#define set_mem_b0_16 set_memory16_asm
#define set_mem_b0_24 set_memory24_asm
.code
.import halt_sim,data
.import g_fcycles_stop,data
.import g_irq_pending,data
.import g_wait_pending,data
.import g_rom_version,data
.import g_num_brk,data
.import g_num_cop,data
.import g_testing,data
.import log_pc,code
.import toolbox_debug_c,code
.import get_memory_io,code
.import set_memory_io,code
.import set_memory16_pieces,code
.import set_memory24_pieces,code
#include "op_routs.h"
.import do_break,code
.import do_cop,code
.import page_info_rd_wr,data
.import get_memory_calls,data
.import slow_mem_changed,data
.import g_cur_dcycs,data
.import g_last_vbl_dcycs,data
.import g_slow_memory_ptr,data
.import g_memory_ptr,data
.import g_dummy_memory1_ptr,data
.import g_rom_fc_ff_ptr,data
.import g_rom_cards_ptr,data
.export fixed_memory_ptrs_init,code
fixed_memory_ptrs_init
LDC(slow_memory,arg0)
LDC(g_slow_memory_ptr,arg1)
stw arg0,(arg1)
LDC(dummy_memory1,arg0)
LDC(g_dummy_memory1_ptr,arg1)
stw arg0,(arg1)
LDC(rom_fc_ff,arg0)
LDC(g_rom_fc_ff_ptr,arg1)
stw arg0,(arg1)
LDC(rom_cards,arg0)
LDC(g_rom_cards_ptr,arg1)
stw arg0,(arg1)
bv 0(link)
nop
.export get_itimer,code
get_itimer
bv 0(link)
mfctl %cr16,ret0
.export enter_asm,data
enter_asm
stwm page_info_ptr,STACK_ENGINE_SIZE(sp)
stw link,-STACK_ENGINE_SIZE+4(sp)
ldo -STACK_ENGINE_SIZE+16(sp),scratch2
stw addr_latch,-STACK_ENGINE_SIZE+8(sp)
fstds,ma fcycles,8(scratch2)
fstds,ma fr_plus_1,8(scratch2)
fcpy,dbl 0,fcycles
fstds,ma fr_plus_2,8(scratch2)
fstds,ma fr_plus_3,8(scratch2)
fcpy,dbl 0,fr_plus_1
fstds,ma fr_plus_x_m1,8(scratch2)
fstds,ma fcycles_stop,8(scratch2)
fcpy,dbl 0,fr_plus_2
fstds,ma fcycles_last_dcycs,8(scratch2)
ldil l%g_cur_dcycs,scratch2
ldil l%g_last_vbl_dcycs,scratch3
fcpy,dbl 0,fr_plus_3
ldo r%g_cur_dcycs(scratch2),scratch2
fcpy,dbl 0,fr_plus_x_m1
ldo r%g_last_vbl_dcycs(scratch3),scratch3
fldds 0(scratch2),ftmp1
ldil l%page_info_rd_wr,page_info_ptr
fldds 0(scratch3),fcycles_last_dcycs
fcpy,dbl 0,fcycles_stop
ldo r%page_info_rd_wr(page_info_ptr),page_info_ptr
bv 0(scratch1)
fsub,dbl ftmp1,fcycles_last_dcycs,fcycles
.export leave_asm,data
leave_asm
ldw -STACK_ENGINE_SIZE+4(sp),link
ldo -STACK_ENGINE_SIZE+16(sp),scratch2
ldw -STACK_ENGINE_SIZE+8(sp),addr_latch
fldds,ma 8(scratch2),fcycles
fldds,ma 8(scratch2),fr_plus_1
fldds,ma 8(scratch2),fr_plus_2
fldds,ma 8(scratch2),fr_plus_3
fldds,ma 8(scratch2),fr_plus_x_m1
fldds,ma 8(scratch2),fcycles_stop
fldds,ma 8(scratch2),fcycles_last_dcycs
bv (link)
ldwm -STACK_ENGINE_SIZE(sp),page_info_ptr
.align 8
.export get_memory_c
get_memory_c
; arg0 = addr
; arg1 = cycles
bl enter_asm,scratch1
nop
bl get_memory_asm,link
nop
b leave_asm
nop
.export get_memory16_c
get_memory16_c
; arg0 = addr
; arg1 = cycles
bl enter_asm,scratch1
nop
bl get_memory16_asm,link
nop
b leave_asm
nop
.export get_memory24_c
get_memory24_c
; arg0 = addr
; arg1 = cycles
bl enter_asm,scratch1
nop
bl get_memory24_asm,link
nop
b leave_asm
nop
#define GET_MEM8(upper16,lower8,ret0) \
extru arg0,23,16,arg3 ! \
CYCLES_PLUS_1 ! \
ldwx,s arg3(page_info_ptr),scratch3 ! \
copy arg0,addr_latch ! \
copy scratch3,scratch2 ! \
dep arg0,31,8,scratch3 ! \
extru,= scratch2,BANK_IO_BIT,1,0 ! \
bl,n get_memory_iocheck_stub_asm,link ! \
ldb (scratch3),ret0
.align 32
.export get_memory_asm
get_memory_asm
; arg0 = addr
extru arg0,23,16,arg3
copy arg0,addr_latch
ldwx,s arg3(page_info_ptr),scratch2
CYCLES_PLUS_1
bb,<,n scratch2,BANK_IO_BIT,get_memory_iocheck_stub_asm
dep arg0,31,8,scratch2
bv 0(link)
ldb (scratch2),ret0
.align 8
.export get_memory16_asm
get_memory16_asm
; arg0 = addr
ldi 0xff,scratch3
extru arg0,23,16,arg3
and scratch3,arg0,scratch4
ldwx,s arg3(page_info_ptr),scratch2
copy arg0,addr_latch
comb,= scratch4,scratch3,get_memory16_pieces_stub_asm
and scratch2,scratch3,scratch3
comb,<> 0,scratch3,get_memory16_pieces_stub_asm
dep arg0,31,8,scratch2
ldb (scratch2),ret0
CYCLES_PLUS_2
ldb 1(scratch2),scratch1
bv 0(link)
dep scratch1,23,8,ret0
.align 8
.export get_memory24_asm
get_memory24_asm
; arg0 = addr
ldi 0xfe,scratch3
extru arg0,23,16,arg3
and scratch3,arg0,scratch4
ldwx,s arg3(page_info_ptr),scratch2
copy arg0,addr_latch
comb,= scratch4,scratch3,get_memory24_pieces_stub_asm
extru scratch2,31,8,scratch3
comb,<> 0,scratch3,get_memory24_pieces_stub_asm
dep arg0,31,8,scratch2
ldb (scratch2),ret0
ldb 1(scratch2),scratch1
CYCLES_PLUS_3
ldb 2(scratch2),scratch2
dep scratch1,23,8,ret0
bv 0(link)
dep scratch2,15,8,ret0
.align 0x20
.export get_memory_iocheck_stub_asm,code
get_memory_iocheck_stub_asm
extru,= scratch2,BANK_BREAK_BIT,1,0
bl check_breakpoints_asm,scratch4
stw link,STACK_GET_MEMORY_SAVE_LINK(sp)
bb,< scratch2,BANK_IO2_BIT,get_memory_io_stub_asm
dep arg0,31,8,scratch2
bv 0(link)
ldb (scratch2),ret0
.export get_memory_io_stub_asm
get_memory_io_stub_asm
FCYCLES_ROUND_1
ldo STACK_SAVE_CYCLES(sp),arg1
FCYCLES_ROUND_2
FCYCLES_ROUND_3
bl get_memory_io,link
fstds fcycles,(arg1)
ldw STACK_GET_MEMORY_SAVE_LINK(sp),link
ldo STACK_SAVE_CYCLES(sp),arg1
bv (link)
fldds (arg1),fcycles
.export get_memory16_pieces_stub_asm,code
get_memory16_pieces_stub_asm
stw addr_latch,STACK_GET_MEMORY16_ADDR_LATCH(sp)
addi 1,arg0,scratch1
stw link,STACK_MEMORY16_SAVE2(sp)
bl get_memory_asm,link
stw scratch1,STACK_MEMORY16_SAVE1(sp)
stw ret0,STACK_MEMORY16_SAVE3(sp)
bl get_memory_asm,link
ldw STACK_MEMORY16_SAVE1(sp),arg0
ldw STACK_MEMORY16_SAVE2(sp),link
copy ret0,scratch1
ldw STACK_MEMORY16_SAVE3(sp),ret0
ldw STACK_GET_MEMORY16_ADDR_LATCH(sp),addr_latch
bv (link)
dep scratch1,23,8,ret0
.export get_memory24_pieces_stub_asm,code
get_memory24_pieces_stub_asm
stw addr_latch,STACK_GET_MEMORY16_ADDR_LATCH(sp)
addi 1,arg0,scratch1
stw link,STACK_GET_MEMORY24_SAVE2(sp)
bl get_memory_asm,link
stw scratch1,STACK_GET_MEMORY24_SAVE1(sp)
stw ret0,STACK_GET_MEMORY24_SAVE3(sp)
bl get_memory_asm,link
ldw STACK_GET_MEMORY24_SAVE1(sp),arg0
ldw STACK_GET_MEMORY24_SAVE1(sp),arg0
stb ret0,STACK_GET_MEMORY24_SAVE3+2(sp)
bl get_memory_asm,link
addi 1,arg0,arg0
ldw STACK_GET_MEMORY24_SAVE2(sp),link
copy ret0,scratch1
ldw STACK_GET_MEMORY24_SAVE3(sp),ret0
ldw STACK_GET_MEMORY16_ADDR_LATCH(sp),addr_latch
bv (link)
dep scratch1,15,8,ret0
; C callable routine to wrap around set_memory_asm
.export set_memory_c
set_memory_c
;arg0 = addr
;arg1 = val
;arg2 = cycles
bl enter_asm,scratch1
nop
bl set_memory_asm,link
nop
b leave_asm
nop
.export set_memory16_c
set_memory16_c
;arg0 = addr
;arg1 = val
;arg2 = cycles
bl enter_asm,scratch1
nop
bl set_memory16_asm,link
nop
b leave_asm
nop
.export set_memory24_c
set_memory24_c
;arg0 = addr
;arg1 = val
;arg2 = cycles
bl enter_asm,scratch1
nop
bl set_memory24_asm,link
nop
b leave_asm
nop
.align 32
.export set_memory_asm
set_memory_asm
; arg0 = addr
; arg1 = val
extru arg0,23,16,arg3
addil l%PAGE_INFO_WR_OFFSET,arg3
CYCLES_PLUS_1
ldwx,s r1(page_info_ptr),scratch2
ldi 0xff,scratch3
and scratch2,scratch3,scratch3
dep arg0,31,8,scratch2
comib,<>,n 0,scratch3,set_memory_special_case
set_memory_cont_asm
bv 0(link)
stb arg1,(scratch2)
.export set_memory_special_case
set_memory_special_case
extru,= scratch3,BANK_BREAK_BIT,1,0
bl check_breakpoints_asm,scratch4
extru arg1,31,8,arg1
set_memory_special_case2
bb,< scratch3,BANK_IO2_BIT,set_memory_io_stub_asm
ldil l%slow_memory,scratch4
bb,< scratch3,BANK_SHADOW_BIT,set_memory_shadow1_asm
extru arg0,31,16,arg3
bb,< scratch3,BANK_SHADOW2_BIT,set_memory_shadow2_asm
nop
bb,< scratch3,BANK_BREAK_BIT,set_memory_cont_asm
nop
break
set_memory_shadow1_asm
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_1
#endif
add arg3,scratch4,scratch4
extru arg3,31-SHIFT_PER_CHANGE,5,scratch1
ldb r%slow_memory(scratch4),arg2
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_2
#endif
mtctl scratch1,cr11
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_3
#endif
comclr,<> arg2,arg1,0
bv 0(link)
stb arg1,(scratch2)
zvdepi 1,1,arg2
extru arg3,31-CHANGE_SHIFT,16-CHANGE_SHIFT,scratch2
ldil l%slow_mem_changed,scratch1
sh2add scratch2,scratch1,scratch1
ldw r%slow_mem_changed(scratch1),scratch3
stb arg1,r%slow_memory(scratch4)
or arg2,scratch3,scratch3
bv 0(link)
stw scratch3,r%slow_mem_changed(scratch1)
set_memory_shadow2_asm
depi 1,15,1,arg3
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_1
#endif
add arg3,scratch4,scratch4
extru arg3,31-SHIFT_PER_CHANGE,5,scratch1
ldb r%slow_memory(scratch4),arg2
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_2
#endif
mtctl scratch1,cr11
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_3
#endif
comclr,<> arg2,arg1,0
bv 0(link)
stb arg1,(scratch2)
zvdepi 1,1,arg2
extru arg3,31-CHANGE_SHIFT,16-CHANGE_SHIFT,scratch2
ldil l%slow_mem_changed,scratch1
sh2add scratch2,scratch1,scratch1
ldw r%slow_mem_changed(scratch1),scratch3
stb arg1,r%slow_memory(scratch4)
or arg2,scratch3,scratch3
bv 0(link)
stw scratch3,r%slow_mem_changed(scratch1)
set_memory_io_stub_asm
FCYCLES_ROUND_1
ldo STACK_SAVE_CYCLES(sp),arg2
FCYCLES_ROUND_2
stw link,STACK_SET_MEMORY_SAVE_LINK(sp)
FCYCLES_ROUND_3
bl set_memory_io,link
fstds fcycles,(arg2)
ldw STACK_SET_MEMORY_SAVE_LINK(sp),link
ldo STACK_SAVE_CYCLES(sp),arg2
bv (link)
fldds (arg2),fcycles
.align 8
.export set_memory16_asm
set_memory16_asm
; arg0 = addr
; arg1 = val
extru arg0,23,16,arg3
addil l%PAGE_INFO_WR_OFFSET,arg3
extrs arg0,31,8,scratch4
ldwx,s r1(page_info_ptr),scratch2
ldi 0xff,scratch3
and scratch3,scratch2,scratch3
dep arg0,31,8,scratch2
comib,=,n -1,scratch4,set_memory16_pieces_stub_asm
comib,<>,n 0,scratch3,set_memory16_special_case
set_memory16_cont_asm
stb arg1,0(scratch2)
CYCLES_PLUS_2
extru arg1,23,8,arg3
bv 0(link)
stb arg3,1(scratch2)
.align 8
set_memory16_shadow1_asm
CYCLES_PLUS_2
copy arg1,arg2
extru arg1,23,8,arg1
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_1
#endif
add arg3,scratch4,scratch4
dep arg2,23,8,arg1
extru arg3,31-SHIFT_PER_CHANGE,5,scratch1
ldh r%slow_memory(scratch4),arg2
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_2
#endif
mtctl scratch1,cr11
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_3
#endif
comclr,<> arg2,arg1,0 ;return if arg2 == arg1
bv 0(link)
sth arg1,(scratch2)
zvdepi 1,1,arg2
extru arg3,31-CHANGE_SHIFT,16-CHANGE_SHIFT,scratch2
ldil l%slow_mem_changed,scratch1
sh2add scratch2,scratch1,scratch1
ldw r%slow_mem_changed(scratch1),scratch3
sth arg1,r%slow_memory(scratch4)
or arg2,scratch3,scratch3
bv 0(link)
stw scratch3,r%slow_mem_changed(scratch1)
.align 8
set_memory16_shadow2_asm
CYCLES_PLUS_2
copy arg1,arg2
extru arg1,23,8,arg1
depi 1,15,1,arg3
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_1
#endif
dep arg2,23,8,arg1
add arg3,scratch4,scratch4
extru arg3,31-SHIFT_PER_CHANGE,5,scratch1
ldh r%slow_memory(scratch4),arg2
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_2
#endif
mtctl scratch1,cr11
#ifdef ACCURATE_SLOW_MEM
FCYCLES_ROUND_3
#endif
comclr,<> arg2,arg1,0
bv 0(link)
sth arg1,(scratch2)
zvdepi 1,1,arg2
extru arg3,31-CHANGE_SHIFT,16-CHANGE_SHIFT,scratch2
ldil l%slow_mem_changed,scratch1
sh2add scratch2,scratch1,scratch1
ldw r%slow_mem_changed(scratch1),scratch3
sth arg1,r%slow_memory(scratch4)
or arg2,scratch3,scratch3
bv 0(link)
stw scratch3,r%slow_mem_changed(scratch1)
.align 8
set_memory16_special_case
extru,= scratch3,BANK_BREAK_BIT,1,0
bl check_breakpoints_asm,scratch4
extru arg1,31,16,arg1
set_memory16_special_case2
bb,< scratch3,BANK_IO2_BIT,set_memory16_pieces_stub_asm
ldil l%slow_memory,scratch4
; if not halfword aligned, go through pieces_stub_asm
bb,<,n arg0,31,set_memory16_pieces_stub_asm
bb,< scratch3,BANK_SHADOW2_BIT,set_memory16_shadow2_asm
extru arg0,31,16,arg3
bb,< scratch3,BANK_SHADOW_BIT,set_memory16_shadow1_asm
nop
bb,< scratch3,BANK_BREAK_BIT,set_memory16_cont_asm
nop
break
.align 8
set_memory16_pieces_stub_asm
addi 1,arg0,scratch1
stw link,STACK_MEMORY16_SAVE3(sp)
extru arg1,23,8,scratch2
stw scratch1,STACK_MEMORY16_SAVE1(sp)
bl set_memory_asm,link
stw scratch2,STACK_MEMORY16_SAVE2(sp)
ldw STACK_MEMORY16_SAVE1(sp),arg0
ldw STACK_MEMORY16_SAVE2(sp),arg1
b set_memory_asm
ldw STACK_MEMORY16_SAVE3(sp),link
.align 8
.export set_memory24_asm
set_memory24_asm
; arg0 = addr
; arg1 = val
extru arg0,23,16,arg3
addil l%PAGE_INFO_WR_OFFSET,arg3
extrs arg0,30,7,scratch4
ldwx,s r1(page_info_ptr),scratch2
ldi 0xff,scratch3
and scratch3,scratch2,scratch3
dep arg0,31,8,scratch2
comib,=,n -1,scratch4,set_memory24_pieces_stub_asm
comib,<>,n 0,scratch3,set_memory24_pieces_stub_asm
stb arg1,0(scratch2)
extru arg1,23,8,arg3
CYCLES_PLUS_3
stb arg3,1(scratch2)
extru arg1,15,8,arg3
bv 0(link)
stb arg3,2(scratch2)
set_memory24_pieces_stub_asm
addi 1,arg0,scratch1
stw link,STACK_SET_MEMORY24_SAVE3(sp)
extru arg1,23,16,scratch2
stw scratch1,STACK_SET_MEMORY24_SAVE1(sp)
bl set_memory_asm,link
stw scratch2,STACK_SET_MEMORY24_SAVE2(sp)
ldw STACK_SET_MEMORY24_SAVE1(sp),arg0
bl set_memory_asm,link
ldw STACK_SET_MEMORY24_SAVE2(sp),arg1
ldw STACK_SET_MEMORY24_SAVE1(sp),arg0
ldw STACK_SET_MEMORY24_SAVE3(sp),link
addi 1,arg0,arg0
b set_memory_asm
ldb STACK_SET_MEMORY24_SAVE2+2(sp),arg1
.import g_num_breakpoints,data
.import g_breakpts,data
.align 8
.export check_breakpoints_asm,code
check_breakpoints_asm
; can't use arg0-arg3. don't use scratch2,scratch3
; scratch4: return link
;
ldil l%g_num_breakpoints,scratch1
ldil l%g_breakpts,ret0
ldw r%g_num_breakpoints(scratch1),r1
ldo r%g_breakpts(ret0),ret0
addi,>= -1,r1,r1
bv,n 0(scratch4)
ldwx,s r1(ret0),scratch1
check_breakpoints_loop_asm
comb,=,n scratch1,arg0,check_breakpoints_hit
addib,>=,n -1,r1,check_breakpoints_loop_asm
ldwx,s r1(ret0),scratch1
bv 0(scratch4)
nop
.export check_breakpoints_hit,code
check_breakpoints_hit
LDC(halt_sim,scratch1)
ldw (scratch1),r1
ldil l%g_fcycles_stop,ret0
depi 1,31,1,r1
stw 0,r%g_fcycles_stop(ret0)
stw 0,r%g_fcycles_stop+4(ret0)
bv 0(scratch4)
stw r1,(scratch1)
nop
nop
nop
.align 8
.export set_mem_yreg
set_mem_yreg
; arg0 = addr to write
extru,= psr,27,1,0 ;null branch if 16 bit
b set_memory_asm
copy yreg,arg1
;if get here, 16 bit yreg
b,n set_memory16_asm
nop
.align 8
.export set_mem_xreg
set_mem_xreg
; arg0 = addr to write
extru,= psr,27,1,0 ;null branch if 16 bit
b set_memory_asm
copy xreg,arg1
;if get here, 16 bit xreg
b,n set_memory16_asm
nop
.export get_memory_outofrange,code
get_memory_outofrange
break
get_mem_b0_16_stub
b get_mem_b0_16
nop
.align 8
get_mem_b0_direct_page_16
; get 2 bytes for direct-page fetch.
; arg0 = addr;
; if emul and dl = 0, then stick dh in
; into high bytes.
; if emul, grab + 1 byte from dh page also.
; if not emul, just call get_mem_b0
ldi 0xff,scratch2
extru,<> psr,23,1,0 ;null next if emul bit set
b get_mem_b0_16
extru direct,23,8,scratch1
and arg0,scratch2,scratch3
extru,<> direct,31,8,0 ;null if direct not page aligned
dep scratch1,23,24,arg0 ;..done only if direct is page aligned
comb,<> scratch3,scratch2,get_mem_b0_16_stub
stw link,STACK_GET_MEM_B0_DIRECT_SAVELINK(sp)
; we're at 0x??ff, so next byte needs to come from 0x??00.
bl get_mem_b0_8,link
stw arg0,STACK_GET_MEM_B0_DIRECT_ARG0(sp)
; now, get next byte
ldw STACK_GET_MEM_B0_DIRECT_ARG0(sp),arg0
extru direct,23,8,scratch1
stw ret0,STACK_GET_MEM_B0_DIRECT_RET0(sp)
addi 1,arg0,arg0
extru,<> direct,31,8,0 ;null if direct not page aligned
dep scratch1,23,24,arg0 ;..done only if direct is page aligned
bl get_mem_b0_8,link
nop
; and return
copy ret0,scratch2
ldw STACK_GET_MEM_B0_DIRECT_SAVELINK(sp),scratch1
ldb STACK_GET_MEM_B0_DIRECT_RET0+3(sp),ret0
bv (scratch1)
dep scratch2,23,8,ret0
push_8
copy arg0,arg1
copy stack,arg0
addi -1,stack,stack
extru,= psr,23,1,0 ;emul mode?
depi 1,23,24,stack
b set_mem_b0_8
extru stack,31,16,stack
pull_8
addi 1,stack,stack
extru,= psr,23,1,0
depi 1,23,24,stack
extru stack,31,16,stack
b get_mem_b0_8
copy stack,arg0
push_16
copy arg0,arg1
bb,>= psr,23,push_16_native
extru stack,30,7,scratch1
; push_16_emul
addi -2,stack,stack
comib,= 0,scratch1,push_16_emul_page
addi 1,stack,arg0 ;we know we are not at end of page
b set_mem_b0_16
depi 1,23,24,stack
push_16_emul_page
stw link,STACK_SAVE_PUSH16_LINK(sp)
addi 1,arg0,arg0
stw arg1,STACK_SAVE_PUSH16_ARG1(sp)
depi 1,23,24,arg0
bl set_mem_b0_8,link
extru arg1,23,8,arg1
; and do next push
addi 1,stack,arg0
depi 1,23,24,stack
ldw STACK_SAVE_PUSH16_LINK(sp),link
ldb STACK_SAVE_PUSH16_ARG1+3(sp),arg1
b set_mem_b0_8
depi 1,23,24,arg0
push_16_native
; here, we're a native push_16
addi -2,stack,stack
comib,= 0,scratch1,push_16_nat_page
addi 1,stack,arg0 ;we know we are not at end of page
b set_mem_b0_16
extru stack,31,16,stack
push_16_nat_page
stw link,STACK_SAVE_PUSH16_LINK(sp)
addi 1,arg0,arg0
stw arg1,STACK_SAVE_PUSH16_ARG1(sp)
extru arg0,31,16,arg0
bl set_mem_b0_8,link
extru arg1,23,8,arg1
; and do next push
addi 1,stack,arg0
extru stack,31,16,stack
ldw STACK_SAVE_PUSH16_LINK(sp),link
ldb STACK_SAVE_PUSH16_ARG1+3(sp),arg1
b set_mem_b0_8
extru arg0,31,16,arg0
push_16_unsafe
copy arg0,arg1
addi -1,stack,arg0
addi -2,stack,stack
extru,= psr,23,1,0
depi 1,23,24,stack
extru arg0,31,16,arg0
b set_mem_b0_16
extru stack,31,16,stack
push_24_unsafe
copy arg0,arg1
addi -2,stack,arg0
addi -3,stack,stack
extru,= psr,23,1,0
depi 1,23,24,stack
extru arg0,31,16,arg0
b set_mem_b0_24
extru stack,31,16,stack
pull_16_unsafe
addi 1,stack,stack
extru,= psr,23,1,0
depi 1,23,24,stack
extru stack,31,16,arg0
addi 1,stack,stack
extru,= psr,23,1,0
depi 1,23,24,stack
b get_mem_b0_16
extru stack,31,16,stack
.align 8
pull_16
extrs stack,29,6,scratch1
bb,< psr,23,pull_16_emul
addi 1,stack,arg0
comib,= -1,scratch1,pull_16_nat_page
addi 2,stack,stack
; if we get here, native & not near page cross
extru arg0,31,16,arg0
b get_mem_b0_16
extru stack,31,16,stack
pull_16_emul
comib,= -1,scratch1,pull_16_emul_page
addi 2,stack,stack
; if get here, emul & not near page cross
b get_mem_b0_16
depi 1,23,24,stack
pull_16_nat_page
stw link,STACK_SAVE_PULL16_LINK(sp)
bl get_mem_b0_8,link
extru arg0,31,16,arg0
; got first byte
stw ret0,STACK_SAVE_PULL16_RET0(sp)
extru stack,31,16,stack
bl get_mem_b0_8,link
copy stack,arg0
; got second byte
ldw STACK_SAVE_PULL16_LINK(sp),link
copy ret0,scratch1
ldb STACK_SAVE_PULL16_RET0+3(sp),ret0
bv 0(link)
dep scratch1,23,8,ret0
pull_16_emul_page
stw link,STACK_SAVE_PULL16_LINK(sp)
bl get_mem_b0_8,link
depi 1,23,24,arg0
; got first byte
stw ret0,STACK_SAVE_PULL16_RET0(sp)
depi 1,23,24,stack
bl get_mem_b0_8,link
copy stack,arg0
; got second byte
ldw STACK_SAVE_PULL16_LINK(sp),link
copy ret0,scratch1
ldb STACK_SAVE_PULL16_RET0+3(sp),ret0
bv 0(link)
dep scratch1,23,8,ret0
.export pull_24,code
pull_24
extrs stack,29,6,scratch1
bb,< psr,23,pull_24_emul
addi 1,stack,arg0
comib,= -1,scratch1,pull_24_nat_page
addi 3,stack,stack
; if we get here, native & not near page cross, go for it
extru arg0,31,16,arg0
b get_mem_b0_24
extru stack,31,16,stack
pull_24_emul
depi 1,23,24,arg0
comib,= -1,scratch1,pull_24_emul_page
addi 3,stack,stack
; if we get here, emul & not near page cross
b get_mem_b0_24
depi 1,23,24,stack
pull_24_nat_page
stw link,STACK_SAVE_PULL24_LINK(sp)
bl get_mem_b0_8,link
extru arg0,31,16,arg0
; got first byte
stw ret0,STACK_SAVE_PULL24_RET0(sp)
addi -1,stack,arg0
extru stack,31,16,stack
bl get_mem_b0_8,link
extru arg0,31,16,arg0
; got second byte
stb ret0,STACK_SAVE_PULL24_RET0+2(sp)
bl get_mem_b0_8,link
copy stack,arg0
; got all bytes
ldw STACK_SAVE_PULL24_LINK(sp),link
copy ret0,scratch1
ldw STACK_SAVE_PULL24_RET0(sp),ret0
bv (link)
dep scratch1,15,8,ret0
pull_24_emul_page
stw link,STACK_SAVE_PULL24_LINK(sp)
bl get_mem_b0_8,link
nop
; got first byte
addi -1,stack,arg0
stw ret0,STACK_SAVE_PULL24_RET0(sp)
depi 1,23,24,stack
bl get_mem_b0_8,link
depi 1,23,24,arg0
; got second byte
stb ret0,STACK_SAVE_PULL24_RET0+2(sp)
bl get_mem_b0_8,link
copy stack,arg0
; got all bytes
ldw STACK_SAVE_PULL24_LINK(sp),link
copy ret0,scratch1
ldw STACK_SAVE_PULL24_RET0(sp),ret0
bv (link)
dep scratch1,15,8,ret0
update_system_state_and_change_kbank
; kbank already changed..do nothing
update_system_state
; psr is new psw state
; arg0 is old in bits 31 and 30
ldi 0x30,scratch1
extru,= psr,23,1,0
depi 3,27,2,psr
and psr,scratch1,scratch1
extru,= psr,23,1,0
depi 1,23,24,stack
dep arg0,29,2,scratch1
blr scratch1,0
addit,>= -0x3d,scratch1,0
; 0000: no change
b update_sys9
nop ! nop ! nop
nop ! nop ! nop ! nop
; 0001: x from 1->0
b update_sys9
ldi 2,scratch1
nop ! nop
nop ! nop ! nop ! nop
; 0010: m from 1->0
b resize_acc_to16
ldi 0,ret0
nop ! nop
nop ! nop ! nop ! nop
; 0011: m,x from 1->0
b resize_acc_to16
ldi 0,ret0
nop ! nop
nop ! nop ! nop ! nop
; 0100: x from 0->1
depi 0,23,24,yreg
b update_sys9
depi 0,23,24,xreg
nop
nop ! nop ! nop ! nop
; 0101: no change
b update_sys9
nop ! nop ! nop
nop ! nop ! nop ! nop
; 0110: x from 0->1, m from 1->0
depi 0,23,24,yreg
ldi 0,ret0
b resize_acc_to16
depi 0,23,24,xreg
nop ! nop ! nop ! nop
; 0111: m from 1->0
b resize_acc_to16
ldi 0,ret0
nop ! nop
nop ! nop ! nop ! nop
; 1000: m from 0->1
b resize_acc_to8
ldi 0,ret0
nop ! nop
nop ! nop ! nop ! nop
; 1001: m from 0->1, x from 1->0
b resize_acc_to8
ldi 0,ret0
nop ! nop
nop ! nop ! nop ! nop
; 1010: no change
b update_sys9
nop ! nop ! nop
nop ! nop ! nop ! nop
; 1011: x from 1->0
b update_sys9
nop ! nop ! nop
nop ! nop ! nop ! nop
; 1100: m,x from 0->1
depi 0,23,24,yreg
ldi 0,ret0
b resize_acc_to8
depi 0,23,24,xreg
nop ! nop ! nop ! nop
; 1101: m from 0->1
b resize_acc_to8
ldi 0,ret0
nop ! nop
nop ! nop ! nop ! nop
; 1110: x from 0->1
depi 0,23,24,yreg
ldi 0,ret0
b update_sys9
depi 0,23,24,xreg
nop ! nop ! nop ! nop
; 1111: no change
b update_sys9
nop ! nop ! nop
nop ! nop ! nop ! nop
; 10000
break
.export get_yreg_from_mem,code
get_yreg_from_mem
; arg0 = addr to read from, write into yreg
bb,>=,n psr,27,get_yreg_from_mem16
bl get_mem_b0_8,link
extru arg0,31,24,arg0
extru ret0,31,8,zero
extru ret0,24,1,neg
b dispatch
copy zero,yreg
.export get_yreg_from_mem16,code
get_yreg_from_mem16
bl get_mem_b0_16,link
extru arg0,31,24,arg0
extru ret0,31,16,zero
extru ret0,16,1,neg
b dispatch
copy zero,yreg
.export get_xreg_from_mem,code
get_xreg_from_mem
; arg0 = addr to read from, write into xreg
bb,>=,n psr,27,get_xreg_from_mem16
bl get_mem_b0_8,link
extru arg0,31,24,arg0
extru ret0,31,8,zero
extru ret0,24,1,neg
b dispatch
copy zero,xreg
.export get_xreg_from_mem16,code
get_xreg_from_mem16
bl get_mem_b0_16,link
extru arg0,31,24,arg0
extru ret0,31,16,zero
extru ret0,16,1,neg
b dispatch
copy zero,xreg
.export enter_engine,code
enter_engine
; load up regs with struct vals
.proc
.callinfo frame=STACK_ENGINE_SIZE,caller,save_rp,entry_gr=18,entry_fr=19
.enter
ldw ENGINE_FPLUS_PTR(arg0),scratch1 ;fplus ptr
fldds ENGINE_FCYCLES(arg0),fcycles
ldil l%g_fcycles_stop,fcycles_stop_ptr
ldw ENGINE_REG_ACC(arg0),acc
ldo r%g_fcycles_stop(fcycles_stop_ptr),fcycles_stop_ptr
fldds FPLUS_PLUS_1(scratch1),fr_plus_1
ldo FPLUS_PLUS_3(scratch1),ret0
fldds FPLUS_PLUS_2(scratch1),fr_plus_2
ldil l%g_last_vbl_dcycs,ret1
fldds FPLUS_PLUS_3-FPLUS_PLUS_3(ret0),fr_plus_3
ldo r%g_last_vbl_dcycs(ret1),ret1
fldds FPLUS_PLUS_X_M1-FPLUS_PLUS_3(ret0),fr_plus_x_m1
fldds 0(ret1),fcycles_last_dcycs
ldil l%table8,ret0
ldw ENGINE_REG_XREG(arg0),xreg
ldil l%table16,inst_tab_ptr
ldw ENGINE_REG_YREG(arg0),yreg
ldo r%table8(ret0),ret0
ldw ENGINE_REG_STACK(arg0),stack
ldo r%table16(inst_tab_ptr),inst_tab_ptr
ldw ENGINE_REG_PSR(arg0),psr
ldi 0,zero
ldw ENGINE_REG_DBANK(arg0),dbank
ldil l%page_info_rd_wr,page_info_ptr
ldw ENGINE_REG_DIRECT(arg0),direct
extru,= psr,26,1,0 ;nullify if acc size = 0 == 16bit
copy ret0,inst_tab_ptr
ldw ENGINE_REG_KPC(arg0),kpc
ldo r%page_info_rd_wr(page_info_ptr),page_info_ptr
extru,<> psr,30,1,0
ldi 1,zero
extru psr,24,1,neg
stw arg0,STACK_SAVE_ARG0(sp)
ldi 0xfd,const_fd
b dispatch
ldi 0,scratch1
.export resize_acc_to8,code
resize_acc_to8
ldil l%table8,inst_tab_ptr
extru psr,27,1,scratch1 ;size of x
b update_sys9
ldo r%table8(inst_tab_ptr),inst_tab_ptr
.export resize_acc_to16,code
resize_acc_to16
ldil l%table16,inst_tab_ptr
extru psr,27,1,scratch1
b update_sys9
ldo r%table16(inst_tab_ptr),inst_tab_ptr
dispatch_done_cycles_mismatch
ldi -1,ret0
b dispatch_done
nop
.export dispatch_done
dispatch_done
bl refresh_engine_struct,link
ldw STACK_SAVE_ARG0(sp),arg0
.leave
.procend
refresh_engine_struct
; warning--this routine must not change arg1, arg2, arg3, or ret0
; can only change scratch1
comiclr,<> 0,zero,scratch1
ldi 1,scratch1
dep neg,24,1,psr
dep scratch1,30,1,psr
stw acc,ENGINE_REG_ACC(arg0)
stw xreg,ENGINE_REG_XREG(arg0)
stw yreg,ENGINE_REG_YREG(arg0)
stw stack,ENGINE_REG_STACK(arg0)
stw dbank,ENGINE_REG_DBANK(arg0)
stw direct,ENGINE_REG_DIRECT(arg0)
stw psr,ENGINE_REG_PSR(arg0)
stw kpc,ENGINE_REG_KPC(arg0)
bv 0(link)
fstds fcycles,ENGINE_FCYCLES(arg0)
.export check_irqs_pending,code
update_sys9
check_irqs_pending
; if any g_irq_pending, return RET_IRQ
ldil l%g_irq_pending,scratch1
ldw r%g_irq_pending(scratch1),scratch2
bb,<,n psr,29,dispatch
comib,= 0,scratch2,dispatch
zdepi RET_IRQ,3,4,ret0
b,n dispatch_done
nop
.export clr_halt_act
.export set_halt_act
clr_halt_act
LDC(halt_sim,scratch1)
bv 0(link)
stw 0,(scratch1)
set_halt_act
LDC(halt_sim,scratch1)
ldw (scratch1),scratch2
ldil l%g_fcycles_stop,scratch3
stw 0,r%g_fcycles_stop(scratch3)
or scratch2,arg0,arg0
stw 0,r%g_fcycles_stop+4(scratch3)
bv 0(link)
stw arg0,(scratch1)
.align 32
.export dispatch_fast,code
dispatch_fast
; instr is the instr to fetch
#ifdef LOG_PC
b dispatch
nop
#endif
fldds 0(fcycles_stop_ptr),fcycles_stop
extru kpc,23,16,arg2
extru kpc,31,8,scratch4
ldwx,s arg2(page_info_ptr),scratch2
ldwx,s instr(inst_tab_ptr),link
fcmp,>,dbl fcycles,fcycles_stop ;C=1 if must stop
addl scratch4,scratch2,scratch1
comclr,>= scratch4,const_fd,0 ;stop for pieces if near end of page
ldi -1,scratch2
bb,<,n scratch2,BANK_IO_BIT,dispatch_instr_io
ftest ;null next if can cont
bv 0(link)
CYCLES_PLUS_2
b dispatch_instr_io
CYCLES_MINUS_2
.align 32
.export dispatch,code
dispatch
#ifdef CHECK_SIZE_CONSISTENCY
nop
bl check_size_consist,link
nop
#endif
#ifdef DEBUG_TOOLBOX
ldil l%g_rom_version,scratch1
ldw r%g_rom_version(scratch1),scratch1
ldi 0x00db,scratch1 ;ROM 01
comiclr,> 3,scratch1,0
ldi 0x00e5,scratch1 ;ROM 03
depi -2,15,8,scratch1 ;set bank to 0xfe
comb,<>,n scratch1,kpc,no_debug_toolbox
copy xreg,arg0
copy stack,arg1
bl toolbox_debug_c,link
copy cycles,arg2
extru kpc,23,16,scratch2
no_debug_toolbox
#endif
fldds 0(fcycles_stop_ptr),fcycles_stop
extru kpc,23,16,arg2
ldi 0xfd,scratch3
ldwx,s arg2(page_info_ptr),scratch2
fcmp,<=,dbl fcycles,fcycles_stop ;C=1 if can cont
extru kpc,31,8,scratch4
ldbx scratch4(scratch2),instr
comclr,>= scratch4,scratch3,0 ;stop for pieces if near end of page
ftest ;null next if can cont
ldi -1,scratch2
ldwx,s instr(inst_tab_ptr),link
addl scratch4,scratch2,scratch1
bb,<,n scratch2,BANK_IO_BIT,dispatch_instr_io
; depi 0,31,3,link
#ifndef LOG_PC
bv 0(link)
CYCLES_PLUS_2
#else
CYCLES_PLUS_2
.import log_pc_ptr,data
.import log_pc_start_ptr,data
.import log_pc_end_ptr,data
.export log_pc_asm
log_pc_asm
; save regs into log_pc_ptr, wrap around to log_pc_start_ptr if
; log_pc_ptr gets > log_pc_end_ptr
ldb 1(scratch1),scratch3
dep neg,24,1,psr ;set neg
ldb 2(scratch1),scratch2
ldil l%log_pc_ptr,scratch4
ldb 3(scratch1),ret0
fsub,dbl fcycles_last_dcycs,fr_plus_2,ftmp1
dep scratch2,23,8,scratch3
ldo r%log_pc_ptr(scratch4),scratch4
dep instr,7,8,scratch3
ldw 0(scratch4),scratch2
dep ret0,15,8,scratch3
copy kpc,ret1
depi 0,30,1,psr ;zero
comiclr,<> 0,zero,0
depi 1,30,1,psr ;set zero
stw scratch3,LOG_PC_INSTR(scratch2)
dep dbank,7,8,ret1
copy acc,scratch3
dep psr,15,16,scratch3
fadd,dbl fcycles,ftmp1,ftmp1
stw ret1,LOG_PC_DBANK_KPC(scratch2)
copy yreg,ret1
stw scratch3,LOG_PC_PSR_ACC(scratch2)
dep xreg,15,16,ret1
copy direct,scratch3
fstds ftmp1,LOG_PC_DCYCS(scratch2)
ldw rs%log_pc_end_ptr-log_pc_ptr(scratch4),ret0
dep stack,15,16,scratch3
stw ret1,LOG_PC_XREG_YREG(scratch2)
addi LOG_PC_SIZE,scratch2,r31
stw scratch3,LOG_PC_STACK_DIRECT(scratch2)
; comb,>= r31,ret0,log_pc_oflow
; nop
comclr,< r31,ret0,0
; reload log_pc with log_pc_start_ptr
ldw rs%log_pc_start_ptr-log_pc_ptr(scratch4),r31
bv 0(link)
stw r31,0(scratch4)
log_pc_oflow
ldil l%g_fcycles_stop,scratch3
ldil l%halt_sim,ret0
stw 0,r%g_fcycles_stop(scratch3)
ldi 2,arg0
stw 0,r%g_fcycles_stop+4(scratch3)
stw arg0,r%halt_sim(ret0)
ldw rs%log_pc_start_ptr-log_pc_ptr(scratch4),r31
bv 0(link)
stw r31,0(scratch4)
#endif
.export dispatch_instr_io,code
dispatch_instr_io
; check if we're here because of timeout or halt required
fcmp,<=,dbl fcycles,fcycles_stop ;C=1 if we can cont
ldwx,s arg2(page_info_ptr),scratch2
ftest ;do next instr if must stop
b,n dispatch_done_clr_ret0
bb,>=,n scratch2,BANK_IO_BIT,dispatch_instr_pieces
ldil l%0xc700,scratch1
ldo r%0xc700(scratch1),scratch1
addi 0x0a,scratch1,scratch2
comb,= scratch1,kpc,dispatch_done
zdepi RET_C700,3,4,ret0
addi 0xd,scratch1,scratch3
comb,= scratch2,kpc,dispatch_done
zdepi RET_C70A,3,4,ret0
comb,= scratch3,kpc,dispatch_done
zdepi RET_C70D,3,4,ret0
.export dispatch_instr_pieces,code
dispatch_instr_pieces
; fetch pc, get size from inst_info_ptr
bl get_mem_long_8,link
copy kpc,arg0
; ret is instr
ldwx,s ret0(inst_tab_ptr),link
ldil l%sizes_tab,scratch4
copy ret0,instr
ldo r%sizes_tab(scratch4),scratch4
addi 1,kpc,arg0
ldbx instr(scratch4),scratch2
#ifdef LOG_PC
; save "real" link so call_log_pc can restore it
stw link,STACK_SAVE_DISPATCH_LINK(sp)
LDC(call_log_pc,link)
stw instr,STACK_SAVE_INSTR(sp)
#endif
stw link,STACK_SAVE_DISP_PIECES_LINK(sp)
ldi 0x1bea,ret0
sh3add scratch2,0,scratch2
ldo STACK_SAVE_TMP_INST(sp),scratch1
blr scratch2,0
addit,>= -48,scratch2,0
/* must correct cycle count so all instrs are called with cycls += 2 */
/* since get_mem will auto-inc cycles by the number of bytes, we */
/* need to "patch" things here, by adding 1 for 1byte, and subbing */
/* from 3 and 4 byte instrs */
; 0
bv 0(link)
CYCLES_PLUS_1
nop
nop
nop ! nop ! nop ! nop
nop ! nop ! nop ! nop
nop ! nop ! nop ! nop
; 1
bl get_mem_long_8,link
nop
ldw STACK_SAVE_DISP_PIECES_LINK(sp),link
dep ret0,15,8,ret0
ldo STACK_SAVE_TMP_INST(sp),scratch1
bv 0(link)
stw ret0,0(scratch1)
nop ! nop
nop ! nop ! nop ! nop
nop ! nop ! nop ! nop
; 2
bl get_mem_long_16,link
CYCLES_MINUS_1
ldo STACK_SAVE_TMP_INST(sp),scratch1
ldw STACK_SAVE_DISP_PIECES_LINK(sp),link
dep ret0,15,8,ret0
bv 0(link)
stw ret0,0(scratch1)
nop
nop ! nop ! nop ! nop
nop ! nop ! nop ! nop
; 3
bl get_mem_long_24,link
CYCLES_MINUS_2
shd ret0,ret0,16,scratch2
ldw STACK_SAVE_DISP_PIECES_LINK(sp),link
extru ret0,23,8,ret0
ldo STACK_SAVE_TMP_INST(sp),scratch1
dep ret0,23,8,scratch2
bv 0(link)
stw scratch2,0(scratch1)
nop ! nop ! nop
nop ! nop ! nop ! nop
; 4 variable acc size
extru,<> psr,26,1,0
bl,n get_mem_long_16,link
bl,n get_mem_long_8,link
CYCLES_MINUS_1
ldw STACK_SAVE_DISP_PIECES_LINK(sp),link
ldo STACK_SAVE_TMP_INST(sp),scratch1
dep ret0,15,8,ret0
bv 0(link)
stw ret0,0(scratch1)
nop ! nop ! nop
nop ! nop ! nop ! nop
; 5 variable x size
extru,<> psr,27,1,0
bl,n get_mem_long_16,link
bl,n get_mem_long_8,link
CYCLES_MINUS_1
ldw STACK_SAVE_DISP_PIECES_LINK(sp),link
ldo STACK_SAVE_TMP_INST(sp),scratch1
dep ret0,15,8,ret0
bv 0(link)
stw ret0,0(scratch1)
nop ! nop ! nop
nop ! nop ! nop ! nop
; 6 = evil
break
#ifdef LOG_PC
.export call_log_pc,code
call_log_pc
; ret0 = operands
; must get instr = instruction
; and link = correct dispatch loc
ldw STACK_SAVE_INSTR(sp),instr
b log_pc_asm
ldw STACK_SAVE_DISPATCH_LINK(sp),link
#endif
dispatch_done_clr_ret0
nop ;just in case of bad nullification
b dispatch_done
ldi 0,ret0
#ifdef CHECK_SIZE_CONSISTENCY
.import size_fail,code
.export check_size_consist
check_size_consist
ldil l%table16,scratch1
ldil l%table8,scratch2
ldo r%table16(scratch1),scratch1
bb,< psr,26,check_tab_8_bit
ldo r%table8(scratch2),scratch2
; else 16
comb,= scratch1,inst_tab_ptr,acc_size_ok
nop
.export acc_tab_fail1
acc_tab_fail1
copy inst_tab_ptr,arg1
copy scratch1,arg2
bl size_fail,link
ldi 0x100,arg0
b,n dispatch_done_clr_ret0
; 8
.export check_tab_8_bit
check_tab_8_bit
comb,= scratch2,inst_tab_ptr,acc_size_ok
nop
.export acc_tab_fail0
acc_tab_fail0
copy inst_tab_ptr,arg1
copy scratch2,arg2
bl size_fail,link
ldi 0x101,arg0
b dispatch_done
ldi 0,ret0
.export acc_size_ok
acc_size_ok
bv 0(link)
nop
#endif
.align 8
adc_binary_8_entry2
extru psr,31,1,scratch3
add ret0,scratch3,ret0
dep ret0,31,8,acc
extru ret0,31,8,zero
/* and calc overflow */
xor arg0,ret0,arg2 /* cmp binary add res w/ src1 */
xor arg0,scratch2,scratch3 /* cmp signs of two inputs */
extru ret0,24,1,neg
andcm arg2,scratch3,scratch3 /* and that with ~res. */
extru ret0,23,1,scratch4
extru scratch3,24,1,scratch3
dep scratch4,31,1,psr /* set carry */
b dispatch
dep scratch3,25,1,psr /* set overflow */
.align 8
.export adc_binary_8
adc_binary_8
extru ret0,31,8,scratch2
bb,>= psr,28,adc_binary_8_entry2
add arg0,scratch2,ret0
ldil l%dispatch,link
b adc_decimal_8
ldo r%dispatch(link),link
.export adc_decimal_8
/* adds arg0 to scratch2 */
/* acc8 (in arg0) and ret0 have already been added into ret0. Ignore that */
adc_decimal_8
ldi 0xf,scratch1
extru psr,31,1,ret0
and arg0,scratch1,scratch3
and scratch2,scratch1,scratch4
add scratch3,scratch4,ret1
ldi 0xf0,arg3
add ret0,ret1,ret0
and arg0,arg3,scratch3
addi -0xa,ret0,ret1
and scratch2,arg3,scratch4
depi 1,27,4,ret1
comiclr,> 0xa,ret0,0
copy ret1,ret0
add scratch3,scratch4,ret1
add ret0,ret1,ret0
extru ret0,24,1,ret1
extru ret0,23,1,arg1
xor ret1,arg1,ret1
dep ret1,25,1,psr /* ov=((sum>>2) ^ (sum>>1) & 0x40 */
comiclr,> 0xa0,ret0,0
addi 0x60,ret0,ret0
xor arg0,scratch2,scratch4
extru ret0,31,8,zero
extru,= scratch4,24,1,0
depi 0,25,1,psr /* no overflow! */
depi 0,31,1,psr
comiclr,> 0x100,ret0,0
addi 1,psr,psr
extru ret0,24,1,neg
bv 0(link)
dep zero,31,8,acc
.align 8
.export sbc_binary_8,code
sbc_binary_8
extru ret0,31,8,scratch2
bb,>= psr,28,adc_binary_8_entry2
add arg0,scratch2,ret0
ldil l%dispatch,link
b sbc_decimal_8
ldo r%dispatch(link),link
/* else decimal */
.export sbc_decimal_8,code
sbc_decimal_8
/* do arg0 - scratch2 = acc */
ldi 0xf,scratch1
extru psr,31,1,ret0
and scratch2,scratch1,scratch3
and arg0,scratch1,scratch4
add scratch3,ret0,ret0
add ret0,scratch4,ret0
ldi 0xf0,arg3
addi -0x6,ret0,ret1
and scratch2,arg3,scratch3
and ret1,scratch1,ret1 /* sum2 = (sum - 0x6) & 0xf */
and arg0,arg3,scratch4
comiclr,<= 0x10,ret0,0
copy ret1,ret0 /* sum = sum2 */
add scratch3,scratch4,ret1
ldi 0xff,arg2
add ret0,ret1,ret0
extru ret0,24,1,ret1
addi 0xa0,ret0,scratch3
extru ret0,23,1,arg3
and scratch3,arg2,scratch3 /* (sum = sum + 0xa0) & 0xff */
xor ret1,arg3,ret1
dep ret1,25,1,psr /* overflow = ((sum >> 2) ^ */
/* (sum >> 1)) & 0x40 */
depi 0,31,1,psr
comiclr,<= 0x100,ret0,arg3
or,TR scratch3,0,ret0
addi 1,psr,psr
and ret0,arg2,zero
extru ret0,24,1,neg
xor arg0,scratch2,ret1
extru,= ret1,24,1,0
depi 0,25,1,psr /* clear overflow */
bv 0(link)
dep ret0,31,8,acc
.align 8
.export adc_binary_16
adc_binary_16
extru ret0,31,16,scratch2
bb,< psr,28,adc_decimal_16
add arg0,scratch2,ret0
adc_binary_16_entry2
extru psr,31,1,scratch1
add ret0,scratch1,ret0
dep ret0,31,16,acc
extru ret0,31,16,zero
/* and calc overflow */
xor arg0,ret0,arg2 /* cmp binary add res w/ src1 */
xor arg0,scratch2,scratch3
extru ret0,16,1,neg
andcm arg2,scratch3,scratch3 /* and that with ~res. */
extru ret0,15,1,scratch4
extru scratch3,16,1,scratch3
dep scratch4,31,1,psr /* set carry */
b dispatch
dep scratch3,25,1,psr /* set overflow */
.export adc_decimal_16
adc_decimal_16
/* must save arg0, scratch2 */
stw arg0,STACK_SAVE_DECIMAL16_A(sp)
extru arg0,31,8,arg0
stw scratch2,STACK_SAVE_DECIMAL16_B(sp)
bl adc_decimal_8,link
extru scratch2,31,8,scratch2
ldb STACK_SAVE_DECIMAL16_A+2(sp),arg0
ldb STACK_SAVE_DECIMAL16_B+2(sp),scratch2
bl adc_decimal_8,link
stw acc,STACK_SAVE_DECIMAL16_A(sp)
ldw STACK_SAVE_DECIMAL16_A(sp),scratch1
zdep acc,23,8,acc
dep scratch1,31,8,acc
b dispatch
copy acc,zero
.align 8
.export sbc_binary_16,code
sbc_binary_16
extru ret0,31,16,scratch2
bb,>= psr,28,adc_binary_16_entry2
add arg0,scratch2,ret0
/* else decimal */
.export sbc_decimal_16,code
sbc_decimal_16
stw arg0,STACK_SAVE_DECIMAL16_A(sp)
extru arg0,31,8,arg0
stw scratch2,STACK_SAVE_DECIMAL16_B(sp)
bl sbc_decimal_8,link
extru scratch2,31,8,scratch2
ldb STACK_SAVE_DECIMAL16_A+2(sp),arg0
ldb STACK_SAVE_DECIMAL16_B+2(sp),scratch2
bl sbc_decimal_8,link
stw acc,STACK_SAVE_DECIMAL16_A(sp)
ldw STACK_SAVE_DECIMAL16_A(sp),scratch1
zdep acc,23,8,acc
dep scratch1,31,8,acc
b dispatch
copy acc,zero
#define ACC8
.code
#include "defs_instr.h"
#include "8inst_s.h"
.code
#undef SYM
#undef ACC8
.code
#include "defs_instr.h"
#include "16inst_s.h"
.code
#undef SYM
.export inst00_8
.export inst01_8
.export inst02_8
.export inst03_8
.export inst04_8
.export inst05_8
.export inst06_8
.export inst07_8
.export inst08_8
.export inst09_8
.export inst0a_8
.export inst0b_8
.export inst0c_8
.export inst0d_8
.export inst0e_8
.export inst0f_8
.export inst10_8
.export inst11_8
.export inst12_8
.export inst13_8
.export inst14_8
.export inst15_8
.export inst16_8
.export inst17_8
.export inst18_8
.export inst19_8
.export inst1a_8
.export inst1b_8
.export inst1c_8
.export inst1d_8
.export inst1e_8
.export inst1f_8
.export inst20_8
.export inst21_8
.export inst22_8
.export inst23_8
.export inst24_8
.export inst25_8
.export inst26_8
.export inst27_8
.export inst28_8
.export inst29_8
.export inst2a_8
.export inst2b_8
.export inst2c_8
.export inst2d_8
.export inst2e_8
.export inst2f_8
.export inst30_8
.export inst31_8
.export inst32_8
.export inst33_8
.export inst34_8
.export inst35_8
.export inst36_8
.export inst37_8
.export inst38_8
.export inst39_8
.export inst3a_8
.export inst3b_8
.export inst3c_8
.export inst3d_8
.export inst3e_8
.export inst3f_8
.export inst40_8
.export inst41_8
.export inst42_8
.export inst43_8
.export inst44_8
.export inst45_8
.export inst46_8
.export inst47_8
.export inst48_8
.export inst49_8
.export inst4a_8
.export inst4b_8
.export inst4c_8
.export inst4d_8
.export inst4e_8
.export inst4f_8
.export inst50_8
.export inst51_8
.export inst52_8
.export inst53_8
.export inst54_8
.export inst55_8
.export inst56_8
.export inst57_8
.export inst58_8
.export inst59_8
.export inst5a_8
.export inst5b_8
.export inst5c_8
.export inst5d_8
.export inst5e_8
.export inst5f_8
.export inst60_8
.export inst61_8
.export inst62_8
.export inst63_8
.export inst64_8
.export inst65_8
.export inst66_8
.export inst67_8
.export inst68_8
.export inst69_8
.export inst6a_8
.export inst6b_8
.export inst6c_8
.export inst6d_8
.export inst6e_8
.export inst6f_8
.export inst70_8
.export inst71_8
.export inst72_8
.export inst73_8
.export inst74_8
.export inst75_8
.export inst76_8
.export inst77_8
.export inst78_8
.export inst79_8
.export inst7a_8
.export inst7b_8
.export inst7c_8
.export inst7d_8
.export inst7e_8
.export inst7f_8
.export inst80_8
.export inst81_8
.export inst82_8
.export inst83_8
.export inst84_8
.export inst85_8
.export inst86_8
.export inst87_8
.export inst88_8
.export inst89_8
.export inst8a_8
.export inst8b_8
.export inst8c_8
.export inst8d_8
.export inst8e_8
.export inst8f_8
.export inst90_8
.export inst91_8
.export inst92_8
.export inst93_8
.export inst94_8
.export inst95_8
.export inst96_8
.export inst97_8
.export inst98_8
.export inst99_8
.export inst9a_8
.export inst9b_8
.export inst9c_8
.export inst9d_8
.export inst9e_8
.export inst9f_8
.export insta0_8
.export insta1_8
.export insta2_8
.export insta3_8
.export insta4_8
.export insta5_8
.export insta6_8
.export insta7_8
.export insta8_8
.export insta9_8
.export instaa_8
.export instab_8
.export instac_8
.export instad_8
.export instae_8
.export instaf_8
.export instb0_8
.export instb1_8
.export instb2_8
.export instb3_8
.export instb4_8
.export instb5_8
.export instb6_8
.export instb7_8
.export instb8_8
.export instb9_8
.export instba_8
.export instbb_8
.export instbc_8
.export instbd_8
.export instbe_8
.export instbf_8
.export instc0_8
.export instc1_8
.export instc2_8
.export instc3_8
.export instc4_8
.export instc5_8
.export instc6_8
.export instc7_8
.export instc8_8
.export instc9_8
.export instca_8
.export instcb_8
.export instcc_8
.export instcd_8
.export instce_8
.export instcf_8
.export instd0_8
.export instd1_8
.export instd2_8
.export instd3_8
.export instd4_8
.export instd5_8
.export instd6_8
.export instd7_8
.export instd8_8
.export instd9_8
.export instda_8
.export instdb_8
.export instdc_8
.export instdd_8
.export instde_8
.export instdf_8
.export inste0_8
.export inste1_8
.export inste2_8
.export inste3_8
.export inste4_8
.export inste5_8
.export inste6_8
.export inste7_8
.export inste8_8
.export inste9_8
.export instea_8
.export insteb_8
.export instec_8
.export insted_8
.export instee_8
.export instef_8
.export instf0_8
.export instf1_8
.export instf2_8
.export instf3_8
.export instf4_8
.export instf5_8
.export instf6_8
.export instf7_8
.export instf8_8
.export instf9_8
.export instfa_8
.export instfb_8
.export instfc_8
.export instfd_8
.export instfe_8
.export instff_8
.export inst00_16
.export inst01_16
.export inst02_16
.export inst03_16
.export inst04_16
.export inst05_16
.export inst06_16
.export inst07_16
.export inst08_16
.export inst09_16
.export inst0a_16
.export inst0b_16
.export inst0c_16
.export inst0d_16
.export inst0e_16
.export inst0f_16
.export inst10_16
.export inst11_16
.export inst12_16
.export inst13_16
.export inst14_16
.export inst15_16
.export inst16_16
.export inst17_16
.export inst18_16
.export inst19_16
.export inst1a_16
.export inst1b_16
.export inst1c_16
.export inst1d_16
.export inst1e_16
.export inst1f_16
.export inst20_16
.export inst21_16
.export inst22_16
.export inst23_16
.export inst24_16
.export inst25_16
.export inst26_16
.export inst27_16
.export inst28_16
.export inst29_16
.export inst2a_16
.export inst2b_16
.export inst2c_16
.export inst2d_16
.export inst2e_16
.export inst2f_16
.export inst30_16
.export inst31_16
.export inst32_16
.export inst33_16
.export inst34_16
.export inst35_16
.export inst36_16
.export inst37_16
.export inst38_16
.export inst39_16
.export inst3a_16
.export inst3b_16
.export inst3c_16
.export inst3d_16
.export inst3e_16
.export inst3f_16
.export inst40_16
.export inst41_16
.export inst42_16
.export inst43_16
.export inst44_16
.export inst45_16
.export inst46_16
.export inst47_16
.export inst48_16
.export inst49_16
.export inst4a_16
.export inst4b_16
.export inst4c_16
.export inst4d_16
.export inst4e_16
.export inst4f_16
.export inst50_16
.export inst51_16
.export inst52_16
.export inst53_16
.export inst54_16
.export inst55_16
.export inst56_16
.export inst57_16
.export inst58_16
.export inst59_16
.export inst5a_16
.export inst5b_16
.export inst5c_16
.export inst5d_16
.export inst5e_16
.export inst5f_16
.export inst60_16
.export inst61_16
.export inst62_16
.export inst63_16
.export inst64_16
.export inst65_16
.export inst66_16
.export inst67_16
.export inst68_16
.export inst69_16
.export inst6a_16
.export inst6b_16
.export inst6c_16
.export inst6d_16
.export inst6e_16
.export inst6f_16
.export inst70_16
.export inst71_16
.export inst72_16
.export inst73_16
.export inst74_16
.export inst75_16
.export inst76_16
.export inst77_16
.export inst78_16
.export inst79_16
.export inst7a_16
.export inst7b_16
.export inst7c_16
.export inst7d_16
.export inst7e_16
.export inst7f_16
.export inst80_16
.export inst81_16
.export inst82_16
.export inst83_16
.export inst84_16
.export inst85_16
.export inst86_16
.export inst87_16
.export inst88_16
.export inst89_16
.export inst8a_16
.export inst8b_16
.export inst8c_16
.export inst8d_16
.export inst8e_16
.export inst8f_16
.export inst90_16
.export inst91_16
.export inst92_16
.export inst93_16
.export inst94_16
.export inst95_16
.export inst96_16
.export inst97_16
.export inst98_16
.export inst99_16
.export inst9a_16
.export inst9b_16
.export inst9c_16
.export inst9d_16
.export inst9e_16
.export inst9f_16
.export insta0_16
.export insta1_16
.export insta2_16
.export insta3_16
.export insta4_16
.export insta5_16
.export insta6_16
.export insta7_16
.export insta8_16
.export insta9_16
.export instaa_16
.export instab_16
.export instac_16
.export instad_16
.export instae_16
.export instaf_16
.export instb0_16
.export instb1_16
.export instb2_16
.export instb3_16
.export instb4_16
.export instb5_16
.export instb6_16
.export instb7_16
.export instb8_16
.export instb9_16
.export instba_16
.export instbb_16
.export instbc_16
.export instbd_16
.export instbe_16
.export instbf_16
.export instc0_16
.export instc1_16
.export instc2_16
.export instc3_16
.export instc4_16
.export instc5_16
.export instc6_16
.export instc7_16
.export instc8_16
.export instc9_16
.export instca_16
.export instcb_16
.export instcc_16
.export instcd_16
.export instce_16
.export instcf_16
.export instd0_16
.export instd1_16
.export instd2_16
.export instd3_16
.export instd4_16
.export instd5_16
.export instd6_16
.export instd7_16
.export instd8_16
.export instd9_16
.export instda_16
.export instdb_16
.export instdc_16
.export instdd_16
.export instde_16
.export instdf_16
.export inste0_16
.export inste1_16
.export inste2_16
.export inste3_16
.export inste4_16
.export inste5_16
.export inste6_16
.export inste7_16
.export inste8_16
.export inste9_16
.export instea_16
.export insteb_16
.export instec_16
.export insted_16
.export instee_16
.export instef_16
.export instf0_16
.export instf1_16
.export instf2_16
.export instf3_16
.export instf4_16
.export instf5_16
.export instf6_16
.export instf7_16
.export instf8_16
.export instf9_16
.export instfa_16
.export instfb_16
.export instfc_16
.export instfd_16
.export instfe_16
.export instff_16
.data
#include "8size_s.h"
.export table8,data
table8
#include "8size_s.h"
.export table16,data
table16
#include "16size_s.h"
.export sizes_tab,data
sizes_tab
#include "size_s.h"
.export g_engine_c_mode,data
g_engine_c_mode
.word 0
.bss
.export slow_memory,data
.export rom_fc_ff,data
.export rom_cards,data
.export dummy_memory1,data
.align 0x100
slow_memory .block 128*1024
dummy_memory1 .block 3*1024
rom_fc_ff .block 256*1024
rom_cards .block 256*16