X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fasm6502.c;h=c95e5babd9e8e50cbb9fd0cf3017e173edfbeb18;hp=aeda48267efaf7b95d0ba5f5fe92d726926cc0e4;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hpb=c8c6deae79b408cffbc88043c766b3bc12cf0f13 diff --git a/hacks/asm6502.c b/hacks/asm6502.c index aeda4826..c95e5bab 100644 --- a/hacks/asm6502.c +++ b/hacks/asm6502.c @@ -1,3 +1,4 @@ +/*-*- indent-tabs-mode:nil -*- */ /* Copyright (C) 2007 Jeremy English * * Permission to use, copy, modify, distribute, and sell this software and its @@ -19,8 +20,6 @@ I changed the structure of the assembler in this version. */ -#define NDEBUG /* Uncomment when done with debugging */ - #include #include /*#include */ @@ -30,11 +29,27 @@ #include #include #include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#if defined(HAVE_STDINT_H) +# include +#elif defined(HAVE_INTTYPES_H) +# include +#endif #include +#include "yarandom.h" #include "asm6502.h" +/*#ifdef DEBUGGER +# define random rand +#endif*/ + +#ifndef HAVE_MOBILE +# define READ_FILES +#endif + typedef enum{ LEFT, RIGHT } Side; @@ -63,7 +78,7 @@ typedef BOOL (*CharTest) (char); /*typedef void (*JumpFunc) (machine_6502* AddrMode);*/ typedef struct { - AddrMode type; + m6502_AddrMode type; Bit32 value[MAX_PARAM_VALUE]; unsigned int vp; /*value pointer, index into the value table.*/ char *label; @@ -89,45 +104,16 @@ typedef struct { Bit16 value; } Pointer; -/* eprintf - Taken from "Practice of Programming" by Kernighan and Pike */ -static void eprintf(char *fmt, ...){ - va_list args; - - char *progname = "Assembler"; - - fflush(stdout); - if (progname != NULL) - fprintf(stderr, "%s: ", progname); - - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - - if (fmt[0] != '\0' && fmt[strlen(fmt) -1] == ':') - fprintf(stderr, " %s", strerror(errno)); - fprintf(stderr, "\n"); - exit(2); /* conventional value for failed execution */ -} -/* emalloc - Taken from "Practice of Programming" by Kernighan and - Pike. If memory allocatiion fails the program will print a message - an exit. */ -static void *emalloc(size_t n) { - void *p; - - p = malloc(n); - if (p == NULL) - eprintf("malloc of %u bytes failed:", n); +/*static void *emalloc(size_t n) { + void *p = malloc(n); + if (! p) abort(); return p; -} +}*/ -/* ecalloc - Dose the same thing as emalloc just calls calloc instead. */ static void *ecalloc(uint32_t nelm, size_t nsize){ - void *p; - - p = calloc(nelm, nsize); - if (p == NULL) - eprintf("calloc of %u bytes failed:", nelm * nsize); + void *p = calloc(nelm, nsize); + if (!p) abort(); return p; } @@ -179,10 +165,11 @@ static Bit8 stackPop(machine_6502 *machine) { } static void pushByte(machine_6502 *machine, Bit32 value ) { - Bit32 address = 0x600 + machine->codeLen; + Bit32 address = machine->defaultCodePC; checkAddress(address); - machine->memory[0x600 + machine->codeLen] = value & 0xff; + machine->memory[address] = value & 0xff; machine->codeLen++; + machine->defaultCodePC++; } /* @@ -282,7 +269,7 @@ static Bit8 nibble(Bit8 value, Side side){ /* used for tracing. XXX: combined with function getvalue */ -static BOOL peekValue(machine_6502 *machine, AddrMode adm, Pointer *pointer, Bit16 PC){ +static BOOL peekValue(machine_6502 *machine, m6502_AddrMode adm, Pointer *pointer, Bit16 PC){ Bit8 zp; pointer->value = 0; pointer->addr = 0; @@ -295,9 +282,9 @@ static BOOL peekValue(machine_6502 *machine, AddrMode adm, Pointer *pointer, Bit pointer->value = memReadByte(machine, PC); return TRUE; case INDIRECT_X: - zp = memReadByte(machine, PC); + zp = memReadByte(machine, PC) + machine->regX; pointer->addr = memReadByte(machine,zp) + - (memReadByte(machine,zp+1)<<8) + machine->regX; + (memReadByte(machine,zp+1)<<8); pointer->value = memReadByte(machine, pointer->addr); return TRUE; case INDIRECT_Y: @@ -347,7 +334,7 @@ static BOOL peekValue(machine_6502 *machine, AddrMode adm, Pointer *pointer, Bit /* Figure out how to get the value from the addrmode and get it.*/ -static BOOL getValue(machine_6502 *machine, AddrMode adm, Pointer *pointer){ +static BOOL getValue(machine_6502 *machine, m6502_AddrMode adm, Pointer *pointer){ Bit8 zp; pointer->value = 0; pointer->addr = 0; @@ -360,9 +347,9 @@ static BOOL getValue(machine_6502 *machine, AddrMode adm, Pointer *pointer){ pointer->value = popByte(machine); return TRUE; case INDIRECT_X: - zp = popByte(machine); + zp = popByte(machine) + machine->regX; pointer->addr = memReadByte(machine,zp) + - (memReadByte(machine,zp+1)<<8) + machine->regX; + (memReadByte(machine,zp+1)<<8); pointer->value = memReadByte(machine, pointer->addr); return TRUE; case INDIRECT_Y: @@ -408,6 +395,66 @@ static BOOL getValue(machine_6502 *machine, AddrMode adm, Pointer *pointer){ } +#if 0 +static void dismem(machine_6502 *machine, m6502_AddrMode adm, char *output){ + Bit8 zp; + Bit16 n; + switch(adm){ + case SINGLE: + *output = 0; + break; + case IMMEDIATE_LESS: + case IMMEDIATE_GREAT: + case IMMEDIATE_VALUE: + n = popByte(machine); + sprintf(output,"#$%x",n); + break; + case INDIRECT_X: + zp = popByte(machine); + n = memReadByte(machine,zp) + + (memReadByte(machine,zp+1)<<8); + sprintf(output,"($%x,x)",n); + break; + case INDIRECT_Y: + zp = popByte(machine); + n = memReadByte(machine,zp) + + (memReadByte(machine,zp+1)<<8); + sprintf(output,"($%x),y",n); + break; + case ABS_OR_BRANCH: + case ZERO: + n = popByte(machine); + sprintf(output,"$%x",n); + break; + case ZERO_X: + n = popByte(machine); + sprintf(output,"$%x,x",n); + break; + case ZERO_Y: + n = popByte(machine); + sprintf(output,"$%x,y",n); + break; + case ABS_VALUE: + n = popWord(machine); + sprintf(output,"$%x",n); + break; + case ABS_LABEL_X: + case ABS_X: + n = popWord(machine); + sprintf(output,"$%x,x",n); + break; + case ABS_LABEL_Y: + case ABS_Y: + n = popWord(machine); + sprintf(output,"$%x,x",n); + break; + case DCB_PARAM: + *output = 0; + break; + } +} +#endif + /* manZeroNeg - Manage the negative and zero flags */ static void manZeroNeg(machine_6502 *machine, Bit8 value){ machine->regP = setBit(machine->regP, ZERO_FL, (value == 0)); @@ -420,7 +467,7 @@ static void warnValue(BOOL isValue){ } } -static void jmpADC(machine_6502 *machine, AddrMode adm){ +static void jmpADC(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; Bit16 tmp; Bit8 c = bitOn(machine->regP, CARRY_FL); @@ -471,7 +518,7 @@ static void jmpADC(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine,machine->regA); } -static void jmpAND(machine_6502 *machine, AddrMode adm){ +static void jmpAND(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -479,7 +526,7 @@ static void jmpAND(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine,machine->regA); } -static void jmpASL(machine_6502 *machine, AddrMode adm){ +static void jmpASL(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); if (isValue){ @@ -498,7 +545,7 @@ static void jmpASL(machine_6502 *machine, AddrMode adm){ } -static void jmpBIT(machine_6502 *machine, AddrMode adm){ +static void jmpBIT(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -515,7 +562,7 @@ static void jumpBranch(machine_6502 *machine, Bit16 offset){ machine->regPC = machine->regPC + offset; } -static void jmpBPL(machine_6502 *machine, AddrMode adm){ +static void jmpBPL(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -524,7 +571,7 @@ static void jmpBPL(machine_6502 *machine, AddrMode adm){ } -static void jmpBMI(machine_6502 *machine, AddrMode adm){ +static void jmpBMI(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -533,7 +580,7 @@ static void jmpBMI(machine_6502 *machine, AddrMode adm){ } -static void jmpBVC(machine_6502 *machine, AddrMode adm){ +static void jmpBVC(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -541,7 +588,7 @@ static void jmpBVC(machine_6502 *machine, AddrMode adm){ jumpBranch(machine, ptr.addr); } -static void jmpBVS(machine_6502 *machine, AddrMode adm){ +static void jmpBVS(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -549,7 +596,7 @@ static void jmpBVS(machine_6502 *machine, AddrMode adm){ jumpBranch(machine, ptr.addr); } -static void jmpBCC(machine_6502 *machine, AddrMode adm){ +static void jmpBCC(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -557,7 +604,7 @@ static void jmpBCC(machine_6502 *machine, AddrMode adm){ jumpBranch(machine, ptr.addr); } -static void jmpBCS(machine_6502 *machine, AddrMode adm){ +static void jmpBCS(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -565,7 +612,7 @@ static void jmpBCS(machine_6502 *machine, AddrMode adm){ jumpBranch(machine, ptr.addr); } -static void jmpBNE(machine_6502 *machine, AddrMode adm){ +static void jmpBNE(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -573,7 +620,7 @@ static void jmpBNE(machine_6502 *machine, AddrMode adm){ jumpBranch(machine, ptr.addr); } -static void jmpBEQ(machine_6502 *machine, AddrMode adm){ +static void jmpBEQ(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -586,28 +633,28 @@ static void doCompare(machine_6502 *machine, Bit16 reg, Pointer *ptr){ manZeroNeg(machine,(reg - ptr->value)); } -static void jmpCMP(machine_6502 *machine, AddrMode adm){ +static void jmpCMP(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); doCompare(machine,machine->regA,&ptr); } -static void jmpCPX(machine_6502 *machine, AddrMode adm){ +static void jmpCPX(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); doCompare(machine,machine->regX,&ptr); } -static void jmpCPY(machine_6502 *machine, AddrMode adm){ +static void jmpCPY(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); doCompare(machine,machine->regY,&ptr); } -static void jmpDEC(machine_6502 *machine, AddrMode adm){ +static void jmpDEC(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -619,7 +666,7 @@ static void jmpDEC(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine,ptr.value); } -static void jmpEOR(machine_6502 *machine, AddrMode adm){ +static void jmpEOR(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -627,35 +674,35 @@ static void jmpEOR(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine, machine->regA); } -static void jmpCLC(machine_6502 *machine, AddrMode adm){ +static void jmpCLC(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = setBit(machine->regP, CARRY_FL, 0); } -static void jmpSEC(machine_6502 *machine, AddrMode adm){ +static void jmpSEC(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = setBit(machine->regP, CARRY_FL, 1); } -static void jmpCLI(machine_6502 *machine, AddrMode adm){ +static void jmpCLI(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = setBit(machine->regP, INTERRUPT_FL, 0); } -static void jmpSEI(machine_6502 *machine, AddrMode adm){ +static void jmpSEI(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = setBit(machine->regP, INTERRUPT_FL, 1); } -static void jmpCLV(machine_6502 *machine, AddrMode adm){ +static void jmpCLV(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = setBit(machine->regP, OVERFLOW_FL, 0); } -static void jmpCLD(machine_6502 *machine, AddrMode adm){ +static void jmpCLD(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = setBit(machine->regP, DECIMAL_FL, 0); } -static void jmpSED(machine_6502 *machine, AddrMode adm){ +static void jmpSED(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = setBit(machine->regP, DECIMAL_FL, 1); } -static void jmpINC(machine_6502 *machine, AddrMode adm){ +static void jmpINC(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -664,14 +711,14 @@ static void jmpINC(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine,ptr.value); } -static void jmpJMP(machine_6502 *machine, AddrMode adm){ +static void jmpJMP(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); machine->regPC = ptr.addr; } -static void jmpJSR(machine_6502 *machine, AddrMode adm){ +static void jmpJSR(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; /* Move past the 2 byte parameter. JSR is always followed by absolute address. */ @@ -683,7 +730,7 @@ static void jmpJSR(machine_6502 *machine, AddrMode adm){ machine->regPC = ptr.addr; } -static void jmpLDA(machine_6502 *machine, AddrMode adm){ +static void jmpLDA(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -691,7 +738,7 @@ static void jmpLDA(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine, machine->regA); } -static void jmpLDX(machine_6502 *machine, AddrMode adm){ +static void jmpLDX(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -699,7 +746,7 @@ static void jmpLDX(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine, machine->regX); } -static void jmpLDY(machine_6502 *machine, AddrMode adm){ +static void jmpLDY(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -707,7 +754,7 @@ static void jmpLDY(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine, machine->regY); } -static void jmpLSR(machine_6502 *machine, AddrMode adm){ +static void jmpLSR(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); if (isValue){ @@ -729,11 +776,11 @@ static void jmpLSR(machine_6502 *machine, AddrMode adm){ } } -static void jmpNOP(machine_6502 *machine, AddrMode adm){ +static void jmpNOP(machine_6502 *machine, m6502_AddrMode adm){ /* no operation */ } -static void jmpORA(machine_6502 *machine, AddrMode adm){ +static void jmpORA(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -741,17 +788,17 @@ static void jmpORA(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine,machine->regA); } -static void jmpTAX(machine_6502 *machine, AddrMode adm){ +static void jmpTAX(machine_6502 *machine, m6502_AddrMode adm){ machine->regX = machine->regA; manZeroNeg(machine,machine->regX); } -static void jmpTXA(machine_6502 *machine, AddrMode adm){ +static void jmpTXA(machine_6502 *machine, m6502_AddrMode adm){ machine->regA = machine->regX; manZeroNeg(machine,machine->regA); } -static void jmpDEX(machine_6502 *machine, AddrMode adm){ +static void jmpDEX(machine_6502 *machine, m6502_AddrMode adm){ if (machine->regX > 0) machine->regX--; else @@ -759,23 +806,23 @@ static void jmpDEX(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine, machine->regX); } -static void jmpINX(machine_6502 *machine, AddrMode adm){ +static void jmpINX(machine_6502 *machine, m6502_AddrMode adm){ Bit16 value = machine->regX + 1; machine->regX = value & 0xFF; manZeroNeg(machine, machine->regX); } -static void jmpTAY(machine_6502 *machine, AddrMode adm){ +static void jmpTAY(machine_6502 *machine, m6502_AddrMode adm){ machine->regY = machine->regA; manZeroNeg(machine, machine->regY); } -static void jmpTYA(machine_6502 *machine, AddrMode adm){ +static void jmpTYA(machine_6502 *machine, m6502_AddrMode adm){ machine->regA = machine->regY; manZeroNeg(machine, machine->regA); } -static void jmpDEY(machine_6502 *machine, AddrMode adm){ +static void jmpDEY(machine_6502 *machine, m6502_AddrMode adm){ if (machine->regY > 0) machine->regY--; else @@ -783,13 +830,13 @@ static void jmpDEY(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine, machine->regY); } -static void jmpINY(machine_6502 *machine, AddrMode adm){ +static void jmpINY(machine_6502 *machine, m6502_AddrMode adm){ Bit16 value = machine->regY + 1; machine->regY = value & 0xff; manZeroNeg(machine, machine->regY); } -static void jmpROR(machine_6502 *machine, AddrMode adm){ +static void jmpROR(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; Bit8 cf; BOOL isValue = getValue(machine, adm, &ptr); @@ -814,7 +861,7 @@ static void jmpROR(machine_6502 *machine, AddrMode adm){ } } -static void jmpROL(machine_6502 *machine, AddrMode adm){ +static void jmpROL(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; Bit8 cf; BOOL isValue = getValue(machine, adm, &ptr); @@ -839,12 +886,12 @@ static void jmpROL(machine_6502 *machine, AddrMode adm){ } } -static void jmpRTI(machine_6502 *machine, AddrMode adm){ +static void jmpRTI(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = stackPop(machine); machine->regPC = stackPop(machine); } -static void jmpRTS(machine_6502 *machine, AddrMode adm){ +static void jmpRTS(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); Bit16 nr = stackPop(machine); @@ -853,21 +900,21 @@ static void jmpRTS(machine_6502 *machine, AddrMode adm){ machine->regPC = (nl << 8) | nr; } -static void jmpSBC(machine_6502 *machine, AddrMode adm){ +static void jmpSBC(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; - Bit8 vflag; + /*Bit8 vflag;*/ Bit8 c = bitOn(machine->regP, CARRY_FL); Bit16 tmp, w; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); - vflag = (bitOn(machine->regA,NEGATIVE_FL) && - bitOn(ptr.value, NEGATIVE_FL)); + /*vflag = (bitOn(machine->regA,NEGATIVE_FL) && + bitOn(ptr.value, NEGATIVE_FL));*/ if (bitOn(machine->regP, DECIMAL_FL)) { Bit8 ar = nibble(machine->regA, RIGHT); Bit8 br = nibble(ptr.value, RIGHT); Bit8 al = nibble(machine->regA, LEFT); - Bit8 bl = nibble(machine->regA, LEFT); + Bit8 bl = nibble(ptr.value, LEFT); tmp = 0xf + ar - br + c; if ( tmp < 0x10){ @@ -909,48 +956,48 @@ static void jmpSBC(machine_6502 *machine, AddrMode adm){ manZeroNeg(machine,machine->regA); } -static void jmpSTA(machine_6502 *machine, AddrMode adm){ +static void jmpSTA(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); memStoreByte(machine,ptr.addr,machine->regA); } -static void jmpTXS(machine_6502 *machine, AddrMode adm){ +static void jmpTXS(machine_6502 *machine, m6502_AddrMode adm){ stackPush(machine,machine->regX); } -static void jmpTSX(machine_6502 *machine, AddrMode adm){ +static void jmpTSX(machine_6502 *machine, m6502_AddrMode adm){ machine->regX = stackPop(machine); manZeroNeg(machine, machine->regX); } -static void jmpPHA(machine_6502 *machine, AddrMode adm){ +static void jmpPHA(machine_6502 *machine, m6502_AddrMode adm){ stackPush(machine, machine->regA); } -static void jmpPLA(machine_6502 *machine, AddrMode adm){ +static void jmpPLA(machine_6502 *machine, m6502_AddrMode adm){ machine->regA = stackPop(machine); manZeroNeg(machine, machine->regA); } -static void jmpPHP(machine_6502 *machine, AddrMode adm){ +static void jmpPHP(machine_6502 *machine, m6502_AddrMode adm){ stackPush(machine,machine->regP); } -static void jmpPLP(machine_6502 *machine, AddrMode adm){ +static void jmpPLP(machine_6502 *machine, m6502_AddrMode adm){ machine->regP = stackPop(machine); machine->regP = setBit(machine->regP, FUTURE_FL, 1); } -static void jmpSTX(machine_6502 *machine, AddrMode adm){ +static void jmpSTX(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); memStoreByte(machine,ptr.addr,machine->regX); } -static void jmpSTY(machine_6502 *machine, AddrMode adm){ +static void jmpSTY(machine_6502 *machine, m6502_AddrMode adm){ Pointer ptr; BOOL isValue = getValue(machine, adm, &ptr); warnValue(isValue); @@ -960,10 +1007,10 @@ static void jmpSTY(machine_6502 *machine, AddrMode adm){ /* OPCODES */ -static void assignOpCodes(Opcodes *opcodes){ +static void assignOpCodes(m6502_Opcodes *opcodes){ #define SETOP(num, _name, _Imm, _ZP, _ZPX, _ZPY, _ABS, _ABSX, _ABSY, _INDX, _INDY, _SNGL, _BRA, _func) \ -{opcodes[num].name[4] = '\0'; \ +{opcodes[num].name[3] = '\0'; \ strncpy(opcodes[num].name, _name, 3); opcodes[num].Imm = _Imm; opcodes[num].ZP = _ZP; \ opcodes[num].ZPX = _ZPX; opcodes[num].ZPY = _ZPY; opcodes[num].ABS = _ABS; \ opcodes[num].ABSX = _ABSX; opcodes[num].ABSY = _ABSY; opcodes[num].INDX = _INDX; \ @@ -1082,7 +1129,7 @@ static void buildIndexCache(machine_6502 *machine){ /* opIndex() - Search the opcode table for a match. If found return the index into the optable and the address mode of the opcode. If the opcode is not found then return -1. */ -static int opIndex(machine_6502 *machine, Bit8 opcode, AddrMode *adm){ +static int opIndex(machine_6502 *machine, Bit8 opcode, m6502_AddrMode *adm){ /* XXX could catch errors by setting a addressmode of error or something */ *adm = machine->opcache[opcode].adm; return machine->opcache[opcode].index; @@ -1095,7 +1142,7 @@ static Param *newParam(void){ Param *newp; int i = 0; - newp = (Param *) emalloc(sizeof(Param)); + newp = (Param *) ecalloc(1, sizeof(Param)); newp->type = SINGLE; for (i = 0; i < MAX_PARAM_VALUE; i++) newp->value[i] = 0; @@ -1118,7 +1165,7 @@ static void copyParam(Param *p1, Param *p2){ static Label *newLabel(void){ Label *newp; - newp = (Label *) emalloc(sizeof(Label)); + newp = (Label *) ecalloc(1, sizeof(Label)); newp->addr = 0; newp->label = ecalloc(MAX_LABEL_LEN,sizeof(char)); @@ -1129,7 +1176,7 @@ static AsmLine *newAsmLine(char *cmd, char *label, BOOL decl, Param *param, int { AsmLine *newp; - newp = (AsmLine *) emalloc(sizeof(AsmLine)); + newp = (AsmLine *) ecalloc(1, sizeof(AsmLine)); newp->labelDecl = decl; newp->label = newLabel(); strncpy(newp->label->label,label,MAX_LABEL_LEN); @@ -1185,7 +1232,8 @@ static void freeallAsmLine(AsmLine *listp) } static BOOL addvalue(Param *param,Bit32 value){ - if (0 <= param->vp && param->vp < MAX_PARAM_VALUE) { + /* jwz: suppress "0 <= unsigned" warning */ + if (/*0 <= param->vp &&*/ param->vp < MAX_PARAM_VALUE) { param->value[param->vp++] = value; return TRUE; } @@ -1260,15 +1308,24 @@ static BOOL ishexdigit(char c){ } } +/* isCmdChar() - Is this a valid character for a command. All of the + command are alpha except for the entry point code that is "*=" */ +static BOOL isCmdChar(char c){ + return (isalpha(c) || c == '*' || c == '='); +} + + /* command() - parse a command from the source code. We pass along a machine so the opcode can be validated. */ static BOOL command(machine_6502 *machine, char **s, char **cmd){ int i = 0; skipSpace(s); - for(;isalpha(**s) && i < MAX_CMD_LEN; (*s)++) + for(;isCmdChar(**s) && i < MAX_CMD_LEN; (*s)++) (*cmd)[i++] = **s; if (i == 0) return TRUE; /* Could be a blank line. */ + else if (strcmp(*cmd,"*=") == 0) + return TRUE; /* This is an entry point. */ else return isCommand(machine,*cmd); } @@ -1321,8 +1378,10 @@ static BOOL parseDec(char **s, Bit32 *value){ free(dec); return TRUE; } - else + else{ + free(dec); return FALSE; + } } static BOOL parseValue(char **s, Bit32 *value){ @@ -1618,8 +1677,9 @@ static AsmLine *parseAssembly(machine_6502 *machine, BOOL *codeOk, const char *c return listp; } +#ifdef READ_FILES /* fileToBuffer() - Allocates a buffer and loads all of the file into memory. */ -static char *fileToBuffer(char *filename){ +static char *fileToBuffer(const char *filename){ const int defaultSize = 1024; FILE *ifp; int c; @@ -1627,12 +1687,10 @@ static char *fileToBuffer(char *filename){ int i = 0; char *buffer = ecalloc(defaultSize,sizeof(char)); - if (buffer == NULL) - eprintf("Could not allocate memory for buffer."); + if (!buffer) abort(); ifp = fopen(filename, "rb"); - if (ifp == NULL) - eprintf("Could not open file."); + if (!ifp) abort(); while((c = getc(ifp)) != EOF){ buffer[i++] = c; @@ -1640,20 +1698,19 @@ static char *fileToBuffer(char *filename){ size += defaultSize; buffer = realloc(buffer, size); if (buffer == NULL) { - fclose(ifp); - eprintf("Could not resize buffer."); + abort(); } } } fclose(ifp); buffer = realloc(buffer, i+2); - if (buffer == NULL) - eprintf("Could not resize buffer."); + if (!buffer) abort(); /* Make sure we have a line feed at the end */ buffer[i] = '\n'; buffer[i+1] = '\0'; return buffer; } +#endif /* Routines */ @@ -1675,7 +1732,7 @@ static void reset(machine_6502 *machine){ machine->regX = 0; machine->regY = 0; machine->regP = setBit(machine->regP, FUTURE_FL, 1); - machine->regPC = 0x600; + machine->defaultCodePC = machine->regPC = PROG_START; machine->regSP = STACK_TOP; machine->runForever = FALSE; machine->labelPtr = 0; @@ -1683,7 +1740,7 @@ static void reset(machine_6502 *machine){ } /* hexDump() - Dump the memory to output */ -void hexDump(machine_6502 *machine, Bit16 start, Bit16 numbytes, FILE *output){ +void m6502_hexDump(machine_6502 *machine, Bit16 start, Bit16 numbytes, FILE *output){ Bit32 address; Bit32 i; for( i = 0; i < numbytes; i++){ @@ -1696,26 +1753,26 @@ void hexDump(machine_6502 *machine, Bit16 start, Bit16 numbytes, FILE *output){ fprintf(output,"%s\n",(i&1)?"--":""); } -void save_program(machine_6502 *machine, char *filename){ - FILE *ofp; - Bit16 pc = 0x600; - Bit16 end = pc + machine->codeLen; - Bit16 n; - ofp = fopen(filename, "w"); - if (ofp == NULL) - eprintf("Could not open file."); +/* XXX */ +/* void save_program(machine_6502 *machine, char *filename){ */ +/* FILE *ofp; */ +/* Bit16 pc = PROG_START; */ +/* Bit16 end = pc + machine->codeLen; */ +/* Bit16 n; */ +/* ofp = fopen(filename, "w"); */ +/* if (!ofp) abort(); */ - fprintf(ofp,"Bit8 prog[%d] =\n{",machine->codeLen); - n = 1; - while(pc < end) - fprintf(ofp,"0x%.2x,%s",machine->memory[pc++],n++%10?" ":"\n"); - fseek(ofp,-2,SEEK_CUR); - fprintf(ofp,"};\n"); +/* fprintf(ofp,"Bit8 prog[%d] =\n{",machine->codeLen); */ +/* n = 1; */ +/* while(pc < end) */ +/* fprintf(ofp,"0x%.2x,%s",machine->memory[pc++],n++%10?" ":"\n"); */ +/* fseek(ofp,-2,SEEK_CUR); */ +/* fprintf(ofp,"};\n"); */ - fclose(ofp); -} +/* fclose(ofp); */ +/* } */ -static BOOL translate(Opcodes *op,Param *param, machine_6502 *machine){ +static BOOL translate(m6502_Opcodes *op,Param *param, machine_6502 *machine){ switch(param->type){ case SINGLE: if (op->SNGL) @@ -1738,7 +1795,7 @@ static BOOL translate(Opcodes *op,Param *param, machine_6502 *machine){ case IMMEDIATE_GREAT: if (op->Imm) { pushByte(machine, op->Imm); - pushByte(machine, param->lbladdr / 0xFF); + pushByte(machine, param->lbladdr >> 8); break; } else { @@ -1823,12 +1880,11 @@ static BOOL translate(Opcodes *op,Param *param, machine_6502 *machine){ else { if (op->BRA) { pushByte(machine, op->BRA); - if (param->lbladdr < (machine->codeLen + 0x600)) - pushByte(machine, - (0xff - (machine->codeLen-param->lbladdr)) & 0xff); - else - pushByte(machine, - (param->lbladdr - machine->codeLen-1) & 0xff); + { + int diff = abs((int)param->lbladdr - (int)machine->defaultCodePC); + int backward = (param->lbladdr < machine->defaultCodePC); + pushByte(machine, (backward) ? 0xff - diff : diff - 1); + } } else { fprintf(stderr,"%s does not take BRANCH parameters.\n",op->name); @@ -1889,8 +1945,10 @@ static BOOL compileLine(AsmLine *asmline, void *args){ machine_6502 *machine; machine = args; if (isBlank(asmline->command)) return TRUE; - - if (strcmp("DCB",asmline->command) == 0){ + if (strcmp("*=",asmline->command) == 0){ + machine->defaultCodePC = asmline->param->value[0]; + } + else if (strcmp("DCB",asmline->command) == 0){ int i; for(i = 0; i < asmline->param->vp; i++) pushByte(machine, asmline->param->value[i]); @@ -1898,7 +1956,7 @@ static BOOL compileLine(AsmLine *asmline, void *args){ else{ int i; char *command = asmline->command; - Opcodes op; + m6502_Opcodes op; for(i = 0; i < NUM_OPCODES; i++){ if (strcmp(machine->opcodes[i].name, command) == 0){ op = machine->opcodes[i]; @@ -1917,14 +1975,28 @@ static BOOL compileLine(AsmLine *asmline, void *args){ static BOOL indexLabels(AsmLine *asmline, void *arg){ machine_6502 *machine; int thisPC; + Bit16 oldDefault; machine = arg; + oldDefault = machine->defaultCodePC; thisPC = machine->regPC; /* Figure out how many bytes this instruction takes */ machine->codeLen = 0; + if ( ! compileLine(asmline, machine) ){ return FALSE; } - machine->regPC += machine->codeLen; + + /* If the machine's defaultCodePC has changed then we encountered a + *= which changes the load address. We need to initials our code + *counter with the current default. */ + if (oldDefault == machine->defaultCodePC){ + machine->regPC += machine->codeLen; + } + else { + machine->regPC = machine->defaultCodePC; + /*oldDefault = machine->defaultCodePC;*/ + } + if (asmline->labelDecl) { asmline->label->addr = thisPC; } @@ -1955,7 +2027,7 @@ static BOOL compileCode(machine_6502 *machine, const char *code){ AsmLine *asmlist; reset(machine); - machine->regPC = 0x600; + machine->defaultCodePC = machine->regPC = PROG_START; asmlist = parseAssembly(machine, &codeOk, code); if(codeOk){ @@ -1964,13 +2036,31 @@ static BOOL compileCode(machine_6502 *machine, const char *code){ return FALSE; /* update label references */ linkLabels(asmlist); + +#if 0 /* prints out some debugging information */ + { + AsmLine *p; + if(asmlist != NULL){ + for (p = asmlist; p != NULL; p = p->next) + fprintf(stderr,"%s lbl: %s addr: %d ParamLbl: %s ParamAddr: %d\n", + p->command, p->label->label, p->label->addr, + p->param->label, p->param->lbladdr); + } + } + +#endif + /* Second pass: translate the instructions */ machine->codeLen = 0; + /* Link label call push_byte which increments defaultCodePC. + We need to reset it so the compiled code goes in the + correct spot. */ + machine->defaultCodePC = PROG_START; if (!apply(asmlist, compileLine, machine)) return FALSE; - if (machine->codeLen > 0 ){ - machine->memory[0x600+machine->codeLen] = 0x00; + if (machine->defaultCodePC > PROG_START ){ + machine->memory[machine->defaultCodePC] = 0x00; codeOk = TRUE; } else{ @@ -1995,7 +2085,7 @@ static BOOL compileCode(machine_6502 *machine, const char *code){ static void execute(machine_6502 *machine){ Bit8 opcode; - AddrMode adm; + m6502_AddrMode adm; int opidx; if(!machine->codeRunning) return; @@ -2011,29 +2101,28 @@ static void execute(machine_6502 *machine){ fprintf(stderr,"Invalid opcode!\n"); } if( (machine->regPC == 0) || - (!machine->codeRunning) || - (machine->regPC > (machine->codeLen+0x600)) ) { + (!machine->codeRunning) ) { machine->codeRunning = FALSE; } } -machine_6502 *build6502(){ +machine_6502 *m6502_build(void){ machine_6502 *machine; - machine = emalloc(sizeof(machine_6502)); + machine = ecalloc(1, sizeof(machine_6502)); assignOpCodes(machine->opcodes); buildIndexCache(machine); reset(machine); return machine; } -void destroy6502(machine_6502 *machine){ +void m6502_destroy6502(machine_6502 *machine){ free(machine); machine = NULL; } -void trace(machine_6502 *machine, FILE *output){ +void m6502_trace(machine_6502 *machine, FILE *output){ Bit8 opcode = memReadByte(machine,machine->regPC); - AddrMode adm; + m6502_AddrMode adm; Pointer ptr; int opidx = opIndex(machine,opcode,&adm); int stacksz = STACK_TOP - machine->regSP; @@ -2059,14 +2148,41 @@ void trace(machine_6502 *machine, FILE *output){ fprintf(output,"\n"); } fprintf(output,"STACK:"); - hexDump(machine,(STACK_TOP - stacksz) + 1, stacksz, output); - fprintf(output,"\n================================================================================\n"); + m6502_hexDump(machine,(STACK_TOP - stacksz) + 1, stacksz, output); } - +#if 0 +void disassemble(machine_6502 *machine, FILE *output){ + /* Read the opcode + increment the program counter + print the opcode + loop until end of program. */ + m6502_AddrMode adm; + Bit16 addr; + Bit8 opcode; + int opidx; + char *mem; + int i; + Bit16 opc = machine->regPC; + mem = calloc(20,sizeof(char)); + machine->regPC = PROG_START; + do{ + addr = machine->regPC; + opcode = popByte(machine); + opidx = opIndex(machine,opcode,&adm); + for (i = 0; i < 20; i++) mem[i] = '\0'; + dismem(machine, adm, mem); + fprintf(output,"%x\t%s\t%s\n", + addr,machine->opcodes[opidx].name,mem); + }while((machine->regPC - PROG_START) < machine->codeLen); /*XXX - may need to change since defaultCodePC */ + free(mem); + machine->regPC = opc; +} +#endif -void eval_file(machine_6502 *machine, char *filename, Plotter plot, void *plotterState){ +#ifdef READ_FILES +void m6502_eval_file(machine_6502 *machine, const char *filename, m6502_Plotter plot, void *plotterState){ char *code = NULL; machine->plot = plot; @@ -2074,13 +2190,11 @@ void eval_file(machine_6502 *machine, char *filename, Plotter plot, void *plotte code = fileToBuffer(filename); - if (! compileCode(machine, code) ){ - eprintf("Could not compile code.\n"); - } + if (! compileCode(machine, code) ) abort(); free(code); - machine->regPC = 0x600; + machine->defaultCodePC = machine->regPC = PROG_START; machine->codeRunning = TRUE; do{ sleep(0); /* XXX */ @@ -2088,12 +2202,10 @@ void eval_file(machine_6502 *machine, char *filename, Plotter plot, void *plotte trace(machine); #endif execute(machine); - if (!machine->codeRunning) - break; - }while((machine->regPC - 0x600) < machine->codeLen); + }while(machine->codeRunning); } -void start_eval_file(machine_6502 *machine, char *filename, Plotter plot, void *plotterState){ +void m6502_start_eval_file(machine_6502 *machine, const char *filename, m6502_Plotter plot, void *plotterState){ char *code = NULL; reset(machine); @@ -2102,42 +2214,57 @@ void start_eval_file(machine_6502 *machine, char *filename, Plotter plot, void * code = fileToBuffer(filename); - if (! compileCode(machine, code) ){ - eprintf("Could not compile code.\n"); - } + if (! compileCode(machine, code) ) abort(); free(code); - machine->regPC = 0x600; + machine->defaultCodePC = machine->regPC = PROG_START; machine->codeRunning = TRUE; execute(machine); } +#endif /* READ_FILES */ -void start_eval_binary(machine_6502 *machine, Bit8 *program, - unsigned int proglen, - Plotter plot, void *plotterState){ - unsigned int pc, n; +void m6502_start_eval_string(machine_6502 *machine, const char *code, + m6502_Plotter plot, void *plotterState){ reset(machine); + machine->plot = plot; machine->plotterState = plotterState; - machine->regPC = 0x600; - pc = machine->regPC; - machine->codeLen = proglen; - n = 0; - while (n < proglen){ - machine->memory[pc++] = program[n++]; + if (! compileCode(machine, code) ){ + fprintf(stderr,"Could not compile code.\n"); } + + machine->defaultCodePC = machine->regPC = PROG_START; machine->codeRunning = TRUE; execute(machine); } -void next_eval(machine_6502 *machine, int insno){ +/* void start_eval_binary(machine_6502 *machine, Bit8 *program, */ +/* unsigned int proglen, */ +/* Plotter plot, void *plotterState){ */ +/* unsigned int pc, n; */ +/* reset(machine); */ +/* machine->plot = plot; */ +/* machine->plotterState = plotterState; */ + +/* machine->regPC = PROG_START; */ +/* pc = machine->regPC; */ +/* machine->codeLen = proglen; */ +/* n = 0; */ +/* while (n < proglen){ */ +/* machine->memory[pc++] = program[n++]; */ +/* } */ +/* machine->codeRunning = TRUE; */ +/* execute(machine); */ +/* } */ + +void m6502_next_eval(machine_6502 *machine, int insno){ int i = 0; for (i = 1; i < insno; i++){ - if (machine->codeRunning){/* && ((machine->regPC - 0x600) < machine->codeLen))*/ + if (machine->codeRunning){ #if 0 - trace(machine); + trace(machine, stdout); #endif execute(machine); }