1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-04-07 16:41:59 +00:00

Place bytecode in external memory

This commit is contained in:
David Schmenk 2024-08-16 17:02:28 -07:00
parent 2315282ec9
commit b9e9fa2397
4 changed files with 266 additions and 115 deletions

View File

@ -31,6 +31,10 @@ byte *lastsym = symtbl;
byte *perr;
uword keybdbuf = 0x0200;
uword heap = 0x0300;
typedef struct {
uword modofst;
uword defaddr;
} defxlat_t;
/*
* Standard Library exported functions.
*/
@ -157,6 +161,7 @@ unsigned char keypressed(M6502 *mpu)
{
if (cin == 0x03) // CTRL-C
{
trace = SINGLE_STEP;
mpu->flags |= M6502_SingleStep;
paused = 1;
}
@ -189,15 +194,16 @@ int setPLVMTraps(M6502 *mpu)
//
// Hooks for BRK, enter VM or native code
//
M6502_setCallback(mpu, call, VM_IRQ_ENTRY, vm_irq);
M6502_setCallback(mpu, call, VM_INLINE_ENTRY, vm_indef);
M6502_setCallback(mpu, call, VM_INDIRECT_ENTRY, vm_iidef);
M6502_setCallback(mpu, call, VM_EXT_ENTRY, vm_exdef);
M6502_setCallback(mpu, call, VM_NATV_ENTRY, vm_natvdef);
M6502_setCallback(mpu, call, 0x0000, vm_irq);
return 0;
}
int setApple1Traps(M6502 *mpu)
{
M6502_setCallback(mpu, call, VM_IRQ_ENTRY, vm_irq);
//
// Apple 1 memory-mapped IO
//
@ -212,11 +218,6 @@ int setApple1Traps(M6502 *mpu)
M6502_setCallback(mpu, call, 0x9000, bye);
M6502_setCallback(mpu, call, 0x900C, cffa1);
M6502_setCallback(mpu, call, 0xFFEF, cout);
//
// !!! Hook Apple 1 VM entrypoints for testing purposes !!!
//
M6502_setCallback(mpu, call, 0x0283, vm_indef);
M6502_setCallback(mpu, call, 0x0293, vm_iidef);
return 0;
}
/*
@ -234,7 +235,7 @@ void M6502_exec(M6502 *mpu)
M6502_dump(mpu, state);
M6502_disassemble(mpu, mpu->registers->pc, insn);
printf("%s : %s\r\n", state, insn);
if (paused || (keypressed(mpu) && keypending == 0x83))
if ((trace == SINGLE_STEP) && (paused || (keypressed(mpu) && keypending == 0x83)))
{
keypending = 0;
while (!keypressed(mpu));
@ -386,6 +387,18 @@ int add_sym(byte *dci, uword addr)
/*
* DEF routines - Create entryoint for 6502 that calls out to PLVM or native code
*/
void dump_def(defxlat_t *defxtbl, uword defcnt)
{
if (defcnt)
{
printf("DEF XLATE table:\n");
while (defcnt--)
{
printf("$%04X -> $%04X\n", defxtbl->modofst, defxtbl->defaddr);
defxtbl++;
}
}
}
byte *add_def(byte type, uword haddr, byte *lastdef)
{
*lastdef++ = 0x20; // JSR opcode
@ -416,19 +429,18 @@ byte *add_def(byte type, uword haddr, byte *lastdef)
*lastdef++ = haddr >> 8;
return lastdef;
}
uword lookup_def(byte *deftbl, int defaddr)
void xlat_def(uword addr, uword ofst, defxlat_t *defxtbl)
{
int calldef = 0;
while (*deftbl)
{
if ((deftbl[3] | (deftbl[4] << 8)) == defaddr)
{
calldef = deftbl - mem_6502;
break;
}
deftbl += 5;
}
return (uword)calldef;
while (defxtbl->defaddr)
defxtbl++;
defxtbl->modofst = ofst;
defxtbl->defaddr = addr;
}
uword lookup_def(defxlat_t *defxtbl, uword ofst)
{
while (defxtbl->defaddr && defxtbl->modofst != ofst)
defxtbl++;
return defxtbl->defaddr;
}
uword add_natv( VM_Callout natvfn)
{
@ -472,15 +484,27 @@ int load_mod(M6502 *mpu, byte *mod)
uword sysflags = 0, defcnt = 0, init = 0;
word modfix, modofst;
byte *deftbl, *deflast, *moddep, *rld, *esd, *sym;
code *extcode;
defxlat_t *defxtbl;
byte header[128];
int fd;
char filename[48], string[17];
char filename[128], string[17];
dcitos(mod, filename);
printf("Load module %s\n", filename);
if (strlen(filename) < 4 || (filename[strlen(filename) - 4] != '.'))
if (strlen(filename) > 4 && (filename[strlen(filename) - 4] != '.'))
strcat(filename, ".mod");
fd = open(filename, O_RDONLY, 0);
if (fd <= 0 && filename[0] != '/' && strlen(filename) < 17)
{
//
// Search syspath if module not found
//
strcpy(string, filename);
strcpy(filename, (char *)mem_6502 + SYSPATH_BUF);
strcat(filename, string);
fd = open(filename, O_RDONLY, 0);
}
if ((fd > 0) && (len = read(fd, header, 128)) > 0)
{
moddep = header + 1;
@ -521,6 +545,16 @@ int load_mod(M6502 *mpu, byte *mod)
len = read(fd, header, 128);
}
}
else
{
//
// Standard REL file - probaby generated from EDASM
//
sysflags = 0;
bytecode = 0;
defcnt = 0;
init = 0;
}
//
// Allocate heap space for DEF table.
//
@ -553,40 +587,55 @@ int load_mod(M6502 *mpu, byte *mod)
esd = rld; // Extern+Entry Symbol Directory
for (esd = rld; *esd; esd += 4); // Scan to end of RLD
esd++; // ESD starts just past RLD
if (show_state)
if (trace)
{
//
// Dump different parts of module.
//
printf("Module load addr: $%04X\n", modaddr);
printf("Module size: %d\n", end - modaddr + hdrlen);
printf("Module code+data size: %d\n", modsize);
printf("Module size: $%04X (%d)\n", modsize, modsize);
printf("Module code+data size: $%04X (%d)\n", end - modaddr, end - modaddr);
printf("Module magic: $%04X\n", magic);
printf("Module sysflags: $%04X\n", sysflags);
printf("Module bytecode: $%04X\n", bytecode);
printf("Module def count: $%04X\n", defcnt);
printf("Module init: $%04X\n", init ? init + modofst : 0);
if (defcnt)
{
printf("Module def count: %d\n", defcnt);
printf("Module bytecode: $%04X\n", bytecode);
printf("Module init: $%04X\n", init ? init + modofst : 0);
printf("Module def size: $%04X (%d)\n", end - bytecode, end - bytecode);
printf("Module def end: $%04X\n", end);
}
}
//
// Add module to symbol table.
//
add_sym(mod, modaddr);
//
// Allocate external code memory
//
if (defcnt)
{
extcode = code_alloc(end - bytecode);
defxtbl = malloc(sizeof(defxlat_t) * defcnt);
memset(defxtbl, 0, sizeof(defxlat_t) * defcnt);
}
//
// Print out the Re-Location Dictionary.
//
if (show_state)
if (trace)
printf("\nRe-Location Dictionary:\n");
while (rld[0])
{
addr = rld[1] | (rld[2] << 8);
if (rld[0] == 0x02)
{
if (show_state) printf("\tDEF CODE");
if (trace) printf("\tDEF CODE");
//
// This is a bytcode def entry - add it to the def directory.
//
addr += modofst;
deflast = add_def(VM_DEF, addr, deflast);
addr += modofst;
xlat_def(deflast - mem_6502, addr, defxtbl);
deflast = add_def(VM_EXT_DEF, vm_addxdef(extcode + addr - bytecode), deflast);
}
else
{
@ -611,7 +660,7 @@ int load_mod(M6502 *mpu, byte *mod)
//
// Resolve external symbol
//
if (show_state) printf("\tEXTERN[$%02X] ", rld[3]);
if (trace) printf("\tEXTERN[$%02X] ", rld[3]);
fixup += lookup_extern(esd, rld[3]);
}
else
@ -625,25 +674,26 @@ int load_mod(M6502 *mpu, byte *mod)
//
// Replace with call def dictionary.
//
if (show_state) printf("\tDEF[$%04X->", fixup);
fixup = lookup_def(deftbl, fixup);
if (show_state) printf("$%04X] ", fixup);
if (trace) printf("\tDEF[$%04X->", fixup);
fixup = lookup_def(defxtbl, fixup);
if (trace) printf("$%04X] ", fixup);
if (!fixup) pfail("Unresolved DEF");
}
else
if (show_state) printf("\tINTERN ");
if (trace) printf("\tINTERN ");
}
if (rld[0] & 0x80)
{
//
// 16 bit fixup
//
if (show_state) printf("WORD");
if (trace) printf("WORD");
mem_6502[addr] = fixup;
mem_6502[addr + 1] = fixup >> 8;
}
else
{
if (show_state) printf(rld[0] & 0x40 ? "MSBYTE" : "LSBYTE");
if (trace) printf(rld[0] & 0x40 ? "MSBYTE" : "LSBYTE");
if (rld[0] & 0x40)
//
// 8 bit MSB fixup
@ -656,10 +706,10 @@ int load_mod(M6502 *mpu, byte *mod)
mem_6502[addr] = fixup;
}
}
if (show_state) printf("@$%04X\n", addr);
if (trace) printf("@$%04X\n", addr);
rld += 4;
}
if (show_state) printf("\nExternal/Entry Symbol Directory:\n");
if (trace) printf("\nExternal/Entry Symbol Directory:\n");
while (esd[0])
{
sym = esd;
@ -671,12 +721,12 @@ int load_mod(M6502 *mpu, byte *mod)
//
addr = esd[1] | (esd[2] << 8);
addr += modofst;
if (show_state) printf("\tEXPORT %s@$%04X\n", string, addr);
if (trace) printf("\tEXPORT %s@$%04X\n", string, addr);
if (addr >= bytecode)
//
// Convert to def entry address
//
addr = lookup_def(deftbl, addr);
addr = lookup_def(defxtbl, addr);
//
// Add symbol to PLASMA symbol table
//
@ -691,17 +741,26 @@ int load_mod(M6502 *mpu, byte *mod)
pfail("");
}
//
// Reserve heap space for relocated module.
// Reserve heap space for relocated module and copy bytecode extrnally.
//
if (defcnt)
{
if (init) defcnt--;
if (trace) dump_def(defxtbl, defcnt);
free(defxtbl);
if (trace) printf("Copy bytecode from $%04X to 0x%08X, size %d\n", bytecode, (unsigned int)extcode, end - bytecode);
memcpy(extcode, mem_6502 + bytecode, end - bytecode);
end = bytecode; // Free up bytecode in main memory
}
alloc_heap(end - modaddr);
//
//Call init routine.
//
if (init)
{
vm_interp(mpu, mem_6502 + init + modfix - REL_ADDR);
if (!(sysflags & SYSFLAG_INITKEEP))
release_heap(init + modofst); // Free up init code
vm_interp(mpu, extcode + init + modofst - bytecode);
//if (!(sysflags & SYSFLAG_INITKEEP))
// release_heap(init + modofst); // Free up init code
init = mem_6502[++mpu->registers->s + 0x100];
init |= mem_6502[++mpu->registers->s + 0x100] << 8;
return init;
@ -793,6 +852,31 @@ void sysputh(M6502 *mpu)
POP_ESTK(prhex);
printf("%04X", prhex);
}
void sysgetc(M6502 *mpu)
{
char c;
//
// Push getchar()
//
c = getchar();
PUSH_ESTK(c);
}
void sysgets(M6502 *mpu)
{
uword strptr;
int len;
char instr[256];
//
// Push gets(), limiting it to 128 chars
//
len = strlen(gets(instr));
if (len > 128)
len = 128;
mem_6502[CMDLINE_STR] = len;
memcpy(mem_6502 + CMDLINE_BUF, instr, len);
PUSH_ESTK(CMDLINE_STR);
}
void sysdivmod(M6502 *mpu)
{
word prhex;
@ -813,8 +897,8 @@ void export_cmdsys(void)
uword defaddr;
mem_6502[cmdsys + 0] = 0x11; // Version 2.11
mem_6502[cmdsys + 1] = 0x02;
mem_6502[cmdsys + 2] = 0x80; // syspath
mem_6502[cmdsys + 3] = 0x02;
mem_6502[cmdsys + 2] = (byte)SYSPATH_STR; // syspath
mem_6502[cmdsys + 3] = (byte)(SYSPATH_STR >> 8);
mem_6502[cmdsys + 4] = (byte)CMDLINE_STR; // cmdline
mem_6502[cmdsys + 5] = (byte)(CMDLINE_STR >> 8);
defaddr = add_natv(sysexecmod); // sysexecmod
@ -849,6 +933,8 @@ void export_cmdsys(void)
export_natv("PUTI", sysputi);
export_natv("PUTB", sysputb);
export_natv("PUTH", sysputh);
export_natv("GETC", sysgetc);
export_natv("GETS", sysgets);
#if 0
char sysstr[] = "SYSCALL";
char callstr[] = "CALL";
@ -892,6 +978,7 @@ int main(int argc, char **argv)
//
M6502 *mpu = M6502_new(0, mem_6502, 0);
M6502_reset(mpu);
M6502_setVector(mpu, IRQ, VM_IRQ_ENTRY); // Dummy address to BRK/IRQ on
mpu->registers->x = ESTK_SIZE;
//
// Parse command line options
@ -901,10 +988,16 @@ int main(int argc, char **argv)
argv++;
while (argc && (*argv)[0] == '-')
{
if ((*argv)[1] == 's')
show_state = 1;
else if ((*argv)[1] == 't')
if ((*argv)[1] == 't')
{
trace = TRACE;
mpu->flags |= M6502_SingleStep;
}
else if ((*argv)[1] == 's')
{
trace = SINGLE_STEP;
mpu->flags |= M6502_SingleStep;
}
argc--;
argv++;
}
@ -933,35 +1026,35 @@ int main(int argc, char **argv)
//
// 64K - 256 RAM
//
mem_6502[FPL] = 0x00;
mem_6502[FPH] = 0xFF;
mem_6502[PPL] = 0x00;
mem_6502[PPH] = 0xFF;
mem_6502[FPL] = 0x00; // Frame pointer = $FF00
mem_6502[FPH] = 0xFF;
mem_6502[PPL] = 0x00; // Pool pointer = $FF00
mem_6502[PPH] = 0xFF;
//
// Load module from command line - PLVM version
//
export_cmdsys();
stodci(modfile, dci);
if (show_state) dump_sym();
if (trace) dump_sym();
load_mod(mpu, dci);
if (show_state) dump_sym();
if (trace) dump_sym();
}
else
{
setRawInput();
setApple1Traps(mpu);
//
// 32K RAM
//
mem_6502[FPL] = 0x00;
mem_6502[FPH] = 0x80;
mem_6502[PPL] = 0x00;
mem_6502[PPH] = 0x80;
mem_6502[FPL] = 0x00; // Frame pointer = $8000
mem_6502[FPH] = 0x80;
mem_6502[PPL] = 0x00; // Pool pointer = $8000 (unused)
mem_6502[PPH] = 0x80;
//
// Load Apple 1 emulation - lib6502 version
//
if (!load(0x280, cmdfile))
pfail(cmdfile);
setRawInput();
mpu->registers->pc = 0x0280;
M6502_exec(mpu);
}

