1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-07-20 07:28:56 +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;
/*
* 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

View File

@ -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

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
// 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);
}

View File

@ -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;
}

View File

@ -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)