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:
+2
-2
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user