From 047eaf800f7681140efaf4a43e921b0bc5b7d62e Mon Sep 17 00:00:00 2001 From: Daniel Loffgren Date: Sat, 19 Dec 2015 23:29:19 +0000 Subject: [PATCH] Refactored PIA code to bind to a CPU, rather than just the memory bus. This way it can also be in charge of freezing the entire machine state. Also added 2k of character history for buffering video state. git-svn-id: svn+ssh://svn.phoenixbox.net/svn/apple1/trunk@74 64f78de7-aa59-e511-a0e8-0002a5492df0 --- apple1/main.c | 2 +- apple1/pia.c | 18 ++++++++---------- apple1/pia.h | 28 ++++++++++++++++++++++++---- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/apple1/main.c b/apple1/main.c index d87dd34..f352fa8 100644 --- a/apple1/main.c +++ b/apple1/main.c @@ -112,7 +112,7 @@ int main(int argc, const char * argv[]) // Attach PIA printf("Initializing PIA...\n"); - pia = pia_create(cpu->memory); + pia = pia_create(cpu); printf("Resetting CPU...\n"); v6502_reset(cpu); diff --git a/apple1/pia.c b/apple1/pia.c index 1bec039..6b3f6ad 100644 --- a/apple1/pia.c +++ b/apple1/pia.c @@ -18,7 +18,7 @@ #define KEYBOARD_NOTREADY 0x00 #define ANSI_BGCOLOR_GREEN "\x1b[42;1m" -void saveFreeze(v6502_memory *mem, const char *fname) { +void saveFreeze(a1pia *pia, const char *fname) { FILE *f = fopen(fname, "w"); if (!f) { endwin(); @@ -26,7 +26,7 @@ void saveFreeze(v6502_memory *mem, const char *fname) { } for (uint16_t offset = 0; offset < v6502_memoryStartCeiling; offset++) { - uint8_t byte = v6502_read(mem, offset, NO); + uint8_t byte = v6502_read(pia->cpu->memory, offset, NO); fwrite(&byte, sizeof(uint8_t), 1, f); } @@ -87,8 +87,6 @@ uint8_t keyboardReadReadyCallback(struct _v6502_memory *memory, uint16_t offset, return KEYBOARD_READY; } - saveFreeze(memory, "freeze.ram"); - if (context->suspended) { printf("Keyboard readiness register ($D011) trap read.\n"); printf("Press a key for input to keyboard register ($D010): "); @@ -133,16 +131,16 @@ uint8_t keyboardReadCharacterCallback(struct _v6502_memory *memory, uint16_t off return 0; } -a1pia *pia_create(v6502_memory *mem) { +a1pia *pia_create(v6502_cpu *cpu) { a1pia *pia = malloc(sizeof(a1pia)); - pia->memory = mem; + pia->cpu = cpu; pia->screen = NULL; pia->buf = '\0'; - assert(v6502_map(mem, A1PIA_KEYBOARD_INPUT_REGISTER, 1, (v6502_readFunction *)keyboardReadCharacterCallback, NULL, pia)); - assert(v6502_map(mem, A1PIA_KEYBOARD_READY_REGISTER, 1, (v6502_readFunction *)keyboardReadReadyCallback, NULL, pia)); - assert(v6502_map(mem, A1PIA_VIDEO_OUTPUT_REGISTER, 1, FIXME_I_SHOULDNT_BE_NULL, (v6502_writeFunction *)videoWriteCharCallback, pia)); - assert(v6502_map(mem, A1PIA_VIDEO_ATTR_REGISTER, 1, FIXME_I_SHOULDNT_BE_NULL, (v6502_writeFunction *)videoWriteNewlineCallback, pia)); + assert(v6502_map(cpu->memory, A1PIA_KEYBOARD_INPUT_REGISTER, 1, (v6502_readFunction *)keyboardReadCharacterCallback, NULL, pia)); + assert(v6502_map(cpu->memory, A1PIA_KEYBOARD_READY_REGISTER, 1, (v6502_readFunction *)keyboardReadReadyCallback, NULL, pia)); + assert(v6502_map(cpu->memory, A1PIA_VIDEO_OUTPUT_REGISTER, 1, FIXME_I_SHOULDNT_BE_NULL, (v6502_writeFunction *)videoWriteCharCallback, pia)); + assert(v6502_map(cpu->memory, A1PIA_VIDEO_ATTR_REGISTER, 1, FIXME_I_SHOULDNT_BE_NULL, (v6502_writeFunction *)videoWriteNewlineCallback, pia)); return pia; } diff --git a/apple1/pia.h b/apple1/pia.h index d3ee3d0..b16e546 100644 --- a/apple1/pia.h +++ b/apple1/pia.h @@ -9,7 +9,7 @@ #ifndef __apple1__pia__ #define __apple1__pia__ -#include +#include #include #define A1PIA_KEYBOARD_INPUT_REGISTER 0xD010 @@ -20,17 +20,37 @@ typedef struct { /** @brief Curses output object */ WINDOW *screen; - /** @brief Hardwired memory used to trap video activity and report keyboard input */ - v6502_memory *memory; + /** @brief Hardwired cpu used to trap video activity and report + * keyboard input back via memory mapped registers. */ + v6502_cpu *cpu; char buf; int signalled; int suspended; + char history[2048]; + int hist_pos; } a1pia; -a1pia *pia_create(v6502_memory *mem); +a1pia *pia_create(v6502_cpu *cpu); void pia_destroy(a1pia *pia); void pia_start(a1pia *pia, int continuous); void pia_stop(a1pia *pia); +/* The freeze format is as follows: + * 0x00000-0x0FFFF: The contents of memory + * 0x10001-0x10002: CPU Program Counter + * 0x10003: CPU Accumulator + * 0x10004: CPU X Register + * 0x10005: CPU Y Register + * 0x10006: CPU Status Register + * 0x10007-0x10807: Video Buffer History + * + * The video buffer history is a 2 kilobyte ring buffer that is preserved + * by the PIA. On load, it is replayed, which should restore the video + * output to a pretty close approximation, depending on terminal size and + * history. + */ +void saveFreeze(a1pia *pia, const char *fname); +void loadFreeze(a1pia *pia, const char *fname); + #endif /* defined(__apple1__pia__) */