1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-06-28 01:29:37 +00:00

Add switch read/write for display buffer switches

This commit is contained in:
Peter Evans 2018-01-16 23:48:49 -06:00
parent b1177784a0
commit 9811bbe450
2 changed files with 157 additions and 0 deletions

View File

@ -7,5 +7,7 @@
extern SEGMENT_READER(apple2_dbuf_read);
extern SEGMENT_WRITER(apple2_dbuf_write);
extern void apple2_dbuf_map(vm_segment *);
extern SEGMENT_READER(apple2_dbuf_switch_read);
extern SEGMENT_WRITER(apple2_dbuf_switch_write);
#endif

View File

@ -4,6 +4,33 @@
#include "apple2.dbuf.h"
static size_t switch_reads[] = {
0xC01A,
0xC01B,
0xC01E,
0xC01F,
0xC07E,
0xC07F,
};
static size_t switch_writes[] = {
0xC00C,
0xC00D,
0xC00E,
0xC00F,
0xC050,
0xC051,
0xC052,
0xC053,
0xC056,
0xC057,
0xC059,
0xC05E,
0xC05F,
0xC07E,
0xC07F,
};
/*
* Handle reads from text page 1 and hires graphics page 1 (the display
* buffers).
@ -71,6 +98,7 @@ void
apple2_dbuf_map(vm_segment *segment)
{
size_t addr;
int i, rlen, wlen;
for (addr = 0x400; addr < 0x800; addr++) {
vm_segment_read_map(segment, addr, apple2_dbuf_read);
@ -81,13 +109,140 @@ apple2_dbuf_map(vm_segment *segment)
vm_segment_read_map(segment, addr, apple2_dbuf_read);
vm_segment_write_map(segment, addr, apple2_dbuf_write);
}
rlen = sizeof(switch_reads) / sizeof(size_t);
wlen = sizeof(switch_writes) / sizeof(size_t);
for (i = 0; i < rlen; i++) {
vm_segment_read_map(segment, switch_reads[i], apple2_dbuf_switch_read);
}
for (i = 0; i < wlen; i++) {
vm_segment_write_map(segment, switch_writes[i], apple2_dbuf_switch_write);
}
}
/*
* Handle all read switches for display buffer code. Some switches
* respond to either reads _or_ writes, so you may see some cases
* duplicated in the write map.
*
* Additionally, a number of the display modes also count as memory
* modes, and are handled in apple2.mem.c. Notably, some are HIRES,
* PAGE2, and 80STORE.
*/
SEGMENT_READER(apple2_dbuf_switch_read)
{
apple2 *mach = (apple2 *)_mach;
switch (addr) {
case 0xC01E:
return mach->display_mode & DISPLAY_ALTCHAR
? 0x80
: 0x00;
case 0xC01F:
return mach->display_mode & DISPLAY_80COL
? 0x80
: 0x00;
case 0xC01A:
return mach->display_mode & DISPLAY_TEXT
? 0x80
: 0x00;
case 0xC01B:
return mach->display_mode & DISPLAY_MIXED
? 0x80
: 0x00;
// NOTE: IOUDIS is the only bit that seems to share a write
// address with a read address. We can certainly handle that,
// since we support separate read and write tables! But it's
// interesting that they chose to do that, where they mostly
// stick with separate addresses for separate functions.
case 0xC07E:
return mach->display_mode & DISPLAY_IOUDIS
? 0x80
: 0x00;
case 0xC07F:
return mach->display_mode & DISPLAY_DHIRES
? 0x80
: 0x00;
}
// ???
return 0;
}
/*
* Here we update the statuses of the various display soft switches,
* and--there's a bunch of them!
*/
SEGMENT_WRITER(apple2_dbuf_switch_write)
{
apple2 *mach = (apple2 *)_mach;
switch (addr) {
case 0xC00E:
apple2_set_display(mach,
mach->display_mode | DISPLAY_ALTCHAR);
break;
case 0xC00F:
apple2_set_display(mach,
mach->display_mode & ~DISPLAY_ALTCHAR);
break;
case 0xC00C:
apple2_set_display(mach,
mach->display_mode | DISPLAY_80COL);
break;
case 0xC00D:
apple2_set_display(mach,
mach->display_mode & ~DISPLAY_80COL);
break;
case 0xC050:
apple2_set_display(mach,
mach->display_mode | DISPLAY_TEXT);
break;
case 0xC051:
apple2_set_display(mach,
mach->display_mode & ~DISPLAY_TEXT);
break;
case 0xC052:
apple2_set_display(mach,
mach->display_mode | DISPLAY_MIXED);
break;
case 0xC053:
apple2_set_display(mach,
mach->display_mode & ~DISPLAY_MIXED);
break;
case 0xC07E:
apple2_set_display(mach,
mach->display_mode | DISPLAY_IOUDIS);
break;
case 0xC07F:
apple2_set_display(mach,
mach->display_mode & ~DISPLAY_IOUDIS);
break;
case 0xC05E:
apple2_set_display(mach,
mach->display_mode | DISPLAY_DHIRES);
break;
case 0xC05F:
apple2_set_display(mach,
mach->display_mode & ~DISPLAY_DHIRES);
break;
}
}