From 834959c10aaca057ed35079007fa117df2eca70d Mon Sep 17 00:00:00 2001 From: Peter Evans Date: Tue, 2 Jan 2018 16:24:51 -0600 Subject: [PATCH] Add rom, ram2 bank memory; modify read/write sig The signature for read/write map functions now accepts a void pointer so that we can pass in the machine that those functions may need to know about. This is a bit hairy, but allows us to avoid the need for a yet-uglier global variable. --- include/apple2.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/apple2.c | 20 ++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/include/apple2.h b/include/apple2.h index 03a2460..714805f 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -6,6 +6,21 @@ #include "vm_bitfont.h" #include "vm_screen.h" +/* + * The size of our block of ROM is 12k + */ +#define APPLE2_ROM_SIZE 0x3000 + +/* + * Whereas the second bank of RAM is a mere 4k + */ +#define APPLE2_RAM2_SIZE 0x1000 + +/* + * This is the base address (or offset) for all bank-switched memory + */ +#define APPLE2_BANK_OFFSET 0xD000 + enum video_modes { VIDEO_40COL_TEXT, VIDEO_LORES, @@ -41,6 +56,17 @@ enum lores_colors { LORES_WHITE, }; +/* + * These are the potential memory modes we understand. You can only have + * one memory mode at a time. + */ +enum memory_mode { + MEMORY_BANK_ROM, // the last 12k is system ROM + MEMORY_BANK_RAM1, // the last 12k is system RAM + MEMORY_BANK_RAM2, // the first 4k of the last 12k is a separate RAM + // block from that in RAM1 +}; + typedef struct { /* * The apple 2 hardware used an MOS-6502 processor. @@ -54,6 +80,21 @@ typedef struct { */ vm_segment *memory; + /* + * The Apple II used a system of bank-switched memory to enable + * software to address a separate block of ROM. + */ + vm_segment *rom; + + /* + * Additionally, the Apple II had a standalone block of RAM (with no + * good name for it, really, hence the regrettably vague "ram2") so + * that you technically could use 16k of RAM from a set of 12k + * addresses. The extra 4k lives a lonely life in the garage + * apartment. + */ + vm_segment *ram2; + /* * The screen wherein we shall render all of our graphics. */ @@ -80,6 +121,13 @@ typedef struct { */ int color_mode; + /* + * This describes the behavior of our bank-switching scheme. We need + * our read/write mappers to know where writes into the + * bank-switched area of memory should target. + */ + int memory_mode; + /* * Our two disk drives. */ diff --git a/src/apple2.c b/src/apple2.c index e90c1dc..765a738 100644 --- a/src/apple2.c +++ b/src/apple2.c @@ -39,6 +39,8 @@ apple2_create(int width, int height) // Forward set these to NULL in case we fail to build the machine // properly; that way, we won't try to free garbage data + mach->rom = NULL; + mach->ram2 = NULL; mach->sysfont = NULL; mach->screen = NULL; mach->drive1 = NULL; @@ -51,8 +53,18 @@ apple2_create(int width, int height) return NULL; } + // Our memory is that which is owned by the CPU. mach->memory = mach->cpu->memory; + // Initliaze our system ROM and separate bank-switched block of RAM + mach->rom = vm_segment_create(APPLE2_ROM_SIZE); + mach->ram2 = vm_segment_create(APPLE2_RAM2_SIZE); + if (mach->rom == NULL || mach->ram2 == NULL) { + log_critical("Could not initialize ROM / RAM2!"); + apple2_free(mach); + return NULL; + } + // Our two drives -- we create both of them, even if we intend to // use only one. mach->drive1 = apple2dd_create(); @@ -179,6 +191,14 @@ apple2_free(apple2 *mach) mos6502_free(mach->cpu); } + if (mach->rom) { + vm_segment_free(mach->rom); + } + + if (mach->ram2) { + vm_segment_free(mach->ram2); + } + if (mach->sysfont) { vm_bitfont_free(mach->sysfont); }