1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-08-21 15:28:59 +00:00

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.
This commit is contained in:
Peter Evans 2018-01-11 13:19:17 -06:00
parent 288b4a9e8d
commit 9d2f9b6f60
5 changed files with 33 additions and 40 deletions

View File

@ -115,15 +115,6 @@ typedef struct {
*/ */
vm_segment *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 Apple II may have an auxiliary RAM bank; this was possible by * 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 * installing a card there. If you had the 80-column text card (and

View File

@ -4,6 +4,16 @@
#include "apple2.h" #include "apple2.h"
#include "vm_segment.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 * 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 * for the site of the ROM that is associated for the peripheral that
@ -34,11 +44,6 @@
*/ */
#define APPLE2_ROM_SIZE 0x3000 #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 * 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 * could have a whole other 64k of data in auxiliary memory. (Of which

View File

@ -45,14 +45,14 @@ apple2_create(int width, int height)
// Forward set these to NULL in case we fail to build the machine // Forward set these to NULL in case we fail to build the machine
// properly; that way, we won't try to free garbage data // properly; that way, we won't try to free garbage data
mach->rom = NULL; mach->rom = NULL;
mach->ram2 = NULL; mach->aux = NULL;
mach->main = NULL; mach->main = NULL;
mach->sysfont = NULL; mach->sysfont = NULL;
mach->screen = NULL; mach->screen = NULL;
mach->drive1 = NULL; mach->drive1 = NULL;
mach->drive2 = NULL; mach->drive2 = NULL;
mach->main = vm_segment_create(MOS6502_MEMSIZE); mach->main = vm_segment_create(APPLE2_MEMORY_SIZE);
if (mach->main == NULL) { if (mach->main == NULL) {
log_critical("Could not initialize main RAM!"); log_critical("Could not initialize main RAM!");
apple2_free(mach); apple2_free(mach);
@ -74,10 +74,9 @@ apple2_create(int width, int height)
// Initliaze our system ROM and separate bank-switched block of RAM // Initliaze our system ROM and separate bank-switched block of RAM
mach->rom = vm_segment_create(APPLE2_ROM_SIZE); mach->rom = vm_segment_create(APPLE2_ROM_SIZE);
mach->ram2 = vm_segment_create(APPLE2_RAM2_SIZE); mach->aux = vm_segment_create(APPLE2_MEMORY_SIZE);
mach->aux = vm_segment_create(APPLE2_AUX_SIZE); if (mach->rom == NULL || mach->aux == NULL) {
if (mach->rom == NULL || mach->ram2 == NULL || mach->aux == NULL) { log_critical("Could not initialize ROM / AUX!");
log_critical("Could not initialize ROM / RAM2 / AUX!");
apple2_free(mach); apple2_free(mach);
return NULL; return NULL;
} }
@ -260,10 +259,6 @@ apple2_free(apple2 *mach)
vm_segment_free(mach->rom); vm_segment_free(mach->rom);
} }
if (mach->ram2) {
vm_segment_free(mach->ram2);
}
if (mach->main) { if (mach->main) {
vm_segment_free(mach->main); vm_segment_free(mach->main);
} }

View File

@ -22,13 +22,14 @@ SEGMENT_READER(apple2_mem_read_bank)
return vm_segment_get(mach->rom, addr - APPLE2_BANK_OFFSET); return vm_segment_get(mach->rom, addr - APPLE2_BANK_OFFSET);
} }
// If the address is $D000..$DFFF, then we may need to get the byte // Each memory bank (main or auxiliary) have an additional 4k of RAM
// from the ram2 bank. // 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) { if (addr < 0xE000 && mach->bank_switch & MEMORY_RAM2) {
// The same caution holds for getting data from the // The same caution holds for getting data from the
// second RAM bank. // second RAM bank.
return vm_segment_get(mach->ram2, return segment->memory[addr + 0x3000];
addr - APPLE2_BANK_OFFSET);
} }
// Otherwise, the byte is returned from bank 1 RAM, which is the // 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 // time--well, nearly the same time, considering the 6502 does not
// allow parallel actions! // allow parallel actions!
// If bank 2 RAM is turned on, and the address is in the $D000 // In this case, we need to assign the value at the 64-68k range at
// hexapage, then we write to our ram2 segment. // the end of memory; this is just a simple offset from the given
// address.
if (addr < 0xE000 && mach->bank_switch & MEMORY_RAM2) { if (addr < 0xE000 && mach->bank_switch & MEMORY_RAM2) {
vm_segment_set(mach->ram2, segment->memory[addr + 0x3000] = value;
addr - APPLE2_BANK_OFFSET, value);
return; return;
} }

View File

@ -54,14 +54,15 @@ Test(apple2_mem, read_bank)
vm_segment_set(mach->main, 0xD077, val); vm_segment_set(mach->main, 0xD077, val);
cr_assert_eq(vm_segment_get(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->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 // 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 // the value directly in ram2 (which is at $10000 - $1FFFF) and see
// from main memory. // if it's there when addressing from main memory in the $Dnnn
// range.
val = 111; val = 111;
apple2_set_bank_switch(mach, mach->bank_switch | MEMORY_RAM2); 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); cr_assert_eq(vm_segment_get(mach->main, 0xD077), val);
} }
@ -91,18 +92,18 @@ Test(apple2_mem, write_bank)
wrong = 232; wrong = 232;
apple2_set_bank_switch(mach, MEMORY_WRITE); apple2_set_bank_switch(mach, MEMORY_WRITE);
vm_segment_set(mach->main, 0xD078, right); 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->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 // RAM2 is most of the 64k, except the first 4k of the last 12
// ($D000..$DFFF) is in ram2. // ($D000..$DFFF) is in ram2.
right = 210; right = 210;
wrong = 132; wrong = 132;
apple2_set_bank_switch(mach, mach->bank_switch | MEMORY_RAM2); 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); 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) Test(apple2_mem, init_disk2_rom)