From 0595773355ff282f1f8927a6c10a2f95dcdc4c8b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 23 Aug 2022 14:41:45 -0400 Subject: [PATCH] Invents a new virtual select line for extended handling card ROM areas. --- Machines/Apple/AppleII/Card.hpp | 10 ++++++--- Machines/Apple/AppleII/SCSICard.cpp | 34 ++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Machines/Apple/AppleII/Card.hpp b/Machines/Apple/AppleII/Card.hpp index 3a3a784d7..386e5d657 100644 --- a/Machines/Apple/AppleII/Card.hpp +++ b/Machines/Apple/AppleII/Card.hpp @@ -42,9 +42,13 @@ class Card { public: virtual ~Card() {} enum Select: int { - None = 0, // No select line is active. - 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. + None = 0, // No select line is active. + 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. + + 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. }; /*! diff --git a/Machines/Apple/AppleII/SCSICard.cpp b/Machines/Apple/AppleII/SCSICard.cpp index de2560ae9..2d0dac720 100644 --- a/Machines/Apple/AppleII/SCSICard.cpp +++ b/Machines/Apple/AppleII/SCSICard.cpp @@ -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) { switch(select) { - case Select::None: - break; + default: break; case Select::Device: if(is_read) { @@ -85,8 +84,8 @@ void SCSICard::perform_bus_operation(Select select, bool is_read, uint16_t addre case Select::IO: address &= 0xf; switch(address) { - case 0: case 1: case 2: case 3: - case 4: case 5: case 6: case 7: + case 0x0: case 0x1: case 0x2: case 0x3: + case 0x4: case 0x5: case 0x6: case 0x7: if(is_read) { *value = ncr5380_.read(address); } else { @@ -94,12 +93,35 @@ void SCSICard::perform_bus_operation(Select select, bool is_read, uint16_t addre } 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: printf("Unhandled: %04x %c %02x\n", address, is_read ? 'r' : 'w', *value); 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; + } }