Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
telecomadm1145 committed Aug 11, 2024
1 parent b851f75 commit a98b3a6
Show file tree
Hide file tree
Showing 12 changed files with 918 additions and 609 deletions.
130 changes: 101 additions & 29 deletions CasioEmuMsvc/Chipset/Chipset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
#include "../Peripheral/Timer.hpp"
#include "../Peripheral/TimerBaseCounter.hpp"
#include "../Peripheral/WatchdogTimer.hpp"
#include "Uart.h"
#include "../Romu.h"
#include "CPU.hpp"
#include "Uart.h"
// #include "HighResClock.h"
#include "InterruptSource.hpp"
#include "MMU.hpp"
Expand All @@ -43,7 +43,7 @@ namespace casioemu {
pending_interrupt_count = 0;

cpu.SetMemoryModel(CPU::MM_LARGE);
cpu.SetCPUModel(emulator.hardware_id == HW_CLASSWIZ || emulator.hardware_id == HW_CLASSWIZ_II ? CPU::CM_NX_U16 : CPU::CM_NX_U8);
cpu.SetCPUModel(emulator.hardware_id == HW_CLASSWIZ || emulator.hardware_id == HW_CLASSWIZ_II || emulator.hardware_id == HW_TI ? CPU::CM_NX_U16 : CPU::CM_NX_U8);

std::initializer_list<int> segments_es_plus{0, 1, 8}, segments_classwiz{0, 1, 2, 3, 4, 5}, segments_classwiz_ii{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
for (auto segment_index : emulator.hardware_id == HW_ES_PLUS ? segments_es_plus : emulator.hardware_id == HW_CLASSWIZ ? segments_classwiz
Expand Down Expand Up @@ -137,18 +137,44 @@ namespace casioemu {
LSCLKFreq = 16384;

ResetClockGenerator();

region_FCON.Setup(
0xF00A, 1, "ClockGenerator/FCON", this, [](MMURegion* region, size_t) {
if (emulator.hardware_id == HW_TI) {
region_LTBR.Setup(
0xF060, 1, "TimerBaseCounter/LTBR", this, [](MMURegion* region, size_t) {
Chipset* chipset = (Chipset*)region->userdata;
return chipset->data_LTBR; }, [](MMURegion* region, size_t, uint8_t data) {
Chipset* chipset = (Chipset*)region->userdata;
chipset->data_LTBR = 0;
chipset->LTBCReset = true;
chipset->LSCLKTick = true;
chipset->LSCLKTickCounter = 0;
chipset->LSCLKTimeCounter = 0;
chipset->LSCLKFreqAddition = 0; }, emulator);
region_LTBADJ.Setup(
0xF064, 2, "TimerBaseCounter/LTBADJ", this, [](MMURegion* region, size_t offset) {
Chipset* chipset = (Chipset*)region->userdata;
offset -= region->base;
return (uint8_t)((chipset->data_LTBADJ & 0x7FF) >> offset * 8); }, [](MMURegion* region, size_t offset, uint8_t data) {
Chipset* chipset = (Chipset*)region->userdata;
offset -= region->base;
chipset->data_LTBADJ = (chipset->data_LTBADJ & (~(0xFF << offset * 8))) | (data << offset * 8);
chipset->data_LTBADJ &= 0x7FF;
if(chipset->data_LTBADJ != 0)
chipset->LSCLKThresh = (chipset->LSCLKFreq * (1 + 2097152 / (short)chipset->data_LTBADJ)) / chipset->emulator.GetCyclesPerSecond();
else
chipset->LSCLKThresh = 0; }, emulator);
}
else {
region_FCON.Setup(
0xF00A, 1, "ClockGenerator/FCON", this, [](MMURegion* region, size_t) {
Chipset* chipset = (Chipset*)region->userdata;
return chipset->data_FCON; }, [](MMURegion* region, size_t, uint8_t data) {
Chipset* chipset = (Chipset*)region->userdata;
uint8_t OSCLK = (data & 0x70) >> 4;
chipset->data_FCON = data & 0x73;
chipset->ClockDiv = static_cast<int>(std::pow(2, OSCLK == 0 ? OSCLK : OSCLK - 1));
chipset->LSCLKMode = (chipset->data_FCON & 0x03) == 1 ? true : false; }, emulator);
region_LTBR.Setup(
0xF00C, 1, "TimerBaseCounter/LTBR", this, [](MMURegion* region, size_t) {
region_LTBR.Setup(
0xF00C, 1, "TimerBaseCounter/LTBR", this, [](MMURegion* region, size_t) {
Chipset* chipset = (Chipset*)region->userdata;
return chipset->data_LTBR; }, [](MMURegion* region, size_t, uint8_t data) {
Chipset* chipset = (Chipset*)region->userdata;
Expand All @@ -158,8 +184,8 @@ namespace casioemu {
chipset->LSCLKTickCounter = 0;
chipset->LSCLKTimeCounter = 0;
chipset->LSCLKFreqAddition = 0; }, emulator);
region_HTBR.Setup(
0xF00D, 1, "ClockGenerator/HTBR", this, [](MMURegion* region, size_t) {
region_HTBR.Setup(
0xF00D, 1, "ClockGenerator/HTBR", this, [](MMURegion* region, size_t) {
Chipset* chipset = (Chipset*)region->userdata;
return chipset->data_HTBR; }, [](MMURegion* region, size_t, uint8_t data) {
Chipset* chipset = (Chipset*)region->userdata;
Expand All @@ -168,8 +194,8 @@ namespace casioemu {
chipset->HTBCReset = true;
chipset->HSCLKTick = true;
chipset->HSCLKTickCounter = 0; }, emulator);
region_LTBADJ.Setup(
0xF006, 2, "TimerBaseCounter/LTBADJ", this, [](MMURegion* region, size_t offset) {
region_LTBADJ.Setup(
0xF006, 2, "TimerBaseCounter/LTBADJ", this, [](MMURegion* region, size_t offset) {
Chipset* chipset = (Chipset*)region->userdata;
offset -= region->base;
return (uint8_t)((chipset->data_LTBADJ & 0x7FF) >> offset * 8); }, [](MMURegion* region, size_t offset, uint8_t data) {
Expand All @@ -181,6 +207,7 @@ namespace casioemu {
chipset->LSCLKThresh = (chipset->LSCLKFreq * (1 + 2097152 / (short)chipset->data_LTBADJ)) / chipset->emulator.GetCyclesPerSecond();
else
chipset->LSCLKThresh = 0; }, emulator);
}
}

void Chipset::GenerateTickForClock() {
Expand Down Expand Up @@ -293,31 +320,36 @@ namespace casioemu {

ioport = new IOPorts(emulator);
EXIhandle = new ExternalInterrupts(emulator);

peripherals.push_front(ioport);
peripherals.push_front(EXIhandle);
peripherals.push_front(CreateRomWindow(emulator));
peripherals.push_front(CreateBatteryBackedRAM(emulator));
peripherals.push_front(CreateScreen(emulator));
peripherals.push_front(ioport);
peripherals.push_front(EXIhandle);
peripherals.push_front(CreateKeyboard(emulator));
peripherals.push_front(CreateStbCtrl(emulator));
peripherals.push_front(CreateMiscellaneous(emulator));
peripherals.push_front(CreateTimer(emulator));
if (emulator.hardware_id != HW_FX_5800P) // 0x100000
peripherals.push_front(CreatePowerSupply(emulator));
if (emulator.hardware_id == HW_FX_5800P)
peripherals.push_front(CreateFx5800Flash(emulator));
if (emulator.hardware_id == HW_CLASSWIZ_II) {
peripherals.push_front(CreateUart(emulator));
if (emulator.hardware_id == HW_TI) {
peripherals.push_front(CreateTimer(emulator));
peripherals.push_front(CreateWatchdog(emulator));
}
else {
peripherals.push_front(CreateTimer(emulator));
if (emulator.hardware_id != HW_FX_5800P) // 0x100000
peripherals.push_front(CreatePowerSupply(emulator));
if (emulator.hardware_id == HW_FX_5800P)
peripherals.push_front(CreateFx5800Flash(emulator));
if (emulator.hardware_id == HW_CLASSWIZ_II) {
peripherals.push_front(CreateUart(emulator));
}
peripherals.push_front(CreateBuzzerDriver(emulator));
peripherals.push_front(CreateTimerBaseCounter(emulator));
peripherals.push_front(CreateRtc(emulator));
peripherals.push_front(CreateWatchdog(emulator));
if (emulator.hardware_id == HW_CLASSWIZ_II)
peripherals.push_front(CreateBcdCalc(emulator));
if (emulator.hardware_id == HW_CLASSWIZ)
peripherals.push_front(CreateFlash(emulator));
}
peripherals.push_front(CreateBuzzerDriver(emulator));
peripherals.push_front(CreateTimerBaseCounter(emulator));
peripherals.push_front(CreateRtc(emulator));
peripherals.push_front(CreateWatchdog(emulator));
if (emulator.hardware_id == HW_CLASSWIZ_II)
peripherals.push_front(CreateBcdCalc(emulator));
if (emulator.hardware_id == HW_CLASSWIZ)
peripherals.push_front(CreateFlash(emulator));
}

void Chipset::DestructPeripherals() {
Expand Down Expand Up @@ -478,6 +510,46 @@ namespace casioemu {
}

void Chipset::RaiseSoftware(size_t index) {
if (emulator.hardware_id == HW_TI) {
if (index == 0x1) {
std::cout << "SWI #1\n";
// Screen changed.
ti_render_screen = true;
ti_screen_buf = (int)(emulator.chipset.cpu.reg_r[0] & 0xff | (emulator.chipset.cpu.reg_r[1] << 8));
emulator.chipset.cpu.reg_r[1] = 0;
emulator.chipset.cpu.reg_r[0] = 0;
}
else if (index == 0x2) {
if (ti_key != 0)
std::cout << "Write Key " << std::hex << (int)ti_key << std::oct << "\n";
int i = 300;
while ((i > 0) && ti_key ==0) {
i-=24;
SDL_Delay(24);
}
emulator.chipset.cpu.reg_r[1] = 0;
emulator.chipset.cpu.reg_r[0] = ti_key;
ti_key = 0;
}
else if (index == 0x3) {
std::cout << "SWI #3\n";
// UART?
emulator.chipset.cpu.reg_r[1] = 0;
emulator.chipset.cpu.reg_r[0] = 0;
}
else if (index == 0x4) {
ti_status_buf = (int)(emulator.chipset.cpu.reg_r[0] & 0xff | (emulator.chipset.cpu.reg_r[1] << 8));
ti_render_screen = true;
emulator.chipset.cpu.reg_r[1] = 0;
emulator.chipset.cpu.reg_r[0] = 0;
// callTopIconsChanged
}
else if (index == 0x5) {
std::cout << "SWI #5\n";
// Notify the key event processor that a key can repeat
}
return;
}
index += 0x40;
if (interrupts_active[index])
return;
Expand Down
6 changes: 6 additions & 0 deletions CasioEmuMsvc/Chipset/Chipset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ namespace casioemu {

bool isMIBlocked;

// TI syscalls.
uint16_t ti_screen_buf = 0;
bool ti_render_screen = 0;
uint8_t ti_key = 0;
uint16_t ti_status_buf = 0;

/**
* This exists because the Emulator that owns this Chipset is not ready
* to supply a ROM path upon construction. It has to call `LoadROM` later
Expand Down
3 changes: 2 additions & 1 deletion CasioEmuMsvc/Chipset/MMU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ namespace casioemu {
return le_read(rom[offset]);
else
return 0;
case HW_TI:
case HW_CLASSWIZ:
if (emulator.chipset.SegmentAccess && segment_index == 5)
segment_index = 0;
Expand Down Expand Up @@ -191,8 +192,8 @@ namespace casioemu {

MemoryByte& byte = segment[segment_offset];
MMURegion* region = byte.region;

if (!region) {
std::cout << std::hex << offset << std::oct << "\n";
return;
}
region->write(region, offset, data);
Expand Down
1 change: 1 addition & 0 deletions CasioEmuMsvc/Chipset/MMURegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../Emulator.hpp"
#include "Chipset.hpp"
#include "MMU.hpp"
#include <functional>

namespace casioemu
{
Expand Down
63 changes: 27 additions & 36 deletions CasioEmuMsvc/Chipset/MMURegion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,81 +2,72 @@
#include "../Config.hpp"

#include "../Logger.hpp"

#include <cstdint>
#include <string>

namespace casioemu
{
namespace casioemu {
class Emulator;

struct MMURegion
{
typedef uint8_t (*ReadFunction)(MMURegion *, size_t);
typedef void (*WriteFunction)(MMURegion *, size_t, uint8_t);
struct MMURegion {
typedef uint8_t (*ReadFunction)(MMURegion*, size_t);
typedef void (*WriteFunction)(MMURegion*, size_t, uint8_t);

size_t base, size;
std::string description;
void *userdata;
void* userdata;
ReadFunction read;
WriteFunction write;
bool setup_done;
Emulator *emulator;
Emulator* emulator;

MMURegion();
// Note: it should not be possible to copy region because there can only be at most one region
// registered for each memory byte
MMURegion(const MMURegion &) = delete;
MMURegion(const MMURegion&) = delete;
// Note: registered regions are referenced by pointer so they should not change their address
MMURegion(MMURegion &&) = delete;
MMURegion &operator=(const MMURegion &) = delete;
MMURegion &operator=(MMURegion &&) = delete;
MMURegion(MMURegion&&) = delete;
MMURegion& operator=(const MMURegion&) = delete;
MMURegion& operator=(MMURegion&&) = delete;
~MMURegion();
void Setup(size_t base, size_t size, std::string description, void *userdata, ReadFunction read, WriteFunction write, Emulator &emulator);
void Setup(size_t base, size_t size, std::string description, void* userdata, ReadFunction read, WriteFunction write, Emulator& emulator);
void Kill();

template<uint8_t read_value>
static uint8_t IgnoreRead(MMURegion *, size_t)
{
template <uint8_t read_value>
static uint8_t IgnoreRead(MMURegion*, size_t) {
return read_value;
}

static void IgnoreWrite(MMURegion *, size_t, uint8_t)
{
static void IgnoreWrite(MMURegion*, size_t, uint8_t) {
}

template<typename value_type, value_type mask = (value_type)-1>
static uint8_t DefaultRead(MMURegion *region, size_t offset)
{
value_type *value = (value_type *)(region->userdata);
template <typename value_type, value_type mask = (value_type)-1>
static uint8_t DefaultRead(MMURegion* region, size_t offset) {
value_type* value = (value_type*)(region->userdata);
return ((*value) & mask) >> ((offset - region->base) * 8);
}

template<typename value_type, value_type mask = (value_type)-1>
static void DefaultWrite(MMURegion *region, size_t offset, uint8_t data)
{
value_type *value = (value_type *)(region->userdata);
template <typename value_type, value_type mask = (value_type)-1>
static void DefaultWrite(MMURegion* region, size_t offset, uint8_t data) {
value_type* value = (value_type*)(region->userdata);
*value &= ~(((value_type)0xFF) << ((offset - region->base) * 8));
*value |= ((value_type)data) << ((offset - region->base) * 8);
*value &= mask;
}

template<typename value_type, value_type mask = (value_type)-1>
static uint8_t DefaultReadLog(MMURegion *region, size_t offset)
{
template <typename value_type, value_type mask = (value_type)-1>
static uint8_t DefaultReadLog(MMURegion* region, size_t offset) {
logger::Info("SFR read from %06X\n", offset);
value_type *value = (value_type *)(region->userdata);
value_type* value = (value_type*)(region->userdata);
return ((*value) & mask) >> ((offset - region->base) * 8);
}

template<typename value_type, value_type mask = (value_type)-1>
static void DefaultWriteLog(MMURegion *region, size_t offset, uint8_t data)
{
value_type *value = (value_type *)(region->userdata);
template <typename value_type, value_type mask = (value_type)-1>
static void DefaultWriteLog(MMURegion* region, size_t offset, uint8_t data) {
value_type* value = (value_type*)(region->userdata);
*value &= ~(((value_type)0xFF) << ((offset - region->base) * 8));
*value |= ((value_type)data) << ((offset - region->base) * 8);
*value &= mask;
logger::Info("SFR write to %06X (%02X)\n", offset, data);
}
};
}
} // namespace casioemu
5 changes: 4 additions & 1 deletion CasioEmuMsvc/ModelInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ namespace casioemu {
HW_CLASSWIZ = 4,
HW_CLASSWIZ_II = 5,
HW_FX_5800P = 6,
HW_MAX = 6,
HW_TI = 7,
HW_SOLARII = 8,

HW_MAX = 8,
};
struct SpriteInfo {
SDL_Rect src, dest;
Expand Down
Loading

0 comments on commit a98b3a6

Please sign in to comment.