diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index 0a48f4308..3e140e32e 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -35,10 +35,18 @@ class ConcreteMachine: public: ConcreteMachine(const Analyser::Static::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : z80_(*this), - sn76489_(TI::SN76489::Personality::SN76489, audio_queue_, sn76489_divider), + sn76489_(TI::SN76489::Personality::SMS, audio_queue_, sn76489_divider), speaker_(sn76489_) { speaker_.set_input_rate(3579545.0f / static_cast(sn76489_divider)); set_clock_rate(3579545); + + const auto roms = rom_fetcher("MasterSystem", {"bios.sms"}); + if(!roms[0]) { + throw ROMMachine::Error::MissingROMs; + } + + roms[0]->resize(8*1024); + memcpy(&bios_, roms[0]->data(), roms[0]->size()); } ~ConcreteMachine() { @@ -46,7 +54,7 @@ class ConcreteMachine: } void setup_output(float aspect_ratio) override { - vdp_.reset(new TI::TMS::TMS9918(TI::TMS::TMS9918A)); + vdp_.reset(new TI::TMS::TMS9918(TI::TMS::SMSVDP)); get_crt()->set_video_signal(Outputs::CRT::VideoSignal::Composite); } @@ -70,6 +78,69 @@ class ConcreteMachine: time_since_vdp_update_ += cycle.length; time_since_sn76489_update_ += cycle.length; + if(cycle.is_terminal()) { + uint16_t address = cycle.address ? *cycle.address : 0x0000; + switch(cycle.operation) { + case CPU::Z80::PartialMachineCycle::ReadOpcode: +// printf("%04x [%02x]\n", address, bios_[address]); + case CPU::Z80::PartialMachineCycle::Read: + if(address < 0x2000) { + *cycle.value = bios_[address]; + } else if(address >= 0xc000) { + *cycle.value = ram_[address & 8191]; + } else { + *cycle.value = 0xff; + } + break; + + case CPU::Z80::PartialMachineCycle::Write: + if(address >= 0xc000) { + ram_[address & 8191] = *cycle.value; +// printf("w %04x\n", address); + } else { +// printf("mw %04x\n", address); + } + break; + + case CPU::Z80::PartialMachineCycle::Input: + printf("Input %04x\n", address); + break; + + case CPU::Z80::PartialMachineCycle::Output: + switch(address & 0xc1) { + case 0x00: + printf("TODO: memory control\n"); + break; + case 0x01: + printf("TODO: I/O port control\n"); + break; + case 0x40: case 0x41: + update_audio(); + sn76489_.set_register(*cycle.value); + break; + case 0x80: case 0x81: + update_video(); + vdp_->set_register(address, *cycle.value); + break; + case 0xc0: + printf("TODO: I/O port A/N\n"); + break; + case 0xc1: + printf("TODO: I/O port B/misc\n"); + break; + + default: break; + } + break; + + case CPU::Z80::PartialMachineCycle::Interrupt: + *cycle.value = 0xff; + break; + + default: break; + } + } + if(time_until_interrupt_ > 0) { time_until_interrupt_ -= cycle.length; if(time_until_interrupt_ <= HalfCycles(0)) { @@ -104,6 +175,9 @@ class ConcreteMachine: HalfCycles time_since_vdp_update_; HalfCycles time_since_sn76489_update_; HalfCycles time_until_interrupt_; + + uint8_t ram_[8*1024]; + uint8_t bios_[8*1024]; }; } diff --git a/ROMImages/MasterSystem/readme.txt b/ROMImages/MasterSystem/readme.txt new file mode 100644 index 000000000..ed5073cc9 --- /dev/null +++ b/ROMImages/MasterSystem/readme.txt @@ -0,0 +1,5 @@ +BIOS files would ordinarily go here; the copyright status of these is uncertain so they have not been included in this repository. + +Expected files: + +bios.sms — the EU/US Master System BIOS. \ No newline at end of file