From NISC.SRI.COM!unix!Teknowledge.COM!uw-beaver!rice!cs.utexas.edu!usc!apple!oracle!news Sun Apr 15 01:20:37 PDT 1990 Article 771 of comp.binaries.apple2: Path: NISC.SRI.COM!unix!Teknowledge.COM!uw-beaver!rice!cs.utexas.edu!usc!apple!oracle!news >From: pnakada@oracle.com (Paul Nakada) Newsgroups: comp.binaries.apple2 Subject: Repost: Apple ][+ simulator for UNIX/BSD boxes Part 01/03 Message-ID: Date: 13 Apr 90 19:23:19 GMT Sender: news@oracle.com Organization: Oracle Corporation, Belmont, CA Lines: 2480 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # If this archive is complete, you will see the following message at the end: # "End of archive 1 (of 2)." # Contents: README 6502.c PRODOS.IMAGE.D2 README2 debug.c # Wrapped by pnakada@pnakada on Thu Apr 12 00:46:04 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1045 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X XApple ][ Emulator -- (C) 1989 Ben Koning X 408/738-1763 (IP: ben@apple.com) (AL: KONING.BEN) X 1360 Flicker Way Sunnyvale CA 94087-3407 X 18 Ortalon Ave Santa Cruz CA 95060 X X XThis software package is an Apple ][ / Apple ][ Plus emulator for UNIX Xsystems. It emulates a 6502 microprocessor, contains Apple ][ ROM code, Xand emulates a few Apple ][ memory mapped I/O features. X XUsage syntax: X X Apple.II [-t] [-m] [-i] X XIf no parameters are specified, then an Apple ][ Plus (autostart and apple- Xsoft) are selected. Trace (-t) mode causes the state of the processor to be Xprinted to the standard error output at the end of each 6502 instruction. XThe Original Monitor (-m) and Integer Basic (-i) options override the default XROM configuration. X XTo exit the simulation, type Control - A. X XCurrently, the only I/O features supported are Page 1 40-Column text, Xkeyboard input, keyboard strobe, and speaker toggle (sends beep to terminal). XUnimplemented 6502 instructions are executed as NOPs. END_OF_FILE echo shar: NEWLINE appended to \"'README'\" if test 1046 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f '6502.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'6502.c'\" else echo shar: Extracting \"'6502.c'\" \(34909 characters\) sed "s/^X//" >'6502.c' <<'END_OF_FILE' X X/* X *6502.c -- Mostek/Rockwell/Synertek/Siliconix 6502 for Apple II Emulator X *(C) 1989 Ben Koning [556498717 408/738-1763 ben@apple.com] X */ X X#include "apple.h" X X X/* X * 6502 Globals: X */ X Xint A,X,Y,P,S; XADDR PPC; X Xvoid CPUReset (/*_ _*/); Xvoid _push_ (/*_ BYTE _*/); XBYTE _pull_ (/*_ _*/); XBYTE _eaimm_ (/*_ _*/); XBYTE _eazp_ (/*_ _*/); XBYTE _eazpx_ (/*_ _*/); XBYTE _eazpy_ (/*_ _*/); XADDR _eaabs_ (/*_ _*/); XADDR _eaabsind_ (/*_ _*/); XADDR _eaabsx_ (/*_ _*/); XADDR _eaabsy_ (/*_ _*/); XADDR _eaindx_ (/*_ _*/); XADDR _eaindy_ (/*_ _*/); X X Xvoid CPUReset () X{ X /* Setup registers: */ X A = X = Y = P = 0; X S = 0xff; X X /* Set PPC to pointer at $FFFC: */ X PPC = MegaGetMem (0xfffc) + MegaGetMem (0xfffd) * 0x0100; X X /* Should execute instructions forever after this */ X} X X/* This internal routine pushes a byte onto the stack */ Xvoid _push_ (byte) XBYTE byte; X{ X MegaPutMem ((ADDR)(0x100 + S--), byte); X S &= 0xff; X} X X/* This internal routine pulls a byte from the stack */ XBYTE _pull_ () X{ X S++; X S &= 0xff; X return MegaGetMem (0x100 + S); X} X X/* This internal routine fetches an immediate operand value */ XBYTE _eaimm_ () X{ X register BYTE i; X X i = MegaGetMem (PPC++); X PPC &= 0xffff; X return i; X} X X/* This internal routine fetches a zero-page operand address */ XBYTE _eazp_ () X{ X register BYTE a; X X a = MegaGetMem (PPC++); X PPC &= 0xffff; X X return a; X} X X/* This internal routine fetches a zpage,X operand address */ XBYTE _eazpx_ () X{ X register BYTE a; X X a = MegaGetMem (PPC++); X PPC &= 0xffff; X a += X; X a &= 0xff; X X return a; X} X X/* This internal routine fetches a zpage,Y operand address */ XBYTE _eazpy_ () X{ X register BYTE a; X X a = MegaGetMem (PPC++); X PPC &= 0xffff; X a += Y; X a &= 0xff; X X return a; X} X X/* This internal routine fetches an absolute operand address */ XADDR _eaabs_ () X{ X register BYTE lo, hi; X X lo = MegaGetMem (PPC++); X PPC &= 0xffff; X hi = MegaGetMem (PPC++); X PPC &= 0xffff; X X return lo + hi * 0x0100; X} X X/* This internal routine fetches an indirect absolute operand address */ XADDR _eaabsind_ () X{ X register int a, lo, hi; X X a = _eaabs_(); X lo = MegaGetMem ((ADDR)a++); X a &= 0xffff; X hi = MegaGetMem ((ADDR)a); X X return lo + hi * 0x0100; X} X X/* This internal routine fetches an absolute,X operand address */ XADDR _eaabsx_ () X{ X register int a; X X a = _eaabs_() + X; X X return (a & 0xffff); /* Not entirely correct */ X} X X/* This internal routine fetches an absolute,Y operand address */ XADDR _eaabsy_ () X{ X register int a; X X a = _eaabs_() + Y; X X return (a & 0xffff); /* Not entirely correct */ X} X X/* This internal routine fetches a (zpage,X) operand address */ XADDR _eaindx_ () X{ X register int a, lo, hi; X X a = _eazpx_(); X lo = MegaGetMem ((ADDR)a++); X a &= 0xff; X hi = MegaGetMem ((ADDR)a); X X return lo + hi * 0x0100; X} X X/* This internal routine fetches a (zpage),Y operand address */ XADDR _eaindy_ () X{ X register int a, lo, hi; X X a = _eazp_(); X lo = MegaGetMem ((ADDR)a++); X a &= 0xff; X hi = MegaGetMem ((ADDR)a); X X return ( (Y + lo + hi * 0x0100) & 0xffff ); /* Not entirely correct */ X} X#ifdef NEVER X/* Macros to set the P flags: */ X#define _setN_(b) if ((b)!=0) P |= 0x80; else P &= ~0x80 X#define _setV_(b) if ((b)!=0) P |= 0x40; else P &= ~0x40 X/* This bit not implemented */ X#define _setB_(b) if ((b)!=0) P |= 0x10; else P &= ~0x10 X#define _setD_(b) if ((b)!=0) P |= 0x08; else P &= ~0x08 X#define _setI_(b) if ((b)!=0) P |= 0x04; else P &= ~0x04 X#define _setZ_(b) if ((b)!=0) P |= 0x02; else P &= ~0x02 X#define _setC_(b) if ((b)!=0) P |= 0x01; else P &= ~0x01 X#endif X/* Macros to set the P flags: */ Xvoid _setN_(b){ if ((b)!=0) P |= 0x80; else P &= ~0x80;} Xvoid _setV_(b){ if ((b)!=0) P |= 0x40; else P &= ~0x40;} X/* This bit not implemented */ Xvoid _setB_(b){ if ((b)!=0) P |= 0x10; else P &= ~0x10;} Xvoid _setD_(b){ if ((b)!=0) P |= 0x08; else P &= ~0x08;} Xvoid _setI_(b){ if ((b)!=0) P |= 0x04; else P &= ~0x04;} Xvoid _setZ_(b){ if ((b)!=0) P |= 0x02; else P &= ~0x02;} Xvoid _setC_(b){ if ((b)!=0) P |= 0x01; else P &= ~0x01;} X X /* Macros to read the P flags: */ X#define _getN_ ((P & 0x80) ? 1 : 0) X#define _getV_ ((P & 0x40) ? 1 : 0) X/* This bit not implemented */ X#define _getB_ ((P & 0x10) ? 1 : 0) X#define _getD_ ((P & 0x08) ? 1 : 0) X#define _getI_ ((P & 0x04) ? 1 : 0) X#define _getZ_ ((P & 0x02) ? 1 : 0) X#define _getC_ ((P & 0x01) ? 1 : 0) X X/* This routine executes a single instruction. */ Xvoid CPUExecute () X{ X register int opcode; /* Scratch: Opcode fetched */ X register int d; /* Scratch: Data byte fetched */ X register int lo; /* Scratch: Lo8 for building ptr */ X register int hi; /* Scratch: Hi8 for building ptr */ X register int al; /* Scratch: Accumulator lo nibble */ X register int ah; /* Scratch: Accumulator hi nibble */ X register int ol; /* Scratch: Operand lo nibble */ X register int oh; /* Scratch: Operand hi nibble */ X X if (PPC == 0xc780) X prodos(); X opcode = MegaGetMem (PPC++); X PPC &= 0xffff; X X switch (opcode) X { X case 0x69: /* ADC #dd */ X d = _eaimm_(); X if (!_getD_) { X A = A + d + _getC_; X _setC_ (A > 0xff); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al = al + _getC_ + ol; X if (al >= 10) { al -= 10; ah++; } X ah += oh; X _setC_ (ah >= 10); X if (ah >= 10) ah -= 10; X A = al + (ah * 16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0x65: /* ADC aa */ X d = MegaGetMem ((ADDR)_eazp_ ()); X if (!_getD_) { X A = A + d + _getC_; X _setC_ (A > 0xff); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al = al + _getC_ + ol; X if (al >= 10) { al -= 10; ah++; } X ah += oh; X _setC_ (ah >= 10); X if (ah >= 10) ah -= 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0x75: /* ADC aa,X */ X d = MegaGetMem ((ADDR)_eazpx_ ()); X if (!_getD_) { X A = A + d + _getC_; X _setC_ (A > 0xff); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al = al + _getC_ + ol; X if (al >= 10) { al -= 10; ah++; } X ah += oh; X _setC_ (ah >= 10); X if (ah >= 10) ah -= 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0x6d: /* ADC aaaa */ X d = MegaGetMem (_eaabs_ ()); X if (!_getD_) { X A = A + d + _getC_; X _setC_ (A > 0xff); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al = al + _getC_ + ol; X if (al >= 10) { al -= 10; ah++; } X ah += oh; X _setC_ (ah >= 10); X if (ah >= 10) ah -= 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0x7d: /* ADC aaaa,X */ X d = MegaGetMem (_eaabsx_ ()); X if (!_getD_) { X A = A + d + _getC_; X _setC_ (A > 0xff); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al = al + _getC_ + ol; X if (al >= 10) { al -= 10; ah++; } X ah += oh; X _setC_ (ah >= 10); X if (ah >= 10) ah -= 10; X A = al + (ah * 16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0x79: /* ADC aaaa,Y */ X d = MegaGetMem (_eaabsy_ ()); X if (!_getD_) { X A = A + d + _getC_; X _setC_ (A > 0xff); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al = al + _getC_ + ol; X if (al >= 10) { al -= 10; ah++; } X ah += oh; X _setC_ (ah >= 10); X if (ah >= 10) ah -= 10; X A = al + (ah * 16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0x61: /* ADC (aa,X) */ X d = MegaGetMem (_eaindx_ ()); X if (!_getD_) { X A = A + d + _getC_; X _setC_ (A > 0xff); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al = al + _getC_ + ol; X if (al >= 10) { al -= 10; ah++; } X ah += oh; X _setC_ (ah >= 10); X if (ah >= 10) ah -= 10; X A = al + (ah * 16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0x71: /* ADC (aa),Y */ X d = MegaGetMem (_eaindy_ ()); X if (!_getD_) { X A = A + d + _getC_; X _setC_ (A > 0xff); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al = al + _getC_ + ol; X if (al >= 10) { al -= 10; ah++; } X ah += oh; X _setC_ (ah >= 10); X if (ah >= 10) ah -= 10; X A = al + (ah * 16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X X X case 0x29: /* AND #dd */ X A &= _eaimm_ (); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x25: /* AND aa */ X A &= MegaGetMem ((ADDR)_eazp_ ()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x35: /* AND aa,X */ X A &= MegaGetMem ((ADDR)_eazpx_ ()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x2d: /* AND aaaa */ X A &= MegaGetMem (_eaabs_ ()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x3d: /* AND aaaa,X */ X A &= MegaGetMem (_eaabsx_ ()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x39: /* AND aaaa,Y */ X A &= MegaGetMem (_eaabsy_ ()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x21: /* AND (aa,X) */ X A &= MegaGetMem (_eaindx_ ()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x31: /* AND (aa),Y */ X A &= MegaGetMem (_eaindy_ ()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X X X case 0x0a: /* ASL A */ X _setC_ (A >= 0x80); X A = (A << 1) & 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x06: /* ASL aa */ X hi = _eazp_(); X d = MegaGetMem ((ADDR)hi); X _setC_ (d >= 0x80); X d = (d << 1) & 0xff; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x16: /* ASL aa,X */ X hi = _eazpx_(); X d = MegaGetMem ((ADDR)hi); X _setC_ (d >= 0x80); X d = (d << 1) & 0xff; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x0e: /* ASL aaaa */ X hi = _eaabs_(); X d = MegaGetMem ((ADDR)hi); X _setC_ (d >= 0x80); X d = (d << 1) & 0xff; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x1e: /* ASL aaaa,X */ X hi = _eaabsx_(); X d = MegaGetMem ((ADDR)hi); X _setC_ (d >= 0x80); X d = (d << 1) & 0xff; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X X X case 0x90: /* BCC rr */ X lo = _eaimm_ (); X if (lo >= 0x80) lo -= 0x0100; X if (!_getC_) PPC += lo; X break; X X X X case 0xb0: /* BCS rr */ X lo = _eaimm_ (); X if (lo >= 0x80) lo -= 0x0100; X if (_getC_) PPC += lo; X break; X X X X case 0xf0: /* BEQ rr */ X lo = _eaimm_ (); X if (lo >= 0x80) lo -= 0x0100; X if (_getZ_) PPC += lo; X break; X X X X case 0x24: /* BIT aa */ X d = MegaGetMem ((ADDR)_eazp_ ()); X _setN_ (d >= 0x80); X _setV_ ((d & 64) != 0); X _setZ_ ((d & A) == 0); X break; X X case 0x2c: /* BIT aaaa */ X d = MegaGetMem (_eaabs_ ()); X _setN_ (d >= 0x80); X _setV_ ((d & 64) != 0); X _setZ_ ((d & A) == 0); X break; X X X X case 0x30: /* BMI rr */ X lo = _eaimm_ (); X if (lo >= 0x80) lo -= 0x0100; X if (_getN_) PPC += lo; X break; X X X X case 0xd0: /* BNE rr */ X lo = _eaimm_ (); X if (lo >= 0x80) lo -= 0x0100; X if (!_getZ_) PPC += lo; X break; X X X X case 0x10: /* BPL rr */ X lo = _eaimm_ (); X if (lo >= 0x80) lo -= 0x0100; X if (!_getN_) PPC += lo; X break; X X X X case 0x00: /* BRK */ X lo = (PPC+1) & 65535; X _push_ ((BYTE)(lo / 0x0100)); X _push_ ((BYTE)(lo % 0x0100)); X _push_ ((BYTE)P); X _setB_ (1); X lo = MegaGetMem (0xfffe); X hi = MegaGetMem (0xffff); X PPC = lo + (hi*0x0100); X break; X X X X case 0x50: /* BVC rr */ X lo = _eaimm_ (); X if (lo >= 0x80) lo -= 0x0100; X if (!_getV_) PPC += lo; X break; X X X X case 0x70: /* BVS rr */ X lo = _eaimm_ (); X if (lo >= 0x80) lo -= 0x0100; X if (_getV_) PPC += lo; X break; X X X X case 0x18: /* CLC */ X _setC_ (0); X break; X X X X case 0xd8: /* CLD */ X _setD_ (0); X break; X X X X case 0x58: /* CLI */ X _setI_ (0); X break; X X X X case 0xb8: /* CLV */ X _setV_ (0); X break; X X X X case 0xc9: /* CMP #dd */ X d = _eaimm_(); X _setZ_ (A == d); X _setC_ (A >= d); X if (d >= 0x80) d -= 0x0100; X lo = A; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xc5: /* CMP aa */ X d = MegaGetMem ((ADDR)_eazp_()); X _setZ_ (A == d); X _setC_ (A >= d); X if (d >= 0x80) d -= 0x0100; X lo = A; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xd5: /* CMP aa,X */ X d = MegaGetMem ((ADDR)_eazpx_()); X _setZ_ (A == d); X _setC_ (A >= d); X if (d >= 0x80) d -= 0x0100; X lo = A; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xcd: /* CMP aaaa */ X d = MegaGetMem (_eaabs_()); X _setZ_ (A == d); X _setC_ (A >= d); X if (d >= 0x80) d -= 0x0100; X lo = A; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xdd: /* CMP aaaa,X */ X d = MegaGetMem (_eaabsx_()); X _setZ_ (A == d); X _setC_ (A >= d); X if (d >= 0x80) d -= 0x0100; X lo = A; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xd9: /* CMP aaaa,Y */ X d = MegaGetMem (_eaabsy_()); X _setZ_ (A == d); X _setC_ (A >= d); X if (d >= 0x80) d -= 0x0100; X lo = A; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xc1: /* CMP (aa,X) */ X d = MegaGetMem (_eaindx_()); X _setZ_ (A == d); X _setC_ (A >= d); X if (d >= 0x80) d -= 0x0100; X lo = A; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xd1: /* CMP (aa),y */ X d = MegaGetMem (_eaindy_()); X _setZ_ (A == d); X _setC_ (A >= d); X if (d >= 0x80) d -= 0x0100; X lo = A; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X X X case 0xe0: /* CPX #dd */ X d = _eaimm_(); X _setZ_ (X == d); X _setC_ (X >= d); X if (d >= 0x80) d -= 0x0100; X lo = X; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xe4: /* CPX aa */ X d = MegaGetMem ((ADDR)_eazp_()); X _setZ_ (X == d); X _setC_ (X >= d); X if (d >= 0x80) d -= 0x0100; X lo = X; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xec: /* CPX aaaa */ X d = MegaGetMem (_eaabs_()); X _setZ_ (X == d); X _setC_ (X >= d); X if (d >= 0x80) d -= 0x0100; X lo = X; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X X X case 0xc0: /* CPY #dd */ X d = _eaimm_(); X _setZ_ (Y == d); X _setC_ (Y >= d); X if (d >= 0x80) d -= 0x0100; X lo = Y; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xc4: /* CPY aa */ X d = MegaGetMem ((ADDR)_eazp_()); X _setZ_ (Y == d); X _setC_ (Y >= d); X if (d >= 0x80) d -= 0x0100; X lo = Y; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X case 0xcc: /* CPY aaaa */ X d = MegaGetMem (_eaabs_()); X _setZ_ (Y == d); X _setC_ (Y >= d); X if (d >= 0x80) d -= 0x0100; X lo = Y; X if (lo >= 0x80) lo -= 0x0100; X hi = lo - d; X _setN_ ( (hi >= 0x80) || (hi < 0) ); X if (hi < -0x80) _setN_(0); X break; X X X X case 0xc6: /* DEC aa */ X hi = _eazp_(); X d = MegaGetMem ((ADDR)hi) - 1; X if (d < 0) d += 0x0100; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0xd6: /* DEC aa,X */ X hi = _eazpx_(); X d = MegaGetMem ((ADDR)hi) - 1; X if (d < 0) d += 0x0100; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0xce: /* DEC aaaa */ X hi = _eaabs_(); X d = MegaGetMem ((ADDR)hi) - 1; X if (d < 0) d += 0x0100; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0xde: /* DEC aaaa,X */ X hi = _eaabs_(); X d = MegaGetMem ((ADDR)hi) - 1; X if (d < 0) d += 0x0100; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X X X case 0xca: /* DEX */ X X--; X if (X < 0) X += 0x0100; X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X X X case 0x88: /* DEY */ X Y--; X if (Y < 0) Y += 0x0100; X _setN_ (Y >= 0x80); X _setZ_ (Y == 0); X break; X X X X case 0x49: /* EOR #dd */ X d = _eaimm_(); X A ^= d; A &= 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x45: /* EOR aa */ X d = MegaGetMem ((ADDR)_eazp_()); X A ^= d; A &= 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x55: /* EOR aa,X */ X d = MegaGetMem ((ADDR)_eazpx_()); X A ^= d; A &= 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x4d: /* EOR aaaa */ X d = MegaGetMem (_eaabs_()); X A ^= d; A &= 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x5d: /* EOR aaaa,X */ X d = MegaGetMem (_eaabsx_()); X A ^= d; A &= 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x59: /* EOR aaaa,Y */ X d = MegaGetMem (_eaabsy_()); X A ^= d; A &= 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x41: /* EOR (aa,X) */ X d = MegaGetMem (_eaindx_()); X A ^= d; A &= 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x51: /* EOR (aa),Y */ X d = MegaGetMem (_eaindy_()); X A ^= d; A &= 0xff; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X X X case 0xe6: /* INC aa */ X hi = _eazp_(); X d = MegaGetMem ((ADDR)hi) + 1; X d &= 0xff; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0xf6: /* INC aa,X */ X hi = _eazpx_(); X d = MegaGetMem ((ADDR)hi) + 1; X d &= 0xff; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0xee: /* INC aaaa */ X hi = _eaabs_(); X d = MegaGetMem ((ADDR)hi) + 1; X d &= 0xff; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0xfe: /* INC aaaa,X */ X hi = _eaabsx_(); X d = MegaGetMem ((ADDR)hi) + 1; X d &= 0xff; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X X X case 0xe8: /* INX */ X X++; X X &= 0xff; X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X X X case 0xc8: /* INY */ X Y++; X Y &= 0xff; X _setN_ (Y >= 0x80); X _setZ_ (Y == 0); X break; X X X X case 0x4c: /* JMP aaaa */ X PPC = _eaabs_(); X break; X X case 0x6c: /* JMP (aaaa) */ X PPC = _eaabsind_(); X break; X X X X case 0x20: /* JSR aaaa */ X /* Push address of 3rd byte of jsr: */ X lo = (PPC+1) & 65535; X _push_ ((BYTE)(lo / 0x0100)); X _push_ ((BYTE)(lo % 0x0100)); X PPC = _eaabs_(); X break; X X X X case 0xa9: /* LDA #dd */ X A = _eaimm_(); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0xa5: /* LDA aa */ X A = MegaGetMem ((ADDR)_eazp_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0xb5: /* LDA aa,X */ X A = MegaGetMem ((ADDR)_eazpx_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0xad: /* LDA aaaa */ X A = MegaGetMem (_eaabs_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0xbd: /* LDA aaaa,X */ X A = MegaGetMem (_eaabsx_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0xb9: /* LDA aaaa,Y */ X A = MegaGetMem (_eaabsy_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0xa1: /* LDA (aa,X) */ X A = MegaGetMem (_eaindx_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0xb1: /* LDA (aa),Y */ X A = MegaGetMem (_eaindy_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X X X case 0xa2: /* LDX #dd */ X X = _eaimm_(); X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X case 0xa6: /* LDX aa */ X X = MegaGetMem ((ADDR)_eazp_()); X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X case 0xb6: /* LDX aa,Y */ X X = MegaGetMem ((ADDR)_eazpy_()); X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X case 0xae: /* LDX aaaa */ X X = MegaGetMem (_eaabs_()); X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X case 0xbe: /* LDX aaaa,Y */ X X = MegaGetMem (_eaabsy_()); X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X X X case 0xa0: /* LDY #dd */ X Y = _eaimm_(); X _setN_ (Y >= 0x80); X _setZ_ (Y == 0); X break; X X case 0xa4: /* LDY aa */ X Y = MegaGetMem ((ADDR)_eazp_()); X _setN_ (Y >= 0x80); X _setZ_ (Y == 0); X break; X X case 0xb4: /* LDY aa,X */ X Y = MegaGetMem ((ADDR)_eazpx_()); X _setN_ (Y >= 0x80); X _setZ_ (Y == 0); X break; X X case 0xac: /* LDY aaaa */ X Y = MegaGetMem (_eaabs_()); X _setN_ (Y >= 0x80); X _setZ_ (Y == 0); X break; X X case 0xbc: /* LDY aaaa,X */ X Y = MegaGetMem (_eaabsx_()); X _setN_ (Y >= 0x80); X _setZ_ (Y == 0); X break; X X X X case 0x4a: /* LSR A */ X _setC_ (A & 1); X A = A >> 1; X _setN_ (0); X _setZ_ (A == 0); X break; X X case 0x46: /* LSR aa */ X hi = _eazp_(); X d = MegaGetMem ((ADDR)hi); X _setC_ (d & 1); X d = d >> 1; X _setN_ (0); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x56: /* LSR aa,X */ X hi = _eazpx_(); X d = MegaGetMem ((ADDR)hi); X _setC_ (d & 1); X d = d >> 1; X _setN_ (0); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x4e: /* LSR aaaa */ X hi = _eaabs_(); X d = MegaGetMem ((ADDR)hi); X _setC_ (d & 1); X d = d >> 1; X _setN_ (0); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x5e: /* LSR aaaa,X */ X hi = _eaabsx_(); X d = MegaGetMem ((ADDR)hi); X _setC_ (d & 1); X d = d >> 1; X _setN_ (0); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X X X case 0xea: /* NOP */ Xnop: X break; X X X X case 0x09: /* ORA #dd */ X A |= _eaimm_(); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x05: /* ORA aa */ X A |= MegaGetMem ((ADDR)_eazp_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x15: /* ORA aa,X */ X A |= MegaGetMem ((ADDR)_eazpx_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x0d: /* ORA aaaa */ X A |= MegaGetMem (_eaabs_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x1d: /* ORA aaaa,X */ X A |= MegaGetMem (_eaabsx_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x19: /* ORA aaaa,Y */ X A |= MegaGetMem (_eaabsy_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x01: /* ORA (aa,X) */ X A |= MegaGetMem (_eaindx_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x11: /* ORA (aa),Y */ X A |= MegaGetMem (_eaindy_()); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X X X case 0x48: /* PHA */ X _push_ ((BYTE)A); X break; X X X X case 0x08: /* PHP */ X _push_ ((BYTE)P); X break; X X X X case 0x68: /* PLA */ X A = _pull_(); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X X X case 0x28: /* PLP */ X P = _pull_(); X break; X X X X case 0x2a: /* ROL A */ X al = _getC_; X _setC_ (A >= 0x80); X A = (A << 1) & 0xff; X A |= al; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x26: /* ROL aa */ X hi = _eazp_(); X d = MegaGetMem ((ADDR)hi); X al = _getC_; X _setC_ (d >= 0x80); X d = (d << 1) & 0xff; X d |= al; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x36: /* ROL aa,X */ X hi = _eazpx_(); X d = MegaGetMem ((ADDR)hi); X al = _getC_; X _setC_ (d >= 0x80); X d = (d << 1) & 0xff; X d |= al; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x2e: /* ROL aaaa */ X hi = _eaabs_(); X d = MegaGetMem ((ADDR)hi); X al = _getC_; X _setC_ (d >= 0x80); X d = (d << 1) & 0xff; X d |= al; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x3e: /* ROL aaaa,X */ X hi = _eaabsx_(); X d = MegaGetMem ((ADDR)hi); X al = _getC_; X _setC_ (d >= 0x80); X d = (d << 1) & 0xff; X d |= al; X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X X X case 0x6a: /* ROR A */ X al = _getC_; X _setC_ (A & 1); X A = A >> 1; X A |= (al*0x80); X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X case 0x66: /* ROR aa */ X hi = _eazp_(); X d = MegaGetMem ((ADDR)hi); X al = _getC_; X _setC_ (d & 1); X d = d >> 1; X d |= (al*0x80); X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x76: /* ROR aa,X */ X hi = _eazpx_(); X d = MegaGetMem ((ADDR)hi); X al = _getC_; X _setC_ (d & 1); X d = d >> 1; X d |= (al*0x80); X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x6e: /* ROR aaaa */ X hi = _eaabs_(); X d = MegaGetMem ((ADDR)hi); X al = _getC_; X _setC_ (d & 1); X d = d >> 1; X d |= (al*0x80); X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X case 0x7e: /* ROR aaaa,X */ X hi = _eaabsx_(); X d = MegaGetMem ((ADDR)hi); X al = _getC_; X _setC_ (d & 1); X d = d >> 1; X d |= (al*0x80); X _setN_ (d >= 0x80); X _setZ_ (d == 0); X MegaPutMem ((ADDR)hi,(BYTE)d); X break; X X X X case 0x40: /* RTI */ X P = _pull_(); X lo = _pull_(); X hi = _pull_(); X PPC = lo + (hi*0x0100); X break; X X X X X case 0x60: /* RTS */ X lo = _pull_(); X hi = _pull_(); X PPC = 1 + lo + (hi*0x0100); X break; X X X X case 0xe9: /* SBC #dd */ X d = _eaimm_ (); X if (!_getD_) { X A -= d; A -= !_getC_; X _setC_ (! (A < 0)); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al -= !_getC_; al -= ol; X if (al < 0) { al += 10; ah--; } X ah -= oh; X _setC_ (! (ah < 0)); X if (ah < 0) ah += 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X if (A < 0) A += 0x0100; X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0xe5: /* SBC aa */ X d = MegaGetMem ((ADDR)_eazp_ ()); X if (!_getD_) { X A -= d; A -= !_getC_; X _setC_ (! (A < 0)); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al -= !_getC_; al -= ol; X if (al < 0) { al += 10; ah--; } X ah -= oh; X _setC_ (! (ah < 0)); X if (ah < 0) ah += 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X if (A < 0) A += 0x0100; X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0xf5: /* SBC aa,x */ X d = MegaGetMem ((ADDR)_eazpx_ ()); X if (!_getD_) { X A -= d; A -= !_getC_; X _setC_ (! (A < 0)); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al -= !_getC_; al -= ol; X if (al < 0) { al += 10; ah--; } X ah -= oh; X _setC_ (! (ah < 0)); X if (ah < 0) ah += 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X if (A < 0) A += 0x0100; X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0xed: /* SBC aaaa */ X d = MegaGetMem (_eaabs_ ()); X if (!_getD_) { X A -= d; A -= !_getC_; X _setC_ (! (A < 0)); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al -= !_getC_; al -= ol; X if (al < 0) { al += 10; ah--; } X ah -= oh; X _setC_ (! (ah < 0)); X if (ah < 0) ah += 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X if (A < 0) A += 0x0100; X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0xfd: /* SBC aaaa,X */ X d = MegaGetMem (_eaabsx_ ()); X if (!_getD_) { X A -= d; A -= !_getC_; X _setC_ (! (A < 0)); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al -= !_getC_; al -= ol; X if (al < 0) { al += 10; ah--; } X ah -= oh; X _setC_ (! (ah < 0)); X if (ah < 0) ah += 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X if (A < 0) A += 0x0100; X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0xf9: /* SBC aaaa,Y */ X d = MegaGetMem (_eaabsy_ ()); X if (!_getD_) { X A -= d; A -= !_getC_; X _setC_ (! (A < 0)); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al -= !_getC_; al -= ol; X if (al < 0) { al += 10; ah--; } X ah -= oh; X _setC_ (! (ah < 0)); X if (ah < 0) ah += 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X if (A < 0) A += 0x0100; X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0xe1: /* SBC (aa,X) */ X d = MegaGetMem (_eaindx_ ()); X if (!_getD_) { X A -= d; A -= !_getC_; X _setC_ (! (A < 0)); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al -= !_getC_; al -= ol; X if (al < 0) { al += 10; ah--; } X ah -= oh; X _setC_ (! (ah < 0)); X if (ah < 0) ah += 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X if (A < 0) A += 0x0100; X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X case 0xf1: /* SBC (aa),Y */ X d = MegaGetMem (_eaindy_ ()); X if (!_getD_) { X A -= d; A -= !_getC_; X _setC_ (! (A < 0)); X } else { X ah = A / 16; al = A % 16; X oh = d / 16; ol = d % 16; X al -= !_getC_; al -= ol; X if (al < 0) { al += 10; ah--; } X ah -= oh; X _setC_ (! (ah < 0)); X if (ah < 0) ah += 10; X A = al + (ah*16); X } X _setV_ ((A < -0x80) || (A > 0x7f)); X if (A < 0) A += 0x0100; X A %= 0x0100; X _setZ_ (A == 0); X _setN_ (A >= 0x80); X break; X X X X case 0x38: /* SEC */ X _setC_ (1); X break; X X X X case 0xf8: /* SED */ X _setD_ (1); X break; X X X X case 0x78: /* SEI */ X _setI_ (1); X break; X X X X case 0x85: /* STA aa */ X hi = _eazp_(); X MegaPutMem ((ADDR)hi,(BYTE)A); X break; X X X X case 0x95: /* STA aa,X */ X hi = _eazpx_(); X MegaPutMem ((ADDR)hi,(BYTE)A); X break; X X X X case 0x8d: /* STA aaaa */ X hi = _eaabs_(); X MegaPutMem ((ADDR)hi,(BYTE)A); X break; X X X X case 0x9d: /* STA aaaa,X */ X hi = _eaabsx_(); X MegaPutMem ((ADDR)hi,(BYTE)A); X break; X X X X case 0x99: /* STA aaaa,Y */ X hi = _eaabsy_(); X MegaPutMem ((ADDR)hi,(BYTE)A); X break; X X X X case 0x81: /* STA (aa,X) */ X hi = _eaindx_(); X MegaPutMem ((ADDR)hi,(BYTE)A); X break; X X X X case 0x91: /* STA (aa),Y */ X hi = _eaindy_(); X MegaPutMem ((ADDR)hi,(BYTE)A); X break; X X X X case 0x86: /* STX aa */ X hi = _eazp_(); X MegaPutMem ((ADDR)hi,(BYTE)X); X break; X X X X case 0x96: /* STX aa,Y */ X hi = _eazpy_(); X MegaPutMem ((ADDR)hi,(BYTE)X); X break; X X X X case 0x8e: /* STX aaaa */ X hi = _eaabs_(); X MegaPutMem ((ADDR)hi,(BYTE)X); X break; X X X X case 0x84: /* STY aa */ X hi = _eazp_(); X MegaPutMem ((ADDR)hi,(BYTE)Y); X break; X X X X case 0x94: /* STY aa,X */ X hi = _eazpx_(); X MegaPutMem ((ADDR)hi,(BYTE)Y); X break; X X X X case 0x8c: /* STY aaaa */ X hi = _eaabs_(); X MegaPutMem ((ADDR)hi,(BYTE)Y); X break; X X X X case 0xaa: /* TAX */ X X = A; X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X X X case 0xa8: /* TAY */ X Y = A; X _setN_ (Y >= 0x80); X _setZ_ (Y == 0); X break; X X X X case 0xba: /* TSX */ X X = S; X _setN_ (X >= 0x80); X _setZ_ (X == 0); X break; X X X X case 0x8a: /* TXA */ X A = X; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X X X case 0x9a: /* TXS */ X S = X; X break; X X X X case 0x98: /* TYA */ X A = Y; X _setN_ (A >= 0x80); X _setZ_ (A == 0); X break; X X X X default: /* Undefined opcode */ X goto nop; X break; X } X} X END_OF_FILE echo shar: NEWLINE appended to \"'6502.c'\" if test 34910 -ne `wc -c <'6502.c'`; then echo shar: \"'6502.c'\" unpacked with wrong size! fi # end of '6502.c' fi if test -f 'PRODOS.IMAGE.D2' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'PRODOS.IMAGE.D2'\" else echo shar: Extracting \"'PRODOS.IMAGE.D2'\" \(0 characters\) sed "s/^X//" >'PRODOS.IMAGE.D2' <<'END_OF_FILE' END_OF_FILE echo shar: NEWLINE appended to \"'PRODOS.IMAGE.D2'\" if test 1 -ne `wc -c <'PRODOS.IMAGE.D2'`; then echo shar: \"'PRODOS.IMAGE.D2'\" unpacked with wrong size! fi # end of 'PRODOS.IMAGE.D2' fi if test -f 'README2' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README2'\" else echo shar: Extracting \"'README2'\" \(1532 characters\) sed "s/^X//" >'README2' <<'END_OF_FILE' XWhat *YOU* Need to provide X Xfour ROM Files: XAPPLESOFT.ROM <= $d000 to $f777 ][+ Applesoft Basic ROM XAUTOSTART.ROM <= $f800 to $ffff ][+ autostart monitor ROM X Xoptional: XINTEGER.ROM <= $d000 to $f777 Integer Basic ROM XMONITOR.ROM <= $f800 to $ffff Original Monitor ROM X X XPRODOS <= PRODOS System File X X Xhow to boot system: Xstart up simulator X X] CALL 8192 X Xor to boot from slot 7 Drive 2 X X] CALL -151 X X*43:F0 or 70 for slot 7 drive 1 X X*2000G X XDebugger commands Xuse ctrl-A to enter the debugger X Xl load a UNIX binary file into Main Memory Xs single step with trace Xt trace execution with debug output to UNIX file Xc continue execution X same as s Xq quit simulator X Xdebugging technique: Xuse in conjunction with dbx Xbreak into debugger Xstep until a LDA $C000 instruction is executed Xbreak into dbx Xset A = 128 + 'x' where x is the key you want pressed Xcontinue simulator X Xhow to initialize/format slot 7 drive 2 X Xa) startup simulator and PRODOS Xb) enter debugger with ctrl-A Xc) type l this is the load command Xd) enter name of UNIX file containing binary image of a program like COPY ][+ Xe) this will load the binary at $2000 Xf) save this to slot 7 disk 1 Xg) run it, and tell it to format slot 7 disk 2 Xh) this will format a disk with 1024 blocks (change the #define in mega2.c X if you want a larger disk) X X Xrequests does anyone have a generic disk formatter for a ][+? X Xplease forward any enhancements you may have. X XI can be reached at X Xnakada@husc4.harvard.edu Xor Xpnakada@oracle.com X X X END_OF_FILE echo shar: NEWLINE appended to \"'README2'\" if test 1533 -ne `wc -c <'README2'`; then echo shar: \"'README2'\" unpacked with wrong size! fi # end of 'README2' fi if test -f 'debug.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'debug.c'\" else echo shar: Extracting \"'debug.c'\" \(13533 characters\) sed "s/^X//" >'debug.c' <<'END_OF_FILE' X#include "apple.h" X#include X Xint DebugSingle; Xint DebugTrace; XADDR DebugBreak; XFILE *DebugFile; X Xvoid htob (out, byte) XFILE *out; XBYTE byte; X{ X register int i; X X for (i = 7; i >= 0; i--) X (void)fputc (byte & (1 << i) ? '1' : '0', out); X} X Xvoid DebugDisasm (out) XFILE *out; X{ X int opcode = MegaGetMem (PPC); X int n; X char * mne; X X switch (opcode) X { X case 0x69: /* ADC #dd */ X mne = "ADC #$%2X"; n = 1; X break; X case 0x65: /* ADC aa */ X mne = "ADC $%2X"; n = 1; X break; X case 0x75: /* ADC aa,X */ X mne = "ADC $%2X,X"; n = 1; X break; X case 0x6d: /* ADC aaaa */ X mne = "ADC $%4X"; n = 2; X break; X case 0x7d: /* ADC aaaa,X */ X mne = "ADC $%4X,X"; n = 2; X break; X case 0x79: /* ADC aaaa,Y */ X mne = "ADC $%4X,Y"; n = 2; X break; X case 0x61: /* ADC (aa,X) */ X mne = "ADC $(%2X,X)"; n = 1; X break; X case 0x71: /* ADC (aa),Y */ X mne = "ADC $(%2X),Y"; n = 1; X break; X case 0x29: /* AND #dd */ X mne = "AND #$%2X"; n = 1; X break; X case 0x25: /* AND aa */ X mne = "AND $%2X"; n = 1; X break; X case 0x35: /* AND aa,X */ X mne = "AND $%2X,X"; n = 1; X break; X case 0x2d: /* AND aaaa */ X mne = "AND $%4X"; n = 2; X break; X case 0x3d: /* AND aaaa,X */ X mne = "AND $%4X,X"; n = 2; X break; X case 0x39: /* AND aaaa,Y */ X mne = "AND $%4X,Y"; n = 2; X break; X case 0x21: /* AND (aa,X) */ X mne = "AND $(%2X,X)"; n = 1; X break; X case 0x31: /* AND (aa),Y */ X mne = "AND ($%2X),Y"; n = 1; X break; X case 0x0a: /* ASL A */ X mne = "ASL A"; n = 0; X break; X case 0x06: /* ASL aa */ X mne = "ASL $%2X"; n = 1; X break; X case 0x16: /* ASL aa,X */ X mne = "ASL $%2X,X"; n = 1; X break; X case 0x0e: /* ASL aaaa */ X mne = "ASL $%4X"; n = 2; X break; X case 0x1e: /* ASL aaaa,X */ X mne = "ASL $%4X,X"; n = 2; X break; X case 0x90: /* BCC rr */ X mne = "BCC $%2X"; n = -1; X break; X case 0xb0: /* BCS rr */ X mne = "BCS $%2X"; n = -1; X break; X case 0xf0: /* BEQ rr */ X mne = "BEQ $%2X"; n = -1; X break; X case 0x24: /* BIT aa */ X mne = "BIT $%2X"; n = 1; X break; X case 0x2c: /* BIT aaaa */ X mne = "BIT $%4X"; n = 2; X break; X case 0x30: /* BMI rr */ X mne = "BMI $%2X"; n = -1; X break; X case 0xd0: /* BNE rr */ X mne = "BNE $%2X"; n = -1; X break; X case 0x10: /* BPL rr */ X mne = "BPL $%2X"; n = -1; X break; X case 0x00: /* BRK */ X mne = "BRK"; n = 0; X break; X case 0x50: /* BVC rr */ X mne = "BVC $%2X"; n = -1; X break; X case 0x70: /* BVS rr */ X mne = "BVS $%2X"; n = -1; X break; X case 0x18: /* CLC */ X mne = "CLC"; n = 0; X break; X case 0xd8: /* CLD */ X mne = "CLD"; n = 0; X break; X case 0x58: /* CLI */ X mne = "CLI"; n = 0; X break; X case 0xb8: /* CLV */ X mne = "CLV"; n = 0; X break; X case 0xc9: /* CMP #dd */ X mne = "CMP #$%2X"; n = 1; X break; X case 0xc5: /* CMP aa */ X mne = "CMP $%2X"; n = 1; X break; X case 0xd5: /* CMP aa,X */ X mne = "CMP $%2X,X"; n = 1; X break; X case 0xcd: /* CMP aaaa */ X mne = "CMP $%4X"; n = 2; X break; X case 0xdd: /* CMP aaaa,X */ X mne = "CMP $%4X,X"; n = 2; X break; X case 0xd9: /* CMP aaaa,Y */ X mne = "CMP $%4X,Y"; n = 2; X break; X case 0xc1: /* CMP (aa,X) */ X mne = "CMP $(%2X,X)"; n = 1; X break; X case 0xd1: /* CMP (aa),y */ X mne = "CMP $(%2X),y"; n = 1; X break; X case 0xe0: /* CPX #dd */ X mne = "CPX #$%2X"; n = 1; X break; X case 0xe4: /* CPX aa */ X mne = "CPX $%2X"; n = 1; X break; X case 0xec: /* CPX aaaa */ X mne = "CPX $%4X"; n = 2; X break; X case 0xc0: /* CPY #dd */ X mne = "CPY #$%2X"; n = 1; X break; X case 0xc4: /* CPY aa */ X mne = "CPY $%2X"; n = 1; X break; X case 0xcc: /* CPY aaaa */ X mne = "CPY $%4X"; n = 2; X break; X case 0xc6: /* DEC aa */ X mne = "DEC $%2X"; n = 1; X break; X case 0xd6: /* DEC aa,X */ X mne = "DEC $%2X,X"; n = 1; X break; X case 0xce: /* DEC aaaa */ X mne = "DEC $%4X"; n = 2; X break; X case 0xde: /* DEC aaaa,X */ X mne = "DEC $%4X,X"; n = 2; X break; X case 0xca: /* DEX */ X mne = "DEX"; n = 0; X break; X case 0x88: /* DEY */ X mne = "DEY"; n = 0; X break; X case 0x49: /* EOR #dd */ X mne = "EOR #$%2X"; n = 1; X break; X case 0x45: /* EOR aa */ X mne = "EOR $%2X"; n = 1; X break; X case 0x55: /* EOR aa,X */ X mne = "EOR $%2X,X"; n = 1; X break; X case 0x4d: /* EOR aaaa */ X mne = "EOR $%4X"; n = 2; X break; X case 0x5d: /* EOR aaaa,X */ X mne = "EOR $%4X,X"; n = 2; X break; X case 0x59: /* EOR aaaa,Y */ X mne = "EOR $%4X,Y"; n = 2; X break; X case 0x41: /* EOR (aa,X) */ X mne = "EOR ($%2X,X)"; n = 1; X break; X case 0x51: /* EOR (aa),Y */ X mne = "EOR ($%2X),Y"; n = 1; X break; X case 0xe6: /* INC aa */ X mne = "INC $%2X"; n = 1; X break; X case 0xf6: /* INC aa,X */ X mne = "INC $%2X,X"; n = 1; X break; X case 0xee: /* INC aaaa */ X mne = "INC $%4X"; n = 2; X break; X case 0xfe: /* INC aaaa,X */ X mne = "INC $%4X,X"; n = 2; X break; X case 0xe8: /* INX */ X mne = "INX"; n = 0; X break; X case 0xc8: /* INY */ X mne = "INY"; n = 0; X break; X case 0x4c: /* JMP aaaa */ X mne = "JMP $%4X"; n = 2; X break; X case 0x6c: /* JMP (aaaa) */ X mne = "JMP ($%4X)"; n = 2; X break; X case 0x20: /* JSR aaaa */ X mne = "JSR $%4X"; n = 2; X break; X case 0xa9: /* LDA #dd */ X mne = "LDA #$%2X"; n = 1; X break; X case 0xa5: /* LDA aa */ X mne = "LDA $%2X"; n = 1; X break; X case 0xb5: /* LDA aa,X */ X mne = "LDA $%2X,X"; n = 1; X break; X case 0xad: /* LDA aaaa */ X mne = "LDA $%4X"; n = 2; X break; X case 0xbd: /* LDA aaaa,X */ X mne = "LDA $%4X,X"; n = 2; X break; X case 0xb9: /* LDA aaaa,Y */ X mne = "LDA $%4X,Y"; n = 2; X break; X case 0xa1: /* LDA (aa,X) */ X mne = "LDA ($%2X,X)"; n = 1; X break; X case 0xb1: /* LDA (aa),Y */ X mne = "LDA ($%2X),Y"; n = 1; X break; X case 0xa2: /* LDX #dd */ X mne = "LDX #$%2X"; n = 1; X break; X case 0xa6: /* LDX aa */ X mne = "LDX $%2X"; n = 1; X break; X case 0xb6: /* LDX aa,Y */ X mne = "LDX $%2X,Y"; n = 1; X break; X case 0xae: /* LDX aaaa */ X mne = "LDX $%4X"; n = 2; X break; X case 0xbe: /* LDX aaaa,Y */ X mne = "LDX $%4X,Y"; n = 2; X break; X case 0xa0: /* LDY #dd */ X mne = "LDY #$%2X"; n = 1; X break; X case 0xa4: /* LDY aa */ X mne = "LDY $%2X"; n = 1; X break; X case 0xb4: /* LDY aa,X */ X mne = "LDY $%2X,X"; n = 1; X break; X case 0xac: /* LDY aaaa */ X mne = "LDY $%4X"; n = 2; X break; X case 0xbc: /* LDY aaaa,X */ X mne = "LDY $%4X,X"; n = 2; X break; X case 0x4a: /* LSR A */ X mne = "LSR"; n = 0; X break; X case 0x46: /* LSR aa */ X mne = "LSR $%2X"; n = 1; X break; X case 0x56: /* LSR aa,X */ X mne = "LSR $%2X,X"; n = 1; X break; X case 0x4e: /* LSR aaaa */ X mne = "LSR $%4X"; n = 2; X break; X case 0x5e: /* LSR aaaa,X */ X mne = "LSR $%4X,X"; n = 2; X break; X case 0xea: /* NOP */ X mne = "NOP"; n = 0; X break; X case 0x09: /* ORA #dd */ X mne = "ORA #$%2X"; n = 1; X break; X case 0x05: /* ORA aa */ X mne = "ORA $%2X"; n = 1; X break; X case 0x15: /* ORA aa,X */ X mne = "ORA $%2X,X"; n = 1; X break; X case 0x0d: /* ORA aaaa */ X mne = "ORA $%4X"; n = 2; X break; X case 0x1d: /* ORA aaaa,X */ X mne = "ORA $%4X,X"; n = 2; X break; X case 0x19: /* ORA aaaa,Y */ X mne = "ORA $%4X,Y"; n = 2; X break; X case 0x01: /* ORA (aa,X) */ X mne = "ORA ($%2X,X)"; n = 1; X break; X case 0x11: /* ORA (aa),Y */ X mne = "ORA ($%2X),Y"; n = 1; X break; X case 0x48: /* PHA */ X mne = "PHA"; n = 0; X break; X case 0x08: /* PHP */ X mne = "PHP"; n = 0; X break; X case 0x68: /* PLA */ X mne = "PLA"; n = 0; X break; X case 0x28: /* PLP */ X mne = "PLP"; n = 0; X break; X case 0x2a: /* ROL A */ X mne = "ROL A"; n = 0; X break; X case 0x26: /* ROL aa */ X mne = "ROL $%2X"; n = 1; X break; X case 0x36: /* ROL aa,X */ X mne = "ROL $%2X,X"; n = 1; X break; X case 0x2e: /* ROL aaaa */ X mne = "ROL $%4X"; n = 2; X break; X case 0x3e: /* ROL aaaa,X */ X mne = "ROL $%4X,X"; n = 2; X break; X case 0x6a: /* ROR A */ X mne = "ROR A"; n = 0; X break; X case 0x66: /* ROR aa */ X mne = "ROR $%2X"; n = 1; X break; X case 0x76: /* ROR aa,X */ X mne = "ROR $%2X,X"; n = 1; X break; X case 0x6e: /* ROR aaaa */ X mne = "ROR $%4X"; n = 2; X break; X case 0x7e: /* ROR aaaa,X */ X mne = "ROR $%4X,X"; n = 2; X break; X case 0x40: /* RTI */ X mne = "RTI"; n = 0; X break; X case 0x60: /* RTS */ X mne = "RTS"; n = 0; X break; X case 0xe9: /* SBC #dd */ X mne = "SBC #$%2X"; n = 1; X break; X case 0xe5: /* SBC aa */ X mne = "SBC $%2X"; n = 1; X break; X case 0xf5: /* SBC aa,x */ X mne = "SBC $%2X,X"; n = 1; X break; X case 0xed: /* SBC aaaa */ X mne = "SBC $%4X"; n = 2; X break; X case 0xfd: /* SBC aaaa,X */ X mne = "SBC $%4X,X"; n = 2; X break; X case 0xf9: /* SBC aaaa,Y */ X mne = "SBC $%4X,Y"; n = 2; X break; X case 0xe1: /* SBC (aa,X) */ X mne = "SBC ($%2X,X)"; n = 1; X break; X case 0xf1: /* SBC (aa),Y */ X mne = "SBC ($%2X),Y"; n = 1; X break; X case 0x38: /* SEC */ X mne = "SEC"; n = 0; X break; X case 0xf8: /* SED */ X mne = "SED"; n = 0; X break; X case 0x78: /* SEI */ X mne = "SEI"; n = 0; X break; X case 0x85: /* STA aa */ X mne = "STA $%2X"; n = 1; X break; X case 0x95: /* STA aa,X */ X mne = "STA $%2X,X"; n = 1; X break; X case 0x8d: /* STA aaaa */ X mne = "STA $%4X"; n = 2; X break; X case 0x9d: /* STA aaaa,X */ X mne = "STA $%4X,X"; n = 2; X break; X case 0x99: /* STA aaaa,Y */ X mne = "STA $%4X,Y"; n = 2; X break; X case 0x81: /* STA (aa,X) */ X mne = "STA ($%2X,X)"; n = 1; X break; X case 0x91: /* STA (aa),Y */ X mne = "STA ($%2X),Y"; n = 1; X break; X case 0x86: /* STX aa */ X mne = "STX $%2X"; n = 1; X break; X case 0x96: /* STX aa,Y */ X mne = "STX $%2X,Y"; n = 1; X break; X case 0x8e: /* STX aaaa */ X mne = "STX $%4X"; n = 2; X break; X case 0x84: /* STY aa */ X mne = "STY $%2X"; n = 1; X break; X case 0x94: /* STY aa,X */ X mne = "STY $%2X,X"; n = 1; X break; X case 0x8c: /* STY aaaa */ X mne = "STY $%4X"; n = 2; X break; X case 0xaa: /* TAX */ X mne = "TAX"; n = 0; X break; X case 0xa8: /* TAY */ X mne = "TAY"; n = 0; X break; X case 0xba: /* TSX */ X mne = "TSX"; n = 0; X break; X case 0x8a: /* TXA */ X mne = "TXA"; n = 0; X break; X case 0x9a: /* TXS */ X mne = "TXS"; n = 0; X break; X case 0x98: /* TYA */ X mne = "TYA"; n = 0; X break; X default: /* Undefined opcode */ X mne = "UNDEFINED"; n = 0; X break; X } X (void)fprintf (out, "%4X: ", PPC); X switch (n) X { X case -1: X (void)fprintf (out, mne, PPC + (char)MegaGetMem (PPC + 1) + 2); X break; X case 0: X (void)fprintf (out, mne); X break; X case 1: X (void)fprintf (out, mne, MegaGetMem (PPC + 1)); X break; X case 2: X (void)fprintf (out, mne, MegaGetMem (PPC + 1) + 256 * MegaGetMem (PPC + 2)); X break; X } X (void)fputc ('\n', out); X} X X X X Xvoid Debugger() X{ X int done = 0; X FILE *out = stdout; X char buffer[255]; X X echo(); X noraw(); X standend(); X refresh(); X X if (DebugTrace) X out = DebugFile; X X (void)fprintf (out, " A=%2X, Y=%2X, X=%2X, S=%2X, P=%%",A,Y,X,S); X htob (out, (BYTE)P); X (void)fprintf (out, " | "); X DebugDisasm (out); X if (!DebugTrace && !DebugSingle) X { X (void)printf ("\nApple ][+ Emulator Debugger\n"); X } X X if (DebugTrace) goto traceout; X X while (!done) X { X (void)printf ("DBG> "); X (void)fflush (stdout); X (void)gets (buffer); X X switch (buffer[0]) X { X case 'q': X DebugSingle = 0; X DebugTrace = 0; X MegaQuitDetect = 1; X done = 1; X break; X case 'l': /* load */ X { X ADDR addr = 0x2000; X FILE *fp; X int ch; X X (void)printf ("Filename: "); X (void)fflush (stdout); X (void)gets (buffer); X fp = fopen (buffer, "r"); X while ((ch = fgetc (fp)) != EOF) X MegaPutMem (addr++, (BYTE)ch); X X (void)printf ("%s: loaded at ,a$2000, l$%x\n", buffer, addr - 0x2000 - 1); X MegaQuitDetect = 0; X done = 0; X break; X } X case 't': X (void)printf ("Filename: "); X (void)fflush (stdout); X (void)gets (buffer); X DebugFile = fopen (buffer, "w"); X DebugTrace = 1; X MegaQuitDetect = 0; X done = 0; X break; X case 'c': X DebugSingle = 0; X MegaQuitDetect = 0; X done = 1; X break; X case 's': X case '\0': X DebugSingle = 1; X DebugTrace = 0; X MegaQuitDetect = 0; X done = 1; X break; X default: X MegaQuitDetect = 0; X } X } Xtraceout: X raw(); X noecho(); X} X END_OF_FILE echo shar: NEWLINE appended to \"'debug.c'\" if test 13534 -ne `wc -c <'debug.c'`; then echo shar: \"'debug.c'\" unpacked with wrong size! fi # end of 'debug.c' fi echo shar: End of archive 1 \(of 2\). cp /dev/null ark1isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0