Enhancements t file6502, run6502

This commit is contained in:
Curtis F Kaylor 2021-09-19 16:46:45 -04:00
parent 1fc3f1cde4
commit dee6b20bba
3 changed files with 180 additions and 6 deletions

View File

@ -13,12 +13,16 @@
#include "lib6502.h"
#include "file6502.h"
typedef uint8_t byte;
typedef uint16_t word;
int debug;
byte *xmemory[16]; //Extended Memory
byte xmembank; //Extended Memory Current Bank
word xmemaddr; //Extended Memory Current Address
word smemaddr; //System Memory Address
#define STRLEN 128
#define STRSIZ STRLEN+1
@ -664,6 +668,106 @@ extern int syscmd(M6502 *mpu, word addr, byte data) {
mpu->registers->y = y;
}
/* Initialize Extended RAM */
extern void initxmem(void) {
for (int i=0; i<16; i++) xmemory[i] = (byte *) malloc(0x10000);
xmembank = 0;
xmemaddr = 0;
}
/* Increment Ext Memory Address and Page */
static void xmemnext() {
xmemaddr++;
if (xmemaddr > 0xFFFF) {xmembank++; xmemaddr = 0;}
if (xmembank > 0x0F) xmembank = 0;
}
/* Read/Write Extended Memory */
static byte readxmem(int inc) {
byte b = xmemory[xmembank][xmemaddr];
//if (debug) fprintf(stderr, "read byte %d from bank %02x address %04x\n", b, xmembank, xmemaddr);
if (inc) xmemnext();
return b;
}
static void writexmem(byte b, int inc) {
//if (debug) fprintf(stderr, "writing byte %d to bank %02x address %04x\n", b, xmembank, xmemaddr);
xmemory[xmembank][xmemaddr] = b;
if (inc) xmemnext();
}
/* Emulate extended memory command dispatch at addr */
extern int xmemcmd(M6502 *mpu, word addr, byte data) {
char mode[2][8] = {"reading", "writing"};
byte a = mpu->registers->a;
byte x = mpu->registers->x;
byte y = mpu->registers->y;
byte p = mpu->registers->p;
word yx = y << 8 | x;
byte cs = (p & 1);
if (debug) fprintf(stderr, "executing ext memory command '%c' with options %02x,%02x,%02x\n", a, y, x, p);
switch(a) {
case 'A': //Get/Set Address - YX = address, CC = get, CS = set
if (cs) {
xmemaddr = yx;
if (debug) fprintf(stderr, "set extended memory address to $%04x\n", xmemaddr);
} else {
if (debug) fprintf(stderr, "returning extended memory address $%04x\n", xmemaddr);
y = xmemaddr >> 8; x = xmemaddr & 0xFF;
}
break;
case 'B': //Get/Set Bank - X/A = bank, CC = get, CS = set
if (cs) {
xmembank = x & 0x0F;
if (debug) fprintf(stderr, "set extended memory bank to $%02x\n", xmembank);
} else {
if (debug) fprintf(stderr, "returning extended memory bank $%02x\n", xmembank);
a = xmembank;
}
break;
case 'C': //Read/Write Byte w/o Increment - X/A = Byte, CC = Read, CS = Write
if (cs) writexmem(x,0); else a = readxmem(0);
break;
case 'M': //Read/Write Bytes to RAM - YX = Byte Count, CC = Read, CS = Write
if (debug) fprintf(stderr, "%s %d bytes: %02x-%04x <-> %04x\n{", mode[cs], yx, xmembank, xmemaddr, smemaddr);
for (int i=0; i<yx; i++) {
if (cs) writexmem(mpu->memory[smemaddr], -1);
else mpu->memory[smemaddr] = readxmem(-1);
if (debug) {if (i) putc(',', stderr); fprintf(stderr, "%d", mpu->memory[smemaddr]);}
smemaddr++; if (smemaddr > 0xFFFF) smemaddr = 0;
}
if (debug) fprintf(stderr, "}\n");
a = xmembank; y = xmemaddr >> 8; x = xmemaddr & 0xFF;
break;
case 'N': //Read/Write Next Byte - X/A = Byte, CC = Read, CS = Write
if (cs) writexmem(x,-1); else a = readxmem(-1);
break;
case 'S': //Set System RAM Address - YX = address
smemaddr = yx;
if (debug) fprintf(stderr, "set system memory address to $%04x\n", smemaddr);
break;
case 'W': //Read/Write Next Word - YX = Word, CC = Read, CS = Write
if (cs) {writexmem(x,-1); writexmem(y,-1);}
else {x = readxmem(-1); y = readxmem(-1);}
break;
case 'X': //Read/Write Bytes to RAM - YX = Byte Count, CC = Read, CS = Write
if (debug) fprintf(stderr, "swapping %d bytes: %02x-%04x <-> %04x\n{", yx, xmembank, xmemaddr, smemaddr);
for (int i=0; i<yx; i++) {
byte temp = mpu->memory[smemaddr];
mpu->memory[smemaddr] = readxmem(-1);
writexmem(temp, -1);
smemaddr++; if (smemaddr > 0xFFFF) smemaddr = 0;
}
a = xmembank; y = xmemaddr >> 8; x = xmemaddr & 0xFF;
break;
default:
if (debug) fprintf(stderr, "invalid command '%x'\n", a);
}
if (debug) fprintf(stderr, "returning values %02x, %02x, %02x, %02x\n", a, y, x, p);
mpu->registers->a = a;
mpu->registers->x = x;
mpu->registers->y = y;
}
/* Read Keys Directly from Console, Eliminating getc() buffering */
extern int getkey(M6502 *mpu, word addr, byte data) {
int a = 0, y=0, x=0; //Initialize Key Press to None
@ -693,4 +797,4 @@ extern int putcon(M6502 *mpu, word addr, byte data) {
default: a = _putch(a);
}
mpu->registers->a = a;
}
}

