mirror of
https://github.com/pevans/erc-c.git
synced 2024-11-27 20:51:17 +00:00
Add display buffer read/write mappers
This commit is contained in:
parent
45eb7b5e58
commit
cadc19b3e5
11
include/apple2.dbuf.h
Normal file
11
include/apple2.dbuf.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef _APPLE2_DBUF_H_
|
||||
#define _APPLE2_DBUF_H_
|
||||
|
||||
#include "apple2.h"
|
||||
#include "vm_segment.h"
|
||||
|
||||
extern SEGMENT_READER(apple2_dbuf_read);
|
||||
extern SEGMENT_WRITER(apple2_dbuf_write);
|
||||
extern void apple2_dbuf_map(vm_segment *);
|
||||
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
set(erc_sources
|
||||
apple2.c
|
||||
apple2.bank.c
|
||||
apple2.dbuf.c
|
||||
apple2.dd.c
|
||||
apple2.draw.c
|
||||
apple2.mem.c
|
||||
|
84
src/apple2.dbuf.c
Normal file
84
src/apple2.dbuf.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* apple2.dbuf.c
|
||||
*/
|
||||
|
||||
#include "apple2.dbuf.h"
|
||||
|
||||
/*
|
||||
* Handle reads from text page 1 and hires graphics page 1 (the display
|
||||
* buffers).
|
||||
*/
|
||||
SEGMENT_READER(apple2_dbuf_read)
|
||||
{
|
||||
apple2 *mach = (apple2 *)_mach;
|
||||
|
||||
// When 80STORE is high, we are allowed to look into two other flags
|
||||
// to see if they are set and modify our behavior accordingly.
|
||||
if (mach->memory_mode & MEMORY_80STORE) {
|
||||
// If the address is contained within text page 1, then we need
|
||||
// to look up memory in aux. (Uh, don't ask why we switch page 1
|
||||
// with the PAGE2 flag.) Otherwise, if the address is contained
|
||||
// in hires graphics page 1, then that must also use aux memory
|
||||
// if _both_ the PAGE2 and HIRES bits are set.
|
||||
if (addr >= 0x400 && addr < 0x800 &&
|
||||
mach->memory_mode & MEMORY_PAGE2
|
||||
) {
|
||||
segment = mach->aux;
|
||||
} else if (addr >= 0x2000 && addr < 0x4000 &&
|
||||
mach->memory_mode & MEMORY_PAGE2 & MEMORY_HIRES
|
||||
) {
|
||||
segment = mach->aux;
|
||||
}
|
||||
}
|
||||
|
||||
// In all other cases, we _must_ use the segment that was passed in.
|
||||
// That segment may be aux memory if MEMORY_READ_AUX is set, and if
|
||||
// so, that would be the desired behavior.
|
||||
return segment->memory[addr];
|
||||
}
|
||||
|
||||
/*
|
||||
* Many of the cautions and notes in the apple2_dbuf_read function
|
||||
* apply here as well.
|
||||
*/
|
||||
SEGMENT_WRITER(apple2_dbuf_write)
|
||||
{
|
||||
apple2 *mach = (apple2 *)_mach;
|
||||
|
||||
if (mach->memory_mode & MEMORY_80STORE) {
|
||||
if (addr >= 0x400 && addr < 0x800 &&
|
||||
mach->memory_mode & MEMORY_PAGE2
|
||||
) {
|
||||
segment = mach->aux;
|
||||
} else if (addr >= 0x2000 && addr < 0x4000 &&
|
||||
mach->memory_mode & MEMORY_PAGE2 &&
|
||||
mach->memory_mode & MEMORY_HIRES
|
||||
) {
|
||||
segment = mach->aux;
|
||||
}
|
||||
}
|
||||
|
||||
// Again, segment is allowed to be that which was passed in if
|
||||
// 80STORE is low.
|
||||
segment->memory[addr] = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the text page 1 and hires graphics page 1 addresses to the dbuf
|
||||
* read and write functions.
|
||||
*/
|
||||
void
|
||||
apple2_dbuf_map(vm_segment *segment)
|
||||
{
|
||||
size_t addr;
|
||||
|
||||
for (addr = 0x400; addr < 0x800; addr++) {
|
||||
vm_segment_read_map(segment, addr, apple2_dbuf_read);
|
||||
vm_segment_write_map(segment, addr, apple2_dbuf_write);
|
||||
}
|
||||
|
||||
for (addr = 0x2000; addr < 0x4000; addr++) {
|
||||
vm_segment_read_map(segment, addr, apple2_dbuf_read);
|
||||
vm_segment_write_map(segment, addr, apple2_dbuf_write);
|
||||
}
|
||||
}
|
@ -2,9 +2,10 @@
|
||||
* apple2.mem.c
|
||||
*/
|
||||
|
||||
#include "apple2.bank.h"
|
||||
#include "apple2.dbuf.h"
|
||||
#include "apple2.h"
|
||||
#include "apple2.mem.h"
|
||||
#include "apple2.bank.h"
|
||||
#include "objstore.h"
|
||||
|
||||
/*
|
||||
@ -21,6 +22,9 @@ apple2_mem_map(apple2 *mach, vm_segment *segment)
|
||||
// of it.
|
||||
apple2_bank_map(segment);
|
||||
|
||||
// Here we handle the 80STORE bit for our display buffers.
|
||||
apple2_dbuf_map(segment);
|
||||
|
||||
// We will do the mapping for the zero page and stack addresses.
|
||||
// Accessing those addresses can be affected by bank-switching, but
|
||||
// those addresses do not actually exist in the capital
|
||||
|
69
tests/apple2.dbuf.c
Normal file
69
tests/apple2.dbuf.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <criterion/criterion.h>
|
||||
|
||||
#include "apple2.h"
|
||||
#include "apple2.dbuf.h"
|
||||
#include "vm_segment.h"
|
||||
|
||||
static apple2 *mach = NULL;
|
||||
|
||||
static void
|
||||
setup()
|
||||
{
|
||||
mach = apple2_create(100, 100);
|
||||
vm_segment_set_map_machine(mach);
|
||||
}
|
||||
|
||||
static void
|
||||
teardown()
|
||||
{
|
||||
apple2_free(mach);
|
||||
vm_segment_set_map_machine(NULL);
|
||||
}
|
||||
|
||||
TestSuite(apple2_dbuf, .init = setup, .fini = teardown);
|
||||
|
||||
Test(apple2_dbuf, map)
|
||||
{
|
||||
size_t addr;
|
||||
int i;
|
||||
vm_segment *segments[2];
|
||||
|
||||
segments[0] = mach->main;
|
||||
segments[1] = mach->aux;
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (addr = 0x400; addr < 0x800; addr++) {
|
||||
cr_assert_eq(segments[i]->read_table[addr], apple2_dbuf_read);
|
||||
cr_assert_eq(segments[i]->write_table[addr], apple2_dbuf_write);
|
||||
}
|
||||
|
||||
for (addr = 0x2000; addr < 0x4000; addr++) {
|
||||
cr_assert_eq(segments[i]->read_table[addr], apple2_dbuf_read);
|
||||
cr_assert_eq(segments[i]->write_table[addr], apple2_dbuf_write);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This test also works on apple2_dbuf_write.
|
||||
*
|
||||
* Test(apple2_dbuf, write)
|
||||
*/
|
||||
Test(apple2_dbuf, read)
|
||||
{
|
||||
apple2_set_memory_mode(mach, MEMORY_80STORE | MEMORY_PAGE2);
|
||||
vm_segment_set(mach->main, 0x400, 123);
|
||||
vm_segment_set(mach->main, 0x2000, 234);
|
||||
cr_assert_neq(mach->main->memory[0x400], 123);
|
||||
cr_assert_eq(mach->aux->memory[0x400], 123);
|
||||
cr_assert_eq(mach->main->memory[0x2000], 234);
|
||||
cr_assert_neq(mach->aux->memory[0x2000], 234);
|
||||
|
||||
apple2_set_memory_mode(mach, MEMORY_80STORE | MEMORY_PAGE2 | MEMORY_HIRES);
|
||||
vm_segment_set(mach->main, 0x2000, 234);
|
||||
cr_assert_eq(mach->main->memory[0x2000], 234);
|
||||
cr_assert_eq(mach->aux->memory[0x2000], 234);
|
||||
}
|
||||
|
||||
Test(apple2_dbuf, write)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue
Block a user