From 8d3aaacf14997bbac177ae37ccab4618264cf29c Mon Sep 17 00:00:00 2001 From: alekseiplusplus Date: Wed, 29 Nov 2023 13:32:45 +1100 Subject: work on peripherals and display --- .gitignore | 3 ++- compile-rom.sh | 2 ++ src/Makefile | 6 +++--- src/apple.c | 36 +++++++++++++++++++++++++++++++++++- src/apple.h | 7 +++++-- src/cpu/core.h | 7 ++++++- src/video/interface.h | 5 ++++- src/video/ncurses.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ src/video/signetics.c | 17 ----------------- wozmon.txt | 32 ++++++++++++++++++++++++++++++++ 10 files changed, 132 insertions(+), 32 deletions(-) create mode 100755 compile-rom.sh create mode 100644 wozmon.txt diff --git a/.gitignore b/.gitignore index 41bcb26..c72f7f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode/* -build/* \ No newline at end of file +apple-c +interpreter diff --git a/compile-rom.sh b/compile-rom.sh new file mode 100755 index 0000000..9cea27c --- /dev/null +++ b/compile-rom.sh @@ -0,0 +1,2 @@ +#!/bin/sh +cat wozmon.txt | cut -c 7- | tr -d [:space:] | xxd -r -p > rom.bin diff --git a/src/Makefile b/src/Makefile index 866334d..7ac3085 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,10 +9,10 @@ BUILD_STATIC_LIBRARY = ar -rcs $@ $^ # Executable Targets default: computer.a video.a - gcc -o ../build/apple-c -lncurses main.c $^ + gcc -o ../apple-c -lncurses main.c $^ interpreter: computer.a - gcc -o ../build/interpreter interpreter.c $^ + gcc -o ../interpreter interpreter.c $^ @@ -34,4 +34,4 @@ clean: rm *.a rm *.o rm cpu/*.o - rm video/*.o \ No newline at end of file + rm video/*.o diff --git a/src/apple.c b/src/apple.c index dae09cc..b9fd6ae 100644 --- a/src/apple.c +++ b/src/apple.c @@ -3,19 +3,53 @@ void AppleOn(){ Memory = calloc(MEMORY_SIZE, sizeof(byte)); initInstructionTable(); + + // Load ROM + FILE *ROM = fopen ("rom.bin", "rb"); + for (int i = 0; i < 256; i++) { + Memory[0xFF00+i] = fgetc(ROM); + } } void AppleReset(){ acc = 0; X = 0; Y = 0; P = 0; S = 0; idata.cycles = 0; idata.length = 0; idata.add = 0; idata.value = 0; + PC = 0xFF00; free(Memory); Memory = calloc(MEMORY_SIZE, sizeof(byte)); } +byte ToAppleASCII(char x) +{ + if (x < 0x20 || x >= 0x60) + return -1; + if (x >= 0x40) + x -= 0x40; + return x; +} + +byte ToRegularASCII(char x) +{ + if (x < 0x20) + x += 0x40; + return x; +} + + byte getMemory(address x){ + switch(x) + { + // I opted to make the kbd return successfully at all times for the sake of simplicity. + // This is not "accurate" behavior however. + case KBD: + return 0b10000000 | ToAppleASCII(UserInput()); + case KBD_CR: case DSP: + return 0b10000000; + } + return Memory[x]; } void setMemory(address x, byte y){ Memory[x] = y; -} \ No newline at end of file +} diff --git a/src/apple.h b/src/apple.h index ea1f04e..988a297 100644 --- a/src/apple.h +++ b/src/apple.h @@ -2,6 +2,7 @@ #define APPLE_H #include "cpu/core.h" +#include #include #define MEMORY_SIZE 4096 @@ -21,7 +22,9 @@ #define DSP_CR 0xD013 void AppleOn(); - void AppleReset(); -#endif \ No newline at end of file +byte ToAppleAscii(char); +byte ToRegularAscii(char); + +#endif diff --git a/src/cpu/core.h b/src/cpu/core.h index b305021..fb6bdf6 100644 --- a/src/cpu/core.h +++ b/src/cpu/core.h @@ -49,6 +49,11 @@ struct AddData } AddData; + + +// getMemory and setMemory are declared here, but defined in apple.c +// This is because memory access of particular memory locations is influenced by the Apple I's specific setup, not by the CPU alone. + byte getMemory(address x); void setMemory(address x, byte y); @@ -57,4 +62,4 @@ extern void *current_instruction; extern AddData idata; extern void (*func)(Addressing, address); -#endif \ No newline at end of file +#endif diff --git a/src/video/interface.h b/src/video/interface.h index 49ac75c..5100032 100644 --- a/src/video/interface.h +++ b/src/video/interface.h @@ -1,8 +1,11 @@ // interface.h // Provides the interface with which all video interactions must occur. +// Common procedure for taking in user input. +char UserInput(); + void TerminalInit(); void TerminalClose(); -void TerminalInput(char n); \ No newline at end of file +void TerminalInput(char n); diff --git a/src/video/ncurses.c b/src/video/ncurses.c index 76bfb26..380c57a 100644 --- a/src/video/ncurses.c +++ b/src/video/ncurses.c @@ -10,28 +10,64 @@ int TermX = 0; int TermY = 0; +WINDOW *AppleWindow; + + +char UserInput() +{ + return getch(); +} + + + void TerminalInit() { initscr(); cbreak(); noecho(); curs_set(0); + keypad(stdscr, TRUE); + + AppleWindow = newwin(24, 40, 1, 1); + + // Draw the 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); + + + mvwaddch(AppleWindow, TermY, TermX, '@' | A_BLINK); TerminalShiftRegister = (byte*)malloc(960); TerminalShiftRegisterPosition = TerminalShiftRegister; TerminalShiftRegisterOffset = 0; + + refresh(); } + + + void TerminalClose() { free(TerminalShiftRegister); - curs_set(0); + curs_set(1); endwin(); } +// Takes an an Apple I ASCII character. void TerminalInput(char n) { - mvaddch(TermY,TermX,n); + mvwaddch(AppleWindow, TermY,TermX,n); *TerminalShiftRegisterPosition = n; TerminalShiftRegisterPosition++; @@ -64,7 +100,7 @@ void TerminalInput(char n) if (offset >= (TerminalShiftRegister + 960)) offset -= 960; - mvaddch(i,j, *(offset)); + mvwaddch(AppleWindow, i, j, *(offset)); offset++; }} @@ -72,8 +108,9 @@ void TerminalInput(char n) TermX = 0; // Clear bottom line. - mvwprintw(stdscr, TermY, TermX, " "); + mvwprintw(AppleWindow, TermY, TermX, " "); } - mvaddch(TermY, TermX, '@' | A_BLINK); -} \ No newline at end of file + mvwaddch(AppleWindow, TermY, TermX, '@' | A_BLINK); + wrefresh(AppleWindow); +} diff --git a/src/video/signetics.c b/src/video/signetics.c index c6dca10..4a996d8 100644 --- a/src/video/signetics.c +++ b/src/video/signetics.c @@ -16,20 +16,3 @@ const byte* TerminalShiftRegister; byte* TerminalShiftRegisterPosition; int TerminalShiftRegisterOffset; - -byte ToAppleASCII(char x) -{ - if (x < 0x20 || x >= 0x60) - return -1; - if (x >= 0x40) - x -= 0x40; - return x; -} - -byte ToRegularASCII(char x) -{ - if (x < 0x20) - x += 0x40; - return x; -} - diff --git a/wozmon.txt b/wozmon.txt new file mode 100644 index 0000000..d2a5b42 --- /dev/null +++ b/wozmon.txt @@ -0,0 +1,32 @@ +FF00: D8 58 A0 7F 8C 12 D0 A9 +FF08: A7 8D 11 D0 8D 13 D0 C9 +FF10: DF F0 13 C9 9B F0 03 C8 +FF18: 10 0F A9 DC 20 EF FF A9 +FF20: 8D 20 EF FF A0 01 88 30 +FF28: F6 AD 11 D0 10 FB AD 10 +FF30: D0 99 00 02 20 EF FF C9 +FF38: 8D D0 D4 A0 FF A9 00 AA +FF40: 0A 85 2B C8 B9 00 02 C9 +FF48: 8D F0 D4 C9 AE 90 F4 F0 +FF50: F0 C9 BA F0 EB C9 D2 F0 +FF58: 3B 86 28 86 29 84 2A B9 +FF60: 00 02 49 B0 C9 0A 90 06 +FF68: 69 88 C9 FA 90 11 0A 0A +FF70: 0A 0A A2 04 0A 26 28 26 +FF78: 29 CA D0 F8 C8 D0 E0 C4 +FF80: 2A F0 97 24 2B 50 10 A5 +FF88: 28 81 26 E6 26 D0 B5 E6 +FF90: 27 4C 44 FF 6C 24 00 30 +FF98: 2B A2 02 B5 27 95 25 95 +FFA0: 23 CA D0 F7 D0 14 A9 8D +FFA8: 20 EF FF A5 25 20 DC FF +FFB0: A5 24 20 DC FF A9 BA 20 +FFB8: EF FF A9 A0 20 EF FF A1 +FFC0: 24 20 DC FF 86 2B A5 24 +FFC8: C5 28 A5 25 E5 29 B0 C1 +FFD0: E6 24 D0 02 E6 25 A5 24 +FFD8: 29 07 10 C8 48 4A 4A 4A +FFE0: 4A 20 E5 FF 68 29 0F 09 +FFE8: B0 C9 BA 90 02 69 06 2C +FFF0: 12 D0 30 FB 8D 12 D0 60 +FFF8: 00 00 00 0F 00 FF 00 00 -- cgit v1.2.3