View File

@ -7,7 +7,6 @@ typedef uint16_t word;
extern void setdebug(int dbg);
/**********************************************************************************************
* Process File Command *
* Command passed in A and parameters in X, Y, and Carry *
@ -97,9 +96,41 @@ extern int filecmd(M6502 *mpu, word addr, byte data);
**********************************************************************************************/
extern int syscmd(M6502 *mpu, word addr, byte data);
/* Initialize Extended RAM */
extern void initxmem(void);
/**********************************************************************************************
* Process Extended Memory Command *
* Extended Memory consists of 16 banks of 64KiB of memory, for a total of 1 MB of memory *
* not directly addressable by the 6502. *
* Memory is read and written a byte or word at a time to an 16 bit address within a bank. *
* After each read or write, the address is incremented, and at the end of a bank, the *
* address reset to zero and the next bank selected, wrapping around to bank 0 at the end. * *
* Command passed in A and parameters in X, Y, and Carry *
* 16-Bit values are passed with the MSB in Y and the LSB in X *
* Results returned in A, X, and Y *
* *
* A=Command Description Parameters Returns *
* A GETADDR Get Address (Carry Clear) Y,X=Address *
* SETADDR Set Address (Carry Set) Y,X=Address *
* B GETBANK Get Bank (Carry Clear) A=Bank *
* SETBANK Set Bank (Carry Set) X=Bank *
* C GETCHAR Read Byte (Carry Clear) A=Byte *
* PUTCHAR Write Byte (Carry Set) X=Byte *
* M GETMBLK Get Memory Block (Carry Clear) Y,X=Byte Count A,Y,X=Extended Address *
* SETMBLK Set Memory Block (Carry Set) Y,X=Byte Count A,Y,X=Extended Address *
* N GETNEXT Read Next Byte (Carry Clear) A=Byte *
* PUTNEXT Write Next Byte (Carry Set) X=Byte *
* S SYSADDR Set System RAM Address Y,X=Address *
* W GETWORD Read Next Word (Carry Clear) Y,X=Word *
* PUTWORD Write Next Word (Carry Set) Y,X=Word *
* X SWPMBLK Swap Memory Block Y,X=Byte Count A,Y,X=Extended Address *
**********************************************************************************************/
extern int xmemcmd(M6502 *mpu, word addr, byte data);
/**********************************************************************************************
* Read Key Directly from Console *
* Bypasses getc() from stdin, eliminating input buffering *
* Bypasses getc() from stdin, eliminating input buffering *
* Returns ASCII key value in A, extended Key Code in Y and X *
* Cursor Control Keys produce an ASCII value with the high bit set *
**********************************************************************************************/

