// ncurses.c // Implements interface.h // Provides an in-terminal interface to the emulator. #include #include"interface.h" #include"../apple.h" #include"../cpu/6502.h" int TermX = 0; int TermY = 0; WINDOW *AppleWindow; const byte* VRAM; byte* VRAM_Position; int VRAM_Offset; void PrintInfo() { mvprintw(2, 43, " acc : %02x", acc); mvprintw(3, 43, " X : %02x", X ); mvprintw(4, 43, " Y : %02x", Y ); mvprintw(5, 43, " PC : %04x", PC); mvprintw(6, 43, " S : %02x", S ); mvprintw(7, 43, "Flags : %c%c_%c%c%c%c%c", getFlag(flag_N) ? 'N':'.' , getFlag(flag_V) ? 'V':'.' , getFlag(flag_B) ? 'B':'.' , getFlag(flag_D) ? 'D':'.' , getFlag(flag_I) ? 'I':'.' , getFlag(flag_Z) ? 'Z':'.' , getFlag(flag_C) ? 'C':'.' ); mvprintw(2, 65, "Stack"); int count = 3; for (int i = 0x1ff; i > 0x1e8; i--) { if (i == (0x1ff-S)) // Indicate the stack pointer! attron(A_REVERSE); mvprintw(count, 65, "%x : %x", i, GetMemory(i)); attroff(A_REVERSE); count++; } refresh(); } void DisplayInit() { // ncurses initialization functions. initscr(); cbreak(); noecho(); curs_set(0); keypad(stdscr, TRUE); // Draw decorative border. attron(A_REVERSE); move(0, 0); printw(" "); for (int i = 1; i <= 24; i++) { mvaddch(i, 0, ' '); mvaddch(i, 41, ' '); } mvprintw(25, 0, " ~ "); mvprintw(26, 0, " Alekseis Apple I "); mvprintw(27, 0, " "); attroff(A_REVERSE); // Create seperate Apple screen window. AppleWindow = newwin(24, 40, 1, 1); // @ prompt. mvwaddch(AppleWindow, TermY, TermX, '@' | A_BLINK); // Initialize the terminal shift register variables. VRAM = (byte*)malloc(960); VRAM_Position = VRAM; VRAM_Offset = 0; refresh(); } void DisplayClose() { free(VRAM); curs_set(1); endwin(); } void DisplayInput(byte n) { if (n == BS) { return; } // Clear @ mvwaddch(AppleWindow, TermY, TermX, ' '); if (n == CR) { // Add spacing characters into VRAM do { *VRAM_Position = ' '; VRAM_Position++; } while (((int)(VRAM_Position - VRAM) % 40) > 0); // Set display to next line TermX = 0; TermY++; } else { // Place character mvwaddch(AppleWindow, TermY, TermX, n & 0x7F); // Add character to VRAM *VRAM_Position = n & 0x7f; VRAM_Position++; // Set display to next character/next line TermX++; if (TermX >= 40) { TermX = 0; TermY++; } } // Reset VRAM_Position if it's value is too great. if (VRAM_Position >= (VRAM + 960)) VRAM_Position -= 960; // If Y is past height.. if (TermY >= 24) { //.. discard the first line.. VRAM_Offset += 40; //.. verify the register offset.. if (VRAM_Offset >= 960) VRAM_Offset = VRAM; //.. and create an offset variable to cycle through memory with. byte *offset = VRAM + VRAM_Offset; // Then, for every cell of the screen, fill with the contents of the video memory. for (int i = 0; i < 23; i++) { for (int j = 0; j < 40; j++) { if (offset >= (VRAM + 960)) offset -= 960; mvwaddch(AppleWindow, i, j, *offset ); offset++; }} // Set to start of final line, and clear line. TermY = 23; TermX = 0; mvwprintw(AppleWindow, TermY, TermX, " "); } // Place @ mvwaddch(AppleWindow, TermY, TermX, '@' | A_BLINK); wrefresh(AppleWindow); }