jac@paul.rutgers.edu (Jonathan A. Chandross) (11/19/90)
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