#include #ifndef _WIN32 #include #include "../perfect6502.h" /************************************************************ * * Interface to OS Library Code / Monitor * ************************************************************/ /* imported by runtime.c */ unsigned char A, X, Y, S, P; unsigned short PC; int N, Z, C; void init_monitor() { FILE *f; f = fopen("apple1basic.bin", "r"); fread(memory + 0xE000, 1, 4096, f); fclose(f); memory[0xfffc] = 0x00; memory[0xfffd] = 0xE0; } void charout(char ch) { unsigned char S = readSP(); unsigned short a = 1 + memory[0x0100+S+1] | memory[0x0100+((S+2) & 0xFF)] << 8; /* * Apple I BASIC prints every character received * from the terminal. UNIX terminals do this * anyway, so we have to avoid printing every * line again */ if (a==0xe2a6) /* character echo */ return; if (a==0xe2b6) /* CR echo */ return; /* * Apple I BASIC prints a line break and 6 spaces * after every 37 characters. UNIX terminals do * line breaks themselves, so ignore these * characters */ if (a==0xe025 && (ch==10 || ch==' ')) return; /* INPUT */ if (a==0xe182) { #if _WIN32 if (!isatty(0)) return; #else struct stat st; fstat(0, &st); if (S_ISFIFO (st.st_mode)) return; #endif } #endif putc(ch, stdout); fflush(stdout); } void handle_monitor() { if (readRW()) { unsigned short a = readAddressBus(); if ((a & 0xFF1F) == 0xD010) { unsigned char c = getchar(); if (c == 10) c = 13; c |= 0x80; writeDataBus(c); } if ((a & 0xFF1F) == 0xD011) { if (readPC() == 0xE006) /* if the code is reading a character, we have one ready */ writeDataBus(0x80); else /* if the code checks for a STOP condition, nothing is pressed */ writeDataBus(0); } if ((a & 0xFF1F) == 0xD012) { /* 0x80 would mean we're not yet ready to receive a character */ writeDataBus(0); } } else { unsigned short a = readAddressBus(); unsigned char d = readDataBus(); if ((a & 0xFF1F) == 0xD012) { unsigned char temp8 = d & 0x7F; if (temp8 == 13) temp8 = 10; charout(temp8); } } } int main() { int clk = 0; initAndResetChip(); /* set up memory for user program */ init_monitor(); /* emulate the 6502! */ for (;;) { step(); clk = !clk; if (!clk) handle_monitor(); chipStatus(); //if (!(cycle % 1000)) printf("%d\n", cycle); }; }