From 9d2f9b6f6043271eca2d8813c50fc515fac8f0b9 Mon Sep 17 00:00:00 2001 From: Peter Evans Date: Thu, 11 Jan 2018 13:19:17 -0600 Subject: [PATCH] Refactor to remove ram2 Both main and auxiliary memory need to keep an extra 4k of memory that is bank-switchable, so we have changed to store that memory literally within the main and aux segments. --- include/apple2.h | 9 --------- include/apple2.mem.h | 15 ++++++++++----- src/apple2.c | 15 +++++---------- src/apple2.mem.c | 17 +++++++++-------- tests/apple2.mem.c | 17 +++++++++-------- 5 files changed, 33 insertions(+), 40 deletions(-) diff --git a/include/apple2.h b/include/apple2.h index f307022..39d29b4 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -115,15 +115,6 @@ typedef struct { */ 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 Apple II may have an auxiliary RAM bank; this was possible by * installing a card there. If you had the 80-column text card (and diff --git a/include/apple2.mem.h b/include/apple2.mem.h index f89d2ac..386e9b6 100644 --- a/include/apple2.mem.h +++ b/include/apple2.mem.h @@ -4,6 +4,16 @@ #include "apple2.h" #include "vm_segment.h" +/* + * The MOS 6502 expects 64k of addressable space, but the Apple II + * technically has 68k of memory in each bank. (Along with having both a + * main and an auxiliary memory bank, with identical address schemes.) + * This is handled through bank-switching; the additional memory (which + * is accessible through $D000 - $DFFF) is actually stored in the + * 64k-68k block at the end. + */ +#define APPLE2_MEMORY_SIZE 0x11000 + /* * Given a slot number (1-7), this will return the memory page address * for the site of the ROM that is associated for the peripheral that @@ -34,11 +44,6 @@ */ #define APPLE2_ROM_SIZE 0x3000 -/* - * Whereas the second bank of RAM is a mere 4k - */ -#define APPLE2_RAM2_SIZE 0x1000 - /* * At the highest point (with the IIe extended 80 column text card), you * could have a whole other 64k of data in auxiliary memory. (Of which diff --git a/src/apple2.c b/src/apple2.c index 7b15448..1c75fdf 100644 --- a/src/apple2.c +++ b/src/apple2.c @@ -45,14 +45,14 @@ 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->aux = NULL; mach->main = NULL; mach->sysfont = NULL; mach->screen = NULL; mach->drive1 = NULL; mach->drive2 = NULL; - mach->main = vm_segment_create(MOS6502_MEMSIZE); + mach->main = vm_segment_create(APPLE2_MEMORY_SIZE); if (mach->main == NULL) { log_critical("Could not initialize main RAM!"); apple2_free(mach); @@ -74,10 +74,9 @@ apple2_create(int width, int height) // 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); - mach->aux = vm_segment_create(APPLE2_AUX_SIZE); - if (mach->rom == NULL || mach->ram2 == NULL || mach->aux == NULL) { - log_critical("Could not initialize ROM / RAM2 / AUX!"); + mach->aux = vm_segment_create(APPLE2_MEMORY_SIZE); + if (mach->rom == NULL || mach->aux == NULL) { + log_critical("Could not initialize ROM / AUX!"); apple2_free(mach); return NULL; } @@ -260,10 +259,6 @@ apple2_free(apple2 *mach) vm_segment_free(mach->rom); } - if (mach->ram2) { - vm_segment_free(mach->ram2); - } - if (mach->main) { vm_segment_free(mach->main); } diff --git a/src/apple2.mem.c b/src/apple2.mem.c index c4d371f..3c18bd8 100644 --- a/src/apple2.mem.c +++ b/src/apple2.mem.c @@ -22,13 +22,14 @@ SEGMENT_READER(apple2_mem_read_bank) return vm_segment_get(mach->rom, addr - APPLE2_BANK_OFFSET); } - // If the address is $D000..$DFFF, then we may need to get the byte - // from the ram2 bank. + // Each memory bank (main or auxiliary) have an additional 4k of RAM + // that you can access through bank-switching in the $D000 - $DFFF + // range, which is actually held at the _end_ of memory beyond the + // 64k mark. if (addr < 0xE000 && mach->bank_switch & MEMORY_RAM2) { // The same caution holds for getting data from the // second RAM bank. - return vm_segment_get(mach->ram2, - addr - APPLE2_BANK_OFFSET); + return segment->memory[addr + 0x3000]; } // Otherwise, the byte is returned from bank 1 RAM, which is the @@ -58,11 +59,11 @@ SEGMENT_WRITER(apple2_mem_write_bank) // time--well, nearly the same time, considering the 6502 does not // allow parallel actions! - // If bank 2 RAM is turned on, and the address is in the $D000 - // hexapage, then we write to our ram2 segment. + // In this case, we need to assign the value at the 64-68k range at + // the end of memory; this is just a simple offset from the given + // address. if (addr < 0xE000 && mach->bank_switch & MEMORY_RAM2) { - vm_segment_set(mach->ram2, - addr - APPLE2_BANK_OFFSET, value); + segment->memory[addr + 0x3000] = value; return; } diff --git a/tests/apple2.mem.c b/tests/apple2.mem.c index 08f5a51..4f77f7e 100644 --- a/tests/apple2.mem.c +++ b/tests/apple2.mem.c @@ -54,14 +54,15 @@ Test(apple2_mem, read_bank) vm_segment_set(mach->main, 0xD077, val); cr_assert_eq(vm_segment_get(mach->main, 0xD077), val); cr_assert_neq(vm_segment_get(mach->rom, 0x77), val); - cr_assert_neq(vm_segment_get(mach->ram2, 0x77), val); + cr_assert_neq(vm_segment_get(mach->main, 0x10077), val); // Finally, in RAM2 bank mode, we test similarly to ROM mode. Set - // the value directly in ram2 and see if it's there when addressing - // from main memory. + // the value directly in ram2 (which is at $10000 - $1FFFF) and see + // if it's there when addressing from main memory in the $Dnnn + // range. val = 111; apple2_set_bank_switch(mach, mach->bank_switch | MEMORY_RAM2); - vm_segment_set(mach->ram2, 0x77, val); + vm_segment_set(mach->main, 0x10077, val); cr_assert_eq(vm_segment_get(mach->main, 0xD077), val); } @@ -91,18 +92,18 @@ Test(apple2_mem, write_bank) wrong = 232; apple2_set_bank_switch(mach, MEMORY_WRITE); vm_segment_set(mach->main, 0xD078, right); - vm_segment_set(mach->ram2, 0x78, wrong); + vm_segment_set(mach->main, 0x10078, wrong); cr_assert_eq(vm_segment_get(mach->main, 0xD078), right); - cr_assert_eq(vm_segment_get(mach->ram2, 0x78), wrong); + cr_assert_eq(vm_segment_get(mach->main, 0x10078), wrong); // RAM2 is most of the 64k, except the first 4k of the last 12 // ($D000..$DFFF) is in ram2. right = 210; wrong = 132; apple2_set_bank_switch(mach, mach->bank_switch | MEMORY_RAM2); - vm_segment_set(mach->ram2, 0x73, wrong); + vm_segment_set(mach->main, 0x10073, wrong); vm_segment_set(mach->main, 0xD073, right); - cr_assert_eq(vm_segment_get(mach->ram2, 0x73), right); + cr_assert_eq(vm_segment_get(mach->main, 0x10073), right); } Test(apple2_mem, init_disk2_rom)