mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Attempts retroactively to enforce the rule that 8-bit index modes => no top byte.
(Rather than a preserved but ignored top byte)
This commit is contained in:
parent
53f60f7c87
commit
0178aaee2b
@ -98,6 +98,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
forceinline Cycles perform_bus_operation(const CPU::WDC65816::BusOperation operation, const uint32_t address, uint8_t *const value) {
|
forceinline Cycles perform_bus_operation(const CPU::WDC65816::BusOperation operation, const uint32_t address, uint8_t *const value) {
|
||||||
const auto ®ion = MemoryMapRegion(memory_, address);
|
const auto ®ion = MemoryMapRegion(memory_, address);
|
||||||
|
static bool log = false;
|
||||||
|
|
||||||
// TODO: potentially push time to clock_.
|
// TODO: potentially push time to clock_.
|
||||||
|
|
||||||
@ -106,7 +107,8 @@ class ConcreteMachine:
|
|||||||
const bool is_read = isReadOperation(operation);
|
const bool is_read = isReadOperation(operation);
|
||||||
memory_.access(uint16_t(address), is_read);
|
memory_.access(uint16_t(address), is_read);
|
||||||
|
|
||||||
switch(address & 0xffff) {
|
const auto address_suffix = address & 0xffff;
|
||||||
|
switch(address_suffix) {
|
||||||
|
|
||||||
// New video register.
|
// New video register.
|
||||||
case 0xc029:
|
case 0xc029:
|
||||||
@ -193,7 +195,7 @@ class ConcreteMachine:
|
|||||||
#undef LanguageRead
|
#undef LanguageRead
|
||||||
#undef SwitchRead
|
#undef SwitchRead
|
||||||
|
|
||||||
// Video switches.
|
// Video switches (and annunciators).
|
||||||
case 0xc050: case 0xc051:
|
case 0xc050: case 0xc051:
|
||||||
video_.set_text(address & 1);
|
video_.set_text(address & 1);
|
||||||
break;
|
break;
|
||||||
@ -206,6 +208,11 @@ class ConcreteMachine:
|
|||||||
case 0xc056: case 0xc057:
|
case 0xc056: case 0xc057:
|
||||||
video_.set_high_resolution(address&1);
|
video_.set_high_resolution(address&1);
|
||||||
break;
|
break;
|
||||||
|
case 0xc058: case 0xc059:
|
||||||
|
case 0xc05a: case 0xc05b:
|
||||||
|
case 0xc05c: case 0xc05d:
|
||||||
|
// Annunciators 0, 1 and 2.
|
||||||
|
break;
|
||||||
case 0xc05e: case 0xc05f:
|
case 0xc05e: case 0xc05f:
|
||||||
video_.set_annunciator_3(!(address&1));
|
video_.set_annunciator_3(!(address&1));
|
||||||
break;
|
break;
|
||||||
@ -271,19 +278,105 @@ class ConcreteMachine:
|
|||||||
case 0xc071: case 0xc072: case 0xc073: case 0xc074: case 0xc075: case 0xc076: case 0xc077:
|
case 0xc071: case 0xc072: case 0xc073: case 0xc074: case 0xc075: case 0xc076: case 0xc077:
|
||||||
case 0xc078: case 0xc079: case 0xc07a: case 0xc07b: case 0xc07c: case 0xc07d: case 0xc07e: case 0xc07f:
|
case 0xc078: case 0xc079: case 0xc07a: case 0xc07b: case 0xc07c: case 0xc07d: case 0xc07e: case 0xc07f:
|
||||||
if(is_read) {
|
if(is_read) {
|
||||||
*value = rom_[rom_.size() - 65536 + (address & 0xffff)];
|
*value = rom_[rom_.size() - 65536 + address_suffix];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Analogue inputs. All TODO.
|
||||||
|
case 0xc060: case 0xc061: case 0xc062: case 0xc063:
|
||||||
|
// Joystick buttons (and keyboard modifiers).
|
||||||
|
if(is_read) {
|
||||||
|
*value = 0x00;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xc064: case 0xc065: case 0xc066: case 0xc067:
|
||||||
|
// Analogue inputs.
|
||||||
|
if(is_read) {
|
||||||
|
*value = 0x00;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xc070:
|
||||||
|
// TODO: begin analogue channel charge.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xc02d:
|
||||||
|
// TODO: slot register selection.
|
||||||
|
// b7: 0 = internal ROM code for slot 7;
|
||||||
|
// b6: 0 = internal ROM code for slot 6;
|
||||||
|
// b5: 0 = internal ROM code for slot 5;
|
||||||
|
// b4: 0 = internal ROM code for slot 4;
|
||||||
|
// b3: reserved;
|
||||||
|
// b2: internal ROM code for slot 2;
|
||||||
|
// b1: internal ROM code for slot 1;
|
||||||
|
// b0: reserved.
|
||||||
|
if(is_read) {
|
||||||
|
*value = card_mask_;
|
||||||
|
} else {
|
||||||
|
card_mask_ = *value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Addresses that seemingly map to nothing; provided as a separate break out for now,
|
||||||
|
// while I have an assert on unknown reads.
|
||||||
|
case 0xc049: case 0xc04a: case 0xc04b: case 0xc04c: case 0xc04d: case 0xc04e: case 0xc04f:
|
||||||
|
case 0xc069: case 0xc06a: case 0xc06b: case 0xc06c:
|
||||||
|
printf("Ignoring %04x\n", address_suffix);
|
||||||
|
log = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 'Test Mode', whatever that is (?)
|
||||||
|
case 0xc06e: case 0xc06f:
|
||||||
|
test_mode_ = address & 1;
|
||||||
|
break;
|
||||||
|
case 0xc06d:
|
||||||
|
if(is_read) {
|
||||||
|
*value = test_mode_ * 0x80;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if((address & 0xffff) < 0xc100) {
|
// Check for a card access.
|
||||||
// TODO: all other IO accesses.
|
if(address_suffix >= 0xc080 && address_suffix < 0xc800) {
|
||||||
printf("Unhandled IO: %04x\n", address & 0xffff);
|
// This is an abridged version of the similar code in AppleII.cpp from
|
||||||
assert(false);
|
// line 653; it would be good to factor that out and support cards here.
|
||||||
|
// For now just either supply the internal ROM or nothing as per the
|
||||||
|
// current card mask.
|
||||||
|
|
||||||
|
size_t card_number = 0;
|
||||||
|
if(address >= 0xc100) {
|
||||||
|
/*
|
||||||
|
Decode the area conventionally used by cards for ROMs:
|
||||||
|
0xCn00 to 0xCnff: card n.
|
||||||
|
*/
|
||||||
|
card_number = (address - 0xc000) >> 8;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
Decode the area conventionally used by cards for registers:
|
||||||
|
C0n0 to C0nF: card n - 8.
|
||||||
|
*/
|
||||||
|
card_number = (address - 0xc080) >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t permitted_card_mask_ = card_mask_ & 0xf6;
|
||||||
|
if(permitted_card_mask_ & (1 << card_number)) {
|
||||||
|
// TODO: Access an actual card.
|
||||||
|
if(is_read) {
|
||||||
|
*value = 0xff;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: disk-port soft switches should be in COEx.
|
||||||
|
printf("Internal card-area access: %04x\n", address_suffix);
|
||||||
|
if(is_read) {
|
||||||
|
*value = rom_[rom_.size() - 65536 + address_suffix];
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Card IO. Not implemented!
|
if(address_suffix < 0xc080) {
|
||||||
if(isReadOperation(operation)) {
|
// TODO: all other IO accesses.
|
||||||
*value = 0xff;
|
printf("Unhandled IO: %04x\n", address_suffix);
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,20 +392,23 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("%06x %s %02x", address, isReadOperation(operation) ? "->" : "<-", *value);
|
// log |= (address >= 0xffa6d9) && (address < 0xffa6ec);
|
||||||
// if(operation == CPU::WDC65816::BusOperation::ReadOpcode) {
|
if(log) {
|
||||||
// printf(" a:%04x x:%04x y:%04x s:%04x e:%d p:%02x db:%02x pb:%02x d:%04x\n",
|
printf("%06x %s %02x", address, isReadOperation(operation) ? "->" : "<-", *value);
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::A),
|
if(operation == CPU::WDC65816::BusOperation::ReadOpcode) {
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::X),
|
printf(" a:%04x x:%04x y:%04x s:%04x e:%d p:%02x db:%02x pb:%02x d:%04x\n",
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::Y),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::A),
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::StackPointer),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::X),
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::EmulationFlag),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::Y),
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::Flags),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::StackPointer),
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::DataBank),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::EmulationFlag),
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::ProgramBank),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::Flags),
|
||||||
// m65816_.get_value_of_register(CPU::WDC65816::Register::Direct)
|
m65816_.get_value_of_register(CPU::WDC65816::Register::DataBank),
|
||||||
// );
|
m65816_.get_value_of_register(CPU::WDC65816::Register::ProgramBank),
|
||||||
// } else printf("\n");
|
m65816_.get_value_of_register(CPU::WDC65816::Register::Direct)
|
||||||
|
);
|
||||||
|
} else printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
Cycles duration = Cycles(5);
|
Cycles duration = Cycles(5);
|
||||||
|
|
||||||
@ -333,9 +429,7 @@ class ConcreteMachine:
|
|||||||
CPU::WDC65816::Processor<ConcreteMachine, false> m65816_;
|
CPU::WDC65816::Processor<ConcreteMachine, false> m65816_;
|
||||||
MemoryMap memory_;
|
MemoryMap memory_;
|
||||||
|
|
||||||
Apple::Clock::ParallelClock clock_;
|
// MARK: - Timing.
|
||||||
Apple::IIgs::Video::Video video_;
|
|
||||||
Apple::IIgs::ADB::GLU adb_glu_;
|
|
||||||
|
|
||||||
int fast_access_phase_ = 0;
|
int fast_access_phase_ = 0;
|
||||||
int slow_access_phase_ = 0;
|
int slow_access_phase_ = 0;
|
||||||
@ -348,7 +442,18 @@ class ConcreteMachine:
|
|||||||
std::vector<uint8_t> rom_;
|
std::vector<uint8_t> rom_;
|
||||||
|
|
||||||
// MARK: - Other components.
|
// MARK: - Other components.
|
||||||
|
|
||||||
|
Apple::Clock::ParallelClock clock_;
|
||||||
|
Apple::IIgs::Video::Video video_;
|
||||||
|
Apple::IIgs::ADB::GLU adb_glu_;
|
||||||
Zilog::SCC::z8530 scc_;
|
Zilog::SCC::z8530 scc_;
|
||||||
|
|
||||||
|
// MARK: - Cards.
|
||||||
|
|
||||||
|
// TODO: most of cards.
|
||||||
|
uint8_t card_mask_ = 0x00;
|
||||||
|
|
||||||
|
bool test_mode_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ class MemoryMap {
|
|||||||
const uint8_t diff = value ^ shadow_register_;
|
const uint8_t diff = value ^ shadow_register_;
|
||||||
shadow_register_ = value;
|
shadow_register_ = value;
|
||||||
|
|
||||||
if(diff & 0x40) { // IO/language-card inhibit
|
if(diff & 0x40) { // IO/language-card inhibit.
|
||||||
set_language_card_paging();
|
set_language_card_paging();
|
||||||
set_card_paging();
|
set_card_paging();
|
||||||
}
|
}
|
||||||
|
@ -1097,7 +1097,6 @@ void ProcessorStorage::set_emulation_mode(bool enabled) {
|
|||||||
|
|
||||||
if(enabled) {
|
if(enabled) {
|
||||||
set_m_x_flags(true, true);
|
set_m_x_flags(true, true);
|
||||||
registers_.x.halves.high = registers_.y.halves.high = 0;
|
|
||||||
registers_.e_masks[0] = 0xff00;
|
registers_.e_masks[0] = 0xff00;
|
||||||
registers_.e_masks[1] = 0x00ff;
|
registers_.e_masks[1] = 0x00ff;
|
||||||
} else {
|
} else {
|
||||||
@ -1109,17 +1108,24 @@ void ProcessorStorage::set_emulation_mode(bool enabled) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ProcessorStorage::set_m_x_flags(bool m, bool x) {
|
void ProcessorStorage::set_m_x_flags(bool m, bool x) {
|
||||||
// true/1 => 8bit for both flags.
|
// Reset the top byte of x and y if _exiting_ 8-bit mode.
|
||||||
registers_.mx_flags[0] = m;
|
// TODO: rationalise this sort of logic, both here and
|
||||||
registers_.mx_flags[1] = x;
|
// with regards to the stack pointer.
|
||||||
|
if(!x && registers_.mx_flags[1]) {
|
||||||
|
registers_.x.halves.high = registers_.y.halves.high = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
registers_.x_masks[0] = x ? 0xff00 : 0x0000;
|
||||||
|
registers_.x_masks[1] = x ? 0x00ff : 0xffff;
|
||||||
|
registers_.x_shift = x ? 0 : 8;
|
||||||
|
|
||||||
registers_.m_masks[0] = m ? 0xff00 : 0x0000;
|
registers_.m_masks[0] = m ? 0xff00 : 0x0000;
|
||||||
registers_.m_masks[1] = m ? 0x00ff : 0xffff;
|
registers_.m_masks[1] = m ? 0x00ff : 0xffff;
|
||||||
registers_.m_shift = m ? 0 : 8;
|
registers_.m_shift = m ? 0 : 8;
|
||||||
|
|
||||||
registers_.x_masks[0] = x ? 0xff00 : 0x0000;
|
// true/1 => 8bit for both flags.
|
||||||
registers_.x_masks[1] = x ? 0x00ff : 0xffff;
|
registers_.mx_flags[0] = m;
|
||||||
registers_.x_shift = x ? 0 : 8;
|
registers_.mx_flags[1] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ProcessorStorage::get_flags() const {
|
uint8_t ProcessorStorage::get_flags() const {
|
||||||
|
Loading…
Reference in New Issue
Block a user