mirror of
https://github.com/digarok/gsplus.git
synced 2024-11-30 16:50:45 +00:00
2482 lines
51 KiB
ArmAsm
2482 lines
51 KiB
ArmAsm
/*
|
|
GSPLUS - Advanced Apple IIGS Emulator Environment
|
|
Copyright (C) 2016 - Dagen Brock
|
|
|
|
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
|