+/*-*- indent-tabs-mode:nil -*- */
/* Copyright (C) 2007 Jeremy English <jhe@jeremyenglish.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
I changed the structure of the assembler in this version.
*/
-#define NDEBUG /* Uncomment when done with debugging */
-
#include <stdlib.h>
#include <stdio.h>
/*#include <malloc.h>*/
#include <assert.h>
#include <ctype.h>
#include <math.h>
-#include <stdint.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
#include <unistd.h>
+#include "yarandom.h"
#include "asm6502.h"
+/*#ifdef DEBUGGER
+# define random rand
+#endif*/
+
+#ifndef HAVE_MOBILE
+# define READ_FILES
+#endif
+
typedef enum{
LEFT, RIGHT
} Side;
/*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;
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;
}
}
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++;
}
/*
/* 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;
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:
/* 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;
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:
}
+#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));
}
}
-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);
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);
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){
}
-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);
- machine->regP = setBit(machine->regP, ZERO_FL, (ptr.value & machine->regA));
+ machine->regP = setBit(machine->regP, ZERO_FL, !(ptr.value & machine->regA));
machine->regP = setBit(machine->regP, OVERFLOW_FL, bitOn(ptr.value, OVERFLOW_FL));
machine->regP = setBit(machine->regP, NEGATIVE_FL, bitOn(ptr.value, NEGATIVE_FL));
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);
}
-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);
}
-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);
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);
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);
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);
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);
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);
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);
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);
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);
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. */
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);
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);
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);
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){
}
}
-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);
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
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
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);
}
}
-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);
}
}
-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);
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){
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);
\f
/* 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; \
/* 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;
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;
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));
{
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);
}
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;
}
}
}
+/* 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);
}
free(dec);
return TRUE;
}
- else
+ else{
+ free(dec);
return FALSE;
+ }
}
static BOOL parseValue(char **s, Bit32 *value){
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;
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;
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
\f
/* Routines */
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;
}
/* 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++){
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)
case IMMEDIATE_GREAT:
if (op->Imm) {
pushByte(machine, op->Imm);
- pushByte(machine, param->lbladdr / 0xFF);
+ pushByte(machine, param->lbladdr >> 8);
break;
}
else {
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);
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]);
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];
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;
}
AsmLine *asmlist;
reset(machine);
- machine->regPC = 0x600;
+ machine->defaultCodePC = machine->regPC = PROG_START;
asmlist = parseAssembly(machine, &codeOk, code);
if(codeOk){
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: %x ParamLbl: %s ParamAddr: %x\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{
static void execute(machine_6502 *machine){
Bit8 opcode;
- AddrMode adm;
+ m6502_AddrMode adm;
int opidx;
if(!machine->codeRunning) return;
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;
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
\f
-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;
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 */
#if 0
- trace(machine);
+ m6502_trace(machine, stdout);
#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);
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);
}