From a86f9e23d3a4ba77aa35c615059bf9801fb2c849 Mon Sep 17 00:00:00 2001 From: Benjamin Jones Date: Tue, 3 Sep 2019 23:25:58 -0700 Subject: [PATCH] Cross platform --- cpu.c | 15 +++++-- emulate.c | 129 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 98 insertions(+), 46 deletions(-) diff --git a/cpu.c b/cpu.c index d68ebed..2dc09cf 100644 --- a/cpu.c +++ b/cpu.c @@ -11,10 +11,19 @@ #include #include #include -#include -#include +#include #include "cpu.h" +#ifdef _WIN32 + +#include + +#else + +#include + +#endif + unsigned char CROSSED_PAGE; unsigned char different_page(uint16_t address1, uint16_t address2){ @@ -1635,7 +1644,7 @@ void execute_6502(CPU_6502 *cpu, uint8_t (*read)(uint16_t), void (*write)(uint16 cpu->cycles += 2; //Unknown operation } else { - printf("Error: Unknown operation 0x%x\n", (int) opcode); + printw("Error: Unknown operation 0x%x\n", (int) opcode); exit(1); } } diff --git a/emulate.c b/emulate.c index bf8e9ca..f704983 100644 --- a/emulate.c +++ b/emulate.c @@ -1,10 +1,27 @@ #include #include #include -#include -#include +#include #include "cpu.h" +#ifdef _WIN32 + +#include + +#else + +#include + +void Sleep(long int msec){ + struct timespec sleep_time; + + sleep_time.tv_sec = msec/1000; + sleep_time.tv_nsec = (msec%1000)*1000000; + nanosleep(&sleep_time, NULL); +} + +#endif + unsigned char DEBUG_STEP = 0; uint8_t memory[0x10000]; @@ -26,19 +43,19 @@ unsigned char tape_reading; unsigned char current_tape_value; void print_state(CPU_6502 cpu){ - printf("A: %02x X:%02x Y:%02x SP:%02x P:%02x PC:%02x\n", (int) cpu.A_reg, (int) cpu.X_reg, (int) cpu.Y_reg, (int) cpu.SP_reg, (int) cpu.P_reg, (int) cpu.PC_reg); - printf("\nNext: %02x %02x %02x\n", (int) memory[cpu.PC_reg], (int) memory[cpu.PC_reg + 1], (int) memory[cpu.PC_reg + 2]); + printw("A: %02x X:%02x Y:%02x SP:%02x P:%02x PC:%02x\n", (int) cpu.A_reg, (int) cpu.X_reg, (int) cpu.Y_reg, (int) cpu.SP_reg, (int) cpu.P_reg, (int) cpu.PC_reg); + printw("\nNext: %02x %02x %02x\n", (int) memory[cpu.PC_reg], (int) memory[cpu.PC_reg + 1], (int) memory[cpu.PC_reg + 2]); } void load_tape(char *file_name){ FILE *fp; fp = fopen(file_name, "rb"); - printf("Reading from tape file named \"%s\"\n", file_name); + printw("Reading from tape file named \"%s\"\n", file_name); if(fp){ fread(tape, 4, 0x100000, fp); fclose(fp); } else { - printf("file error\n"); + printw("file error\n"); } return; @@ -46,13 +63,13 @@ void load_tape(char *file_name){ void store_tape(char *file_name){ FILE *fp; - printf("Storing tape to file named \"%s\"\n", file_name); + printw("Storing tape to file named \"%s\"\n", file_name); fp = fopen(file_name, "wb"); if(fp){ fwrite(tape, 4, 0x100000, fp); fclose(fp); } else { - printf("file error\n"); + printw("file error\n"); } } @@ -61,7 +78,7 @@ uint8_t read_mem(uint16_t index){ uint8_t output; if(DEBUG_STEP){ - printf("READ: %04x ", index); + printw("READ: %04x ", index); } if(tape_writing && index >= 0xC000 && index <= 0xC0FF){ @@ -82,7 +99,7 @@ uint8_t read_mem(uint16_t index){ output = 0; } if(DEBUG_STEP){ - printf("%02x\n", memory[index]); + printw("%02x\n", memory[index]); } return output; } @@ -93,16 +110,16 @@ void write_mem(uint16_t index, uint8_t value){ uint8_t y; if(DEBUG_STEP){ - printf("WRITE: %02x --> %04x\n", value, index); + printw("WRITE: %02x --> %04x\n", value, index); } if((index&0xFF0F) == 0xD002){ if((value&0x7F) == '\n' || (value&0x7F) == '\r'){//Print \n instead of \r - printf("\n"); + printw("\n"); } else if((value&0x7F) == 0x5F){//Make the 0x5F character map to ASCII backspace - printf("\b \b"); + printw("\b \b"); } else if((value&0x7F) >= 0x20 && (value&0x7F) != 127){ //Output a character - printf("%c", value&0x7F); + printw("%c", value&0x7F); } } memory[index] = value; @@ -111,15 +128,15 @@ void write_mem(uint16_t index, uint8_t value){ int main(){ CPU_6502 cpu; FILE *fp; - unsigned char key_hit; + int key_hit; unsigned int count = 0; - unsigned long int last_time; - unsigned long int next_time; - struct timeval current_time; char temp_char; unsigned char str_index; unsigned long long int last_cycles; unsigned char last_cycle_diff; + unsigned long long int last_time; + struct timespec current_time; + unsigned long long int next_time; cpu.A_reg = 0; cpu.X_reg = 0; @@ -130,24 +147,32 @@ int main(){ tape_writing = 0; tape_reading = 0; + initscr(); + cbreak(); + noecho(); + scrollok(stdscr, 1); + //Load Integer Basic fp = fopen("BASIC", "rb"); if(fp){ fread(memory + 0xE000, 1, 0x1000, fp); + fclose(fp); } else { - printf("Warning: could not load file named \"BASIC\".\nStarting without apple 1 BASIC loaded.\nApple 1 basic can still be loaded from a cassette file into address 0xE000.\n---\n"); + printw("Warning: could not load file named \"BASIC\".\nStarting without apple 1 BASIC loaded.\nApple 1 basic can still be loaded from a cassette file into address 0xE000.\n---\n"); + printw("Press any key to continue...\n"); + getch(); + clear(); } - fclose(fp); //Load Woz's ACI fp = fopen("WOZACI", "rb"); if(fp){ fread(memory + 0xC000, 1, 0x100, fp); + fclose(fp); } else { - printf("file error\n"); + fprintf(stderr, "file error\n"); exit(1); } - fclose(fp); memcpy(memory + 0xC100, memory + 0xC000, 0x100); @@ -155,32 +180,33 @@ int main(){ fp = fopen("WOZMON", "rb"); if(fp){ fread(memory + 0xFF00, 1, 0x100, fp); + fclose(fp); } else { - printf("file error\n"); + fprintf(stderr, "file error\n"); exit(1); } - fclose(fp); reset_6502(&cpu, read_mem);//Reset the cpu cpu.cycles = 0; last_cycles = 0; //Initialize the timing - gettimeofday(¤t_time, NULL); - last_time = current_time.tv_usec + current_time.tv_sec*1000000; + clock_gettime(CLOCK_MONOTONIC, ¤t_time); + last_time = 0; last_cycle_diff = 0; next_tape_index = 0; + nodelay(stdscr, 1); while(1){ /* Limit the speed of the processor * based on how many cycles the last * instruction took. The 6502 on the - * Apple 1 was clocked at 1MHz. + * Apple 1 was clocked at 1 MHz. */ if(!DEBUG_STEP){ - do{ - gettimeofday(¤t_time, NULL); - next_time = current_time.tv_usec + current_time.tv_sec*1000000; - } while(next_time - last_time < last_cycle_diff); - last_time = last_time + last_cycle_diff; + last_time += last_cycle_diff; + if(last_time > 1000){ + Sleep(last_time/1000); + last_time -= 1000; + } } //Execute the instruction @@ -190,26 +216,29 @@ int main(){ //Debugging I/O if(DEBUG_STEP){ memset(str_buffer, 256, 0); - fgets(str_buffer, 256, stdin); + echo(); + getstr(str_buffer); + noecho(); temp_char = str_buffer[6]; str_buffer[6] = (char) 0; if(!strcmp(str_buffer, "resume")){ DEBUG_STEP = 0; - gettimeofday(¤t_time, NULL); - last_time = current_time.tv_usec + current_time.tv_sec*1000000; + clock_gettime(CLOCK_MONOTONIC, ¤t_time); + last_time = 0; + nodelay(stdscr, 1); } else if(temp_char == ' ' && !strcmp(str_buffer, "tstart")){ tape_active = 1; str_buffer[12] = (char) 0; if(temp_char == ' ' && !strcmp(str_buffer + 7, "write")){ tape_writing = 1; - printf("WRITING TO TAPE\n"); + printw("WRITING TO TAPE\n"); } str_buffer[11] = (char) 0; if(temp_char == ' ' && !strcmp(str_buffer + 7, "read")){ tape_reading = 1; current_tape_value = 0; - printf("READING FROM TAPE\n"); + printw("READING FROM TAPE\n"); } tape_index = 0; } else if(temp_char == ' ' && !strcmp(str_buffer, "tstore")){ @@ -231,11 +260,13 @@ int main(){ tape_reading = 0; } else if(!strcmp(str_buffer, "reset")){ reset_6502(&cpu, read_mem); + } else if(!strcmp(str_buffer, "quit")){ + break; } if(temp_char == ' ' && !strcmp(str_buffer, "tload")){ str_index = 0; - while(str_buffer[str_index] != '\n' && str_index < 255){ + while(str_buffer[str_index] != '\r' && str_buffer[str_index] != '\n' && str_index < 255){ str_index++; } str_buffer[str_index] = (char) 0; @@ -249,15 +280,14 @@ int main(){ } //Handle keyboard I/O - if(!(count%200) && kbhit()){ - key_hit = getch(); - + if(!(count%200) && (key_hit = getch()) != ERR){ if(key_hit == 0x08){//Emulate the backspace character memory[0xD010] = 0xDF; memory[0xD011] |= 0x80; } else if(key_hit == '~'){//Emulate the control character - while(!kbhit()){} + nodelay(stdscr, 0); key_hit = getch(); + nodelay(stdscr, 1); if(key_hit == 'd' || key_hit == 'D'){//Ctrl-D memory[0xD010] = 0x84; memory[0xD011] |= 0x80; @@ -270,13 +300,19 @@ int main(){ } } else if(key_hit == '|'){ DEBUG_STEP = 1; - printf("\n"); + printw("\n"); + nodelay(stdscr, 0); } else { //Convert lower case characters to upper case if(key_hit >= 'a' && key_hit <= 'z'){ key_hit += 'A' - 'a'; } + //Replace \n with \r + if(key_hit == '\n'){ + key_hit = '\r'; + } + memory[0xD010] = key_hit|0x80; memory[0xD011] |= 0x80; } @@ -304,5 +340,12 @@ int main(){ } else { last_cycles = cpu.cycles; } + refresh(); } + + printw("Press any key to exit...\n"); + nodelay(stdscr, 0); + getch(); + + endwin(); }