home *** CD-ROM | disk | FTP | other *** search
- From: skrenta@blekko.UUCP (Rich Skrenta)
- Newsgroups: alt.sources
- Subject: a2 - Apple II emulator, part 1/2
- Message-ID: <122@blekko.UUCP>
- Date: 23 May 90 16:34:28 GMT
-
- Here's my Apple II emulator. I can't post the ROM images, they're
- copyrighted, so keep in mind that you'll need them before you can do
- anything interesting with the emulator.
-
- Features: high level DOS 3.3 & Prodos interception, scroll interception,
- memory map Disk II support (raw disk reads).
- It's fast, too. If you have one of those new spiffy RISC
- workstations you may even be able to run the emulator at
- the speed of the original Apple.
-
- Doesn't have: graphics, raw disk writes.
-
- Send bug fixes and enhancements to me so they can be included in a
- future release.
-
-
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # This archive contains:
- # Makefile Notes Snarf Cli.doc
- # a2.c a2.h curses.c disk.c
- # tbl.c
- #
-
- echo x - Makefile
- cat >Makefile <<'@EOF'
-
-
- #
- # Use -O if you can. It gave a 20% speedup on one test.
- #
- CFLAGS = -O
- LIBS = -lcurses -ltermcap
-
- # If Using 286 Xenix, uncomment the following lines:
- # CFLAGS = -M2l -O
- # LARGE = -LARGE
- #
- # Make SYSTEM be -DBSD for Berkeley-ish machines, leave blank otherwise
- #
- SYSTEM =
- #SYSTEM = -DBSD
-
-
- OBJECTS = a2.o table.o jump.o curses.o main.o screen.o \
- mem.o tbl.o parse.o commands.o dos.o cli.o vidout.o \
- disk.o prodos.o
-
- a2: $(OBJECTS)
- cc -o a2 $(CFLAGS) $(OBJECTS) $(LIBS)
-
- curses.o: curses.c
- cc -c $(SYSTEM) $(CFLAGS) curses.c
-
- shar:
- -mv ../a2.shar ../a2.shar-
- shar -v Makefile Notes Snarf Cli.doc Todo *.[ch] > ../a2.shar
-
- tar:
- -mv ../a2.tar ../a2.tar-
- tar -cvf ../a2.tar [A-Z]* *.[ch]
-
- clean:
- rm -f *.o core
-
- clobber: clean
- rm -f a2
-
-
- a2.o: a2.h a2.c
- cc $(LARGE) $(CFLAGS) -c a2.c
-
- cli.o: cli.c a2.h cli.h
- commands.o: commands.c cli.h a2.h
- disk.o: disk.c a2.h
- dos.o: dos.c a2.h
- jump.o: jump.c a2.h
- main.o: main.c a2.h
- mem.o: mem.c a2.h
- parse.o: parse.c cli.h a2.h
- pascal.o: pascal.c a2.h
- screen.o: screen.c a2.h
- table.o: table.c a2.h
- tbl.o: tbl.c cli.h a2.h
- vidout.o: vidout.c a2.h
- @EOF
-
- chmod 644 Makefile
-
- echo x - Notes
- cat >Notes <<'@EOF'
- The default escape character is ~
-
- Speed is everything in the emulator. I use macros instead of functions;
- autoincrement wherever I can; suitably sized variables to take advantage
- of wraparound so I don't have to & 0xFF or & 0xFFFF. These things are done
- for speed, not safety, although they should work on most machines. Hopefully
- the safety_check() routine will assert fail if at least some of these
- assumptions are not true.
-
- The main loop of the cpu is handled by a big switch statement. There
- are no function calls since they incur a large overhead. I count on
- your compiler generating an efficient jump table for the switch.
-
- The Apple's memory is represented by a 64K array of bytes (unsigned char).
- All memory references, with the exception of special locataions in the
- C000-CFFF range, come unintercepted from the mem array.
-
- References in the C000-CFFF range are taken from the mem_map() function.
- It implements things such as the keyboard read & strobe locations and
- the bank switching toggles. If mem_map() doesn't have a special hook
- for a Cxxx location, it will return the mem[] value associated with
- the location. Thus you can load device PROM images there and you will
- be able to reference them.
-
- Memory stores may be caught on a per-page basis. For example, stores to
- the C0xx range are caught by store_c0(). Besides the Cxxx functions,
- store catching routines are used for the memory mapped video from $400-7FF
- also for the language card.
-
- Certain PC values are intercepted and dealt with by C routines. The 64K
- array jmp_tbl[] determines whether a location is "caught"; if zero, nothing
- will happen. If non-zero, the value is passed to jump(). Pc's are only
- intercepted on JMP and JSR instructions (so that we don't pay a speed
- penalty for every instruction fetch). This imposes obvious limitations
- on what code can be caught.
-
- Intercepted routines include the ROM routines to handle scrolling, the
- ROM wait and bell calls, and some Cxxx calls. Scrolling must be caught
- and done separately or it looks horrible. RWTS and Prodos are also
- caught at the block read/write level to speed up disk access.
-
- Note that none of the jump intercepts are necessary. They speed up
- scrolling and disk access (for Prodos & DOS 3.3) quite a bit, but you
- can turn them all off and the emulator will still run. The memory map
- support is enough.
-
- The Pc catches ignore whether the language card is active or not; instead,
- they look for key values to see if they routines they're supposed to sit
- on top of really are there. If not, they let the real code execute.
- If we just caught ROM calls, and didn't catch calls that executed when
- the RAM card was active, then copying the ROM into the language card and
- switching to it would cause us to lose all of our interception.
-
- Beware when adding intercepts for the ROM or other functions: there's
- always some piece of code that depends on a side effect of a function.
-
- The blocks in the disk image are ordered in DOS 3.3 layout. The prodos
- code uses a mapping table. Thus, one Prodos block consists of two non-
- contiguous 256 byte blocks in a disk image.
-
- I only have the old Disk II boot prom from $C600. Jump.c patches it to
- look something like a Prodos device controller, so that Prodos has high-
- level disk intercept support. I don't know if a prom image from a newer
- disk controller will work or not.
-
- The emulator supports raw access to the disk controller by nibble
- encoding sector images as they're fed in through the shift data register.
- A routine decodes the motion of the disk head based on references to
- the stepper magnets.
-
- @EOF
-
- chmod 644 Notes
-
- echo x - Snarf
- cat >Snarf <<'@EOF'
- Snarfing the ROM images
- -----------------------
-
- In order to run the Apple II emulator you will need several ROM images.
- Since they are copyrighted they cannot be distributed with this program.
-
-
- File to put image in Location in Apple
-
- AUTOSTART.ROM F800-FFFF
- APPLESOFT.ROM D000-EFFF
- DISK.PROM C600-C6FF (slot 6 Disk II cont.)
-
- MONITOR.ROM F800-FFFF (old Apples)
- INTEGER.ROM D000-EFFF (old Apples)
-
-
- How I snarfed the ROMs:
-
- My Apple has an el-cheapo serial card; neither Kermit nor any of my
- communications programs would talk to it. If I'd had any sort of working
- communications software when I set out to snarf my ROMs I probably wouldn't
- have done it this way; as it turns out, however, I've been very happy
- with this method.
-
- I have my Apple connected to my Unix box through the serial card. I
- can type IN#2 on my apple and cu into it from the Unix machine (typing
- PR#2 once I'm connected).
-
- Once I'm cu'd in, it's easy to use the ROM monitor to dump stuff. It
- looks something like this:
-
- $ cu -l /dev/tty06 -s 9600 -e | tee log
- Connected
- <type PR#2>
- ]CALL -151
-
- *F800.FFFF
-
- F800- 00 00 00 ...
- ...
- *
-
- Then when I escape back to the Unix side I have a log of the session
- in "log". I use this sed command to strip off the junk and only leave
- the hex data:
-
- sed -n -e 's/^M$//' -e '/^[0-9A-F]...-/p'
-
- In other words, put the above in a file, say 'fix', chmod +w fix, and say:
-
- fix < log > foo
-
- Then I run the hex dump through a simple C program to turn it back into
- binary (the program is called hex.c, and should be in the directory with
- the emulator source):
-
- hex < foo > AUTOSTART.ROM
-
- I snarf disk images in much the same way. Here's a little DOS 3.3
- routine to dump an entire disk in hex:
-
-
- 0300- A9 00 LDA #$00 ; set up IOB
- 0302- 8D F0 B7 STA $B7F0 ; BUFFL
- 0305- 8D EB B7 STA $B7EB ; VOLUME
- 0308- 8D EC B7 STA $B7EC ; TRACK
- 030B- 8D ED B7 STA $B7ED ; SECTOR
- 030E- A9 10 LDA #$10
- 0310- 8D F1 B7 STA $B7F1 ; BUFFH
- 0313- A9 B7 LDA #$B7 ; IOBH
- 0315- A0 E8 LDY #$E8 ; IOBL
- 0317- 20 B5 B7 JSR $B7B5 ; call RWTS
- 031A- EE F1 B7 INC $B7F1 ; next page of memory
- 031D- EE ED B7 INC $B7ED ; next sector
- 0320- AD ED B7 LDA $B7ED
- 0323- C9 10 CMP #$10 ; end of track?
- 0325- 90 EC BCC $0313
- 0327- 20 3A 03 JSR $033A ; dump 1000-1FFF in hex
- 032A- A9 00 LDA #$00 ; Start at sector 0 again
- 032C- 8D ED B7 STA $B7ED
- 032F- EE EC B7 INC $B7EC ; next track
- 0332- AD EC B7 LDA $B7EC
- 0335- C9 23 CMP #$23 ; last track on disk?
- 0337- 90 D5 BCC $030E
- 0339- 60 RTS
- 033A- A9 00 LDA #$00
- 033C- 85 3C STA $3C
- 033E- A9 FF LDA #$FF ; range 1000-1FFF
- 0340- 85 3E STA $3E
- 0342- A9 10 LDA #$10
- 0344- 85 3D STA $3D
- 0346- A9 1F LDA #$1F
- 0348- 85 3F STA $3F
- 034A- 20 B3 FD JSR $FDB3 ; dump hex region
- 034D- 60 RTS
-
- Run fix and hex on the log, and you can put together binary disk images
- for the emulator. I've converted about 45 of my disks this way.
-
- Since the emulator expects disk images to be in DOS 3.3 sector ordering,
- if you use another tool to snarf disk you may need to convert them.
- The program mapper.c converts from Prodos sector ordered disks into
- DOS 3.3 sector ordered images:
-
- mapper < foo > bar
-
- @EOF
-
- chmod 644 Snarf
-
- echo x - Cli.doc
- cat >Cli.doc <<'@EOF'
-
- CLI Basics
- ----------
- The ~ key (default value) will break the emulation and put the User into
- the Command Language Interpreter (CLI). The CLI prompt is >>> . The
- user may type ? to see a list of available commands in the CLI. The CLI
- allows partial completion of commands. The partial command name must
- be unambiguous. For instance, "e" or "exam" may be
- substituted for "examine".
-
- General Commands
- ----------------
-
- cd [path] - With no paramters, displays current working directory (CWD).
- Otherwise attempts to set the CWD to path.
-
- continue or c - Resume the emulation and refresh the screen.
-
- escape [char] - Make the character which breaks the emulator into char or
- display current escape char.
-
- dup l|p
- pop l|p
- push l|p|addr
- - The CLI maintains a value stack for the convenience of
- the user. The emulator doesnt use the stack at all.
- Values may be pushed on the stack with push and
- retrieved later with pop or dup. The l and p parameters
- are used to retrive/store values into the lpoint (list
- point) and pc.
-
- help - Gives a quick list of commands
-
- map - Toggle lower to uppercase mapping during emulation. The
- default is to perform mapping.
-
- quit - Exit the Emulator
-
- . - Display the current point
-
- ![command] - Unix Shell escape. Without command, the shell is called.
- Otherwise, command is executed.
-
- File Commands
- -------------
-
- bload file addr
- - Bload will Allow the loading of binary images into the memory of
- the emulator. bload binfile F000 will load file "binfile" at
- address F000.
-
- bsave file addr1 size
- - Bsave will save a section of memory to a file. For instance,
- bsave mybin 300 FF will save all of the memory from 300 to 3FF
- to file "mybin".
-
- disk
- - Display the names of the disks which are currently inserted in
- the virtual disk drives.
-
- insert file [drive#]
- - Insert will make a file the disk in a particular drive. For
- Instance: insert mydisk will make the file "mydisk" appear
- to the emulator as the disk in drive 1.
-
- Register Manipulation
- ---------------------
-
- cl[cdinvz] - Clears Status register bit. For instance, clc will clear
- the carry bit. clz will clear the zero bit.
-
- se[cdinvz] - Set Status register bit. For instance, sec will set the
- carry flag. sez will set the zero bit.
-
- ld[axys] value
- - Load a value into a register. lda ff will load ff into
- the accumulator. lds 02 will load 02 into the Stack Pointer.
-
- jmp addr
- - Sets PC = addr. A continue will resume at that location.
-
- reset or ~
- - Sets PC = addr in the Apple II reset Vector. Combined
- with continue, will emulate the pressing of the reset
- button on the Apple II.
-
- Memory Manipulation/Examination
- -------------------------------
-
- examine addr [addr]
- - Display current memory location if no paramters are givin.
- If one parameter is givin, the contents of that location are
- displayed. If two parameters are givin, all memory between
- the two locations is displayed. examine 300 400 will display
- all memory between $300 and $400. e 300 will display the
- 8 bit contents of $300
-
- deposit addr value [value]+
- - Put values into memory. Addr must be specified as well as
- one or more values. Deposit 300 20 will put 20 into memory
- location 300. Deposit 300 10 20 30 40 will load 10,20,30,40
- into consequtive addresses beginning at 300.
-
- list [low] [high]
- - Dissassembly. If noparameters are supplied, dissassembly
- begins at the current point and continues for 1 page. If
- low is specified, dissassembly begins at low and continues
- for 1 page. If both low and high are specified the region
- between low and high is dissassembled.
-
- Debugging Commands
- ------------------
-
- breakpoint [addr]
- - Set breakpoint. If addr is not specified, the current
- breakpoint is displayed. Otherwise, the breakpoint is set
- to addr. When PC == addr, the emulator breaks into the
- command mode. break 3FFF sets the breakpoint to 3FFF.
-
- nobreak - Turn of breakpoint.
-
- trace [low high] [file]
- - Enable tracing. With no parameters, the current trace status
- is displayed. When low and high are givin, tracing for that
- region is enabled (i.e. when low <= pc <= high ). An output
- consisting of dissassembly and status registers is written to
- the trace file. If file is specified, output is sent to that
- file, otherwise the file "trace" is used. For instance,
- trace 3F0 400 will trace the region of 3F0-400 and send its
- output to trace.
-
- notrace - Disable tracing.
-
- phantom location high low [file]
- - Enable phantom tracing of range low,high. Phantom tracing
- allows a trace to be performed AFTER location is reached.
- For instance, phantom 300 F300 F400 will enable tracing of
- f300-f400 only AFTER PC == 300. Once the PC has reached 300,
- tracing between F300-F400 is enabled. If file is specified
- trace output will go to the specified file. Otherwise, "trace"
- is assumed.
- nophantom
- - disable phantom trace.
-
- @EOF
-
- chmod 600 Cli.doc
-
- echo x - a2.c
- cat >a2.c <<'@EOF'
- /*
- * a2, an Apple II emulator in C
- * (c) Copyright 1990 by Rich Skrenta
- *
- * Command line interface written by Tom Markson
- *
- * Distribution agreement:
- *
- * You may freely copy or redistribute this software, so long
- * as there is no profit made from its use, sale, trade or
- * reproduction. You may not change this copyright notice,
- * and it must be included prominently in any copy made.
- *
- * Send emulator related mail to: skrenta@blekko.commodore.com
- * skrenta@blekko.uucp
- */
-
-
- #include <stdio.h>
- #include "a2.h"
-
- #define BRANCH() val = mem[Pc++]; if (val & 0x80) Pc += val - 256; else Pc += val;
-
- #define put_status(s) stmp = s; N = stmp & 0x80; V = stmp & 0x40; B = stmp & 0x10; D = stmp & 0x08; I = stmp & 0x04; NZ = !(stmp & 0x02); C = stmp & 0x01;
-
-
- extern long trace_lo, trace_hi;
- extern FILE *logging_fp;
- extern long phantom_location;
- extern long breakpoint;
-
-
-
- run()
- {
- register unsigned short ptr;
- register unsigned short ptmp;
- register unsigned int val;
- register unsigned int tmp;
- register unsigned int num;
- unsigned char stmp;
- int foo;
- int show_flags = FALSE;
-
-
- do { /* while (tracing) */
- if (tracing) {
-
- if (breakpoint == Pc) {
- MoveCursor(term_lines, 0);
- printf("Break at $%.4X\n", Pc);
- return;
- }
-
- if (phantom_location == (long) Pc)
- phantom_location = -1; /* start tracing now */
-
- if (phantom_location == -1
- && trace_lo != -1
- && (long) Pc >= trace_lo
- && (long) Pc <= trace_hi) {
- diss(Pc, logging_fp);
- show_flags = TRUE;
- } else
- show_flags = FALSE;
- }
-
-
- do { /* while (running) */
- switch (mem[Pc++]) {
- case 0x00: /* BRK */
- PCINC;
- push(high(Pc));
- push(low(Pc));
- B = 1; /* set I flag? */
- push(get_status());
- Pc = join(mem[0xFFFE], mem[0xFFFF]);
- break;
-
- case 0x01: /* ORA (indirect, X) */
- INDX;
- A |= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x02:
- break;
-
- case 0x03:
- break;
-
- case 0x04: /* TSB zero page 65C02 */
- break;
-
- case 0x05: /* ORA zero page */
- A |= rZEROP;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x06: /* ASL zero page */
- ZEROP;
- val = REFzero << 1;
- CARRY(val);
- val &= 0xFF;
- SETzero(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x07:
- break;
-
- case 0x08: /* PHP */
- push(get_status());
- break;
-
- case 0x09: /* ORA immediate */
- A |= REFimm;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x0A: /* ASL accumulator */
- A = A << 1;
- CARRY(A);
- A &= 0xFF;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x0B:
- break;
-
- case 0x0C: /* TSB absolute 65C02 */
- break;
-
- case 0x0D: /* ORA absolute */
- ABSOL;
- A |= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x0E: /* ASL absolute */
- ABSOL;
- val = REFptr << 1;
- CARRY(val);
- val &= 0xFF;
- SETptr(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x0F:
- break;
-
- case 0x10: /* BPL */
- if (N) {
- PCINC;
- } else {
- BRANCH();
- }
- break;
-
- case 0x11: /* ORA (indirect), Y */
- INDY;
- A |= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x12: /* ORA (indz) 65C02 */
- break;
-
- case 0x13:
- break;
-
- case 0x14: /* TRB zero page 65C02 */
- break;
-
- case 0x15: /* ORA zero page, X */
- A |= rZEROX;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x16: /* ASL zero page, X */
- ZEROX;
- val = REFzero << 1;
- CARRY(val);
- val &= 0xFF;
- SETzero(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x17:
- break;
-
- case 0x18: /* CLC */
- C = 0;
- break;
-
- case 0x19: /* ORA absolute, Y */
- ABSY;
- A |= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x1A: /* INA 65C02 */
- break;
-
- case 0x1C: /* TRB absolute 65C02 */
- break;
-
- case 0x1D: /* ORA absolute, X */
- ABSX;
- A |= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x1E: /* ASL absolute, X */
- ABSX;
- val = REFptr << 1;
- CARRY(val);
- val &= 0xFF;
- SETptr(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x1F:
- break;
-
- case 0x20: /* JSR */
- ptmp = REFimm;
- ptmp |= mem[Pc] << 8;
- push(high(Pc));
- push(low(Pc));
- Pc = ptmp;
-
- if (jmp_tbl[Pc])
- jump(jmp_tbl[Pc]);
- break;
-
- case 0x21: /* AND (indirect, X) */
- INDX;
- A &= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x22:
- break;
-
- case 0x23:
- break;
-
- case 0x24: /* BIT zero page */
- tmp = rZEROP;
- ZERO(A & tmp);
- N = tmp & 0x80;
- V = tmp & 0x40;
- break;
-
- case 0x25: /* AND zero page */
- A &= rZEROP;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x26: /* ROL zero page */
- ZEROP;
- val = REFzero;
- tmp = C;
- val = val << 1;
- CARRY(val);
- val = (val & 0xFF) | tmp;
- SETzero(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x27:
- break;
-
- case 0x28: /* PLP */
- put_status(pop());
- break;
-
- case 0x29: /* AND immediate */
- A &= REFimm;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x2A: /* ROL accumulator */
- tmp = C;
- A = A << 1;
- CARRY(A);
- A = (A & 0xFF) | tmp;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x2B:
- break;
-
- case 0x2C: /* BIT absolute */
- ABSOL;
- tmp = REFptr;
- ZERO(A & tmp);
- N = tmp & 0x80;
- V = tmp & 0x40;
- break;
-
- case 0x2D: /* AND absolute */
- ABSOL;
- A &= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x2E: /* ROL absolute */
- ABSOL;
- val = REFptr;
- tmp = C;
- val = val << 1;
- CARRY(val);
- val = (val & 0xFF) | tmp;
- SETptr(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x2F:
- break;
-
- case 0x30: /* BMI */
- if (N) {
- BRANCH();
- } else{
- PCINC;
- }
- break;
-
- case 0x31: /* AND (indirect), Y */
- INDY;
- A &= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x32: /* AND (indz) 65C02 */
- break;
-
- case 0x33:
- break;
-
- case 0x34: /* BIT zero page, X 65C02 */
- break;
-
- case 0x35: /* AND zero page, X */
- A &= rZEROX;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x36: /* ROL zero page, X */
- ZEROX;
- val = REFzero;
- tmp = C;
- val = val << 1;
- CARRY(val);
- val = (val & 0xFF) | tmp;
- SETzero(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x37:
- break;
-
- case 0x38: /* SEC */
- C = 1;
- break;
-
- case 0x39: /* AND absolute, Y */
- ABSY;
- A &= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x3A: /* DEA 65C02 */
- break;
-
- case 0x3B:
- break;
-
- case 0x3C: /* BIT absolute, X 65C02 */
- break;
-
- case 0x3D: /* AND absolute, X */
- ABSX;
- A &= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x3E: /* ROL absolute, X */
- ABSX;
- val = REFptr;
- tmp = C;
- val = val << 1;
- CARRY(val);
- val = (val & 0xFF) | tmp;
- SETptr(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x3F:
- break;
-
- case 0x40: /* RTI */
- put_status(pop());
- Pc = pop();
- Pc |= pop() << 8;
- break;
-
- case 0x41: /* EOR (indirect, X) */
- INDX;
- A ^= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x42:
- break;
-
- case 0x43:
- break;
-
- case 0x44:
- break;
-
- case 0x45: /* EOR zero page */
- A ^= rZEROP;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x46: /* LSR zero page */
- ZEROP;
- tmp = REFzero;
- C = (tmp & 0x01);
- tmp = tmp >> 1;
- SETzero(tmp);
- N = 0;
- ZERO(tmp);
- break;
-
- case 0x47:
- break;
-
- case 0x48: /* PHA */
- push(A);
- break;
-
- case 0x49: /* EOR immediate */
- A ^= REFimm;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x4A: /* LSR accumulator */
- C = (A & 0x01);
- A = A >> 1;
- N = 0;
- ZERO(A);
- break;
-
- case 0x4B:
- break;
-
- case 0x4C: /* JMP absolute */
- ptmp = REFimm;
- ptmp |= REFimm << 8;
- Pc = ptmp;
-
- if (jmp_tbl[Pc])
- jump(jmp_tbl[Pc]);
- break;
-
- case 0x4D: /* EOR absolute */
- ABSOL;
- A ^= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x4E: /* LSR absolute */
- ABSOL;
- tmp = REFptr;
- C = (tmp & 0x01);
- tmp = tmp >> 1;
- SETptr(tmp);
- N = 0;
- ZERO(tmp);
- break;
-
- case 0x4F:
- break;
-
- case 0x50: /* BVC */
- if (V) {
- PCINC;
- } else {
- BRANCH();
- }
- break;
-
- case 0x51: /* EOR (indirect), Y */
- INDY;
- A ^= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x52: /* EOR (indz) 65C02 */
- break;
-
- case 0x53:
- break;
-
- case 0x54:
- break;
-
- case 0x55: /* EOR zero page, X */
- A ^= rZEROX;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x56: /* LSR zero page, X */
- ZEROX;
- tmp = REFzero;
- C = (tmp & 0x01);
- tmp = tmp >> 1;
- SETzero(tmp);
- N = 0;
- ZERO(tmp);
- break;
-
- case 0x57:
- break;
-
- case 0x58: /* CLI */
- I = 0;
- break;
-
- case 0x59: /* EOR absolute, Y */
- ABSY;
- A ^= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x5A: /* PHY 65C02 */
- break;
-
- case 0x5B:
- break;
-
- case 0x5C:
- break;
-
- case 0x5D: /* EOR absolute, X */
- ABSX;
- A ^= REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x5E: /* LSR absolute, X */
- ABSX;
- tmp = REFptr;
- C = (tmp & 0x01);
- tmp = tmp >> 1;
- SETptr(tmp);
- N = 0;
- ZERO(tmp);
- break;
-
- case 0x5F:
- break;
-
- case 0x60: /* RTS */
- DO_RTS;
- break;
-
- case 0x61: /* ADC (indirect, X) */
- INDX;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- num = tobinary(val);
- val = tobinary(A);
-
- val += num + C;
- dCARRY(val);
- while (val >= 100)
- val -= 100;
-
- A = tobcd(val);
- } else {
- A += val + C;
- CARRY(A);
- A &= 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp == stmp) && (tmp != N);
- break;
-
- case 0x62:
- break;
-
- case 0x63:
- break;
-
- case 0x64: /* STZ zero page 65C02 */
- break;
-
- case 0x65: /* ADC zero page */
- val = rZEROP;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- num = tobinary(val);
- val = tobinary(A);
-
- val += num + C;
- dCARRY(val);
- while (val >= 100)
- val -= 100;
-
- A = tobcd(val);
- } else {
- A += val + C;
- CARRY(A);
- A &= 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp == stmp) && (tmp != N);
- break;
-
-
- case 0x66: /* ROR zero page */
- ZEROP;
- val = REFzero;
- tmp = C;
- C = val & 0x01;
- val = val >> 1;
- val |= tmp << 7;
- SETzero(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x67:
- break;
-
- case 0x68: /* PLA */
- A = pop();
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x69: /* ADC immediate */
- val = REFimm;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- num = tobinary(val);
- val = tobinary(A);
-
- val += num + C;
- dCARRY(val);
- while (val >= 100)
- val -= 100;
-
- A = tobcd(val);
- } else {
- A += val + C;
- CARRY(A);
- A &= 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp == stmp) && (tmp != N);
- break;
-
- case 0x6A: /* ROR accumulator */
- tmp = C;
- C = A & 0x01;
- A = A >> 1;
- A |= tmp << 7;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x6B:
- break;
-
- case 0x6C: /* JMP indirect */
- ptmp = REFimm;
- ptmp |= REFimm << 8;
- Pc = mem[ptmp++];
- Pc |= mem[ptmp] << 8;
-
- if (jmp_tbl[Pc])
- jump(jmp_tbl[Pc]);
- break;
-
- case 0x6D: /* ADC absolute */
- ABSOL;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- num = tobinary(val);
- val = tobinary(A);
-
- val += num + C;
- dCARRY(val);
- while (val >= 100)
- val -= 100;
-
- A = tobcd(val);
- } else {
- A += val + C;
- CARRY(A);
- A &= 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp == stmp) && (tmp != N);
- break;
-
- case 0x6E: /* ROR absolute */
- ABSOL;
- val = REFptr;
- tmp = C;
- C = val & 0x01;
- val = val >> 1;
- val |= tmp << 7;
- SETptr(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x6F:
- break;
-
- case 0x70: /* BVS */
- if (V) {
- BRANCH();
- } else {
- PCINC;
- }
- break;
-
- case 0x71: /* ADC (indirect),Y */
- INDY;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- num = tobinary(val);
- val = tobinary(A);
-
- val += num + C;
- dCARRY(val);
- while (val >= 100)
- val -= 100;
-
- A = tobcd(val);
- } else {
- A += val + C;
- CARRY(A);
- A &= 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp == stmp) && (tmp != N);
- break;
-
- case 0x72: /* ADC (indz) 65C02 */
- break;
-
- case 0x73:
- break;
-
- case 0x74: /* STZ zero page, X 65C02 */
- break;
-
- case 0x75: /* ADC zero page, X */
- val = rZEROX;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- num = tobinary(val);
- val = tobinary(A);
-
- val += num + C;
- dCARRY(val);
- while (val >= 100)
- val -= 100;
-
- A = tobcd(val);
- } else {
- A += val + C;
- CARRY(A);
- A &= 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp == stmp) && (tmp != N);
- break;
-
- case 0x76: /* ROR zero page, X */
- ZEROX;
- val = REFzero;
- tmp = C;
- C = val & 0x01;
- val = val >> 1;
- val |= tmp << 7;
- SETzero(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x77:
- break;
-
- case 0x78: /* SEI */
- I = 1;
- break;
-
- case 0x79: /* ADC absolute, Y */
- ABSY;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- num = tobinary(val);
- val = tobinary(A);
-
- val += num + C;
- dCARRY(val);
- while (val >= 100)
- val -= 100;
-
- A = tobcd(val);
- } else {
- A += val + C;
- CARRY(A);
- A &= 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp == stmp) && (tmp != N);
- break;
-
- case 0x7A: /* PLY 65C02 */
- break;
-
- case 0x7B:
- break;
-
- case 0x7C: /* JMP (abs indirect, X) 65C02 */
- break;
-
- case 0x7D: /* ADC absolute, X */
- ABSX;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- num = tobinary(val);
- val = tobinary(A);
-
- val += num + C;
- dCARRY(val);
- while (val >= 100)
- val -= 100;
-
- A = tobcd(val);
- } else {
- A += val + C;
- CARRY(A);
- A &= 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp == stmp) && (tmp != N);
- break;
-
- case 0x7E: /* ROR absolute, X */
- ABSX;
- val = REFptr;
- tmp = C;
- C = val & 0x01;
- val = val >> 1;
- val |= tmp << 7;
- SETptr(val);
- SIGN(val);
- ZERO(val);
- break;
-
- case 0x7F:
- break;
-
- case 0x80: /* BRA 65C02 */
- break;
-
- case 0x81: /* STA (indirect, X) */
- INDX;
- SETptr(A);
- break;
-
- case 0x82:
- break;
-
- case 0x83:
- break;
-
- case 0x84: /* STY zero page */
- sZEROP(Y);
- break;
-
- case 0x85: /* STA zero page */
- sZEROP(A);
- break;
-
- case 0x86: /* STX zero page */
- sZEROP(X);
- break;
-
- case 0x87:
- break;
-
- case 0x88: /* DEY */
- Y--;
- SIGN(Y);
- ZERO(Y);
- break;
-
- case 0x89:
- break;
-
- case 0x8A: /* TXA */
- A = X;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x8B:
- break;
-
- case 0x8C: /* STY absolute */
- ABSOL;
- SETptr(Y);
- break;
-
- case 0x8D: /* STA absolute */
- ABSOL;
- SETptr(A);
- break;
-
- case 0x8E: /* STX absolute */
- ABSOL;
- SETptr(X);
- break;
-
- case 0x8F:
- break;
-
- case 0x90: /* BCC */
- if (C) {
- PCINC;
- } else {
- BRANCH();
- }
- break;
-
- case 0x91: /* STA (indirect), Y */
- INDY;
- SETptr(A);
- break;
-
- case 0x92:
- break;
-
- case 0x93:
- break;
-
- case 0x94: /* STY zero page, X */
- sZEROX(Y);
- break;
-
- case 0x95: /* STA zero page, X */
- sZEROX(A);
- break;
-
- case 0x96: /* STX zero page, Y */
- sZEROY(X);
- break;
-
- case 0x97:
- break;
-
- case 0x98: /* TYA */
- A = Y;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0x99: /* STA absolute, Y */
- ABSY;
- SETptr(A);
- break;
-
- case 0x9A: /* TXS */
- Sp = X;
- break;
-
- case 0x9B:
- break;
-
- case 0x9C: /* STZ absolute 65C02 */
- break;
-
- case 0x9D: /* STA absolute, X */
- ABSX;
- SETptr(A);
- break;
-
- case 0x9E: /* STZ absolute, X 65C02 */
- break;
-
- case 0x9F:
- break;
-
- case 0xA0: /* LDY immediate */
- Y = REFimm;
- SIGN(Y);
- ZERO(Y);
- break;
-
- case 0xA1: /* LDA (indirect, X) */
- INDX;
- A = REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0xA2: /* LDX immediate */
- X = REFimm;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xA3:
- break;
-
- case 0xA4: /* LDY zero page */
- Y = rZEROP;
- SIGN(Y);
- ZERO(Y);
- break;
-
- case 0xA5: /* LDA zero page */
- A = rZEROP;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0xA6: /* LDX zero page */
- X = rZEROP;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xA7:
- break;
-
- case 0xA8: /* TAY */
- Y = A;
- SIGN(Y);
- ZERO(Y);
- break;
-
- case 0xA9: /* LDA immediate */
- A = REFimm;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0xAA: /* TAX */
- X = A;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xAB:
- break;
-
- case 0xAC: /* LDY absolute */
- ABSOL;
- Y = REFptr;
- SIGN(Y);
- ZERO(Y);
- break;
-
- case 0xAD: /* LDA absolute */
- ABSOL;
- A = REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0xAE: /* LDX absolute */
- ABSOL;
- X = REFptr;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xAF:
- break;
-
- case 0xB0: /* BCS */
- if (C) {
- BRANCH();
- } else {
- PCINC;
- }
- break;
-
- case 0xB1: /* LDA (indirect), Y */
- INDY;
- A = REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0xB2: /* LDA (indz) 65C02 */
- break;
-
- case 0xB3:
- break;
-
- case 0xB4: /* LDY zero page, X */
- Y = rZEROX;
- SIGN(Y);
- ZERO(Y);
- break;
-
- case 0xB5: /* LDA zero page, X */
- A = rZEROX;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0xB6: /* LDX zero page, Y */
- X = rZEROY;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xB7:
- break;
-
- case 0xB8: /* CLV */
- V = 0;
- break;
-
- case 0xB9: /* LDA absolute, Y */
- ABSY;
- A = REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0xBA: /* TSX */
- X = Sp;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xBB:
- break;
-
- case 0xBC: /* LDY absolute, X */
- ABSX;
- Y = REFptr;
- SIGN(Y);
- ZERO(Y);
- break;
-
- case 0xBD: /* LDA absolute, X */
- ABSX;
- A = REFptr;
- SIGN(A);
- ZERO(A);
- break;
-
- case 0xBE: /* LDX absolute, Y */
- ABSY;
- X = REFptr;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xBF:
- break;
-
- case 0xC0: /* CPY immediate */
- tmp = REFimm;
- C = (Y >= tmp);
- tmp = (Y - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xC1: /* CMP (indirect, X) */
- INDX;
- tmp = REFptr;
- C = (A >= tmp);
- tmp = (A - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xC2:
- break;
-
- case 0xC3:
- break;
-
- case 0xC4: /* CPY zero page */
- tmp = rZEROP;
- C = (Y >= tmp);
- tmp = (Y - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xC5: /* CMP zero page */
- tmp = rZEROP;
- C = (A >= tmp);
- tmp = (A - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xC6: /* DEC zero page */
- ZEROP;
- stmp = REFzero - 1;
- SETzero(stmp);
- SIGN(stmp);
- ZERO(stmp);
- break;
-
- case 0xC7:
- break;
-
- case 0xC8: /* INY */
- Y++;
- SIGN(Y);
- ZERO(Y);
- break;
-
- case 0xC9: /* CMP immediate */
- tmp = REFimm;
- C = (A >= tmp);
- tmp = (A - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xCA: /* DEX */
- X--;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xCB:
- break;
-
- case 0xCC: /* CPY absolute */
- ABSOL;
- tmp = REFptr;
- C = (Y >= tmp);
- tmp = (Y - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xCD: /* CMP absolute */
- ABSOL;
- tmp = REFptr;
- C = (A >= tmp);
- tmp = (A - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xCE: /* DEC absolute */
- ABSOL;
- stmp = REFptr - 1;
- SETptr(stmp);
- SIGN(stmp);
- ZERO(stmp);
- break;
-
- case 0xCF:
- break;
-
- case 0xD0: /* BNE */
- if (NZ) {
- BRANCH();
- } else {
- PCINC;
- }
- break;
-
- case 0xD1: /* CMP (indirect), Y */
- INDY;
- tmp = REFptr;
- C = (A >= tmp);
- tmp = (A - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xD2: /* CMP (indz) 65C02 */
- break;
-
- case 0xD3:
- break;
-
- case 0xD4:
- break;
-
- case 0xD5: /* CMP zero page, X */
- tmp = rZEROX;
- C = (A >= tmp);
- tmp = (A - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xD6: /* DEC zero page, X */
- ZEROX;
- stmp = REFzero - 1;
- SETzero(stmp);
- SIGN(stmp);
- ZERO(stmp);
- break;
-
- case 0xD7:
- break;
-
- case 0xD8: /* CLD */
- D = 0;
- break;
-
- case 0xD9: /* CMP absolute, Y */
- ABSY;
- tmp = REFptr;
- C = (A >= tmp);
- tmp = (A - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xDA: /* PHX 65C02 */
- break;
-
- case 0xDB:
- break;
-
- case 0xDC:
- break;
-
- case 0xDD: /* CMP absolute, X */
- ABSX;
- tmp = REFptr;
- C = (A >= tmp);
- tmp = (A - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xDE: /* DEC absolute, X */
- ABSX;
- stmp = REFptr - 1;
- SETptr(stmp);
- SIGN(stmp);
- ZERO(stmp);
- break;
-
- case 0xDF:
- break;
-
- case 0xE0: /* CPX immediate */
- tmp = REFimm;
- C = (X >= tmp);
- tmp = (X - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xE1: /* SBC (indirect, X) */
- INDX;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- assert(FALSE);
- } else {
- foo = A - (val + !C);
- C = (foo >= 0);
- A = foo & 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp != stmp) && (tmp != N);
- break;
-
- case 0xE2:
- break;
-
- case 0xE3:
- break;
-
- case 0xE4: /* CPX zero page */
- tmp = rZEROP;
- C = (X >= tmp);
- tmp = (X - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xE5: /* SBC zero page */
- val = rZEROP;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- assert(FALSE);
- } else {
- foo = A - (val + !C);
- C = (foo >= 0);
- A = foo & 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp != stmp) && (tmp != N);
- break;
-
- case 0xE6: /* INC zero page */
- ZEROP;
- stmp = REFzero + 1;
- SIGN(stmp);
- ZERO(stmp);
- SETzero(stmp);
- break;
-
- case 0xE7:
- break;
-
- case 0xE8: /* INX */
- X++;
- SIGN(X);
- ZERO(X);
- break;
-
- case 0xE9: /* SBC immediate */
- val = REFimm;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- assert(FALSE);
- } else {
- foo = A - (val + !C);
- C = (foo >= 0);
- A = foo & 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp != stmp) && (tmp != N);
- break;
-
- case 0xEA: /* NOP */
- break;
-
- case 0xEB:
- break;
-
- case 0xEC: /* CPX absolute */
- ABSOL;
- tmp = REFptr;
- C = (X >= tmp);
- tmp = (X - tmp) & 0xFF;
- SIGN(tmp);
- ZERO(tmp);
- break;
-
- case 0xED: /* SBC absolute */
- ABSOL;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- assert(FALSE);
- } else {
- foo = A - (val + !C);
- C = (foo >= 0);
- A = foo & 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp != stmp) && (tmp != N);
- break;
-
- case 0xEE: /* INC absolute */
- ABSOL;
- stmp = REFptr + 1;
- SETptr(stmp);
- SIGN(stmp);
- ZERO(stmp);
- break;
-
- case 0xEF:
- break;
-
- case 0xF0: /* BEQ */
- if (NZ) {
- PCINC;
- } else {
- BRANCH();
- }
- break;
-
- case 0xF1: /* SBC (indirect), Y */
- INDY;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- assert(FALSE);
- } else {
- foo = A - (val + !C);
- C = (foo >= 0);
- A = foo & 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp != stmp) && (tmp != N);
- break;
-
- case 0xF2: /* SBC (indz) 65C02 */
- break;
-
- case 0xF3:
- break;
-
- case 0xF4:
- break;
-
- case 0xF5: /* SBC zero page, X */
- val = rZEROX;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- assert(FALSE);
- } else {
- foo = A - (val + !C);
- C = (foo >= 0);
- A = foo & 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp != stmp) && (tmp != N);
- break;
-
- case 0xF6: /* INC zero page, X */
- ZEROX;
- stmp = REFzero + 1;
- SETzero(stmp);
- SIGN(stmp);
- ZERO(stmp);
- break;
-
- case 0xF7:
- break;
-
- case 0xF8: /* SED */
- D = 1;
- break;
-
- case 0xF9: /* SBC absolute, Y */
- ABSY;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- assert(FALSE);
- } else {
- foo = A - (val + !C);
- C = (foo >= 0);
- A = foo & 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp != stmp) && (tmp != N);
- break;
-
- case 0xFA: /* PLX 65C02 */
- break;
-
- case 0xFB:
- break;
-
- case 0xFC:
- break;
-
- case 0xFD: /* SBC absolute, X */
- ABSX;
- val = REFptr;
- tmp = A & 0x80;
- stmp = val & 0x80;
- if (D) {
- assert(FALSE);
- } else {
- foo = A - (val + !C);
- C = (foo >= 0);
- A = foo & 0xFF;
- }
- ZERO(A);
- SIGN(A);
- V = (tmp != stmp) && (tmp != N);
- break;
-
- case 0xFE: /* INC absolute, X */
- ABSX;
- stmp = REFptr + 1;
- SETptr(stmp);
- SIGN(stmp);
- ZERO(stmp);
- break;
-
- case 0xFF:
- break;
- }
- } while (running);
-
- if (show_flags)
- flags(logging_fp);
- } while (tracing);
- }
-
-
- @EOF
-
- chmod 644 a2.c
-
- echo x - a2.h
- cat >a2.h <<'@EOF'
- /*
- * a2, an Apple II emulator in C
- * (c) Copyright 1990 by Rich Skrenta
- *
- * Command line interface written by Tom Markson
- *
- * Distribution agreement:
- *
- * You may freely copy or redistribute this software, so long
- * as there is no profit made from its use, sale, trade or
- * reproduction. You may not change this copyright notice,
- * and it must be included prominently in any copy made.
- *
- * Send emulator related mail to: skrenta@blekko.commodore.com
- * skrenta@blekko.uucp
- */
-
-
-
- #define TRUE 1
- #define FALSE 0
-
- extern FILE *sfp;
-
- /*
- * Assertion verifier
- */
- #define assert(p) if(! (p)) asfail(__FILE__, __LINE__, "p"); else
-
-
- #define join(low, high) ((low) | ((high) << 8))
- #define low(x) ((x) & 0xFF)
- #define high(x) ((x) >> 8)
-
- #define tobinary(v) ((v >> 4) * 10 + (v & 0xF))
- #define tobcd(v) ((v % 10) | ((v / 10) << 4))
-
- #define push(s) mem[0x100 | Sp--] = s;
- #define pop() mem[0x100 | ++Sp]
-
- #define SIGN(x) N = ((x) & 0x80)
- #define ZERO(x) NZ = (x)
- #define CARRY(x) C = ((x) > 0xFF)
- #define dCARRY(x) C = ((x) > 99)
-
-
- #define REF(a) ((a & 0xF000) == 0xC000 ? mem_map(a) : mem[a])
- #define REFptr ((ptr & 0xF000) == 0xC000 ? mem_map(ptr) : mem[ptr])
- #define REFzero mem[ptr]
- #define REFimm mem[Pc++]
-
- #define SET(a,v) if (mem_set[a >> 8]) (*mem_set[a >> 8])(a,v); else mem[a] = v;
- #define SETptr(v) if (mem_set[ptr >> 8]) (*mem_set[ptr >> 8])(ptr,v); else mem[ptr] = v;
- #define SETzero(v) mem[ptr] = v;
-
- #define PCINC Pc++;
-
- #define ABSOL ptr = mem[Pc++]; ptr |= mem[Pc++] << 8;
- #define ABSX ptr = mem[Pc++]; ptr |= mem[Pc++] << 8; ptr += X;
- #define ABSY ptr = mem[Pc++]; ptr |= mem[Pc++] << 8; ptr += Y;
- #define ZEROP ptr = mem[Pc++];
- #define ZEROX ptr = (mem[Pc++] + X) & 0xFF;
- #define ZEROY ptr = (mem[Pc++] + Y) & 0xFF;
- #define INDX stmp = mem[Pc++] + X; ptr = mem[stmp++]; ptr |= mem[stmp] << 8;
- #define INDY stmp = mem[Pc++]; ptr = mem[stmp++]; ptr |= mem[stmp] << 8; ptr += Y;
-
- #define rZEROP mem[ mem[Pc++] ]
- #define rZEROX mem[ (mem[Pc++] + X) & 0xFF ]
- #define rZEROY mem[ (mem[Pc++] + Y) & 0xFF ]
- #define sZEROP(v) mem[ mem[Pc++] ] = v;
- #define sZEROX(v) mem[ (mem[Pc++] + X) & 0xFF ] = v;
- #define sZEROY(v) mem[ (mem[Pc++] + Y) & 0xFF ] = v;
-
- #define ZIND ptr = mem[ mem[Pc++] ];
- #define ABINDX stmp = mem[Pc++]; stmp |= mem[Pc++] << 8; ptr = mem[stmp++]; ptr |= mem[stmp] << 8; ptr += X;
-
-
- /*
- * Since we store flags as 0/nonzero instead of 0/1, we need to turn
- * nonzero back into 1. Thus, "!!" is not a no-op.
- */
-
- #define get_status() ((!!N << 7)|(!!V << 6)|(!!B << 4)|(!!D << 3)|(!!I << 2)|(!NZ << 1)|(!!C))
-
- extern unsigned char mem[]; /* 64K memory image */
- extern unsigned char jmp_tbl[]; /* jmp & jsr interceptor functions */
- extern int (*mem_set[])(); /* memory store interceptors */
-
- extern unsigned char mem_map();
-
-
- extern unsigned short Pc;
- extern unsigned char Sp; /* stack pointer */
- extern unsigned int A; /* accumulator */
- extern unsigned char X; /* X register */
- extern unsigned char Y; /* Y register */
-
- extern unsigned int N; /* 7 - sign */
- extern unsigned int V; /* 6 - Overflow */
- /* 5 - Unused */
- extern unsigned int B; /* 4 - Break */
- extern unsigned int D; /* 3 - Decimal */
- extern unsigned int I; /* 2 - Interrupt */
- extern unsigned int NZ; /* 1 - inverse of Zero */
- extern unsigned int C; /* 0 - Carry */
-
-
- /*
- * Note:
- * Flags are stored as zero/nonzero instead of 0/1, except for
- * N which is stored 0/0x80. NZ is "not Z"; use !NZ to get
- * the zero flag.
- *
- * The flags code is tight, especially around overflow set on ADC
- * and SBC. Integer basic is a good test to see if it still works.
- */
-
-
- #define M_NONE 0
- #define M_ZP 1
- #define M_ZPX 2
- #define M_ZPY 3
- #define M_IND 4
- #define M_INDX 5
- #define M_INDY 6
- #define M_ABS 7
- #define M_ABSX 8
- #define M_ABSY 9
- #define M_IMM 10
- #define M_REL 11
- #define M_ZIND 12 /* zero page indirect, 65C02 */
- #define M_ABINDX 13 /* for jmp $7C in 65C02 */
-
-
- extern int ram_read;
- extern int ram_write;
- extern int bank2_enable;
-
- struct op_info {
- char *name;
- int add_mode;
- };
-
- extern struct op_info opcode[];
- extern int running;
- extern int tracing;
- extern char *my_malloc();
- extern int term_lines, term_cols;
-
- extern int text1[]; /* base addresses for text page 1 */
- extern int last_line; /* line the cursor is on now */
- extern int last_col; /* current column of cursor */
-
- extern int disk[2];
- extern int write_prot[2];
- extern int drive;
-
- #define DO_RTS Pc = pop(); Pc |= pop() << 8; Pc++;
-
- @EOF
-
- chmod 644 a2.h
-
- echo x - curses.c
- cat >curses.c <<'@EOF'
- /*
- * a2, an Apple II emulator in C
- * (c) Copyright 1990 by Rich Skrenta
- *
- * Command line interface written by Tom Markson
- *
- * Distribution agreement:
- *
- * You may freely copy or redistribute this software, so long
- * as there is no profit made from its use, sale, trade or
- * reproduction. You may not change this copyright notice,
- * and it must be included prominently in any copy made.
- *
- * Send emulator related mail to: skrenta@blekko.commodore.com
- * skrenta@blekko.uucp
- */
-
- /*
- ** This a screen management library borrowed with permission from the
- ** Elm mail system (a great mailer--I highly recommend it!).
- **
- ** I've hacked this library to only provide what I need.
- **
- ** Original copyright follows:
- */
- /*******************************************************************************
- * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
- *
- * Copyright (c) 1986 Dave Taylor
- ******************************************************************************/
-
- #ifndef M_XENIX
- #include <sys/termio.h>
- #endif
-
- #include <stdio.h>
- #include <curses.h>
- #include <ctype.h>
-
- #define DEFAULT_term_lines 24
- #define DEFAULT_COLUMNS 80
- #define TTYIN 0
-
-
- #define VERY_LONG_STRING 2500
-
- int term_lines = DEFAULT_term_lines - 1;
- int term_cols = DEFAULT_COLUMNS;
- extern char escape_char;
-
- #ifdef SHORTNAMES
- # define _cleartoeoln _clrtoeoln
- # define _cleartoeos _clr2eos
- #endif
-
- #ifndef BSD
- struct termio raw_tty,
- orig_tty;
- #else
- #define TCGETA TIOCGETP
- #define TCSETAW TIOCSETP
-
- struct sgttyb raw_tty,
- orig_tty;
- #endif
-
- static int inraw = 0; /* are we IN rawmode? */
-
-
- static int _memory_locked = 0; /* are we IN memlock?? */
-
- static int _intransmit; /* are we transmitting keys? */
-
- static
- char *_clearscreen, *_moveto, *_cleartoeoln, *_cleartoeos,
- *_setinverse, *_clearinverse;
-
-
- static
- int _lines,_columns;
-
- static char _terminal[1024]; /* Storage for terminal entry */
- static char _capabilities[1024]; /* String for cursor motion */
-
- static char *ptr = _capabilities; /* for buffering */
-
- int outchar(); /* char output for tputs */
- char *tgetstr(), /* Get termcap capability */
- *tgoto(); /* and the goto stuff */
-
- InitScreen()
- {
- int tgetent(), /* get termcap entry */
- err;
- char termname[40];
- char *strcpy(), *getenv();
-
- if (getenv("TERM") == NULL) {
- fprintf(stderr,
- "TERM variable not set; Screen capabilities required\n");
- return(FALSE);
- }
- if (strcpy(termname, getenv("TERM")) == NULL) {
- fprintf(stderr,"Can't get TERM variable\n");
- return(FALSE);
- }
- if ((err = tgetent(_terminal, termname)) != 1) {
- fprintf(stderr,"Can't get entry for TERM\n");
- return(FALSE);
- }
-
- /* load in all those pesky values */
- _clearscreen = tgetstr("cl", &ptr);
- _moveto = tgetstr("cm", &ptr);
- _cleartoeoln = tgetstr("ce", &ptr);
- _cleartoeos = tgetstr("cd", &ptr);
- _setinverse = tgetstr("so", &ptr);
- _clearinverse = tgetstr("se", &ptr);
- _lines = tgetnum("li");
- _columns = tgetnum("co");
-
- if (!_clearscreen) {
- fprintf(stderr,
- "Terminal must have clearscreen (cl) capability\n");
- return(FALSE);
- }
- if (!_moveto) {
- fprintf(stderr,
- "Terminal must have cursor motion (cm)\n");
- return(FALSE);
- }
- if (!_cleartoeoln) {
- fprintf(stderr,
- "Terminal must have clear to end-of-line (ce)\n");
- return(FALSE);
- }
- if (!_cleartoeos) {
- fprintf(stderr,
- "Terminal must have clear to end-of-screen (cd)\n");
- return(FALSE);
- }
- if (_lines == -1)
- _lines = DEFAULT_term_lines;
- if (_columns == -1)
- _columns = DEFAULT_COLUMNS;
- return(TRUE);
- }
-
- ScreenSize(lines, columns)
- int *lines, *columns;
- {
- /** returns the number of lines and columns on the display. **/
-
- if (_lines == 0) _lines = DEFAULT_term_lines;
- if (_columns == 0) _columns = DEFAULT_COLUMNS;
-
- *lines = _lines - 1; /* assume index from zero*/
- *columns = _columns; /* assume index from one */
- }
-
- ClearScreen()
- {
- /* clear the screen: returns -1 if not capable */
-
- tputs(_clearscreen, 1, outchar);
- fflush(stdout); /* clear the output buffer */
- }
-
- MoveCursor(row, col)
- int row, col;
- {
- /** move cursor to the specified row column on the screen.
- 0,0 is the top left! **/
-
- char *stuff, *tgoto();
-
- stuff = tgoto(_moveto, col, row);
- tputs(stuff, 1, outchar);
- /* fflush(stdout); */
- }
-
- CleartoEOLN()
- {
- /** clear to end of line **/
-
- tputs(_cleartoeoln, 1, outchar);
- fflush(stdout); /* clear the output buffer */
- }
-
- CleartoEOS()
- {
- /** clear to end of screen **/
-
- tputs(_cleartoeos, 1, outchar);
- fflush(stdout); /* clear the output buffer */
- }
-
- Raw(state)
- int state;
- {
- /** state is either TRUE or FALSE, as indicated by call **/
-
- if (state == FALSE && inraw) {
- (void) ioctl(TTYIN, TCSETAW, &orig_tty);
- inraw = 0;
- }
- else if (state == TRUE && ! inraw) {
-
- (void) ioctl(TTYIN, TCGETA, &orig_tty); /** current setting **/
-
- (void) ioctl(TTYIN, TCGETA, &raw_tty); /** again! **/
- #ifdef BSD
- /* raw_tty.sg_flags &= ~(ECHO | CRMOD); /* echo off */
- raw_tty.sg_flags &= ~ECHO; /* echo off */
- raw_tty.sg_flags |= CBREAK; /* raw on */
- #else
- raw_tty.c_lflag &= ~(ICANON | ECHO); /* noecho raw mode */
-
- raw_tty.c_cc[VMIN] = '\01'; /* minimum # of chars to queue */
- raw_tty.c_cc[VTIME] = '\0'; /* minimum time to wait for input */
-
- #endif
- raw_tty.c_cc[VINTR]= escape_char;
- (void) ioctl(TTYIN, TCSETAW, &raw_tty);
- inraw = 1;
- }
- }
-
- int
- ReadCh()
- {
- /** read a character with Raw mode set! **/
-
- register int result;
- char ch;
- result = read(0, &ch, 1);
- return((result <= 0 ) ? EOF : ch);
- }
-
-
- outchar(c)
- char c;
- {
- /** output the given character. From tputs... **/
- /** Note: this CANNOT be a macro! **/
-
- putc(c, stdout);
- }
-
-
- #if 0
- static int inverse = FALSE;
-
- SetInverse() {
-
- if (!inverse) {
- StartInverse();
- inverse = TRUE;
- }
- }
-
- SetNormal() {
-
- if (inverse) {
- EndInverse();
- inverse = FALSE;
- }
- }
- #endif
-
-
- StartInverse()
- {
- /** set inverse video mode **/
-
- if (!_setinverse)
- return(-1);
-
- tputs(_setinverse, 1, outchar);
- /* fflush(stdout); */
- return(0);
- }
-
-
- EndInverse()
- {
- /** compliment of startinverse **/
-
- if (!_clearinverse)
- return(-1);
-
- tputs(_clearinverse, 1, outchar);
- /* fflush(stdout); */
- return(0);
- }
-
- @EOF
-
- chmod 644 curses.c
-
- echo x - disk.c
- cat >disk.c <<'@EOF'
- /*
- * a2, an Apple II emulator in C
- * (c) Copyright 1990 by Rich Skrenta
- *
- * Command line interface written by Tom Markson
- *
- * Distribution agreement:
- *
- * You may freely copy or redistribute this software, so long
- * as there is no profit made from its use, sale, trade or
- * reproduction. You may not change this copyright notice,
- * and it must be included prominently in any copy made.
- *
- * Send emulator related mail to: skrenta@blekko.commodore.com
- * skrenta@blekko.uucp
- */
-
-
- #include <stdio.h>
- #include "a2.h"
-
-
- #define GAP 0x7F; /* data gap byte */
-
-
- /*
- * 4 by 4 nibble encoding macros
- */
-
- #define nib1(a) (((a) >> 1) | 0xAA)
- #define nib2(a) ((a) | 0xAA)
- #define denib(a,b) (((((a) & 0x55) << 1) & 0xFF) | ((b) & 0x55))
-
-
- int cur_track[2] = {0, 0};
- int sect_pos[2]; /* current sector within track */
-
- extern unsigned char tab1[]; /* For nibblizing. At end of this file */
- extern unsigned char tab2[]; /* Disk byte translation table. */
- extern unsigned char phys[]; /* DOS 3.3 to physical sector mapping */
-
- unsigned char sect_buf[2][1024];
- unsigned char *sectp = NULL;
- unsigned char *sect_point[2] = {NULL, NULL};
- unsigned char write_reg; /* write data register */
- int write_mode = FALSE;
-
-
-
- unsigned char
- disk_ref(a, n)
- unsigned short a;
- unsigned char n;
- {
-
- switch (a) {
- case 0xC0E0: /* Phase 0 off */
- case 0xC0E1: /* Phase 0 on */
- case 0xC0E2: /* Phase 1 off */
- case 0xC0E3: /* Phase 1 on */
- case 0xC0E4: /* Phase 2 off */
- case 0xC0E5: /* Phase 2 on */
- case 0xC0E6: /* Phase 3 off */
- case 0xC0E7: /* Phase 3 on */
- step_motor(a);
- break;
-
- case 0xC0E8: /* Drive off */
- break;
-
- case 0xC0E9: /* Drive on */
- break;
-
- case 0xC0EA: /* Select drive 1 */
- sect_point[drive] = sectp;
- drive = 0;
- sectp = sect_point[0];
- break;
-
- case 0xC0EB: /* Select drive 2 */
- sect_point[drive] = sectp;
- drive = 1;
- sectp = sect_point[1];
- break;
-
- case 0xC0EC: /* Shift data register */
- if (disk[drive] < 0)
- return(0xFF);
-
- if (write_mode) {
- raw_disk_write();
- return(0);
- }
-
- if (sectp == NULL || *sectp == '\0') {
- sect_pos[drive]--;
- if (sect_pos[drive] < 0)
- sect_pos[drive] = 15;
- setup_sector(cur_track[drive], sect_pos[drive]);
- }
-
- return(*sectp++);
-
- case 0xC0ED: /* Load data register */
- write_reg = n;
- break;
-
- case 0xC0EE: /* Read mode */
- write_mode = FALSE;
- return(write_prot[drive] ? 0xFF : 0);
- break;
-
- case 0xC0EF: /* Write mode */
- write_mode = TRUE;
- break;
- }
-
- return(0);
- }
-
-
-
- /*
- * Determine what track the disk head is over by watching toggles to
- * the four stepper motor magnets.
- */
-
- step_motor(a)
- unsigned short a;
- {
- static int mag[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}},
- pmag[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}}, /* previous */
- ppmag[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}}, /* previous previous */
- pnum[2] = {0, 0},
- ppnum[2] = {0, 0},
- track_pos[2] = {0, 0};
-
- static int prev_track[2] = {0, 0};
- int magnet_number;
-
- a &= 7;
- magnet_number = a >> 1;
-
- ppmag[drive][ppnum[drive]] = pmag[drive][ppnum[drive]];
- ppnum[drive] = pnum[drive];
-
- pmag[drive][pnum[drive]] = mag[drive][pnum[drive]];
- pnum[drive] = magnet_number;
-
- if ((a & 1) == 0)
- mag[drive][magnet_number] = FALSE;
- else {
- if (ppmag[drive][(magnet_number + 1) & 3]) {
- track_pos[drive]--;
- if (track_pos[drive] < 0) {
- track_pos[drive] = 0;
- if (drive)
- info("recal d2");
- else
- info("recal");
- }
- }
-
- if (ppmag[drive][(magnet_number - 1) & 3]) {
- track_pos[drive]++;
- if (track_pos[drive] > 140)
- track_pos[drive] = 140;
-
- }
- mag[drive][magnet_number] = TRUE;
- }
-
- cur_track[drive] = (track_pos[drive] + 1) / 2;
- if (cur_track[drive] != prev_track[drive]) {
- #if 0
- sprintf(s, "step to %d%s", cur_track[drive],
- drive ? " d2" : "");
- info(s);
- #endif
- sectp[drive] = NULL; /* recompute sector if head moves */
- sect_pos[drive] = 0;
- prev_track[drive] = cur_track[drive];
- }
- }
-
-
-
- setup_sector(track, sector)
- int track;
- int sector;
- {
- int checksum;
- int physical_sector;
- char s[50];
- int i;
-
- physical_sector = phys[sector];
-
- sprintf(s, "raw t=%d s=%d%s", track, sector, drive ? " d2" : "");
- info(s);
-
- sectp = sect_buf[drive];
-
- for (i = 0; i < 16; i++)
- *sectp++ = GAP;
-
- *sectp++ = 0xD5; /* address header */
- *sectp++ = 0xAA;
- *sectp++ = 0x96;
-
- *sectp++ = 0xFF; /* disk volume 254 */
- *sectp++ = 0xFE;
-
- *sectp++ = nib1(track);
- *sectp++ = nib2(track);
-
- *sectp++ = nib1(physical_sector);
- *sectp++ = nib2(physical_sector);
-
- checksum = 254 ^ track ^ physical_sector;
- *sectp++ = nib1(checksum);
- *sectp++ = nib2(checksum);
-
- *sectp++ = 0xDE; /* address trailer */
- *sectp++ = 0xAA;
-
- for (i = 0; i < 8; i++)
- *sectp++ = GAP;
-
- *sectp++ = 0xD5; /* data header */
- *sectp++ = 0xAA;
- *sectp++ = 0xAD;
-
- encode_data(track, sector); /* nibblized data */
-
- *sectp++ = 0xDE; /* data trailer */
- *sectp++ = 0xAA;
- *sectp++ = 0xEB;
-
- *sectp = '\0'; /* ending mark for our use */
- sectp = sect_buf[drive]; /* start reading at beginning */
- }
-
-
- /*
- * Take a normal 256 byte sector and nibblize it into 342 bytes
- * Checksum it with itself; this yields one more byte.
- * Translate the resulting 343 bytes into "disk bytes".
- * Insert them into the sector buffer.
- *
- * See a reference such as _Beneath Apple Prodos_ for an explanation
- * of why & how this is done.
- */
-
- encode_data(track, sector)
- int track;
- int sector;
- {
- unsigned char buf[344];
- unsigned char *one;
- unsigned char *bump;
- unsigned char *two;
- unsigned char *three;
- unsigned char *dest;
- int i;
-
- read_disk(track, sector, &buf[86]);
- buf[342] = 0;
- buf[343] = 0;
-
- dest = buf;
- one = &buf[86];
- two = &buf[86 + 0x56];
- bump = two;
- three = &buf[86 + 0xAC];
-
- do {
- i = (*one++ & 0x03) |
- ((*two++ & 0x03) << 2) | ((*three++ & 0x03) << 4);
-
- *dest++ = tab1[i];
- } while (one != bump);
-
- sectp[0] = buf[0];
- for (i = 1; i <= 342; i++)
- sectp[i] = buf[i - 1] ^ buf[i];
-
- for (i = 0; i <= 342; i++)
- sectp[i] = tab2[ sectp[i] >> 2 ];
-
- sectp = §p[343];
- }
-
-
- raw_disk_write() {
-
- printf("raw write %.2X\n", write_reg);
- }
-
-
- read_disk(track, sector, buf)
- int track;
- int sector;
- unsigned char *buf;
- {
- long block;
-
- block = track * 16 + sector;
-
- lseek(disk[drive], block * 256, 0);
- if (read(disk[drive], buf, 256) != 256)
- perror("bad read");
- }
-
-
- write_disk(track, sector, buf)
- int track;
- int sector;
- unsigned char *buf;
- {
- long block;
-
- block = track * 16 + sector;
-
- lseek(disk[drive], block * 256, 0);
- if (write(disk[drive], buf, 256) != 256)
- perror("bad write");
- }
-
-
- /*
- * Helps with the bit fiddling necessary to extract the bottom
- * two bits during the 256 - 342 byte nibblize.
- */
-
- unsigned char tab1[] = {
- 0x00, 0x08, 0x04, 0x0C, 0x20, 0x28, 0x24, 0x2C,
- 0x10, 0x18, 0x14, 0x1C, 0x30, 0x38, 0x34, 0x3C,
- 0x80, 0x88, 0x84, 0x8C, 0xA0, 0xA8, 0xA4, 0xAC,
- 0x90, 0x98, 0x94, 0x9C, 0xB0, 0xB8, 0xB4, 0xBC,
- 0x40, 0x48, 0x44, 0x4C, 0x60, 0x68, 0x64, 0x6C,
- 0x50, 0x58, 0x54, 0x5C, 0x70, 0x78, 0x74, 0x7C,
- 0xC0, 0xC8, 0xC4, 0xCC, 0xE0, 0xE8, 0xE4, 0xEC,
- 0xD0, 0xD8, 0xD4, 0xDC, 0xF0, 0xF8, 0xF4, 0xFC,
- };
-
-
- /*
- * Translates to "disk bytes"
- */
-
- unsigned char tab2[] = {
- 0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6,
- 0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3,
- 0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC,
- 0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3,
- 0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE,
- 0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC,
- 0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6,
- 0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
- };
-
-
- /*
- * Dos 3.3 to physical sector conversion
- */
-
- unsigned char phys[] = {
- 0x00, 0x0D, 0x0B, 0x09, 0x07, 0x05, 0x03, 0x01,
- 0x0E, 0x0C, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x0F,
- };
-
- @EOF
-
- chmod 644 disk.c
-
- echo x - tbl.c
- cat >tbl.c <<'@EOF'
- /*
- * a2, an Apple II emulator in C
- * (c) Copyright 1990 by Rich Skrenta
- *
- * Command line interface written by Tom Markson
- *
- * Distribution agreement:
- *
- * You may freely copy or redistribute this software, so long
- * as there is no profit made from its use, sale, trade or
- * reproduction. You may not change this copyright notice,
- * and it must be included prominently in any copy made.
- *
- * Send emulator related mail to: skrenta@blekko.commodore.com
- * skrenta@blekko.uucp
- */
-
-
- #include <stdio.h>
- #include "cli.h"
-
-
- int quit_emulator();
- int cont();
- int refresh();
- int clc(), sec(), sev(), clb(), seb();
- int clri(), sei(), sez(), clz(), sen(), cln(), sed(), cld(), clv();
- int ver();
- int shell_escape();
- int do_soft_reset();
- int do_bload();
- int do_bsave();
- int show_point();
- int do_jump();
- int ldx(), ldy(), lds(), lda();
- int trace();
- int set_break_point(), clear_break_point();
- int notrace();
- int insert_disk();
- int dissassemble();
- int hex_dump();
- int deposit();
- int phantom_trace();
- int no_phantom_trace();
- int cd();
- int map();
- int sex();
- int help();
- int set_escape_char();
- int hack();
- int init_point(), push_point(), dup_point(), pop_point();
- int disk_names();
-
- struct cmdtbl first_tbl[] = {
- {"!", shell_escape},
- {".", show_point},
- {"bload", do_bload},
- {"breakpoint", set_break_point},
- {"bsave", do_bsave},
- {"cd", cd},
- {"clc", clc},
- {"cld", cld},
- {"cli", clri},
- {"cln", cln},
- {"clv", clv},
- {"clz", clz},
- {"continue", refresh},
- {"deposit", deposit},
- {"disks", disk_names},
- {"dup", dup_point},
- {"escape", set_escape_char},
- {"examine", hex_dump},
- {".e", hex_dump},
- {"hack", hack},
- {"help", help},
- {"insert", insert_disk},
- {"jmp", do_jump},
- {"lda", lda},
- {"lds", lds},
- {"ldx", ldx},
- {"ldy", ldy},
- {"list", dissassemble},
- {"map", map},
- {"nobreak", clear_break_point},
- {"notrace", notrace},
- {"pop", pop_point},
- {"push", push_point},
- {"quit", quit_emulator},
- {"reset", do_soft_reset},
- {"sec", sec},
- {"sed", sed},
- {"sei", sei},
- {"sen", sen},
- {"sev", sev},
- {".sex", sex},
- {"sez", sez},
- {"trace", trace},
- {".version", ver},
- {".c", refresh},
- {".clb", clb},
- {".d", deposit},
- {".e", hex_dump},
- {".l", dissassemble},
- {".phantom", phantom_trace},
- {".seb", seb},
- {".nophantom", no_phantom_trace},
- {NULL, NULL},
- };
-
- @EOF
-
- chmod 644 tbl.c
-
- exit 0
- --
- skrenta@blekko.commodore.com
-