View File

@ -250,6 +250,7 @@ static void usage(int status)
fprintf(stream, " -d addr last -- disassemble memory between addr and last\n");
fprintf(stream, " -C addr -- emulate _putch at addr\n");
fprintf(stream, " -D -- print debug messages\n");
fprintf(stream, " -E addr maxpage -- emulate extended memory at addr\n");
fprintf(stream, " -F addr -- emulate fileio at addr\n");
fprintf(stream, " -G addr -- emulate getchar(3) at addr\n");
fprintf(stream, " -h -- help (print this message)\n");
@ -265,7 +266,8 @@ static void usage(int status)
fprintf(stream, " -s addr last file -- save memory from addr to last in file\n");
fprintf(stream, " -v -- print version number then exit\n");
fprintf(stream, " -X addr -- terminate emulation if PC reaches addr\n");
fprintf(stream, " -x -- exit wihout further ado\n");
fprintf(stream, " -w addr \"string\" -- write string to memory at addr\n");
fprintf(stream, " -x -- exit without further ado\n");
fprintf(stream, " image -- '-l 8000 image' in available ROM slot\n");
fprintf(stream, "\n");
fprintf(stream, "'last' can be an address (non-inclusive) or '+size' (in bytes)\n");
@ -380,6 +382,26 @@ static int doSave(int argc, char **argv, M6502 *mpu) /* -l addr size file */
return 3;
}
static int doArgs(int argc, char **argv, M6502 *mpu) /* -a addr */
{
return 1;
}
static int doWrite(int argc, char **argv, M6502 *mpu) /* -a addr "string" */
{
int addr = htol(argv[1]);
int size = strlen(argv[2]);
char *args = malloc(size);
strcpy(args, argv[1]);
write(mpu, addr, size, args);
return 2;
}
static int write(M6502 *mpu, word address, int size, char *s)
{
for (int i=0; i<size; i++) mpu->memory[address++] = s[i];
return address;
}
#define doVEC(VEC) \
static int do##VEC(int argc, char **argv, M6502 *mpu) \
@ -397,6 +419,20 @@ doVEC(RST);
#undef doVEC
static int eTrap(M6502 *mpu, word addr, byte data) {
xmemcmd(mpu, addr, data);
rts;
}
static int doEtrap(int argc, char **argv, M6502 *mpu)
{
unsigned addr, page;
if (argc < 2) usage(1);
addr= htol(argv[1]);
initxmem();
M6502_setCallback(mpu, call, addr, eTrap);
return 1;
}
static int fTrap(M6502 *mpu, word addr, byte data) {
filecmd(mpu, addr, data);
rts;
@ -559,10 +595,12 @@ int main(int argc, char **argv)
while (++argv, --argc > 0)
{
int n= 0;
if (!strcmp(*argv, "-B")) bTraps= 1;
if (!strcmp(*argv, "-a")) n= doArgs(argc, argv, mpu);
else if (!strcmp(*argv, "-B")) bTraps= 1;
else if (!strcmp(*argv, "-d")) n= doDisassemble(argc, argv, mpu);
else if (!strcmp(*argv, "-C")) n= doCtrap(argc, argv, mpu);
else if (!strcmp(*argv, "-D")) n= doDebug(argc, argv, mpu);
else if (!strcmp(*argv, "-E")) n= doEtrap(argc, argv, mpu);
else if (!strcmp(*argv, "-F")) n= doFtrap(argc, argv, mpu);
else if (!strcmp(*argv, "-G")) n= doGtrap(argc, argv, mpu);
else if (!strcmp(*argv, "-h")) n= doHelp(argc, argv, mpu);
@ -578,6 +616,7 @@ int main(int argc, char **argv)
else if (!strcmp(*argv, "-S")) n= doStrap(argc, argv, mpu);
else if (!strcmp(*argv, "-s")) n= doSave(argc, argv, mpu);
else if (!strcmp(*argv, "-v")) n= doVersion(argc, argv, mpu);
else if (!strcmp(*argv, "-w")) n= doWrite(argc, argv, mpu);
else if (!strcmp(*argv, "-X")) n= doXtrap(argc, argv, mpu);
else if (!strcmp(*argv, "-x")) exit(0);
else if ('-' == **argv) usage(1);