// 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; byte* VRAM; int vPosition = 0; int vOffset = 0; 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); 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[vPosition] = ' '; vPosition++; } while ((vPosition % 40) > 0); // Set display to next line TermX = 0; TermY++; } else { // Place character mvwaddch(AppleWindow, TermY, TermX, n & 0x7F); // Add character to VRAM VRAM[vPosition] = n & 0x7f; vPosition++; // 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 (vPosition >= 960) vPosition -= 960; // If Y is past height.. if (TermY >= 24) { //.. discard the first line.. vOffset += 40; //.. then, for every cell of the screen except the last line, fill with VRAM.. for (int i = 0; i < 23; i++) { for (int j = 0; j < 40; j++) { mvwaddch(AppleWindow, i, j, VRAM[vOffset++ % 960] ); }} // ..and move offset up to next line. vOffset += 40; // Visually 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); }