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:
parent
288b4a9e8d
commit
9d2f9b6f60
@ -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
|
||||||
|
@ -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
|
||||||
|
15
src/apple2.c
15
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
|
// 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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user