Pointer-ified the apexc core (whatever that is :)

This commit is contained in:
Aaron Giles 2008-12-10 05:51:37 +00:00
parent b99f7aef26
commit 942a56edb9
2 changed files with 137 additions and 140 deletions

View File

@ -1,5 +1,5 @@
/* /*
cpu/apexc/apexc.c: APE(X)C CPU emulation cpu/apexc/cpustate->c: APE(X)C CPU emulation
By Raphael Nabet By Raphael Nabet
@ -40,7 +40,7 @@
be accessed at a time (the 16 first ones, plus 16 others chosen by the programmer), be accessed at a time (the 16 first ones, plus 16 others chosen by the programmer),
and the rotation rate is 3750rpm (62.5 rotations per second). and the rotation rate is 3750rpm (62.5 rotations per second).
* two I/O units: tape reader and tape puncher. A teletyper was designed to read * two I/O units: tape reader and tape puncher. A teletyper was designed to read
specially-encoded punched tapes and print decoded text. (See /systems/apexc.c) specially-encoded punched tapes and print decoded text. (See /systems/cpustate->c)
* machine code has 15 instructions (!), including add, substract, shift, multiply (!), * machine code has 15 instructions (!), including add, substract, shift, multiply (!),
test and branch, input and punch. A so-called vector mode allow to repeat the same test and branch, input and punch. A so-called vector mode allow to repeat the same
operation 32 times with 32 successive memory locations. Note the lack of bitwise operation 32 times with 32 successive memory locations. Note the lack of bitwise
@ -49,7 +49,7 @@
time: 16ms, which would allow about 60IPS when no optimization is made) time: 16ms, which would allow about 60IPS when no optimization is made)
* there is no indirect addressing whatever, although dynamic modification of opcodes (!) * there is no indirect addressing whatever, although dynamic modification of opcodes (!)
allows to simulate it... allows to simulate it...
* a control panel allows operation and debugging of the machine. (See /systems/apexc.c) * a control panel allows operation and debugging of the machine. (See /systems/cpustate->c)
Conventions: Conventions:
Bits are numbered in big-endian order, starting with 1: bit #1 is the Bits are numbered in big-endian order, starting with 1: bit #1 is the
@ -327,7 +327,24 @@ field: X address D Function Y address D (part 2)
#include "debugger.h" #include "debugger.h"
#include "apexc.h" #include "apexc.h"
typedef struct #ifndef SUPPORT_ODD_WORD_SIZES
#define apexc_readmem(address) memory_read_dword_32be(cpustate->program, (address)<<2)
#define apexc_writemem(address, data) memory_write_dword_32be(cpustate->program, (address)<<2, (data))
/* eewww ! - Fortunately, there is no memory mapped I/O, so we can simulate masked write
without danger */
#define apexc_writemem_masked(address, data, mask) \
apexc_writemem((address), (apexc_readmem(address) & ~(mask)) | ((data) & (mask)))
#else
#define apexc_readmem(address) cpu_readmem13_32(address)
#define apexc_writemem(address, data) cpu_writemem13_32((address), (data))
#define apexc_writemem_masked(address, data, mask) cpu_writemem13_32masked((address), (data), (mask))
#endif
#define apexc_readop(address) apexc_readmem(address)
typedef struct _apexc_state apexc_state;
struct _apexc_state
{ {
UINT32 a; /* accumulator */ UINT32 a; /* accumulator */
UINT32 r; /* register */ UINT32 r; /* register */
@ -343,14 +360,11 @@ typedef struct
const device_config *device; const device_config *device;
const address_space *program; const address_space *program;
const address_space *io; const address_space *io;
} apexc_regs; int icount;
};
static apexc_regs apexc;
static int apexc_ICount;
/* decrement ICount by n */ /* decrement ICount by n */
#define DELAY(n) {apexc_ICount -= (n); apexc.current_word = (apexc.current_word + (n)) & 0x1f;} #define DELAY(n) {cpustate->icount -= (n); cpustate->current_word = (cpustate->current_word + (n)) & 0x1f;}
/* /*
@ -369,33 +383,33 @@ static int apexc_ICount;
/* compute complete word address (i.e. translate a logical track address (expressed /* compute complete word address (i.e. translate a logical track address (expressed
in current working store) to an absolute track address) */ in current working store) to an absolute track address) */
static int effective_address(int address) static int effective_address(apexc_state *cpustate, int address)
{ {
if (address & 0x200) if (address & 0x200)
{ {
address = (address & 0x1FF) | (apexc.working_store) << 9; address = (address & 0x1FF) | (cpustate->working_store) << 9;
} }
return address; return address;
} }
/* read word */ /* read word */
static UINT32 word_read(int address, int special) static UINT32 word_read(apexc_state *cpustate, int address, int special)
{ {
UINT32 result; UINT32 result;
/* compute absolute track address */ /* compute absolute track address */
address = effective_address(address); address = effective_address(cpustate, address);
if (special) if (special)
{ {
/* ignore word position in x - use current position instead */ /* ignore word position in x - use current position instead */
address = (address & ~ 0x1f) | apexc.current_word; address = (address & ~ 0x1f) | cpustate->current_word;
} }
else else
{ {
/* wait for requested word to appear under the heads */ /* wait for requested word to appear under the heads */
DELAY(((address /*& 0x1f*/) - apexc.current_word) & 0x1f); DELAY(((address /*& 0x1f*/) - cpustate->current_word) & 0x1f);
} }
/* read 32 bits */ /* read 32 bits */
@ -418,13 +432,13 @@ static UINT32 word_read(int address, int special)
} }
/* write word (or part of a word, according to mask) */ /* write word (or part of a word, according to mask) */
static void word_write(int address, UINT32 data, UINT32 mask) static void word_write(apexc_state *cpustate, int address, UINT32 data, UINT32 mask)
{ {
/* compute absolute track address */ /* compute absolute track address */
address = effective_address(address); address = effective_address(cpustate, address);
/* wait for requested word to appear under the heads */ /* wait for requested word to appear under the heads */
DELAY(((address /*& 0x1f*/) - apexc.current_word) & 0x1f); DELAY(((address /*& 0x1f*/) - cpustate->current_word) & 0x1f);
/* write 32 bits according to mask */ /* write 32 bits according to mask */
#if 0 #if 0
@ -449,14 +463,14 @@ static void word_write(int address, UINT32 data, UINT32 mask)
no address is used, these functions just punch or read 5 bits no address is used, these functions just punch or read 5 bits
*/ */
static int papertape_read(void) static int papertape_read(apexc_state *cpustate)
{ {
return memory_read_byte_8be(apexc.io, 0) & 0x1f; return memory_read_byte_8be(cpustate->io, 0) & 0x1f;
} }
static void papertape_punch(int data) static void papertape_punch(apexc_state *cpustate, int data)
{ {
memory_write_byte_8be(apexc.io, 0, data); memory_write_byte_8be(cpustate->io, 0, data);
} }
/* /*
@ -466,17 +480,17 @@ static void papertape_punch(int data)
/* /*
set the memory location (i.e. address) register, and compute the associated delay set the memory location (i.e. address) register, and compute the associated delay
*/ */
INLINE int load_ml(int address, int vector) INLINE int load_ml(apexc_state *cpustate, int address, int vector)
{ {
int delay; int delay;
/* additionnal delay appears if we switch tracks */ /* additionnal delay appears if we switch tracks */
if (((apexc.ml & 0x3E0) != (address & 0x3E0)) /*|| vector*/) if (((cpustate->ml & 0x3E0) != (address & 0x3E0)) /*|| vector*/)
delay = 6; /* if tracks are different, delay to allow for track switching */ delay = 6; /* if tracks are different, delay to allow for track switching */
else else
delay = 0; /* else, no problem */ delay = 0; /* else, no problem */
apexc.ml = address; /* save ml */ cpustate->ml = address; /* save ml */
return delay; return delay;
} }
@ -496,7 +510,7 @@ INLINE int load_ml(int address, int vector)
execute it. execute it.
This solution makes timing simulation much simpler, too. This solution makes timing simulation much simpler, too.
*/ */
static void execute(void) static void execute(apexc_state *cpustate)
{ {
int x, y, function, c6, vector; /* instruction fields */ int x, y, function, c6, vector; /* instruction fields */
int i = 0; /* misc counter */ int i = 0; /* misc counter */
@ -511,11 +525,11 @@ static void execute(void)
int delay3; /* pre-operand-fetch delay */ int delay3; /* pre-operand-fetch delay */
/* first isolate the instruction fields */ /* first isolate the instruction fields */
x = (apexc.cr >> 22) & 0x3FF; x = (cpustate->cr >> 22) & 0x3FF;
y = (apexc.cr >> 12) & 0x3FF; y = (cpustate->cr >> 12) & 0x3FF;
function = (apexc.cr >> 7) & 0x1F; function = (cpustate->cr >> 7) & 0x1F;
c6 = (apexc.cr >> 1) & 0x3F; c6 = (cpustate->cr >> 1) & 0x3F;
vector = apexc.cr & 1; vector = cpustate->cr & 1;
function &= 0x1E; /* this is a mere guess - the LSBit is reserved for future additions */ function &= 0x1E; /* this is a mere guess - the LSBit is reserved for future additions */
@ -525,7 +539,7 @@ static void execute(void)
if (has_operand) if (has_operand)
{ {
/* load ml with X */ /* load ml with X */
delay1 = load_ml(x, vector); delay1 = load_ml(cpustate, x, vector);
/* burn pre-operand-access delay if needed */ /* burn pre-operand-access delay if needed */
if (delay1) if (delay1)
{ {
@ -542,7 +556,7 @@ static void execute(void)
case 0: case 0:
/* stop */ /* stop */
apexc.running = FALSE; cpustate->running = FALSE;
/* BTW, I don't know whether stop loads y into ml or not, and whether /* BTW, I don't know whether stop loads y into ml or not, and whether
subsequent fetch is done */ subsequent fetch is done */
@ -552,14 +566,14 @@ static void execute(void)
/* I */ /* I */
/* I do not know whether the CPU does an OR or whatever, but since docs say that /* I do not know whether the CPU does an OR or whatever, but since docs say that
the 5 bits must be cleared initially, an OR kind of makes sense */ the 5 bits must be cleared initially, an OR kind of makes sense */
apexc.r |= papertape_read() << 27; cpustate->r |= papertape_read(cpustate) << 27;
delay2 = 32; /* no idea whether this should be counted as an absolute delay delay2 = 32; /* no idea whether this should be counted as an absolute delay
or as a value in delay2 */ or as a value in delay2 */
break; break;
case 4: case 4:
/* P */ /* P */
papertape_punch((apexc.r >> 27) & 0x1f); papertape_punch(cpustate, (cpustate->r >> 27) & 0x1f);
delay2 = 32; /* no idea whether this should be counted as an absolute delay delay2 = 32; /* no idea whether this should be counted as an absolute delay
or as a value in delay2 */ or as a value in delay2 */
break; break;
@ -567,10 +581,10 @@ static void execute(void)
case 6: case 6:
/* B<(x)>=(y) */ /* B<(x)>=(y) */
/* I have no idea what we should do if the vector bit is set */ /* I have no idea what we should do if the vector bit is set */
if (apexc.a & 0x80000000UL) if (cpustate->a & 0x80000000UL)
{ {
/* load ml with X */ /* load ml with X */
delay1 = load_ml(x, vector); delay1 = load_ml(cpustate, x, vector);
/* burn pre-fetch delay if needed */ /* burn pre-fetch delay if needed */
if (delay1) if (delay1)
{ {
@ -592,13 +606,13 @@ static void execute(void)
int shifted_bit = 0; int shifted_bit = 0;
/* shift and increment c6 */ /* shift and increment c6 */
shifted_bit = apexc.r & 1; shifted_bit = cpustate->r & 1;
apexc.r >>= 1; cpustate->r >>= 1;
if (apexc.a & 1) if (cpustate->a & 1)
apexc.r |= 0x80000000UL; cpustate->r |= 0x80000000UL;
apexc.a >>= 1; cpustate->a >>= 1;
if (shifted_bit) if (shifted_bit)
apexc.a |= 0x80000000UL; cpustate->a |= 0x80000000UL;
c6 = (c6+1) & 0x3f; c6 = (c6+1) & 0x3f;
} }
@ -613,10 +627,10 @@ static void execute(void)
while (c6 != 0) while (c6 != 0)
{ {
/* shift and increment c6 */ /* shift and increment c6 */
apexc.r >>= 1; cpustate->r >>= 1;
if (apexc.a & 1) if (cpustate->a & 1)
apexc.r |= 0x80000000UL; cpustate->r |= 0x80000000UL;
apexc.a = ((INT32) apexc.a) >> 1; cpustate->a = ((INT32) cpustate->a) >> 1;
c6 = (c6+1) & 0x3f; c6 = (c6+1) & 0x3f;
} }
@ -637,15 +651,15 @@ static void execute(void)
{ {
int shifted_bit; int shifted_bit;
apexc.a = 0; cpustate->a = 0;
shifted_bit = 0; shifted_bit = 0;
while (1) while (1)
{ {
/* note we read word at current word position */ /* note we read word at current word position */
if (shifted_bit && ! (apexc.r & 1)) if (shifted_bit && ! (cpustate->r & 1))
apexc.a += word_read(x, 1); cpustate->a += word_read(cpustate, x, 1);
else if ((! shifted_bit) && (apexc.r & 1)) else if ((! shifted_bit) && (cpustate->r & 1))
apexc.a -= word_read(x, 1); cpustate->a -= word_read(cpustate, x, 1);
else else
/* Even if we do not read anything, the loop still takes 1 cycle of /* Even if we do not read anything, the loop still takes 1 cycle of
the memory word clock. */ the memory word clock. */
@ -661,11 +675,11 @@ static void execute(void)
c6 = (c6+1) & 0x3f; c6 = (c6+1) & 0x3f;
/* shift */ /* shift */
shifted_bit = apexc.r & 1; shifted_bit = cpustate->r & 1;
apexc.r >>= 1; cpustate->r >>= 1;
if (apexc.a & 1) if (cpustate->a & 1)
apexc.r |= 0x80000000UL; cpustate->r |= 0x80000000UL;
apexc.a = ((INT32) apexc.a) >> 1; cpustate->a = ((INT32) cpustate->a) >> 1;
} }
} }
@ -677,27 +691,27 @@ static void execute(void)
case 16: case 16:
/* +c(x) */ /* +c(x) */
apexc.a = + word_read(apexc.ml, 0); cpustate->a = + word_read(cpustate, cpustate->ml, 0);
break; break;
case 18: case 18:
/* -c(x) */ /* -c(x) */
apexc.a = - word_read(apexc.ml, 0); cpustate->a = - word_read(cpustate, cpustate->ml, 0);
break; break;
case 20: case 20:
/* +(x) */ /* +(x) */
apexc.a += word_read(apexc.ml, 0); cpustate->a += word_read(cpustate, cpustate->ml, 0);
break; break;
case 22: case 22:
/* -(x) */ /* -(x) */
apexc.a -= word_read(apexc.ml, 0); cpustate->a -= word_read(cpustate, cpustate->ml, 0);
break; break;
case 24: case 24:
/* T(x) */ /* T(x) */
apexc.r = word_read(apexc.ml, 0); cpustate->r = word_read(cpustate, cpustate->ml, 0);
break; break;
case 26: case 26:
@ -711,10 +725,10 @@ static void execute(void)
else else
mask = 0xFFFFFFFFUL >> c6; mask = 0xFFFFFFFFUL >> c6;
word_write(apexc.ml, apexc.r, mask); word_write(cpustate, cpustate->ml, cpustate->r, mask);
} }
apexc.r = (apexc.r & 0x80000000UL) ? 0xFFFFFFFFUL : 0; cpustate->r = (cpustate->r & 0x80000000UL) ? 0xFFFFFFFFUL : 0;
delay2 = 1; delay2 = 1;
break; break;
@ -730,7 +744,7 @@ static void execute(void)
else else
mask = 0xFFFFFFFFUL >> c6; mask = 0xFFFFFFFFUL >> c6;
word_write(apexc.ml, apexc.a, mask); word_write(cpustate, cpustate->ml, cpustate->a, mask);
} }
delay2 = 1; delay2 = 1;
@ -738,19 +752,19 @@ static void execute(void)
case 30: case 30:
/* S(x) */ /* S(x) */
apexc.working_store = (x >> 5) & 0xf; /* or is it (x >> 6)? */ cpustate->working_store = (x >> 5) & 0xf; /* or is it (x >> 6)? */
DELAY(32); /* no idea what the value is... All I know is that it takes much DELAY(32); /* no idea what the value is... All I know is that it takes much
more time than track switching (which takes 6 cycles) */ more time than track switching (which takes 6 cycles) */
break; break;
} }
if (vector) if (vector)
/* increment word position in vector operations */ /* increment word position in vector operations */
apexc.ml = (apexc.ml & 0x3E0) | ((apexc.ml + 1) & 0x1F); cpustate->ml = (cpustate->ml & 0x3E0) | ((cpustate->ml + 1) & 0x1F);
} while (vector && has_operand && (++i < 32)); /* iterate 32 times if vector bit is set */ } while (vector && has_operand && (++i < 32)); /* iterate 32 times if vector bit is set */
/* the has_operand is a mere guess */ /* the has_operand is a mere guess */
/* load ml with Y */ /* load ml with Y */
delay3 = load_ml(y, 0); delay3 = load_ml(cpustate, y, 0);
/* compute max(delay2, delay3) */ /* compute max(delay2, delay3) */
if (delay2 > delay3) if (delay2 > delay3)
@ -767,63 +781,59 @@ static void execute(void)
special_fetch: special_fetch:
/* fetch current instruction into control register */ /* fetch current instruction into control register */
apexc.cr = word_read(apexc.ml, 0); cpustate->cr = word_read(cpustate, cpustate->ml, 0);
} }
static CPU_INIT( apexc ) static CPU_INIT( apexc )
{ {
apexc.device = device; apexc_state *cpustate = device->token;
apexc.program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
apexc.io = memory_find_address_space(device, ADDRESS_SPACE_IO); cpustate->device = device;
cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
cpustate->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
} }
static CPU_RESET( apexc ) static CPU_RESET( apexc )
{ {
apexc_state *cpustate = device->token;
/* mmmh... I don't know what happens on reset with an actual APEXC. */ /* mmmh... I don't know what happens on reset with an actual APEXC. */
apexc.working_store = 1; /* mere guess */ cpustate->working_store = 1; /* mere guess */
apexc.current_word = 0; /* well, we do have to start somewhere... */ cpustate->current_word = 0; /* well, we do have to start somewhere... */
/* next two lines are just the product of my bold fantasy */ /* next two lines are just the product of my bold fantasy */
apexc.cr = 0; /* first instruction executed will be a stop */ cpustate->cr = 0; /* first instruction executed will be a stop */
apexc.running = TRUE; /* this causes the CPU to load the instruction at 0/0, cpustate->running = TRUE; /* this causes the CPU to load the instruction at 0/0,
which enables easy booting (just press run on the panel) */ which enables easy booting (just press run on the panel) */
} }
static CPU_GET_CONTEXT( apexc )
{
if (dst)
* ((apexc_regs*) dst) = apexc;
}
static CPU_SET_CONTEXT( apexc )
{
if (src)
apexc = * ((apexc_regs*)src);
}
static CPU_EXECUTE( apexc ) static CPU_EXECUTE( apexc )
{ {
apexc_ICount = cycles; apexc_state *cpustate = device->token;
cpustate->icount = cycles;
do do
{ {
debugger_instruction_hook(device, effective_address(apexc.ml)); debugger_instruction_hook(device, effective_address(cpustate, cpustate->ml));
if (apexc.running) if (cpustate->running)
execute(); execute(cpustate);
else else
{ {
DELAY(apexc_ICount); /* burn cycles once for all */ DELAY(cpustate->icount); /* burn cycles once for all */
} }
} while (apexc_ICount > 0); } while (cpustate->icount > 0);
return cycles - apexc_ICount; return cycles - cpustate->icount;
} }
static CPU_SET_INFO( apexc ) static CPU_SET_INFO( apexc )
{ {
apexc_state *cpustate = device->token;
switch (state) switch (state)
{ {
/* --- the following bits of info are set as 64-bit signed integers --- */ /* --- the following bits of info are set as 64-bit signed integers --- */
@ -832,34 +842,36 @@ static CPU_SET_INFO( apexc )
case CPUINFO_INT_PC: case CPUINFO_INT_PC:
/* keep address 9 LSBits - 10th bit depends on whether we are accessing the permanent /* keep address 9 LSBits - 10th bit depends on whether we are accessing the permanent
track group or a switchable one */ track group or a switchable one */
apexc.ml = info->i & 0x1ff; cpustate->ml = info->i & 0x1ff;
if (info->i & 0x1e00) if (info->i & 0x1e00)
{ /* we are accessing a switchable track group */ { /* we are accessing a switchable track group */
apexc.ml |= 0x200; /* set 10th bit */ cpustate->ml |= 0x200; /* set 10th bit */
if (((info->i >> 9) & 0xf) != apexc.working_store) if (((info->i >> 9) & 0xf) != cpustate->working_store)
{ /* we need to do a store switch */ { /* we need to do a store switch */
apexc.working_store = ((info->i >> 9) & 0xf); cpustate->working_store = ((info->i >> 9) & 0xf);
} }
} }
break; break;
case CPUINFO_INT_SP: (void) info->i; /* no SP */ break; case CPUINFO_INT_SP: (void) info->i; /* no SP */ break;
case CPUINFO_INT_REGISTER + APEXC_CR: apexc.cr = info->i; break; case CPUINFO_INT_REGISTER + APEXC_CR: cpustate->cr = info->i; break;
case CPUINFO_INT_REGISTER + APEXC_A: apexc.a = info->i; break; case CPUINFO_INT_REGISTER + APEXC_A: cpustate->a = info->i; break;
case CPUINFO_INT_REGISTER + APEXC_R: apexc.r = info->i; break; case CPUINFO_INT_REGISTER + APEXC_R: cpustate->r = info->i; break;
case CPUINFO_INT_REGISTER + APEXC_ML: apexc.ml = info->i & 0x3ff; break; case CPUINFO_INT_REGISTER + APEXC_ML: cpustate->ml = info->i & 0x3ff; break;
case CPUINFO_INT_REGISTER + APEXC_WS: apexc.working_store = info->i & 0xf; break; case CPUINFO_INT_REGISTER + APEXC_WS: cpustate->working_store = info->i & 0xf; break;
case CPUINFO_INT_REGISTER + APEXC_STATE: apexc.running = info->i ? TRUE : FALSE; break; case CPUINFO_INT_REGISTER + APEXC_STATE: cpustate->running = info->i ? TRUE : FALSE; break;
} }
} }
CPU_GET_INFO( apexc ) CPU_GET_INFO( apexc )
{ {
apexc_state *cpustate = (device != NULL) ? device->token : NULL;
switch (state) switch (state)
{ {
case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(apexc); break; case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(apexc_state); break;
case CPUINFO_INT_INPUT_LINES: info->i = 0; break; case CPUINFO_INT_INPUT_LINES: info->i = 0; break;
case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; /*don't care*/ break; case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; /*don't care*/ break;
@ -884,29 +896,29 @@ CPU_GET_INFO( apexc )
case CPUINFO_INT_PC: case CPUINFO_INT_PC:
/* no PC - return memory location register instead, this should be /* no PC - return memory location register instead, this should be
equivalent unless executed in the midst of an instruction */ equivalent unless executed in the midst of an instruction */
info->i = effective_address(apexc.ml); info->i = effective_address(cpustate, cpustate->ml);
break; break;
case CPUINFO_INT_PREVIOUSPC: info->i = 0; /* no PC */ break; case CPUINFO_INT_PREVIOUSPC: info->i = 0; /* no PC */ break;
/*case CPUINFO_INT_INPUT_STATE + ...:*/ /* no interrupts */ /*case CPUINFO_INT_INPUT_STATE + ...:*/ /* no interrupts */
case CPUINFO_INT_REGISTER + APEXC_CR: info->i = apexc.cr; break; case CPUINFO_INT_REGISTER + APEXC_CR: info->i = cpustate->cr; break;
case CPUINFO_INT_REGISTER + APEXC_A: info->i = apexc.a; break; case CPUINFO_INT_REGISTER + APEXC_A: info->i = cpustate->a; break;
case CPUINFO_INT_REGISTER + APEXC_R: info->i = apexc.r; break; case CPUINFO_INT_REGISTER + APEXC_R: info->i = cpustate->r; break;
case CPUINFO_INT_REGISTER + APEXC_ML: info->i = apexc.ml; break; case CPUINFO_INT_REGISTER + APEXC_ML: info->i = cpustate->ml; break;
case CPUINFO_INT_REGISTER + APEXC_WS: info->i = apexc.working_store; break; case CPUINFO_INT_REGISTER + APEXC_WS: info->i = cpustate->working_store; break;
case CPUINFO_INT_REGISTER + APEXC_STATE: info->i = apexc.running; break; case CPUINFO_INT_REGISTER + APEXC_STATE: info->i = cpustate->running; break;
case CPUINFO_INT_REGISTER + APEXC_ML_FULL: info->i = effective_address(apexc.ml); break; case CPUINFO_INT_REGISTER + APEXC_ML_FULL: info->i = effective_address(cpustate, cpustate->ml); break;
case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(apexc); break; case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(apexc); break;
case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(apexc); break; case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(dummy); break;
case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(apexc); break; case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(dummy); break;
case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(apexc); break; case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(apexc); break;
case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(apexc); break; case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(apexc); break;
case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(apexc); break; case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(apexc); break;
case CPUINFO_PTR_BURN: info->burn = NULL; break; case CPUINFO_PTR_BURN: info->burn = NULL; break;
case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(apexc); break; case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(apexc); break;
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &apexc_ICount; break; case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
case CPUINFO_STR_NAME: strcpy(info->s, "APEXC"); break; case CPUINFO_STR_NAME: strcpy(info->s, "APEXC"); break;
case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "APEC"); break; case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "APEC"); break;
@ -914,14 +926,14 @@ CPU_GET_INFO( apexc )
case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Raphael Nabet"); break; case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Raphael Nabet"); break;
case CPUINFO_STR_FLAGS: sprintf(info->s, "%c", (apexc.running) ? 'R' : 'S'); break; case CPUINFO_STR_FLAGS: sprintf(info->s, "%c", (cpustate->running) ? 'R' : 'S'); break;
case CPUINFO_STR_REGISTER + APEXC_CR: sprintf(info->s, "CR:%08X", apexc.cr); break; case CPUINFO_STR_REGISTER + APEXC_CR: sprintf(info->s, "CR:%08X", cpustate->cr); break;
case CPUINFO_STR_REGISTER + APEXC_A: sprintf(info->s, "A :%08X", apexc.a); break; case CPUINFO_STR_REGISTER + APEXC_A: sprintf(info->s, "A :%08X", cpustate->a); break;
case CPUINFO_STR_REGISTER + APEXC_R: sprintf(info->s, "R :%08X", apexc.r); break; case CPUINFO_STR_REGISTER + APEXC_R: sprintf(info->s, "R :%08X", cpustate->r); break;
case CPUINFO_STR_REGISTER + APEXC_ML: sprintf(info->s, "ML:%03X", apexc.ml); break; case CPUINFO_STR_REGISTER + APEXC_ML: sprintf(info->s, "ML:%03X", cpustate->ml); break;
case CPUINFO_STR_REGISTER + APEXC_WS: sprintf(info->s, "WS:%01X", apexc.working_store); break; case CPUINFO_STR_REGISTER + APEXC_WS: sprintf(info->s, "WS:%01X", cpustate->working_store); break;
case CPUINFO_STR_REGISTER + APEXC_STATE: sprintf(info->s, "CPU state:%01X", apexc.running ? TRUE : FALSE); break; case CPUINFO_STR_REGISTER + APEXC_STATE: sprintf(info->s, "CPU state:%01X", cpustate->running ? TRUE : FALSE); break;
} }
} }

View File

@ -20,21 +20,6 @@ enum
CPU_GET_INFO( apexc ); CPU_GET_INFO( apexc );
#ifndef SUPPORT_ODD_WORD_SIZES
#define apexc_readmem(address) memory_read_dword_32be(apexc.program, (address)<<2)
#define apexc_writemem(address, data) memory_write_dword_32be(apexc.program, (address)<<2, (data))
/* eewww ! - Fortunately, there is no memory mapped I/O, so we can simulate masked write
without danger */
#define apexc_writemem_masked(address, data, mask) \
apexc_writemem((address), (apexc_readmem(address) & ~(mask)) | ((data) & (mask)))
#else
#define apexc_readmem(address) cpu_readmem13_32(address)
#define apexc_writemem(address, data) cpu_writemem13_32((address), (data))
#define apexc_writemem_masked(address, data, mask) cpu_writemem13_32masked((address), (data), (mask))
#endif
CPU_DISASSEMBLE( apexc ); CPU_DISASSEMBLE( apexc );
#define apexc_readop(address) apexc_readmem(address)
#endif /* __APEXC_H__ */ #endif /* __APEXC_H__ */