1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-25 16:31:42 +00:00

Invents a new virtual select line for extended handling card ROM areas.

This commit is contained in:
Thomas Harte 2022-08-23 14:41:45 -04:00
parent f89ca84902
commit 0595773355
2 changed files with 35 additions and 9 deletions

View File

@ -42,9 +42,13 @@ class Card {
public: public:
virtual ~Card() {} virtual ~Card() {}
enum Select: int { enum Select: int {
None = 0, // No select line is active. None = 0, // No select line is active.
IO = 1 << 0, // IO select is active; i.e. access is in range $C0x0 to $C0xf. IO = 1 << 0, // IO select is active; i.e. access is in range $C0x0 to $C0xf.
Device = 1 << 1, // Device select is active; i.e. access is in range $Cx00 to $Cxff. Device = 1 << 1, // Device select is active; i.e. access is in range $Cx00 to $Cxff.
C8Region = 1 << 2, // Access is to the region $c800 to $cfff, was preceded by at least
// one Device access to this card, and has not yet been followed up
// by an access to $cfff.
}; };
/*! /*!

View File

@ -73,8 +73,7 @@ SCSICard::SCSICard(ROM::Map &map) : scsi_bus_(1), ncr5380_(scsi_bus_, 1) {
void SCSICard::perform_bus_operation(Select select, bool is_read, uint16_t address, uint8_t *value) { void SCSICard::perform_bus_operation(Select select, bool is_read, uint16_t address, uint8_t *value) {
switch(select) { switch(select) {
case Select::None: default: break;
break;
case Select::Device: case Select::Device:
if(is_read) { if(is_read) {
@ -85,8 +84,8 @@ void SCSICard::perform_bus_operation(Select select, bool is_read, uint16_t addre
case Select::IO: case Select::IO:
address &= 0xf; address &= 0xf;
switch(address) { switch(address) {
case 0: case 1: case 2: case 3: case 0x0: case 0x1: case 0x2: case 0x3:
case 4: case 5: case 6: case 7: case 0x4: case 0x5: case 0x6: case 0x7:
if(is_read) { if(is_read) {
*value = ncr5380_.read(address); *value = ncr5380_.read(address);
} else { } else {
@ -94,12 +93,35 @@ void SCSICard::perform_bus_operation(Select select, bool is_read, uint16_t addre
} }
break; break;
case 0xa:
// RAM and ROM select.
if(!is_read) {
const auto rom_base = size_t((*value & 0x0f) << 10);
const auto ram_base = size_t((*value & 0x70) << 6);
rom_pointer_ = &rom_[rom_base];
ram_pointer_ = &ram_[ram_base];
}
break;
default: default:
printf("Unhandled: %04x %c %02x\n", address, is_read ? 'r' : 'w', *value); printf("Unhandled: %04x %c %02x\n", address, is_read ? 'r' : 'w', *value);
break; break;
} }
break; break;
}
// TODO: is it extra-contractual to respond in 0xc800 to 0xd000? Clarify. case Select::C8Region:
if(address & 0x400) {
if(is_read) {
*value = rom_pointer_[address & 0x3ff];
}
} else {
if(is_read) {
*value = ram_pointer_[address & 0x3ff];
} else {
ram_pointer_[address & 0x3ff] = *value;
}
}
break;
}
} }