From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / asm6502.c
index aeda48267efaf7b95d0ba5f5fe92d726926cc0e4..c95e5babd9e8e50cbb9fd0cf3017e173edfbeb18 100644 (file)
@@ -1,3 +1,4 @@
+/*-*- indent-tabs-mode:nil -*- */
 /* Copyright (C) 2007 Jeremy English <jhe@jeremyenglish.org>
  * 
  * 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 <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;
@@ -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){
 \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; \
@@ -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
 
 \f
 /* 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
 
 \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;
@@ -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);
     }