home *** CD-ROM | disk | FTP | other *** search
- Path: wuarchive!zaphod.mps.ohio-state.edu!mips!dimacs.rutgers.edu!aramis.rutgers.edu!remus.rutgers.edu!paul.rutgers.edu!jac
- From: jac@paul.rutgers.edu (Jonathan A. Chandross)
- Newsgroups: comp.sources.apple2
- Subject: v001SRC006: Apple ][ Simulator Part 3/3 (Koning Version)
- Message-ID: <Nov.18.20.59.54.1990.26281@paul.rutgers.edu>
- Date: 19 Nov 90 01:59:57 GMT
- Organization: Rutgers Univ., New Brunswick, N.J.
- Lines: 1224
- Approved: jac@paul.rutgers.edu
-
-
- Submitted-by: None
- Posting-number: Volume 1, Source:6
- Archive-name: unix/simulator/koning/part03
- Architecture: UNIX
- Version-number: 1.00
-
-
- =debug.c
- -#include "apple.h"
- -#include <curses.h>
- -
- -int DebugSingle;
- -int DebugTrace;
- -ADDR DebugBreak;
- -FILE *DebugFile;
- -
- -void htob (out, byte)
- -FILE *out;
- -BYTE byte;
- -{
- - register int i;
- -
- - for (i = 7; i >= 0; i--)
- - (void)fputc (byte & (1 << i) ? '1' : '0', out);
- -}
- -
- -void DebugDisasm (out)
- -FILE *out;
- -{
- - int opcode = MegaGetMem (PPC);
- - int n;
- - char * mne;
- -
- - switch (opcode)
- - {
- - case 0x69: /* ADC #dd */
- - mne = "ADC #$%2X"; n = 1;
- - break;
- - case 0x65: /* ADC aa */
- - mne = "ADC $%2X"; n = 1;
- - break;
- - case 0x75: /* ADC aa,X */
- - mne = "ADC $%2X,X"; n = 1;
- - break;
- - case 0x6d: /* ADC aaaa */
- - mne = "ADC $%4X"; n = 2;
- - break;
- - case 0x7d: /* ADC aaaa,X */
- - mne = "ADC $%4X,X"; n = 2;
- - break;
- - case 0x79: /* ADC aaaa,Y */
- - mne = "ADC $%4X,Y"; n = 2;
- - break;
- - case 0x61: /* ADC (aa,X) */
- - mne = "ADC $(%2X,X)"; n = 1;
- - break;
- - case 0x71: /* ADC (aa),Y */
- - mne = "ADC $(%2X),Y"; n = 1;
- - break;
- - case 0x29: /* AND #dd */
- - mne = "AND #$%2X"; n = 1;
- - break;
- - case 0x25: /* AND aa */
- - mne = "AND $%2X"; n = 1;
- - break;
- - case 0x35: /* AND aa,X */
- - mne = "AND $%2X,X"; n = 1;
- - break;
- - case 0x2d: /* AND aaaa */
- - mne = "AND $%4X"; n = 2;
- - break;
- - case 0x3d: /* AND aaaa,X */
- - mne = "AND $%4X,X"; n = 2;
- - break;
- - case 0x39: /* AND aaaa,Y */
- - mne = "AND $%4X,Y"; n = 2;
- - break;
- - case 0x21: /* AND (aa,X) */
- - mne = "AND $(%2X,X)"; n = 1;
- - break;
- - case 0x31: /* AND (aa),Y */
- - mne = "AND ($%2X),Y"; n = 1;
- - break;
- - case 0x0a: /* ASL A */
- - mne = "ASL A"; n = 0;
- - break;
- - case 0x06: /* ASL aa */
- - mne = "ASL $%2X"; n = 1;
- - break;
- - case 0x16: /* ASL aa,X */
- - mne = "ASL $%2X,X"; n = 1;
- - break;
- - case 0x0e: /* ASL aaaa */
- - mne = "ASL $%4X"; n = 2;
- - break;
- - case 0x1e: /* ASL aaaa,X */
- - mne = "ASL $%4X,X"; n = 2;
- - break;
- - case 0x90: /* BCC rr */
- - mne = "BCC $%2X"; n = -1;
- - break;
- - case 0xb0: /* BCS rr */
- - mne = "BCS $%2X"; n = -1;
- - break;
- - case 0xf0: /* BEQ rr */
- - mne = "BEQ $%2X"; n = -1;
- - break;
- - case 0x24: /* BIT aa */
- - mne = "BIT $%2X"; n = 1;
- - break;
- - case 0x2c: /* BIT aaaa */
- - mne = "BIT $%4X"; n = 2;
- - break;
- - case 0x30: /* BMI rr */
- - mne = "BMI $%2X"; n = -1;
- - break;
- - case 0xd0: /* BNE rr */
- - mne = "BNE $%2X"; n = -1;
- - break;
- - case 0x10: /* BPL rr */
- - mne = "BPL $%2X"; n = -1;
- - break;
- - case 0x00: /* BRK */
- - mne = "BRK"; n = 0;
- - break;
- - case 0x50: /* BVC rr */
- - mne = "BVC $%2X"; n = -1;
- - break;
- - case 0x70: /* BVS rr */
- - mne = "BVS $%2X"; n = -1;
- - break;
- - case 0x18: /* CLC */
- - mne = "CLC"; n = 0;
- - break;
- - case 0xd8: /* CLD */
- - mne = "CLD"; n = 0;
- - break;
- - case 0x58: /* CLI */
- - mne = "CLI"; n = 0;
- - break;
- - case 0xb8: /* CLV */
- - mne = "CLV"; n = 0;
- - break;
- - case 0xc9: /* CMP #dd */
- - mne = "CMP #$%2X"; n = 1;
- - break;
- - case 0xc5: /* CMP aa */
- - mne = "CMP $%2X"; n = 1;
- - break;
- - case 0xd5: /* CMP aa,X */
- - mne = "CMP $%2X,X"; n = 1;
- - break;
- - case 0xcd: /* CMP aaaa */
- - mne = "CMP $%4X"; n = 2;
- - break;
- - case 0xdd: /* CMP aaaa,X */
- - mne = "CMP $%4X,X"; n = 2;
- - break;
- - case 0xd9: /* CMP aaaa,Y */
- - mne = "CMP $%4X,Y"; n = 2;
- - break;
- - case 0xc1: /* CMP (aa,X) */
- - mne = "CMP $(%2X,X)"; n = 1;
- - break;
- - case 0xd1: /* CMP (aa),y */
- - mne = "CMP $(%2X),y"; n = 1;
- - break;
- - case 0xe0: /* CPX #dd */
- - mne = "CPX #$%2X"; n = 1;
- - break;
- - case 0xe4: /* CPX aa */
- - mne = "CPX $%2X"; n = 1;
- - break;
- - case 0xec: /* CPX aaaa */
- - mne = "CPX $%4X"; n = 2;
- - break;
- - case 0xc0: /* CPY #dd */
- - mne = "CPY #$%2X"; n = 1;
- - break;
- - case 0xc4: /* CPY aa */
- - mne = "CPY $%2X"; n = 1;
- - break;
- - case 0xcc: /* CPY aaaa */
- - mne = "CPY $%4X"; n = 2;
- - break;
- - case 0xc6: /* DEC aa */
- - mne = "DEC $%2X"; n = 1;
- - break;
- - case 0xd6: /* DEC aa,X */
- - mne = "DEC $%2X,X"; n = 1;
- - break;
- - case 0xce: /* DEC aaaa */
- - mne = "DEC $%4X"; n = 2;
- - break;
- - case 0xde: /* DEC aaaa,X */
- - mne = "DEC $%4X,X"; n = 2;
- - break;
- - case 0xca: /* DEX */
- - mne = "DEX"; n = 0;
- - break;
- - case 0x88: /* DEY */
- - mne = "DEY"; n = 0;
- - break;
- - case 0x49: /* EOR #dd */
- - mne = "EOR #$%2X"; n = 1;
- - break;
- - case 0x45: /* EOR aa */
- - mne = "EOR $%2X"; n = 1;
- - break;
- - case 0x55: /* EOR aa,X */
- - mne = "EOR $%2X,X"; n = 1;
- - break;
- - case 0x4d: /* EOR aaaa */
- - mne = "EOR $%4X"; n = 2;
- - break;
- - case 0x5d: /* EOR aaaa,X */
- - mne = "EOR $%4X,X"; n = 2;
- - break;
- - case 0x59: /* EOR aaaa,Y */
- - mne = "EOR $%4X,Y"; n = 2;
- - break;
- - case 0x41: /* EOR (aa,X) */
- - mne = "EOR ($%2X,X)"; n = 1;
- - break;
- - case 0x51: /* EOR (aa),Y */
- - mne = "EOR ($%2X),Y"; n = 1;
- - break;
- - case 0xe6: /* INC aa */
- - mne = "INC $%2X"; n = 1;
- - break;
- - case 0xf6: /* INC aa,X */
- - mne = "INC $%2X,X"; n = 1;
- - break;
- - case 0xee: /* INC aaaa */
- - mne = "INC $%4X"; n = 2;
- - break;
- - case 0xfe: /* INC aaaa,X */
- - mne = "INC $%4X,X"; n = 2;
- - break;
- - case 0xe8: /* INX */
- - mne = "INX"; n = 0;
- - break;
- - case 0xc8: /* INY */
- - mne = "INY"; n = 0;
- - break;
- - case 0x4c: /* JMP aaaa */
- - mne = "JMP $%4X"; n = 2;
- - break;
- - case 0x6c: /* JMP (aaaa) */
- - mne = "JMP ($%4X)"; n = 2;
- - break;
- - case 0x20: /* JSR aaaa */
- - mne = "JSR $%4X"; n = 2;
- - break;
- - case 0xa9: /* LDA #dd */
- - mne = "LDA #$%2X"; n = 1;
- - break;
- - case 0xa5: /* LDA aa */
- - mne = "LDA $%2X"; n = 1;
- - break;
- - case 0xb5: /* LDA aa,X */
- - mne = "LDA $%2X,X"; n = 1;
- - break;
- - case 0xad: /* LDA aaaa */
- - mne = "LDA $%4X"; n = 2;
- - break;
- - case 0xbd: /* LDA aaaa,X */
- - mne = "LDA $%4X,X"; n = 2;
- - break;
- - case 0xb9: /* LDA aaaa,Y */
- - mne = "LDA $%4X,Y"; n = 2;
- - break;
- - case 0xa1: /* LDA (aa,X) */
- - mne = "LDA ($%2X,X)"; n = 1;
- - break;
- - case 0xb1: /* LDA (aa),Y */
- - mne = "LDA ($%2X),Y"; n = 1;
- - break;
- - case 0xa2: /* LDX #dd */
- - mne = "LDX #$%2X"; n = 1;
- - break;
- - case 0xa6: /* LDX aa */
- - mne = "LDX $%2X"; n = 1;
- - break;
- - case 0xb6: /* LDX aa,Y */
- - mne = "LDX $%2X,Y"; n = 1;
- - break;
- - case 0xae: /* LDX aaaa */
- - mne = "LDX $%4X"; n = 2;
- - break;
- - case 0xbe: /* LDX aaaa,Y */
- - mne = "LDX $%4X,Y"; n = 2;
- - break;
- - case 0xa0: /* LDY #dd */
- - mne = "LDY #$%2X"; n = 1;
- - break;
- - case 0xa4: /* LDY aa */
- - mne = "LDY $%2X"; n = 1;
- - break;
- - case 0xb4: /* LDY aa,X */
- - mne = "LDY $%2X,X"; n = 1;
- - break;
- - case 0xac: /* LDY aaaa */
- - mne = "LDY $%4X"; n = 2;
- - break;
- - case 0xbc: /* LDY aaaa,X */
- - mne = "LDY $%4X,X"; n = 2;
- - break;
- - case 0x4a: /* LSR A */
- - mne = "LSR"; n = 0;
- - break;
- - case 0x46: /* LSR aa */
- - mne = "LSR $%2X"; n = 1;
- - break;
- - case 0x56: /* LSR aa,X */
- - mne = "LSR $%2X,X"; n = 1;
- - break;
- - case 0x4e: /* LSR aaaa */
- - mne = "LSR $%4X"; n = 2;
- - break;
- - case 0x5e: /* LSR aaaa,X */
- - mne = "LSR $%4X,X"; n = 2;
- - break;
- - case 0xea: /* NOP */
- - mne = "NOP"; n = 0;
- - break;
- - case 0x09: /* ORA #dd */
- - mne = "ORA #$%2X"; n = 1;
- - break;
- - case 0x05: /* ORA aa */
- - mne = "ORA $%2X"; n = 1;
- - break;
- - case 0x15: /* ORA aa,X */
- - mne = "ORA $%2X,X"; n = 1;
- - break;
- - case 0x0d: /* ORA aaaa */
- - mne = "ORA $%4X"; n = 2;
- - break;
- - case 0x1d: /* ORA aaaa,X */
- - mne = "ORA $%4X,X"; n = 2;
- - break;
- - case 0x19: /* ORA aaaa,Y */
- - mne = "ORA $%4X,Y"; n = 2;
- - break;
- - case 0x01: /* ORA (aa,X) */
- - mne = "ORA ($%2X,X)"; n = 1;
- - break;
- - case 0x11: /* ORA (aa),Y */
- - mne = "ORA ($%2X),Y"; n = 1;
- - break;
- - case 0x48: /* PHA */
- - mne = "PHA"; n = 0;
- - break;
- - case 0x08: /* PHP */
- - mne = "PHP"; n = 0;
- - break;
- - case 0x68: /* PLA */
- - mne = "PLA"; n = 0;
- - break;
- - case 0x28: /* PLP */
- - mne = "PLP"; n = 0;
- - break;
- - case 0x2a: /* ROL A */
- - mne = "ROL A"; n = 0;
- - break;
- - case 0x26: /* ROL aa */
- - mne = "ROL $%2X"; n = 1;
- - break;
- - case 0x36: /* ROL aa,X */
- - mne = "ROL $%2X,X"; n = 1;
- - break;
- - case 0x2e: /* ROL aaaa */
- - mne = "ROL $%4X"; n = 2;
- - break;
- - case 0x3e: /* ROL aaaa,X */
- - mne = "ROL $%4X,X"; n = 2;
- - break;
- - case 0x6a: /* ROR A */
- - mne = "ROR A"; n = 0;
- - break;
- - case 0x66: /* ROR aa */
- - mne = "ROR $%2X"; n = 1;
- - break;
- - case 0x76: /* ROR aa,X */
- - mne = "ROR $%2X,X"; n = 1;
- - break;
- - case 0x6e: /* ROR aaaa */
- - mne = "ROR $%4X"; n = 2;
- - break;
- - case 0x7e: /* ROR aaaa,X */
- - mne = "ROR $%4X,X"; n = 2;
- - break;
- - case 0x40: /* RTI */
- - mne = "RTI"; n = 0;
- - break;
- - case 0x60: /* RTS */
- - mne = "RTS"; n = 0;
- - break;
- - case 0xe9: /* SBC #dd */
- - mne = "SBC #$%2X"; n = 1;
- - break;
- - case 0xe5: /* SBC aa */
- - mne = "SBC $%2X"; n = 1;
- - break;
- - case 0xf5: /* SBC aa,x */
- - mne = "SBC $%2X,X"; n = 1;
- - break;
- - case 0xed: /* SBC aaaa */
- - mne = "SBC $%4X"; n = 2;
- - break;
- - case 0xfd: /* SBC aaaa,X */
- - mne = "SBC $%4X,X"; n = 2;
- - break;
- - case 0xf9: /* SBC aaaa,Y */
- - mne = "SBC $%4X,Y"; n = 2;
- - break;
- - case 0xe1: /* SBC (aa,X) */
- - mne = "SBC ($%2X,X)"; n = 1;
- - break;
- - case 0xf1: /* SBC (aa),Y */
- - mne = "SBC ($%2X),Y"; n = 1;
- - break;
- - case 0x38: /* SEC */
- - mne = "SEC"; n = 0;
- - break;
- - case 0xf8: /* SED */
- - mne = "SED"; n = 0;
- - break;
- - case 0x78: /* SEI */
- - mne = "SEI"; n = 0;
- - break;
- - case 0x85: /* STA aa */
- - mne = "STA $%2X"; n = 1;
- - break;
- - case 0x95: /* STA aa,X */
- - mne = "STA $%2X,X"; n = 1;
- - break;
- - case 0x8d: /* STA aaaa */
- - mne = "STA $%4X"; n = 2;
- - break;
- - case 0x9d: /* STA aaaa,X */
- - mne = "STA $%4X,X"; n = 2;
- - break;
- - case 0x99: /* STA aaaa,Y */
- - mne = "STA $%4X,Y"; n = 2;
- - break;
- - case 0x81: /* STA (aa,X) */
- - mne = "STA ($%2X,X)"; n = 1;
- - break;
- - case 0x91: /* STA (aa),Y */
- - mne = "STA ($%2X),Y"; n = 1;
- - break;
- - case 0x86: /* STX aa */
- - mne = "STX $%2X"; n = 1;
- - break;
- - case 0x96: /* STX aa,Y */
- - mne = "STX $%2X,Y"; n = 1;
- - break;
- - case 0x8e: /* STX aaaa */
- - mne = "STX $%4X"; n = 2;
- - break;
- - case 0x84: /* STY aa */
- - mne = "STY $%2X"; n = 1;
- - break;
- - case 0x94: /* STY aa,X */
- - mne = "STY $%2X,X"; n = 1;
- - break;
- - case 0x8c: /* STY aaaa */
- - mne = "STY $%4X"; n = 2;
- - break;
- - case 0xaa: /* TAX */
- - mne = "TAX"; n = 0;
- - break;
- - case 0xa8: /* TAY */
- - mne = "TAY"; n = 0;
- - break;
- - case 0xba: /* TSX */
- - mne = "TSX"; n = 0;
- - break;
- - case 0x8a: /* TXA */
- - mne = "TXA"; n = 0;
- - break;
- - case 0x9a: /* TXS */
- - mne = "TXS"; n = 0;
- - break;
- - case 0x98: /* TYA */
- - mne = "TYA"; n = 0;
- - break;
- - default: /* Undefined opcode */
- - mne = "UNDEFINED"; n = 0;
- - break;
- - }
- - (void)fprintf (out, "%4X: ", PPC);
- - switch (n)
- - {
- - case -1:
- - (void)fprintf (out, mne, PPC + (char)MegaGetMem (PPC + 1) + 2);
- - break;
- - case 0:
- - (void)fprintf (out, mne);
- - break;
- - case 1:
- - (void)fprintf (out, mne, MegaGetMem (PPC + 1));
- - break;
- - case 2:
- - (void)fprintf (out, mne, MegaGetMem (PPC + 1) + 256 * MegaGetMem (PPC + 2));
- - break;
- - }
- - (void)fputc ('\n', out);
- -}
- -
- -
- -
- -
- -void Debugger()
- -{
- - int done = 0;
- - FILE *out = stdout;
- - char buffer[255];
- -
- - echo();
- - noraw();
- - standend();
- - refresh();
- -
- - if (DebugTrace)
- - out = DebugFile;
- -
- - (void)fprintf (out, " A=%2X, Y=%2X, X=%2X, S=%2X, P=%%",A,Y,X,S);
- - htob (out, (BYTE)P);
- - (void)fprintf (out, " | ");
- - DebugDisasm (out);
- - if (!DebugTrace && !DebugSingle)
- - {
- - (void)printf ("\nApple ][+ Emulator Debugger\n");
- - }
- -
- - if (DebugTrace) goto traceout;
- -
- - while (!done)
- - {
- - (void)printf ("DBG> ");
- - (void)fflush (stdout);
- - (void)gets (buffer);
- -
- - switch (buffer[0])
- - {
- - case 'q':
- - DebugSingle = 0;
- - DebugTrace = 0;
- - MegaQuitDetect = 1;
- - done = 1;
- - break;
- - case 'l': /* load */
- - {
- - ADDR addr = 0x2000;
- - FILE *fp;
- - int ch;
- -
- - (void)printf ("Filename: ");
- - (void)fflush (stdout);
- - (void)gets (buffer);
- - fp = fopen (buffer, "r");
- - while ((ch = fgetc (fp)) != EOF)
- - MegaPutMem (addr++, (BYTE)ch);
- -
- - (void)printf ("%s: loaded at ,a$2000, l$%x\n", buffer, addr - 0x2000 - 1);
- - MegaQuitDetect = 0;
- - done = 0;
- - break;
- - }
- - case 't':
- - (void)printf ("Filename: ");
- - (void)fflush (stdout);
- - (void)gets (buffer);
- - DebugFile = fopen (buffer, "w");
- - DebugTrace = 1;
- - MegaQuitDetect = 0;
- - done = 0;
- - break;
- - case 'c':
- - DebugSingle = 0;
- - MegaQuitDetect = 0;
- - done = 1;
- - break;
- - case 's':
- - case '\0':
- - DebugSingle = 1;
- - DebugTrace = 0;
- - MegaQuitDetect = 0;
- - done = 1;
- - break;
- - default:
- - MegaQuitDetect = 0;
- - }
- - }
- -traceout:
- - raw();
- - noecho();
- -}
- -
- -
- =main.c
- -
- -/*
- - *main.c -- Globals and emulation setup for Apple ][ Emulator
- - *(C) 1989 Ben Koning [556498717 408/738-1763 ben@apple.com]
- - */
- -
- -#include "apple.h"
- -#include <curses.h>
- -#define REF_DELAY 2000
- -
- -main (argc,argv)
- -
- -int argc;
- -char *argv [];
- -
- -{
- - short int byte;
- - int i, addr; /* Loop iterators */
- - int refdelay = REF_DELAY;
- - FILE *fp;
- - char *D0FILE = "APPLESOFT.ROM",
- - *F8FILE = "AUTOSTART.ROM" ;
- -
- - /* Interpret args: 'invokename [-t] [-m] [-i]' */
- - for (i = 1; i <= argc-1; i++)
- - {
- - if (!strcmp (argv [i],"-t"))
- - DebugSingle = 1;
- - else
- - if (!strcmp (argv [i],"-m"))
- - F8FILE = "MONITOR.ROM";
- - else
- - if (!strcmp (argv [i],"-i"))
- - D0FILE = "INTEGER.ROM";
- - else
- - {
- - (void)fprintf (stderr,"Usage: %s [-t] [-m] [-i]\n",
- - argv [0]);
- - exit (1);
- - }
- - }
- -
- - /* Print banner message: */
- - (void)fprintf (stderr,"%s: Apple ][ Emulation - Ben Koning - v1.0\n",
- - argv [0]);
- -
- - (void)initscr();
- -
- - /*--------------------------------------------------*\
- - Load the 'ROM' with the appropriate 6502 code:
- - \*--------------------------------------------------*/
- - fp = fopen (D0FILE, "r");
- - for (addr = 0xd000; addr <= 0xf7ff; addr++)
- - Rom [addr - 0xd000] = fgetc (fp);
- - (void)fclose (fp);
- -
- - fp = fopen (F8FILE, "r");
- - for (addr = 0xf800; addr <= 0xffff; addr++)
- - Rom [addr - 0xd000] = fgetc (fp);
- - (void)fclose (fp);
- -
- - /*--------------------------------------------------*\
- - load prodos as $2000
- - \*--------------------------------------------------*/
- - fp = fopen ("PRODOS", "r");
- - addr = 0x2000;
- - while ((byte = fgetc (fp)) != EOF)
- - MMemory [addr++] = byte;
- - (void)fclose (fp);
- -
- - /* Make sure banner message is seen: */
- - sleep (2);
- -
- - /* Initialize the emulation: */
- - MegaStartUp ();
- - CPUReset ();
- -
- - /*--------------------------------------------------*\
- - Run it until user wants to quit:
- - \*--------------------------------------------------*/
- - while (!MegaQuitDetect)
- - {
- - CPUExecute ();
- - if (!(--refdelay))
- - {
- - refresh();
- - refdelay = REF_DELAY;
- - }
- - if (MegaQuitDetect || DebugSingle || DebugTrace)
- - Debugger();
- - }
- -
- - /* Exit cleanly: */
- - MegaShutDown ();
- - exit (0);
- -}
- -
- -
- -
- =mega2.c
- -/*
- - *mega2.c -- Apple ][ soft switches->UNIX emulation for Apple ][ Emulator
- - *(C) 1989 Ben Koning [556498717 408/738-1763 ben@apple.com]
- - */
- -
- -#include "apple.h"
- -#include <curses.h>
- -
- -
- -/*
- - * Termcap globals:
- - */
- -
- -
- -/*
- - * Emulation globals:
- - */
- -
- -BYTE MMemory [49152]; /* Main memory */
- -BYTE Rom [12288]; /* 12K ROM bank of Main memory */
- -BYTE MRam [12288]; /* 12K RAM bank of Main memory */
- -BYTE MRam1 [4096]; /* Main bank 1 $D000-$DFFF */
- -BYTE MRam2 [4096]; /* Main bank 2 $D000-$DFFF */
- -BYTE RamRead = 0; /* set if 16K RAM readable */
- -BYTE RamWrite = 0; /* set if 16K RAM writeable */
- -BYTE Bank2Enable = 0; /* set if bank 2 Ram enabled */
- -
- -BYTE MegaRand = 0; /* Always contains 8-bit random number */
- -BYTE MegaLastKey = 0; /* $C00X keyboard latch value */
- -BYTE MegaQuitDetect = 0; /* Set if user requests to quit */
- -
- -void PutC010();
- -void Put0400();
- -void GetC080();
- -BYTE GetC000();
- -BYTE GetC010();
- -BYTE GetC030();
- -
- -void ProInit();
- -void ProFormat();
- -void ProRead();
- -void ProWrite();
- -void ProStatus();
- -
- -/*
- - * Base address table for 24 lines of text/lores page 1 ($400..$7F8);
- - * 40 bytes for each line. Note that screen "holes" exist:
- - */
- -
- -int LBasCalc [24] =
- -
- -{
- -1024,
- -1152,
- -1280,
- -1408,
- -1536,
- -1664,
- -1792,
- -1920,
- -1064,
- -1192,
- -1320,
- -1448,
- -1576,
- -1704,
- -1832,
- -1960,
- -1104,
- -1232,
- -1360,
- -1488,
- -1616,
- -1744,
- -1872,
- -2000
- -};
- -
- -#define MegaPutChar(c) addch(c)
- -
- -/**************************************************************************/
- -/* Dispatch routines: The MegaPutMem and MegaGetMem, below, have default */
- -/* behavior for I/O space. They may also contain calls to other routines */
- -/* in this file which handle Apple II behavior. If these latter routines */
- -/* need initialization/shutdown, that code should be placed in the two */
- -/* MegaStartUp and MegaShutDown routines, below. */
- -/**************************************************************************/
- -
- -#ifdef NEVER
- -void MegaPutChar (c)
- -char c; /* This makes a function out of the "putchar" macro */
- -
- -{
- - addch (c);
- -}
- -#endif
- -
- -/* This routine is called at emulation startup time. All initialization
- - stuff, like setting terminal modes, opening files, etc. goes here. */
- -void MegaStartUp ()
- -{
- - register int i; /* Iterator */
- -
- - /* init the pseudo disk */
- - ProInit();
- -
- - /* Set input modes on terminal: */
- - noecho();
- - raw();
- -
- - /* Fill 40-column screen with simulated initial memory pattern: */
- - clear();
- - for (i = 0; i <= 23; i++)
- - mvaddstr (i, 0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
- -
- - refresh();
- -
- - /* Initialize some variables: */
- - MegaQuitDetect = 0;
- - MegaLastKey = 0;
- - MegaRand = 0;
- -}
- -
- -
- -
- -/* This routine is called at emulation shutdown time. All things
- - started in MegaStartUp, above, should be cleaned up here. */
- -void MegaShutDown ()
- -{
- - /* Clear screen: */
- - clear();
- - refresh();
- -
- - /* Reset sane modes on terminal: */
- - echo();
- - noraw();
- - endwin();
- -}
- -
- -/* This routine handles ALL stores to the 64K address space, in order to
- - faciliate special Apple ][ - specific effects. Not all behaviors may
- - be implemented; to install a new one, install the call in this routine.
- - Returns: Nothing. */
- -void MegaPutMem (addr, byte)
- -register ADDR addr;
- -register BYTE byte;
- -{
- - /* Make sure these are in range: */
- - addr &= 0xffff;
- - byte &= 0xff;
- -
- - /* Do random number generation: */
- - MegaRand = (MegaRand + addr + byte) & 0xff;
- -
- - /* If in ROM, we are done here: */
- - if (addr >= 0xd000 && !RamWrite)
- - {
- -/* Rom[addr - 0xd000] = byte; */
- - return;
- - }
- -
- - if (addr < 0xc000) /* Main memory */
- - MMemory [addr] = byte;
- - else if (addr >= 0xd000 && addr < 0xe000) /* 4K RAM Banks */
- - {
- - BYTE *bank = Bank2Enable ? MRam2 : MRam1;
- -
- - bank [addr - 0xd000] = byte;
- - }
- - else if (addr >= 0xe000) /* 8K RAM Bank */
- - MRam [addr - 0xe000] = byte;
- - else if ((addr >= 0xc010) && (addr <= 0xc01f)) /* soft switches */
- - PutC010 (0);
- - else if (addr >= 0xc080 && addr < 0xc090)
- - GetC080 (addr);
- -
- - /* Now do the appropriate memory-mapped OUTPUT functions, if any: */
- - if ((addr >= 0x0400) && (addr < 0x0800))
- - Put0400 (addr, byte);
- -}
- -
- -
- -/* This routine handles ALL fetches from the 64K address space, in order to
- - facilitate special Apple ][ - specific effects. Not all behaviors may
- - be implemented; to install a new one, install the call in this routine.
- - Returns: Value at location (could be random if I/O, etc.). */
- -BYTE MegaGetMem (addr)
- -register ADDR addr;
- -{
- - register BYTE data; /* Data from memory space to be returned */
- -
- - /* Make sure we're in range: */
- - addr &= 0xffff;
- -
- - /* If we're just in ROM or RAM, it's easy: */
- - if (addr < 0xc000)
- - return (MMemory [addr]);
- - else if (addr >= 0xd000 && !RamRead) /* rom read enabled */
- - return (Rom[addr - 0xd000]);
- - else if (addr >= 0xe000) /* 8K RAM read */
- - return (MRam[addr - 0xe000]);
- - else if (addr >= 0xd000 && addr < 0xe000) /* 4K Bank RAM */
- - return (Bank2Enable ? MRam2[addr - 0xd000] : MRam1[addr - 0xd000]);
- -
- -
- - /* We must be in C000 space. Default to random value: */
- - data = MegaRand & 0xff;
- - MegaRand = (MegaRand + addr * 25 + data) & 0xff;
- -
- - /* Now do the appropriate memory-mapped INPUT functions, if any: */
- - if ((addr >= 0xc000) && (addr <= 0xc00f))
- - data = GetC000 ();
- - else if ((addr >= 0xc010) && (addr <= 0xc01f))
- - data = GetC010 ();
- - else if ((addr >= 0xc030) && (addr <= 0xc03f))
- - data = GetC030 ();
- - else if ((addr >= 0xc080) && (addr <= 0xc08f))
- - GetC080 (addr);
- - else if (addr == 0xc011)
- - data = 0xFF * Bank2Enable;
- - else if (addr == 0xc012)
- - data = 0xFF * RamRead;
- - else if (addr == 0xc701)
- - data = 0x20;
- - else if (addr == 0xc703)
- - data = 0x00;
- - else if (addr == 0xc705)
- - data = 0x03;
- - else if (addr == 0xc7ff)
- - data = 0x80;
- - else if (addr == 0xc7fe)
- - data = 0x1f;
- - else if (addr == 0xc7fc)
- - data = 0x00;
- - else if (addr == 0xc7fd)
- - data = 0x00;
- - else if (addr == 0xc780)
- - data = 0x60;
- -
- - /* Return the data we came up with to the user: */
- - return (BYTE) (data & 0xff);
- -}
- -
- -
- -
- -
- -
- -/**************************************************************************/
- -/* Memory-Mapped I/O routines: These routines actually perform the spe- */
- -/* cific UNIX operations for get/put to certain addresses. Not all Get */
- -/* or Put routines must necessarily have a companion Put or Get routine: */
- -/* */
- -/* * GetXXXXXX: Return a byte of data from an I/O address */
- -/* * PutXXXXXX: Receive a byte of data for an I/O address */
- -/* */
- -/**************************************************************************/
- -
- -
- -
- -
- -
- -/* Get keyboard data in low 7 bits. Msb indicates if hit since last C010: */
- -BYTE GetC000 ()
- -{
- - register int fflags;
- - char data = '*';
- -
- - /* Set nonblocking input: */
- - fflags = fcntl (0, F_GETFL, 0);
- - (void)fcntl (0, F_SETFL, fflags | O_NDELAY);
- -
- - /* See if a key was pressed. If yes, update and set hi bit; */
- - /* else, leave keyboard latch with last value: */
- - if (read (0, &data, 1) > 0)
- - MegaLastKey = (int) data | 0x80;
- -
- - /* Reset nonblocking input: */
- - (void)fcntl (0, F_SETFL, fflags);
- -
- - /* See if user wants to quit: */
- - MegaQuitDetect = (data == MEGAQUITKEY);
- -
- - return (BYTE)MegaLastKey;
- -}
- -
- -
- -
- -
- -
- -/* Clear keyboard strobe for C000 msb: */
- -BYTE GetC010 ()
- -{
- - MegaLastKey &= 0x7f; /* Clear strobe bit */
- - return (BYTE)(MegaRand & 0xff);
- -}
- -
- -void GetC080 (addr)
- -ADDR addr;
- -{
- - switch (addr & 0x000F)
- - {
- - case 0x00:
- - RamRead = 1;
- - RamWrite = 0;
- - Bank2Enable = 1;
- - break;
- - case 0x01:
- - RamRead = 0;
- - RamWrite = 1;
- - Bank2Enable = 1;
- - break;
- - case 0x02:
- - RamRead = 0;
- - RamWrite = 0;
- - Bank2Enable = 1;
- - break;
- - case 0x03:
- - RamRead = 1;
- - RamWrite = 1;
- - Bank2Enable = 1;
- - break;
- - case 0x08:
- - RamRead = 1;
- - RamWrite = 0;
- - Bank2Enable = 0;
- - break;
- - case 0x09:
- - RamRead = 0;
- - RamWrite = 1;
- - Bank2Enable = 0;
- - break;
- - case 0x0a:
- - RamRead = 0;
- - RamWrite = 0;
- - Bank2Enable = 0;
- - break;
- - case 0x0b:
- - RamRead = 1;
- - RamWrite = 1;
- - Bank2Enable = 0;
- - break;
- - }
- -}
- -
- -/*ARGSUSED*/
- -void PutC010 (data)
- -BYTE data;
- -{
- - (void)GetC010 (); /* Same thing; either one works */
- -}
- -
- -
- -
- -/* Beeps speaker if accessed a lot: */
- -BYTE GetC030 ()
- -{
- - static int count = 0;
- -
- - if (count++ >= 100)
- - {
- - count = 0;
- - /* tputs (TcapBeep,1,MegaPutChar); */
- - /* putchar (7); */
- - /* fflush (stdout); */
- - }
- - return (BYTE)(MegaRand & 0xff);
- -}
- -
- -
- -/* Handles stores to text/lowres page 1 memory */
- -void Put0400 (addr,data)
- -register ADDR addr;
- - BYTE data;
- -{
- - register int linenum; /* Searching for Y-coordinate */
- - register int columnnum; /* Searching for X-coordinate */
- - int screenhole = 1; /* Are we in screen hole? */
- -
- - /* Find which line the given address is in: */
- - for (linenum = 0; linenum <= 23; linenum++)
- - if ( (addr >= LBasCalc [linenum]) &&
- - (addr <= (LBasCalc [linenum] + 39)) )
- - {
- - columnnum = addr - LBasCalc [linenum];
- - screenhole = 0;
- - break;
- - }
- -
- - /* If not on screen, don't draw anything: */
- - if (screenhole)
- - return;
- -
- - /* Put the terminal cursor at the right location on the screen: */
- - /* We assume 80x24 terminal; no need to avoid drawing on last char. */
- - move (linenum, columnnum);
- -
- - /*
- - Set terminal into appropriate output mode and do it:
- - tputs (TcapInverse,1,MegaPutChar);
- - */
- - if (data < 64)
- - {
- - /* attron (A_STANDOUT); */
- - standout();
- - if (data < 32)
- - data += 64;
- - }
- - else if ((data < 128) && (data > 63))
- - {
- - standout();
- - if (data > 95)
- - data -= 64;
- - }
- - else
- - data = data & 127;
- - if (!iscntrl ((char) data))
- - MegaPutChar ((char) data);
- - else
- - MegaPutChar ((char) (data - 64));
- - standend();
- -}
- -
- -#define _setN_(b) if ((b)!=0) P |= 128; else P &= 0x7f
- -#define _setV_(b) if ((b)!=0) P |= 64; else P &= 0xbf
- - /* This bit not implemented */
- -#define _setB_(b) if ((b)!=0) P |= 16; else P &= 0xef
- -#define _setD_(b) if ((b)!=0) P |= 8; else P &= 0xf7
- -#define _setI_(b) if ((b)!=0) P |= 4; else P &= 0xfb
- -#define _setZ_(b) if ((b)!=0) P |= 2; else P &= 0xfd
- -#define _setC_(b) if ((b)!=0) P |= 1; else P &= 0xfe
- -
- -static unsigned char buffer[512];
- -FILE *disk1, /* slot 7, drive 1 280 block 5.25 floppy */
- - *disk2; /* slot 7, drive 2 1024 blocks "hard disk" */
- -
- -#define NBLOCKSD1 280
- -#define NBLOCKSD2 1024
- -
- -void ProInit ()
- -{
- - MegaPutMem (0x0043, (BYTE)0x70); /* boot disk */
- - disk1 = fopen ("PRODOS.IMAGE.D1", "r+");
- - disk2 = fopen ("PRODOS.IMAGE.D2", "r+");
- -}
- -
- -void ProFormat (drive)
- -int drive;
- -{
- - int numblocks = drive ? NBLOCKSD2 : NBLOCKSD1;
- - FILE *disk = drive ? disk2 : disk1;
- -
- - (void)fseek (disk, (long)(512 * numblocks), 0);
- - (void)fwrite (" ", 1, 1, disk);
- -}
- -
- -void ProRead (drive)
- -int drive;
- -{
- - register int i;
- - int block = MegaGetMem (0x46) + MegaGetMem (0x47) * 0x0100;
- - int buf = MegaGetMem (0x44) + MegaGetMem (0x45) * 0x0100;
- - FILE *disk = drive ? disk2 : disk1;
- -
- - (void)fseek (disk, (long)(block * 512), 0);
- -
- - (void)fread ((char *)buffer, 1, 512, disk);
- - for (i = 0; i < 512; i++)
- - MegaPutMem (buf + i, (BYTE)buffer[i]);
- - _setC_(0); /* CLC */
- - A = 0;
- -}
- -
- -void ProWrite (drive)
- -int drive;
- -{
- - register int i;
- - int block = MegaGetMem (0x46) + MegaGetMem (0x47) * 0x0100;
- - int buf = MegaGetMem (0x44) + MegaGetMem (0x45) * 0x0100;
- - FILE *disk = drive ? disk2 : disk1;
- -
- - (void)fseek (disk, (long)(block * 512), 0);
- -
- - for (i = 0; i < 512; i++)
- - buffer[i] = MegaGetMem (buf + i);
- -
- - (void)fwrite ((char *)buffer, 1, 512, disk);
- - _setC_(0); /* CLC */
- - A = 0;
- -}
- -
- -void ProStatus (drive)
- -int drive;
- -{
- - int numblocks = drive ? NBLOCKSD2 : NBLOCKSD1;
- -
- - _setC_(0); /* CLC */
- - A = 0; /* LDA #0 */
- - Y = numblocks / 256;
- - X = numblocks % 256;
- -}
- -
- -void prodos()
- -{
- - int drive = ((MegaGetMem (0x43) >= 128) ? 1 : 0);
- -
- - switch (MegaGetMem (0x42))
- - {
- - case 0:
- - ProStatus (drive); break;
- - case 1:
- - ProRead (drive); break;
- - case 2:
- - ProWrite (drive); break;
- - case 3:
- - ProFormat (drive); break;
- - }
- -}
- -
- -
- + END OF ARCHIVE
-