View File

@ -28,7 +28,7 @@ enum {
flagD= (1<<3), /* decimal mode */
flagI= (1<<2), /* irq disable */
flagZ= (1<<1), /* zero */
flagC= (1<<0) /* carry */
flagC= (1<<0) /* carry */
};
struct _M6502_Registers

View File

@ -6,11 +6,17 @@
#include <ctype.h>
#include <sys/types.h>
#include "plvm.h"
/*
* PLVM eval stack
*/
#define PUSH(v) (*(--esp))=(v)
#define POP ((word)(*(esp++)))
#define UPOP ((uword)(*(esp++)))
#define TOS (esp[0])
/*
* Debug flag
*/
int show_state = 0;
int trace = 0;
/*
* VM def routines
*/
@ -27,8 +33,6 @@ int natv_count = 0;
* Memory for 6502 and VM
*/
byte mem_6502[MEM6502_SIZE];
word eval_stack[ESTK_SIZE];
word *esp = &eval_stack[ESTK_SIZE];
/*
* BRK and VM entrypoint hooks
*/
@ -36,6 +40,7 @@ int vm_irq(M6502 *mpu, uword address, byte data)
{
uword addr, handle;
fflush(stdout);
if (mem_6502[mpu->registers->s + 0x101] & flagB)
{
//
@ -49,10 +54,10 @@ int vm_irq(M6502 *mpu, uword address, byte data)
// default:
// fprintf(stderr, "Unkonw BRK value!\n");
//}
fprintf(stderr, "BRK: $%04X\r\n", addr);
fprintf(stderr, "\nBRK: $%04X\r\n", address);
exit (-1);
}
fprintf(stderr, "Unkonw IRQ!\n");
fprintf(stderr, "\nUnkonw IRQ!\n");
RTI;
}
//
@ -134,23 +139,24 @@ OPTBL DW CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06
for (val = ESTK_SIZE - 1; val >= mpu->registers->x; val--) \
PUSH(mem_6502[ESTKL + val] | (mem_6502[ESTKH + val] << 8))
#define externalize() \
mem_6502[FPL] = vm_fp; \
mem_6502[FPH] = vm_fp >> 8; \
mem_6502[PPL] = vm_pp; \
mem_6502[PPH] = vm_pp >> 8; \
mem_6502[FPL] = (byte)vm_fp; \
mem_6502[FPH] = (byte)(vm_fp >> 8); \
mem_6502[PPL] = (byte)vm_pp; \
mem_6502[PPH] = (byte)(vm_pp >> 8); \
ea = ESTK_SIZE-1; \
{ word *vm_sp; \
for (vm_sp = &eval_stack[ESTK_SIZE-1]; vm_sp >= esp; vm_sp--) { \
mem_6502[ESTKL + ea] = *vm_sp; \
mem_6502[ESTKH + ea] = *vm_sp >> 8; \
mem_6502[ESTKL + ea] = (byte)*vm_sp; \
mem_6502[ESTKH + ea] = (byte)(*vm_sp >> 8); \
ea--; \
} \
}} \
mpu->registers->x = ea + 1
void vm_interp(M6502 *mpu, code *vm_ip)
{
int val, ea, frmsz, parmcnt;
uword vm_fp, vm_pp;
word *vm_sp;
word eval_stack[ESTK_SIZE], *esp;
internalize();
while (1)
@ -158,17 +164,21 @@ void vm_interp(M6502 *mpu, code *vm_ip)
if ((esp - eval_stack) < 0 || (esp - eval_stack) > ESTK_SIZE)
{
printf("Eval stack over/underflow! - $%04X: $%02X [%d]\r\n", (unsigned int)(vm_ip - mem_6502), (unsigned int)*vm_ip, (int)(ESTK_SIZE - (esp - eval_stack)));
show_state = 1;
exit(-1);
}
if (show_state)
if (trace)
{
char cmdline[16];
word *dsp = &eval_stack[ESTK_SIZE - 1];
printf("$%04X: $%02X [ ", (unsigned int)(vm_ip - mem_6502), (unsigned int)*vm_ip);
if (vm_ip >= mem_6502 && vm_ip < (mem_6502 + MEM6502_SIZE))
printf("$%04X: $%02X [ ", (unsigned int)(vm_ip - mem_6502), (unsigned int)*vm_ip);
else
printf("0x%08X: $%02X [ ", (unsigned int)vm_ip, (unsigned int)*vm_ip);
while (dsp >= esp)
printf("$%04X ", (unsigned int)((*dsp--) & 0xFFFF));
printf("]\r\n");
fgets(cmdline, 15, stdin);
if (trace == SINGLE_STEP)
fgets(cmdline, 15, stdin);
}
switch (*vm_ip++)
{
@ -230,7 +240,48 @@ void vm_interp(M6502 *mpu, code *vm_ip)
vm_ip += 2;
break;
case 0x2E: // CS: TOS = CONSTANTSTRING (IP)
PUSH(vm_ip - mem_6502);
if (vm_ip >= mem_6502 && vm_ip < (mem_6502 + MEM6502_SIZE))
{
//
// Main memory code, just push address of string
//
PUSH(vm_ip - mem_6502);
}
else
{
//
// Copy string to string pool
//
for (val = vm_pp; val < vm_fp; val++)
{
if (mem_6502[val] == *vm_ip)
{
//
// Look for mathing string
//
for (ea = BYTE_PTR(vm_ip); ea; ea--)
if (mem_6502[val + ea] != vm_ip[ea])
break;
if (!ea)
{
//
// Already in string pool
//
PUSH(val);
break;
}
}
}
if (val >= vm_fp)
{
//
// Not found, allocate in pool
//
vm_pp -= BYTE_PTR(vm_ip) + 1;
memcpy(mem_6502 + vm_pp, vm_ip, BYTE_PTR(vm_ip) + 1);
PUSH(vm_pp);
}
}
vm_ip += BYTE_PTR(vm_ip) + 1;
break;
/*
@ -343,34 +394,35 @@ void vm_interp(M6502 *mpu, code *vm_ip)
break;
case 0x54: // CALL : TOFP = IP, IP = (IP) ; call
mpu->registers->pc = UWORD_PTR(vm_ip);
mem_6502[0x00FF] = 0xFF; // RTN instruction
mem_6502[mpu->registers->s-- + 0x100] = 0x00; // Address of $FF (RTN) instruction
mem_6502[mpu->registers->s-- + 0x100] = 0xFF; // Address of $FF (RTN) instruction
mem_6502[mpu->registers->s-- + 0x100] = 0xFE;
//mpu->flags |= M6502_SingleStep;
externalize();
if (show_state)
if (trace)
printf("CALL: $%04X\r\n", mpu->registers->pc);
externalize();
M6502_exec(mpu);
internalize();
vm_ip += 2;
break;
case 0x56: // ICALL : IP = TOS ; indirect call
mpu->registers->pc = UPOP;
mem_6502[0x00FF] = 0xFF; // RTN instruction
mem_6502[mpu->registers->s-- + 0x100] = 0x00; // Address of $FF (RTN) instruction
mem_6502[mpu->registers->s-- + 0x100] = 0xFF; // Address of $FF (RTN) instruction
mem_6502[mpu->registers->s-- + 0x100] = 0xFE;
externalize();
if (show_state)
if (trace)
printf("ICAL: $%04X\r\n", mpu->registers->pc);
externalize();
M6502_exec(mpu);
internalize();
break;
case 0x58: // ENTER : NEW FRAME, FOREACH PARAM LOCALVAR = TOS
frmsz = BYTE_PTR(vm_ip);
vm_ip++;
if (show_state)
printf("< $%04X: $%04X > ", vm_fp - frmsz, vm_fp);
vm_fp -= frmsz;
if (trace)
printf("<PP:$%04X FP:$%04X FRMSZ:$%02X> ", vm_pp, vm_fp, frmsz);
mem_6502[--vm_pp] = (byte)(vm_fp >> 8);
mem_6502[--vm_pp] = (byte)vm_fp;
vm_fp = vm_pp - frmsz;
vm_pp = vm_fp;
parmcnt = BYTE_PTR(vm_ip);
vm_ip++;
while (parmcnt--)
@ -378,14 +430,18 @@ void vm_interp(M6502 *mpu, code *vm_ip)
val = POP;
mem_6502[vm_fp + parmcnt * 2 + 0] = val;
mem_6502[vm_fp + parmcnt * 2 + 1] = val >> 8;
if (show_state)
if (trace)
printf("< $%04X: $%04X > ", vm_fp + parmcnt * 2 + 0, mem_6502[vm_fp + parmcnt * 2 + 0] | (mem_6502[vm_fp + parmcnt * 2 + 1] >> 8));
}
if (show_state)
if (trace)
printf("\n");
break;
case 0x5A: // LEAVE : DEL FRAME, IP = TOFP
vm_fp += BYTE_PTR(vm_ip);
vm_pp = vm_fp + BYTE_PTR(vm_ip);
vm_fp = mem_6502[vm_pp++];
vm_fp |= mem_6502[vm_pp++] << 8;
if (trace)
printf("<PP:$%04X FP:$%04X>\n", vm_pp, vm_fp);
case 0x5C: // RET : IP = TOFP
externalize();
return;

View File

@ -28,17 +28,17 @@ typedef uint16_t address;
#define PLP (mpu->registers->p=mem_6502[++mpu->registers->s + 0x100])
#define RTI \
{ \
word pc; \
uword pc; \
PLP; \
pc = mem_6502[++mpu->registers->s + 0x100]; \
pc |= mem_6502[++mpu->registers->s + 0x100] << 8; \
pc |= mem_6502[++mpu->registers->s + 0x100]<<8; \
return pc; \
}
#define RTS \
{ \
word pc; \
uword pc; \
pc = mem_6502[++mpu->registers->s + 0x100]; \
pc |= mem_6502[++mpu->registers->s + 0x100] << 8; \
pc |= mem_6502[++mpu->registers->s + 0x100]<<8; \
return pc + 1; \
}
/*
@ -47,22 +47,15 @@ typedef uint16_t address;
#define PUSH_ESTK(v) \
{ \
--mpu->registers->x; \
mem_6502[ESTKL + mpu->registers->x] = (v); \
mem_6502[ESTKH + mpu->registers->x] = (v) >> 8; \
mem_6502[ESTKL + mpu->registers->x] = (byte)(v); \
mem_6502[ESTKH + mpu->registers->x] = (byte)(v)>>8; \
}
#define POP_ESTK(v) \
{ \
(v) = mem_6502[ESTKL + mpu->registers->x] \
| mem_6502[ESTKH + mpu->registers->x] << 8; \
| mem_6502[ESTKH + mpu->registers->x]<<8; \
++mpu->registers->x; \
}
/*
* PLVM eval stack
*/
#define PUSH(v) (*(--esp))=(v)
#define POP ((word)(*(esp++)))
#define UPOP ((uword)(*(esp++)))
#define TOS (esp[0])
/*
* 6502 memory map
*/
@ -70,6 +63,8 @@ typedef uint16_t address;
#define ESTK_SIZE 16
#define CMDLINE_STR 0x01FF
#define CMDLINE_BUF 0x0200
#define SYSPATH_STR 0x0280
#define SYSPATH_BUF 0x0281
/*
* Zero page VM locations matching Apple ZP
*/
@ -89,16 +84,23 @@ typedef uint16_t address;
#define VM_EXT_DEF 2
#define VM_DEF 1
#define VM_INLINE_DEF 0
#define VM_NATV_ENTRY 0xFFFC
#define VM_EXT_ENTRY 0xFFF8
#define VM_INDIRECT_ENTRY 0xFFF4
#define VM_INLINE_ENTRY 0xFFF0
#define VM_NATV_ENTRY 0xFF0E
#define VM_EXT_ENTRY 0xFF0C
#define VM_INDIRECT_ENTRY 0xFF08
#define VM_INLINE_ENTRY 0xFF04
#define VM_IRQ_ENTRY 0xFF00
/*
* Allocate external code memory
*/
#define code_alloc(size) malloc(size)
#define TRACE 1
#define SINGLE_STEP 2
/*
* VM callouts
*/
void M6502_exec(M6502 *mpu);
typedef void (*VM_Callout)(M6502 *mpu);
extern int show_state;
extern int trace;
extern byte mem_6502[];
extern byte mem_PLVM[];
extern byte *perr;