1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2026-04-19 09:23:06 +00:00

use nopn-conanical imput for PLVM and A1 CFFA

This commit is contained in:
David Schmenk
2024-08-26 18:41:41 -07:00
parent 0cdcb66888
commit a061833ef8
6 changed files with 360 additions and 276 deletions
+2 -2
View File
@@ -192,8 +192,8 @@ $(DRAWL): lisp/s-expr.pla lisp/drawl.pla
vmsrc/lib6502/lib6502.a: vmsrc/lib6502/lib6502.h vmsrc/lib6502/lib6502.c
make -C vmsrc/lib6502
$(PLVM): vmsrc/plvm.c vmsrc/cmdsys.c vmsrc/sysio.c vmsrc/lib6502/lib6502.a
cc vmsrc/plvm.c vmsrc/cmdsys.c vmsrc/sysio.c vmsrc/lib6502/lib6502.a -o $(PLVM)
$(PLVM): vmsrc/plvm.h vmsrc/plvm.c vmsrc/cmdsys.c vmsrc/sysio.c vmsrc/a1cffa.c vmsrc/lib6502/lib6502.a
cc vmsrc/plvm.c vmsrc/cmdsys.c vmsrc/sysio.c vmsrc/a1cffa.c vmsrc/lib6502/lib6502.a -o $(PLVM)
$(PLVMZP_APL): FORCE
-mkdir -p rel
+172
View File
@@ -0,0 +1,172 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include "plvm.h"
/*
* CFFA1 emulation
*/
#define CFFADest 0x00
#define CFFAFileName 0x02
#define CFFAOldName 0x04
#define CFFAFileType 0x06
#define CFFAAuxType 0x07
#define CFFAFileSize 0x09
#define CFFAEntryPtr 0x0B
int save(uword address, unsigned length, const char *path)
{
FILE *file;
int count;
if (!(file = fopen(path, "wb")))
return 0;
while ((count = fwrite(mem_6502 + address, 1, length, file)))
{
address += count;
length -= count;
}
fclose(file);
return 1;
}
int load(uword address, const char *path)
{
FILE *file;
int count;
size_t max = 0x10000 - address;
if (!(file = fopen(path, "rb")))
return 0;
while ((count = fread(mem_6502 + address, 1, max, file)) > 0)
{
address += count;
max -= count;
}
fclose(file);
return 1;
}
char *strlower(char *strptr)
{
int i;
for (i = 0; strptr[i]; i++)
strptr[i] = tolower(strptr[i]);
return strptr;
}
int cffa1(M6502 *mpu, uword address, byte data)
{
char *fileptr, filename[64];
int addr;
struct stat sbuf;
switch (mpu->registers->x)
{
case 0x02: // quit
exit(0);
break;
case 0x14: // find dir entry
addr = mem_6502[CFFAFileName] | (mem_6502[CFFAFileName + 1] << 8);
memset(filename, 0, 64);
strncpy(filename, (char *)(mem_6502 + addr + 1), mem_6502[addr]);
strlower(filename);
//strcat(filename, ".mod");
if (!(stat(filename, &sbuf)))
{
// DirEntry @ $9100
mem_6502[CFFAEntryPtr] = 0x00;
mem_6502[CFFAEntryPtr + 1] = 0x91;
mem_6502[0x9115] = sbuf.st_size;
mem_6502[0x9116] = sbuf.st_size >> 8;
mpu->registers->a = 0;
}
else
mpu->registers->a = -1;
break;
case 0x22: // load file
addr = mem_6502[CFFAFileName] | (mem_6502[CFFAFileName + 1] << 8);
memset(filename, 0, 64);
strncpy(filename, (char *)(mem_6502 + addr + 1), mem_6502[addr]);
strlower(filename);
//strcat(filename, ".mod");
addr = mem_6502[CFFADest] | (mem_6502[CFFADest + 1] << 8);
mpu->registers->a = load(addr, filename) - 1;
break;
default:
{
char state[64];
fprintf(stderr, "Unimplemented CFFA function: %02X\r\n", mpu->registers->x);
M6502_dump(mpu, state);
fflush(stdout);
fprintf(stderr, "\nCFFA1 %s\n", state);
pfail("ABORT");
}
break;
}
RTS;
}
/*
* Character I/O emulation
*/
int bye(M6502 *mpu, uword addr, byte data) { exit(0); return 0; }
int cout(M6502 *mpu, uword addr, byte data) { if (mpu->registers->a == 0x8D) putchar('\n'); putchar(mpu->registers->a & 0x7F); fflush(stdout); RTS; }
int rd6820kbdctl(M6502 *mpu, uword addr, byte data)
{
unsigned char cin, cext[2];
if (read(STDIN_FILENO, &cin, 1) > 0)
{
if (cin == 0x03) // CTRL-C
{
trace = SINGLE_STEP;
mpu->flags |= M6502_SingleStep;
paused = 1;
}
if (cin == 0x1B) // Look for left arrow
{
if (read(STDIN_FILENO, cext, 2) == 2 && cext[0] == '[' && cext[1] == 'D')
cin = 0x08;
}
keyqueue = cin | 0x80;
}
return keyqueue & 0x80;
}
int rd6820kbd(M6502 *mpu, uword addr, byte data)
{ unsigned char cin;
if (!keyqueue)
rd6820kbdctl(mpu, addr, data);
cin = keyqueue;
keyqueue = 0;
return cin;
}
int rd6820vidctl(M6502 *mpu, uword addr, byte data) { return 0x00; }
int rd6820vid(M6502 *mpu, uword addr, byte data) { return 0x80; }
int wr6820vid(M6502 *mpu, uword addr, byte data) { if (data == 0x8D) putchar('\n'); putchar(data & 0x7F); fflush(stdout); return 0; }
int initApple1(M6502 *mpu, uword address, const char *path)
{
M6502_setCallback(mpu, call, VM_IRQ_ENTRY, vm_irq);
//
// Apple 1 memory-mapped IO
//
M6502_setCallback(mpu, read, 0xD010, rd6820kbd);
M6502_setCallback(mpu, read, 0xD011, rd6820kbdctl);
M6502_setCallback(mpu, read, 0xD012, rd6820vid);
M6502_setCallback(mpu, write, 0xD012, wr6820vid);
M6502_setCallback(mpu, read, 0xD013, rd6820vidctl);
//
// CFFA1 and ROM calls
//
M6502_setCallback(mpu, call, 0x9000, bye);
M6502_setCallback(mpu, call, 0x900C, cffa1);
M6502_setCallback(mpu, call, 0xFFEF, cout);
//
// 32K RAM
//
mem_6502[FPL] = 0x00; // Frame pointer = $8000
mem_6502[FPH] = 0x80;
mem_6502[PPL] = 0x00; // Pool pointer = $8000 (unused)
mem_6502[PPH] = 0x80;
return load(address, path);
}
+86 -233
View File
@@ -29,6 +29,8 @@ struct termios org_tio;
byte symtbl[SYMTBL_SIZE]; // Symbol table outside mem_6502 for PLVM
byte *lastsym = symtbl;
byte *perr;
int paused = 0;
byte keyqueue = 0;
uword keybdbuf = 0x0200;
uword heap = 0x0300;
uword cmdsys;
@@ -37,193 +39,46 @@ typedef struct {
uword defaddr;
} defxlat_t;
/*
* Standard Library exported functions.
* Hard fail
*/
/*
* Simple I/O routines
*/
/*
* CFFA1 emulation
*/
#define CFFADest 0x00
#define CFFAFileName 0x02
#define CFFAOldName 0x04
#define CFFAFileType 0x06
#define CFFAAuxType 0x07
#define CFFAFileSize 0x09
#define CFFAEntryPtr 0x0B
void pfail(const char *msg)
{
fflush(stdout);
tcsetattr(STDIN_FILENO, TCSANOW, &org_tio);
perror(msg);
exit(1);
}
int save(uword address, unsigned length, const char *path)
{
FILE *file;
int count;
if (!(file = fopen(path, "wb")))
return 0;
while ((count = fwrite(mem_6502 + address, 1, length, file)))
{
address += count;
length -= count;
}
fclose(file);
return 1;
}
int load(uword address, const char *path)
{
FILE *file;
int count;
size_t max = 0x10000 - address;
if (!(file = fopen(path, "rb")))
return 0;
while ((count = fread(mem_6502 + address, 1, max, file)) > 0)
{
address += count;
max -= count;
}
fclose(file);
return 1;
}
char *strlower(char *strptr)
{
int i;
for (i = 0; strptr[i]; i++)
strptr[i] = tolower(strptr[i]);
return strptr;
}
int cffa1(M6502 *mpu, uword address, byte data)
{
char *fileptr, filename[64];
int addr;
struct stat sbuf;
switch (mpu->registers->x)
{
case 0x02: // quit
exit(0);
break;
case 0x14: // find dir entry
addr = mem_6502[CFFAFileName] | (mem_6502[CFFAFileName + 1] << 8);
memset(filename, 0, 64);
strncpy(filename, (char *)(mem_6502 + addr + 1), mem_6502[addr]);
strlower(filename);
strcat(filename, ".mod");
if (!(stat(filename, &sbuf)))
{
// DirEntry @ $9100
mem_6502[CFFAEntryPtr] = 0x00;
mem_6502[CFFAEntryPtr + 1] = 0x91;
mem_6502[0x9115] = sbuf.st_size;
mem_6502[0x9116] = sbuf.st_size >> 8;
mpu->registers->a = 0;
}
else
mpu->registers->a = -1;
break;
case 0x22: // load file
addr = mem_6502[CFFAFileName] | (mem_6502[CFFAFileName + 1] << 8);
memset(filename, 0, 64);
strncpy(filename, (char *)(mem_6502 + addr + 1), mem_6502[addr]);
strlower(filename);
strcat(filename, ".mod");
addr = mem_6502[CFFADest] | (mem_6502[CFFADest + 1] << 8);
mpu->registers->a = load(addr, filename) - 1;
break;
default:
{
char state[64];
fprintf(stderr, "Unimplemented CFFA function: %02X\n", mpu->registers->x);
M6502_dump(mpu, state);
fflush(stdout);
fprintf(stderr, "\nCFFA1 %s\n", state);
pfail("ABORT");
}
break;
}
RTS;
}
/*
* Character I/O emulation
*/
int paused = 0;
unsigned char keypending = 0;
int bye(M6502 *mpu, uword addr, byte data) { exit(0); return 0; }
int cout(M6502 *mpu, uword addr, byte data) { if (mpu->registers->a == 0x8D) putchar('\n'); putchar(mpu->registers->a & 0x7F); fflush(stdout); RTS; }
unsigned char keypressed(M6502 *mpu)
{
unsigned char cin, cext[2];
if (read(STDIN_FILENO, &cin, 1) > 0)
{
if (cin == 0x03) // CTRL-C
{
trace = SINGLE_STEP;
mpu->flags |= M6502_SingleStep;
paused = 1;
}
if (cin == 0x1B) // Look for left arrow
{
if (read(STDIN_FILENO, cext, 2) == 2 && cext[0] == '[' && cext[1] == 'D')
cin = 0x08;
}
keypending = cin | 0x80;
}
return keypending & 0x80;
}
unsigned char keyin(M6502 *mpu)
{
unsigned char cin;
if (!keypending)
keypressed(mpu);
cin = keypending;
keypending = 0;
return cin;
}
int rd6820kbdctl(M6502 *mpu, uword addr, byte data) { return keypressed(mpu); }
int rd6820vidctl(M6502 *mpu, uword addr, byte data) { return 0x00; }
int rd6820kbd(M6502 *mpu, uword addr, byte data) { return keyin(mpu); }
int rd6820vid(M6502 *mpu, uword addr, byte data) { return 0x80; }
int wr6820vid(M6502 *mpu, uword addr, byte data) { if (data == 0x8D) putchar('\n'); putchar(data & 0x7F); fflush(stdout); return 0; }
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);
return 0;
}
int setApple1Traps(M6502 *mpu)
{
M6502_setCallback(mpu, call, VM_IRQ_ENTRY, vm_irq);
//
// Apple 1 memory-mapped IO
//
M6502_setCallback(mpu, read, 0xD010, rd6820kbd);
M6502_setCallback(mpu, read, 0xD011, rd6820kbdctl);
M6502_setCallback(mpu, read, 0xD012, rd6820vid);
M6502_setCallback(mpu, write, 0xD012, wr6820vid);
M6502_setCallback(mpu, read, 0xD013, rd6820vidctl);
//
// CFFA1 and ROM calls
//
M6502_setCallback(mpu, call, 0x9000, bye);
M6502_setCallback(mpu, call, 0x900C, cffa1);
M6502_setCallback(mpu, call, 0xFFEF, cout);
return 0;
}
/*
* M6502_run() with trace/single step ability
*/
byte keypressed(M6502 *mpu)
{
if (!(keyqueue & 0x80))
{
read(STDIN_FILENO, &keyqueue, 1);
keyqueue |= 0x80;
}
return keyqueue;
}
byte keyin(M6502 *mpu)
{
byte cin = keyqueue & 0x7F;
keyqueue = 0;
while (!cin)
{
if (read(STDIN_FILENO, &cin, 1) > 0)
{
if (cin == 0x03) // CTRL-C
{
cin = 0;
exit(-1);
}
}
else
usleep(10000);
}
return cin;
}
void M6502_exec(M6502 *mpu)
{
char state[64];
@@ -236,21 +91,20 @@ void M6502_exec(M6502 *mpu)
M6502_dump(mpu, state);
M6502_disassemble(mpu, mpu->registers->pc, insn);
printf("%s : %s\r\n", state, insn);
if ((trace == SINGLE_STEP) && (paused || (keypressed(mpu) && keypending == 0x83)))
if ((trace == SINGLE_STEP) && (paused || (keypressed(mpu) && keyqueue == 0x83)))
{
keypending = 0;
keyqueue = 0;
while (!keypressed(mpu));
if (keypending == (0x80|'C'))
if (keyqueue == (0x80|'C'))
paused = 0;
else if (keypending == (0x80|'Q'))
else if (keyqueue == (0x80|'Q'))
break;
else if (keypending == 0x9B) // Escape (QUIT)
else if (keyqueue == 0x9B) // Escape (QUIT)
exit(-1);
keypending = 0;
keyqueue = 0;
}
}
} while (M6502_run(mpu) > 0);
}
void resetInput(void)
{
@@ -337,7 +191,7 @@ void dump_sym(void)
byte *tbl;
tbl = symtbl;
printf("\nSystem Symbol Table:\n");
printf("\r\nSystem Symbol Table:\r\n");
while (*tbl)
{
len = 0;
@@ -350,7 +204,7 @@ void dump_sym(void)
putchar(':');
while (len++ < 15)
putchar(' ');
printf("$%04X\n", tbl[0] | (tbl[1] << 8));
printf("$%04X\r\n", tbl[0] | (tbl[1] << 8));
tbl += 2;
}
}
@@ -371,7 +225,7 @@ uword lookup_sym(byte *dci)
entry += 2;
}
dcitos(dci, str);
if (trace) printf("\nSymbol %s not found in symbol table\n", str);
if (trace) printf("\r\nSymbol %s not found in symbol table\r\n", str);
return 0;
}
uword add_sym(byte *dci, uword addr)
@@ -392,10 +246,10 @@ void dump_def(defxlat_t *defxtbl, uword defcnt)
{
if (defcnt)
{
printf("DEF XLATE table:\n");
printf("DEF XLATE table:\r\n");
while (defcnt--)
{
printf("$%04X -> $%04X\n", defxtbl->modofst, defxtbl->defaddr);
printf("$%04X -> $%04X\r\n", defxtbl->modofst, defxtbl->defaddr);
defxtbl++;
}
}
@@ -507,7 +361,7 @@ int load_mod(M6502 *mpu, byte *mod)
strcat(filename, string);
fd = open(filename, O_RDONLY, 0);
}
if (trace) printf("Load module %s: %d\n", filename, fd);
if (trace) printf("Load module %s: %d\r\n", filename, fd);
if ((fd > 0) && (len = read(fd, header, 128)) > 0)
{
moddep = header + 1;
@@ -595,18 +449,18 @@ int load_mod(M6502 *mpu, byte *mod)
//
// Dump different parts of module.
//
printf("Module load addr: $%04X\n", modaddr);
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 load addr: $%04X\r\n", modaddr);
printf("Module size: $%04X (%d)\r\n", modsize, modsize);
printf("Module code+data size: $%04X (%d)\r\n", end - modaddr, end - modaddr);
printf("Module magic: $%04X\r\n", magic);
printf("Module sysflags: $%04X\r\n", sysflags);
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);
printf("Module def count: %d\r\n", defcnt);
printf("Module bytecode: $%04X\r\n", bytecode);
printf("Module init: $%04X\r\n", init ? init + modofst : 0);
printf("Module def size: $%04X (%d)\r\n", end - bytecode, end - bytecode);
printf("Module def end: $%04X\r\n", end);
}
}
//
@@ -626,7 +480,7 @@ int load_mod(M6502 *mpu, byte *mod)
// Print out the Re-Location Dictionary.
//
if (trace)
printf("\nRe-Location Dictionary:\n");
printf("\r\nRe-Location Dictionary:\r\n");
while (rld[0])
{
addr = rld[1] | (rld[2] << 8);
@@ -709,10 +563,10 @@ int load_mod(M6502 *mpu, byte *mod)
mem_6502[addr] = fixup;
}
}
if (trace) printf("@$%04X\n", addr);
if (trace) printf("@$%04X\r\n", addr);
rld += 4;
}
if (trace) printf("\nExternal/Entry Symbol Directory:\n");
if (trace) printf("\r\nExternal/Entry Symbol Directory:\r\n");
while (esd[0])
{
sym = esd;
@@ -724,7 +578,7 @@ int load_mod(M6502 *mpu, byte *mod)
//
addr = esd[1] | (esd[2] << 8);
addr += modofst;
if (trace) printf("\tEXPORT %s@$%04X\n", string, addr);
if (trace) printf("\tEXPORT %s@$%04X\r\n", string, addr);
if (addr >= bytecode)
//
// Convert to def entry address
@@ -740,7 +594,7 @@ int load_mod(M6502 *mpu, byte *mod)
}
else
{
fprintf(stderr, "\nUnable to load module %s: ", filename);
fprintf(stderr, "\r\nUnable to load module %s: ", filename);
pfail("");
}
//
@@ -751,7 +605,7 @@ int load_mod(M6502 *mpu, byte *mod)
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);
if (trace) printf("Copy bytecode from $%04X to 0x%08X, size %d\r\n", bytecode, (unsigned int)extcode, end - bytecode);
memcpy(extcode, mem_6502 + bytecode, end - bytecode);
end = bytecode; // Free up bytecode in main memory
}
@@ -797,7 +651,7 @@ void syslookuptbl(M6502 *mpu)
/*if (trace)*/
{
dcitos(mem_6502 + sym, symbol);
printf("LOOKUPSYM: %s => $%04X\n", symbol, addr);
printf("LOOKUPSYM: %s => $%04X\r\n", symbol, addr);
}
}
void syscall6502(M6502 *mpu)
@@ -811,7 +665,7 @@ void syscall6502(M6502 *mpu)
switch (cmd)
{
}
fprintf(stderr, "SYSCALL6502 unimplemented!\n");
fprintf(stderr, "SYSCALL6502 unimplemented!\r\n");
PUSH_ESTK(status);
}
void systoupper(M6502 *mpu)
@@ -820,7 +674,7 @@ void systoupper(M6502 *mpu)
PULL_ESTK(c);
c = toupper(c);
PUSH_ESTK(c);
if (trace) printf("TOUPPER\n");
if (trace) printf("TOUPPER\r\n");
}
void sysstrcpy(M6502 *mpu)
{
@@ -829,7 +683,7 @@ void sysstrcpy(M6502 *mpu)
PULL_ESTK(dst);
memcpy(mem_6502 + dst, mem_6502 + src, mem_6502[src] + 1);
PUSH_ESTK(dst);
if (trace) printf("STRCPY\n");
if (trace) printf("STRCPY\r\n");
}
void sysstrcat(M6502 *mpu)
{
@@ -839,7 +693,7 @@ void sysstrcat(M6502 *mpu)
memcpy(mem_6502 + dst + mem_6502[dst] + 1, mem_6502 + src + 1, mem_6502[src]);
mem_6502[dst] += mem_6502[src];
PUSH_ESTK(dst);
if (trace) printf("STRCAT\n");
if (trace) printf("STRCAT\r\n");
}
void sysmemset(M6502 *mpu)
{
@@ -855,7 +709,7 @@ void sysmemset(M6502 *mpu)
}
if (size)
mem_6502[dst] = (byte)val;
if (trace) printf("MEMSET\n");
if (trace) printf("MEMSET\r\n");
}
void sysmemcpy(M6502 *mpu)
{
@@ -864,12 +718,12 @@ void sysmemcpy(M6502 *mpu)
PULL_ESTK(src);
PULL_ESTK(dst);
memcpy(mem_6502 + dst, mem_6502 + src, size);
if (trace) printf("MEMCPY\n");
if (trace) printf("MEMCPY\r\n");
}
void sysheapmark(M6502 *mpu)
{
PUSH_ESTK(heap);
if (trace) printf("HEAPMARK\n");
if (trace) printf("HEAPMARK\r\n");
}
void sysheapallocalign(M6502 *mpu)
{
@@ -884,7 +738,7 @@ void sysheapallocalign(M6502 *mpu)
addr = (heap + align) & ~align;
heap += size;
PUSH_ESTK(addr);
if (trace) printf("HEAPALLOCALIGN\n");
if (trace) printf("HEAPALLOCALIGN\r\n");
}
void sysheapalloc(M6502 *mpu)
{
@@ -893,7 +747,7 @@ void sysheapalloc(M6502 *mpu)
PULL_ESTK(size);
addr = alloc_heap(size);
PUSH_ESTK(addr);
if (trace) printf("HEAPALLOC\n");
if (trace) printf("HEAPALLOC\r\n");
}
void sysheaprelease(M6502 *mpu)
{
@@ -901,13 +755,13 @@ void sysheaprelease(M6502 *mpu)
PULL_ESTK(heap);
avail = vm_fp - heap;
PUSH_ESTK(avail);
if (trace) printf("HEAPRELEASE\n");
if (trace) printf("HEAPRELEASE\r\n");
}
void sysheapavail(M6502 *mpu)
{
uword avail = avail_heap();
PUSH_ESTK(avail);
if (trace) printf("HEAPAVAIL\n");
if (trace) printf("HEAPAVAIL\r\n");
}
void sysisugt(M6502 *mpu)
{
@@ -918,7 +772,7 @@ void sysisugt(M6502 *mpu)
PULL_ESTK(a);
result = a > b ? -1 : 0;
PUSH_ESTK(result);
if (trace) printf("ISUGT\n");
if (trace) printf("ISUGT\r\n");
}
void sysisult(M6502 *mpu)
{
@@ -929,7 +783,7 @@ void sysisult(M6502 *mpu)
PULL_ESTK(a);
result = a < b ? -1 : 0;
PUSH_ESTK(result);
if (trace) printf("ISULT\n");
if (trace) printf("ISULT\r\n");
}
void sysisuge(M6502 *mpu)
{
@@ -940,7 +794,7 @@ void sysisuge(M6502 *mpu)
PULL_ESTK(a);
result = a >= b ? -1 : 0;
PUSH_ESTK(result);
if (trace) printf("ISUGE\n");
if (trace) printf("ISUGE\r\n");
}
void sysisule(M6502 *mpu)
{
@@ -951,7 +805,7 @@ void sysisule(M6502 *mpu)
PULL_ESTK(a);
result = a <= b ? -1 : 0;
PUSH_ESTK(result);
if (trace) printf("ISULE\n");
if (trace) printf("ISULE\r\n");
}
void syssext(M6502 *mpu)
{
@@ -1084,9 +938,17 @@ int main(int argc, char **argv)
//
// Run PLVM or Apple1 environment based on passed in modfile
//
setRawInput();
if (modfile)
{
setPLVMTraps(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);
//
// 64K - 256 RAM
//
@@ -1110,19 +972,10 @@ int main(int argc, char **argv)
}
else
{
setRawInput();
setApple1Traps(mpu);
//
// 32K RAM
//
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))
if (!initApple1(mpu, 0x280, cmdfile))
pfail(cmdfile);
mpu->registers->pc = 0x0280;
M6502_exec(mpu);
+4 -4
View File
@@ -59,7 +59,7 @@ int vm_irq(M6502 *mpu, uword address, byte data)
fprintf(stderr, "\nBRK: $%04X\r\n", address);
exit (-1);
}
fprintf(stderr, "\nUnkonw IRQ!\n");
fprintf(stderr, "\nUnkonw IRQ!\r\n");
RTI;
}
//
@@ -444,14 +444,14 @@ void vm_interp(M6502 *mpu, code *vm_ip)
printf("< $%04X: $%04X > ", vm_fp + parmcnt * 2 + 0, mem_6502[vm_fp + parmcnt * 2 + 0] | (mem_6502[vm_fp + parmcnt * 2 + 1] << 8));
}
if (trace)
printf("\n");
printf("\r\n");
break;
case 0x5A: // LEAVE : DEL FRAME, IP = TOFP
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);
printf("<PP:$%04X FP:$%04X>\r\n", vm_pp, vm_fp);
case 0x5C: // RET : IP = TOFP
externalize();
return;
@@ -761,7 +761,7 @@ void vm_interp(M6502 *mpu, code *vm_ip)
* Odd codes and everything else are errors.
*/
default:
fprintf(stderr, "Illegal opcode 0x%02X @ 0x%04X\n", (unsigned int)vm_ip[-1], (unsigned int)(vm_ip - mem_6502));
fprintf(stderr, "Illegal opcode 0x%02X @ 0x%04X\r\n", (unsigned int)vm_ip[-1], (unsigned int)(vm_ip - mem_6502));
exit(-1);
}
}
+12 -1
View File
@@ -102,12 +102,19 @@ typedef uint16_t address;
* Fatal error
*/
extern void pfail(const char *msg);
/*
* Key handling
*/
extern int trace;
extern int paused;
extern byte keyqueue;
byte keypressed(M6502 *mpu);
byte keyin(M6502 *mpu);
/*
* VM callouts
*/
extern void M6502_exec(M6502 *mpu);
typedef void (*VM_Callout)(M6502 *mpu);
extern int trace;
extern byte mem_6502[];
extern byte mem_PLVM[];
extern byte *perr;
@@ -139,4 +146,8 @@ extern void sysopen(M6502 *mpu);
extern void sysclose(M6502 *mpu);
extern void sysread(M6502 *mpu);
extern void syswrite(M6502 *mpu);
/*
* Apple 1 config
*/
int initApple1(M6502 *mpu, uword address, const char *path);
+84 -36
View File
@@ -13,20 +13,33 @@
#include <termios.h>
#include "plvm.h"
byte keyqueue = 0;
int nlfd[4];
char nlmask[4], nlchar[4];
/*
* Console I/O
*/
void sysputln(M6502 *mpu)
{
putchar('\r'); putchar('\n');
fflush(stdout);
}
void sysputc(M6502 *mpu)
{
char c;
char ch;
//
// Pop char and putchar it
//
PULL_ESTK(c);
putchar(c);
PULL_ESTK(ch);
switch (ch)
{
case '\r':
case '\n':
sysputln(mpu);
break;
default:
putchar(ch);
}
fflush(stdout);
}
void sysputs(M6502 *mpu)
{
@@ -45,16 +58,13 @@ void sysputs(M6502 *mpu)
{
case '\r':
case '\n':
putchar('\n');
sysputln(mpu);
break;
default:
putchar(ch);
}
}
}
void sysputln(M6502 *mpu)
{
putchar('\n');
fflush(stdout);
}
void sysputi(M6502 *mpu)
{
@@ -85,10 +95,8 @@ void sysputh(M6502 *mpu)
}
void syskeypressed(M6502 *mpu)
{
int n;
if (!(keyqueue & 0x80) && (ioctl(STDIN_FILENO, FIONREAD, &n) == 0) && (n > 0))
keyqueue = getchar() | 0x80;
if (!(keyqueue & 0x80))
keypressed(mpu);
PUSH_ESTK(keyqueue);
}
void sysgetc(M6502 *mpu)
@@ -97,29 +105,69 @@ void sysgetc(M6502 *mpu)
//
// Push getchar()
//
if (keyqueue)
if (keyqueue & 0x80)
{
c = keyqueue & 0x7F;
keyqueue = 0;
}
else
c = getchar();
c = keyin(mpu);
PUSH_ESTK(c);
}
void sysgets(M6502 *mpu)
{
uword strptr;
int len;
char instr[256];
char cext[2], instr[256];
//
// Push gets(), limiting it to 128 chars
//
PULL_ESTK(instr[0]);
putchar(instr[0] & 0x7F);
PULL_ESTK(cext[0]);
putchar(cext[0] & 0x7F);
len = 0;
if (keyqueue)
{
putchar(keyqueue & 0x7F);
instr[len++] = keyqueue & 0x7F;
keyqueue = 0;
}
fflush(stdout);
do
{
switch (keyqueue = keyin(mpu))
{
case 0x1B:
if (read(STDIN_FILENO, cext, 2) == 2)
if (cext[0] == '[' && cext[1] == 'D') // Left arrow
keyqueue = 0x08;
else
break;
else
break;
case 0x08: // BS
case 0x7F: // BS
if (len)
{
putchar('\x08');
putchar(' ');
putchar('\x08');
len--;
}
break;
default:
if (keyqueue >= ' ')
putchar(instr[len++] = keyqueue);
}
fflush(stdout);
} while (keyqueue != 0x0D && len < 128);
sysputln(mpu);
keyqueue = 0;
/*
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);
@@ -129,7 +177,7 @@ void sysecho(M6502 *mpu)
int state;
PULL_ESTK(state);
fprintf(stderr, "CONIO:ECHO unimplemented!\n");
fprintf(stderr, "CONIO:ECHO unimplemented!\r\n");
PUSH_ESTK(0);
}
void syshome(M6502 *mpu)
@@ -154,7 +202,7 @@ void sysviewport(M6502 *mpu)
PULL_ESTK(x);
PULL_ESTK(w);
PULL_ESTK(h);
fprintf(stderr, "CONIO:VIEWPORT unimplemented!\n");
fprintf(stderr, "CONIO:VIEWPORT unimplemented!\r\n");
PUSH_ESTK(0);
}
void systexttype(M6502 *mpu)
@@ -162,7 +210,7 @@ void systexttype(M6502 *mpu)
int mode;
PULL_ESTK(mode);
fprintf(stderr, "CONIO:TEXTYPE unimplemented!\n");
fprintf(stderr, "CONIO:TEXTYPE unimplemented!\r\n");
PUSH_ESTK(0);
}
void systextmode(M6502 *mpu)
@@ -205,12 +253,12 @@ void systone(M6502 *mpu)
PULL_ESTK(duration);
PULL_ESTK(pitch);
fprintf(stderr, "CONIO:TONE unimplemented!\n");
fprintf(stderr, "CONIO:TONE unimplemented!\r\n");
PUSH_ESTK(0);
}
void sysrnd(M6502 *mpu)
{
fprintf(stderr, "CONIO:RND unimplemented!\n");
fprintf(stderr, "CONIO:RND unimplemented!\r\n");
PUSH_ESTK(rand());
}
/*
@@ -218,34 +266,34 @@ void sysrnd(M6502 *mpu)
*/
void sysgetpfx(M6502 *mpu)
{
fprintf(stderr, "FILEIO:GETPFX unimplemented!\n");
fprintf(stderr, "FILEIO:GETPFX unimplemented!\r\n");
}
void syssetpfx(M6502 *mpu)
{
fprintf(stderr, "FILEIO:SETPFX unimplemented!\n");
fprintf(stderr, "FILEIO:SETPFX unimplemented!\r\n");
}
void sysgetfileinfo(M6502 *mpu)
{
fprintf(stderr, "FILEIO:GETFILEINFO unimplemented!\n");
fprintf(stderr, "FILEIO:GETFILEINFO unimplemented!\r\n");
}
void syssetfileinfo(M6502 *mpu)
{
fprintf(stderr, "FILEIO:SETFILEINFO unimplemented!\n");
fprintf(stderr, "FILEIO:SETFILEINFO unimplemented!\r\n");
}
void sysgeteof(M6502 *mpu)
{
fprintf(stderr, "FILEIO:GETEOF unimplemented!\n");
fprintf(stderr, "FILEIO:GETEOF unimplemented!\r\n");
}
void sysseteof(M6502 *mpu)
{
fprintf(stderr, "FILEIO:SETEOF unimplemented!\n");
fprintf(stderr, "FILEIO:SETEOF unimplemented!\r\n");
}
void sysiobufs(M6502 *mpu)
{
uword dummy;
PULL_ESTK(dummy);
PUSH_ESTK(0);
if (trace) printf("IOBUFS\n");
if (trace) printf("IOBUFS\r\n");
}
void sysopen(M6502 *mpu)
{
@@ -260,8 +308,8 @@ void sysopen(M6502 *mpu)
memcpy(filename, mem_6502 + filestr + 1, mem_6502[filestr]);
filename[mem_6502[filestr]] = '\0';
fd = open(filename, O_RDWR);
if (trace) printf("FILEIO:OPEN(%s): %d\n", filename, fd);
if (fd > 255) fprintf(stderr, "FILEIO:OPEN fd out of range!\n");
if (trace) printf("FILEIO:OPEN(%s): %d\r\n", filename, fd);
if (fd > 255) fprintf(stderr, "FILEIO:OPEN fd out of range!\r\n");
if (fd < 0){ fd = 0; *perr = errno;}
PUSH_ESTK(fd);
}
@@ -288,7 +336,7 @@ void sysread(M6502 *mpu)
PULL_ESTK(len);
PULL_ESTK(buf);
PULL_ESTK(fd);
if (trace) printf("FILEIO:READ %d $%04X %d\n", fd, buf, len);
if (trace) printf("FILEIO:READ %d $%04X %d\r\n", fd, buf, len);
for (i = 0; i < 4; i++)
{
if (nlfd[i] == fd)
@@ -317,7 +365,7 @@ void syswrite(M6502 *mpu)
PULL_ESTK(len);
PULL_ESTK(buf);
PULL_ESTK(fd);
if (trace) printf("FILEIO:WRITE %d $%04X %d\n", fd, buf, len);
if (trace) printf("FILEIO:WRITE %d $%04X %d\r\n", fd, buf, len);
len = write(fd, mem_6502 + buf, len);
if (len < 0) *perr = errno;
PUSH_ESTK(len);
@@ -393,11 +441,11 @@ void sysonline(M6502 *mpu)
PULL_ESTK(buf);
PULL_ESTK(unit);
PUSH_ESTK(0);
fprintf(stderr, "FILEIO:ONLINE unimplemented!\n");
fprintf(stderr, "FILEIO:ONLINE unimplemented!\r\n");
}
void sysunimpl(M6502 *mpu)
{
fprintf(stderr, "FILEIO:??? unimplemented!\n");
fprintf(stderr, "FILEIO:??? unimplemented!\r\n");
}
/*
* Create PLVM versions of fileio and conio modules.