Compress cpu65_vmem_* function tables to save space

This commit is contained in:
Aaron Culliney 2019-10-27 14:24:30 -07:00
parent 00984b7ab9
commit 8f2ab2f072
17 changed files with 617 additions and 464 deletions

View File

@ -46,6 +46,7 @@
# define wr0 w0 /* scratch/"important byte" */
# define xr1 x1 /* scratch */
# define wr1 w1 /* scratch */
# define xr9 x2 /* scratch */
# define wr9 w2 /* scratch */
# define xr12 x5 /* overloaded both scratch */
@ -87,6 +88,7 @@
# define wr0 r0 /* scratch/"important byte" */
# define xr1 r1 /* scratch */
# define wr1 r1 /* scratch */
# define xr9 r9 /* scratch */
# define wr9 r9 /* scratch */
// NOTE: these need to be preserved in subroutine (C) invocations ... */

View File

@ -129,8 +129,9 @@
#define GetFromPC_B \
mov EffectiveAddr, PC_Reg; \
lsr wr1, EffectiveAddr, #8; \
IncUint16(PC_Reg) \
ldr xr1, [reg_vmem_r, xEffectiveAddr, LSL PTR_SHIFT]; \
ldr xr1, [reg_vmem_r, xr1, LSL PTR_SHIFT]; \
BLX xr1; \
TRACE_ARG
@ -140,14 +141,16 @@
#define GetFromPC_W \
mov EffectiveAddr, PC_Reg; \
lsr wr1, EffectiveAddr, #8; \
AddUint16(PC_Reg, #2) \
lsl PC_Reg, PC_Reg, #16; \
ldr xr1, [reg_vmem_r, xEffectiveAddr, LSL PTR_SHIFT]; \
ldr xr1, [reg_vmem_r, xr1, LSL PTR_SHIFT]; \
BLX xr1; \
TRACE_ARG \
orr word_reg, word_reg, wr0; \
IncUint16(EffectiveAddr) \
ldr xr1, [reg_vmem_r, xEffectiveAddr, LSL PTR_SHIFT]; \
lsr wr1, EffectiveAddr, #8; \
ldr xr1, [reg_vmem_r, xr1, LSL PTR_SHIFT]; \
BLX xr1; \
TRACE_ARG; \
lsl wr0, wr0, #8; /* hi byte */ \
@ -168,20 +171,23 @@
#define GetFromEA_B \
/* Record CPU read: */ \
ldrb wr1, [reg_args, #CPU65_RW]; \
orr wr1, wr1, #1; \
strb wr1, [reg_args, #CPU65_RW]; \
lsr wr1, EffectiveAddr, #8; \
ldrb wr9, [reg_args, #CPU65_RW]; \
orr wr9, wr9, #1; \
strb wr9, [reg_args, #CPU65_RW]; \
\
ldr xr1, [reg_vmem_r, xEffectiveAddr, LSL PTR_SHIFT]; \
ldr xr1, [reg_vmem_r, xr1, LSL PTR_SHIFT]; \
BLX xr1;
#define GetFromEA_W \
lsr wr1, EffectiveAddr, #8; \
lsl PC_Reg, PC_Reg, #16; \
ldr xr1, [reg_vmem_r, xEffectiveAddr, LSL PTR_SHIFT]; \
ldr xr1, [reg_vmem_r, xr1, LSL PTR_SHIFT]; \
BLX xr1; \
orr word_reg, word_reg, wr0; \
IncUint16(EffectiveAddr) \
ldr xr1, [reg_vmem_r, xEffectiveAddr, LSL PTR_SHIFT]; \
lsr wr1, EffectiveAddr, #8; \
ldr xr1, [reg_vmem_r, xr1, LSL PTR_SHIFT]; \
BLX xr1; \
lsl wr0, wr0, #8; /* hi byte */ \
orr wr0, word_reg, wr0; \
@ -191,18 +197,19 @@
#define PutToEA_B \
/* Record CPU write: */ \
lsr wr1, EffectiveAddr, #8; \
strb wr0, [reg_args, #CPU65_D]; \
ldrb wr1, [reg_args, #CPU65_RW]; \
orr wr1, wr1, #2; \
strb wr1, [reg_args, #CPU65_RW]; \
\
ldr xr1, [reg_args, #CPU65_VMEM_W]; \
ldr xr1, [xr1, xEffectiveAddr, LSL PTR_SHIFT]; \
ldrb wr9, [reg_args, #CPU65_RW]; \
orr wr9, wr9, #2; \
strb wr9, [reg_args, #CPU65_RW]; \
ldr xr9, [reg_args, #CPU65_VMEM_W]; \
ldr xr1, [xr9, xr1, LSL PTR_SHIFT]; \
BLX xr1;
#define GetFromMem_B(x) \
mov EffectiveAddr, x; \
ldr xr1, [reg_vmem_r, xEffectiveAddr, LSL PTR_SHIFT]; \
lsr wr1, EffectiveAddr, #8; \
ldr xr1, [reg_vmem_r, xr1, LSL PTR_SHIFT]; \
BLX xr1;
#define GetFromMem_W(x) \
@ -337,7 +344,8 @@
#if CPU_TRACING
#define GetImm \
_GetImm \
ldr xr1, [reg_vmem_r, xEffectiveAddr, LSL PTR_SHIFT]; \
lsr wr1, EffectiveAddr, #8; \
ldr xr1, [reg_vmem_r, xr1, LSL PTR_SHIFT]; \
BLX xr1; \
TRACE_ARG
#else

View File

@ -111,6 +111,9 @@ ENTRY(func) ldrb wr0, [reg_args, x ## off]; \
_GLUE_RET
#define GLUE_INLINE_READ(func,off) _GLUE_INLINE_READ(func,#,off)
#define GLUE_NOP(func) \
ENTRY(func) _GLUE_RET
#define GLUE_C_WRITE(func) \
ENTRY(func) _GLUE_REG_SAVE0; \

View File

@ -2256,8 +2256,8 @@ static void RegisterIoHandler(unsigned int uSlot, iorfunction IOReadC0, iowfunct
assert((uintptr_t)IOWriteC0);
for (unsigned int i = 0; i < 16; i++)
{
cpu65_vmem_r[base_addr+i] = IOReadC0;
cpu65_vmem_w[base_addr+i] = IOWriteC0;
cpu65_vmem_r[(base_addr+i)>>8] = IOReadC0;
cpu65_vmem_w[(base_addr+i)>>8] = IOWriteC0;
}
}
@ -2265,8 +2265,8 @@ static void RegisterIoHandler(unsigned int uSlot, iorfunction IOReadC0, iowfunct
base_addr = 0xC000 + (uSlot<<8); // uSlot == 4 => 0xC400 , uSlot == 5 => 0xC500
for (unsigned int i = 0; i < 0x100; i++)
{
//cpu65_vmem_r[base_addr+i] = IOReadCx; -- CANNOT DO THIS HERE -- DEPENDS ON cxrom softswitch
cpu65_vmem_w[base_addr+i] = IOWriteCx;
//cpu65_vmem_r[(base_addr+i)>>8] = IOReadCx; -- CANNOT DO THIS HERE -- DEPENDS ON cxrom softswitch
cpu65_vmem_w[(base_addr+i)>>8] = IOWriteCx;
}
}
#endif

View File

@ -519,8 +519,7 @@ double speaker_cyclesPerSample(void) {
// --------------------------------------------------------------------------------------------------------------------
// VM system entry point
GLUE_C_READ(speaker_toggle)
{
uint8_t speaker_toggle(void) {
ASSERT_ON_CPU_THREAD();
timing_checkpointCycles();

View File

@ -21,6 +21,7 @@ void speaker_destroy(void) CALL_ON_CPU_THREAD;
void speaker_reset(void);
void speaker_flush(void) CALL_ON_CPU_THREAD;
bool speaker_isActive(void);
uint8_t speaker_toggle(void) CALL_ON_CPU_THREAD;
/*
* returns the machine cycles per sample

View File

@ -29,8 +29,8 @@ static pthread_mutex_t irq_mutex = PTHREAD_MUTEX_INITIALIZER;
uint8_t cpu65_flags_encode[256] = { 0 };
uint8_t cpu65_flags_decode[256] = { 0 };
void *cpu65_vmem_r[0x10000] = { 0 };
void *cpu65_vmem_w[0x10000] = { 0 };
void *cpu65_vmem_r[sizeof(void*) * 256] = { 0 };
void *cpu65_vmem_w[sizeof(void*) * 256] = { 0 };
#if CPU_TRACING
static int8_t opargs[3] = { 0 };

View File

@ -47,8 +47,8 @@ extern bool cpu65_loadState(StateHelper_s *helper);
extern void cpu65_direct_write(int ea,int data);
extern void *cpu65_vmem_r[65536];
extern void *cpu65_vmem_w[65536];
extern void *cpu65_vmem_r[sizeof(void*) * 256];
extern void *cpu65_vmem_w[sizeof(void*) * 256];
extern uint8_t cpu65_flags_encode[256];
extern uint8_t cpu65_flags_decode[256];

View File

@ -679,8 +679,7 @@ static void _disk_modeSelect(uint16_t ea) {
disk6.ddrw = (ea & 0x1);
}
GLUE_C_READ(disk6_ioRead)
{
uint8_t disk6_ioRead(uint16_t ea) {
uint8_t sw = ea & 0xf;
if (sw <= 0x7) { // C0E0 - C0E7
_disk6_phaseChange(ea);
@ -714,8 +713,7 @@ GLUE_C_READ(disk6_ioRead)
return (ea & 1) ? floating_bus() : disk6.disk_byte;
}
GLUE_C_WRITE(disk6_ioWrite)
{
void disk6_ioWrite(uint16_t ea, uint8_t b) {
uint8_t sw = ea & 0xf;
if (sw <= 0x7) { // C0E0 - C0E7
_disk6_phaseChange(ea);
@ -761,14 +759,6 @@ void disk6_init(void) {
// load Disk II ROM
memcpy(apple_ii_64k[0] + 0xC600, slot6_rom, 0x100);
// disk softswitches
// 0xC0Xi : X = slot 0x6 + 0x8 == 0xE
for (unsigned int i = 0xC0E0; i < 0xC0F0; i++) {
cpu65_vmem_r[i] = disk6_ioRead;
cpu65_vmem_w[i] = disk6_ioWrite;
}
stepper_phases = 0;
disk6.disk[0].phase = disk6.disk[1].phase = 0;

View File

@ -87,10 +87,15 @@ extern const char *disk6_eject(int drive);
// flush all I/O
extern void disk6_flush(int drive);
// save/restore state handling
extern bool disk6_saveState(StateHelper_s *helper);
extern bool disk6_loadState(StateHelper_s *helper);
extern bool disk6_stateExtractDiskPaths(StateHelper_s *helper, JSON_ref json);
// CPU thread I/O
extern uint8_t disk6_ioRead(uint16_t ea) CALL_ON_CPU_THREAD;
extern void disk6_ioWrite(uint16_t ea, uint8_t b) CALL_ON_CPU_THREAD;
#if DISK_TRACING
void disk6_traceToggle(const char *read_file, const char *write_file);
void disk6_traceBegin(const char *read_file, const char *write_file);

View File

@ -30,6 +30,8 @@
#define GLUE_EXTERN_C_READ(func) extern uint8_t func(uint16_t)
#define GLUE_NOP(func) extern void func(void);
#if VM_TRACING
#define GLUE_C_WRITE(func) \

View File

@ -1089,7 +1089,6 @@ void c_interface_parameters()
else if ((ch == kESC) || c_keys_is_interface_key(ch))
{
timing_initialize();
vm_reinitializeAudio();
c_joystick_reset();
#if !TESTING
prefs_save();

913
src/vm.c

File diff suppressed because it is too large Load Diff

View File

@ -125,8 +125,6 @@ extern uint8_t language_banks[2][8192];
void vm_initialize(void);
void vm_reinitializeAudio(void);
extern bool vm_saveState(StateHelper_s *helper);
extern bool vm_loadState(StateHelper_s *helper);
@ -141,25 +139,57 @@ void vm_printSoftwitches(FILE *fp, bool output_mem, bool output_pseudo);
#endif // !defined(__ASSEMBLER__)
// softswitch flag bits
// SHIFT macros are for generating 0x80 or 0x00 bytes
#define SS_TEXT 0x00000001
#define SS_TEXT_SHIFT <<7
#define SS_MIXED 0x00000002
#define SS_MIXED_SHIFT <<6
#define SS_HIRES 0x00000004
#define SS_HIRES_SHIFT <<5
#define SS_PAGE2 0x00000008
#define SS_PAGE2_SHIFT <<4
#define SS_BANK2 0x00000010
#define SS_BANK2_SHIFT <<3
#define SS_LCRAM 0x00000020
#define SS_LCRAM_SHIFT <<2
#define SS_LCSEC 0x00000040 // Pseudo-softswitch : enabled if 2+ reads have occurred
#define SS_LCWRT 0x00000080 // Pseudo-softswitch : LC write enable
#define SS_80STORE 0x00000100
#define SS_80STORE_SHFT >>1
#define SS_80COL 0x00000200
#define SS_80COL_SHIFT >>2
#define SS_RAMRD 0x00000400
#define SS_RAMRD_SHIFT >>3
#define SS_RAMWRT 0x00000800
#define SS_RAMWRT_SHIFT >>4
#define SS_ALTZP 0x00001000
#define SS_ALTZP_SHIFT >>5
#define SS_DHIRES 0x00002000
#define SS_DHIRES_SHIFT >>6
#define SS_IOUDIS 0x00004000
#define SS_IOUDIS_SHIFT >>7
#define SS_CXROM 0x00008000
#define SS_CXROM_SHIFT >>8
#define SS_C3ROM 0x00010000
#define SS_ALTCHAR 0x00020000
#define SS_ALTCHAR_SHFT >>10
// Pseudo soft switches. These are actually functions of other SSes, but are tiresome to calculate as needed.
#define SS_SCREEN 0x00040000 /* PAGE2 && !80STORE */

View File

@ -34,7 +34,8 @@
#define X86_AF_Bit 0x4 /* x86 adj (nybble carry) */
#if __LP64__
# define SZ_PTR 8
# define SIZ_PTR 8
# define SIZ_PTR_SHIFT 3
# define ROR_BIT 63
// x86_64 registers
# define _XBP %rbp /* x86_64 base ptr/ scratch*/
@ -71,7 +72,8 @@
# define testLQ testq
# define xorLQ xorq
#else
# define SZ_PTR 4
# define SIZ_PTR 4
# define SIZ_PTR_SHIFT 2
# define ROR_BIT 31
// x86 registers
# define _XBP %ebp /* x86 base ptr / scratch */
@ -122,13 +124,16 @@
movLQ BASE(reg_args), _XBP; \
movb (_XBP,OFF,1), REG;
#define CALL_IND(BASE,OFF) \
movLQ BASE(reg_args), _XBP; \
callLQ *(_XBP,OFF,SZ_PTR);
#define VMEM_RW_ACCESS(BASE) \
movLQ EffectiveAddr_X, _XBP; \
shrLQ $8, _XBP; \
shlLQ $SIZ_PTR_SHIFT, _XBP; \
addLQ BASE(reg_args), _XBP; \
callLQ *(_XBP);
#define JUMP_IND(BASE,OFF) \
movLQ BASE(reg_args), _XBP; \
jmp *(_XBP,OFF,SZ_PTR);
jmp *(_XBP,OFF,SIZ_PTR);
#endif // whole file

View File

@ -56,17 +56,17 @@
#define GetFromPC_B \
movLQ PC_Reg_X, EffectiveAddr_X; \
incw PC_Reg; \
CALL_IND(CPU65_VMEM_R,EffectiveAddr_X); \
VMEM_RW_ACCESS(CPU65_VMEM_R); \
TRACE_ARG;
#define GetFromPC_W \
movLQ PC_Reg_X, EffectiveAddr_X; \
addw $2, PC_Reg; \
CALL_IND(CPU65_VMEM_R,EffectiveAddr_X); \
VMEM_RW_ACCESS(CPU65_VMEM_R); \
TRACE_ARG; \
movb %al, %ah; \
incw EffectiveAddr; \
CALL_IND(CPU65_VMEM_R,EffectiveAddr_X); \
VMEM_RW_ACCESS(CPU65_VMEM_R); \
TRACE_ARG; \
xchgb %al, %ah;
@ -82,23 +82,23 @@
#define GetFromEA_B \
orb $1, CPU65_RW(reg_args); \
CALL_IND(CPU65_VMEM_R,EffectiveAddr_X);
VMEM_RW_ACCESS(CPU65_VMEM_R);
#define GetFromEA_W \
incw EffectiveAddr; \
CALL_IND(CPU65_VMEM_R,EffectiveAddr_X); \
VMEM_RW_ACCESS(CPU65_VMEM_R); \
decw EffectiveAddr; \
movb %al, %ah; \
CALL_IND(CPU65_VMEM_R,EffectiveAddr_X);
VMEM_RW_ACCESS(CPU65_VMEM_R);
#define PutToEA_B \
orb $2, CPU65_RW(reg_args); \
movb %al, CPU65_D(reg_args); \
CALL_IND(CPU65_VMEM_W,EffectiveAddr_X);
VMEM_RW_ACCESS(CPU65_VMEM_W);
#define GetFromMem_B(x) \
movLQ x, EffectiveAddr_X; \
CALL_IND(CPU65_VMEM_R,EffectiveAddr_X);
VMEM_RW_ACCESS(CPU65_VMEM_R);
#define GetFromMem_W(x) \
movLQ x, EffectiveAddr_X; \
@ -191,7 +191,7 @@
#if CPU_TRACING
#define GetImm \
_GetImm \
CALL_IND(CPU65_VMEM_R,EffectiveAddr_X); \
VMEM_RW_ACCESS(CPU65_VMEM_R); \
TRACE_ARG;
#else
#define GetImm \
@ -2216,11 +2216,6 @@ exit_reinit: movb $0, CPU65__SIGNAL(reg_args)
------------------------------------------------------------------------- */
ENTRY(cpu65_direct_write)
pushLQ EffectiveAddr_X
movLQ 8(_XSP),EffectiveAddr_X
movLQ 12(_XSP),_XAX
movLQ CPU65_VMEM_W(reg_args), _XBP;
callLQ *(_XBP,EffectiveAddr_X,SZ_PTR)
popLQ EffectiveAddr_X
#warning FIXME TODO correctly implement cpu65_direct_write ...
ret

View File

@ -69,6 +69,9 @@ ENTRY(func) addLQ pointer(reg_args), EffectiveAddr_X; \
ENTRY(func) movb off(reg_args), %al; \
ret;
#define GLUE_NOP(func) \
ENTRY(func) ret;
#ifdef __LP64__
# define _PUSH_ARGS pushLQ EffectiveAddr_X; /* preserve */ \