mirror of
https://github.com/RevCurtisP/C02.git
synced 2025-02-19 19:31:04 +00:00
Enhancements t file6502, run6502
This commit is contained in:
parent
1fc3f1cde4
commit
dee6b20bba
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 *
|
||||
**********************************************************************************************/
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user