Skip to content

Commit

Permalink
Fixed GPIO Interrupt
Browse files Browse the repository at this point in the history
  • Loading branch information
telecomadm1145 committed Aug 20, 2024
1 parent 8450a90 commit 62fa758
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 16 deletions.
2 changes: 2 additions & 0 deletions CasioEmuMsvc/Chipset/Chipset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ namespace casioemu {
return nullptr;
}
Chipset::Chipset(Emulator& _emulator) : emulator(_emulator), cpu(*new CPU(emulator)), mmu(*new MMU(emulator)) {
tiDiagMode = false;
tiKey = 0;
}

void Chipset::Setup() {
Expand Down
2 changes: 1 addition & 1 deletion CasioEmuMsvc/Ext/LabelFile.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <fstream>
#include <iostream>
#include <sstream>
Expand Down
67 changes: 53 additions & 14 deletions CasioEmuMsvc/Peripheral/ML620Ports.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "ML620Ports.h"
#include "ML620Ports.h"
#include "Chipset.hpp"
#include "Config.hpp"
#include "Emulator.hpp"
#include "MMURegion.hpp"
#include "Peripheral.hpp"
#define DefSfr(x) \
Expand Down Expand Up @@ -29,13 +31,13 @@ namespace casioemu {
DefSfr(ic);
DefSfr(iu);

// 端口电平
// 端口电平
uint8_t PortLevel{};

public:
// 端口电平输入
// 端口电平输入
uint8_t PortInput{};
// 端口电平输入是否存在(悬空)
// 端口电平输入是否存在(悬空)
uint8_t PortInputExists{};

private:
Expand Down Expand Up @@ -115,7 +117,7 @@ namespace casioemu {
},
emulator);
}
// 启用 IS
// 启用 IS
reg_ie.Setup(
pbase++, 1, "PortN/Enable", this, MMURegion::IgnoreRead<0>,
[](MMURegion* reg, size_t off, uint8_t dat) {
Expand All @@ -124,9 +126,9 @@ namespace casioemu {
p->UpdateStatus();
},
emulator);
// 这是只读寄存器 xd
// 这是只读寄存器 xd
reg_is.Setup(pbase++, 1, "PortN/Status", &dat_is, MMURegion::DefaultRead<uint8_t>, MMURegion::IgnoreWrite, emulator);
// 清除 IS
// 清除 IS
reg_ic.Setup(
pbase++, 1, "PortN/Clear", this, MMURegion::IgnoreRead<0>,
[](MMURegion* reg, size_t off, uint8_t dat) {
Expand Down Expand Up @@ -195,9 +197,9 @@ namespace casioemu {
public:
ML620Port* ports[16]{};
MMURegion ExiSelect{};
uint8_t ExiSelect_d[8];
uint8_t ExiSelect_d[8]{};
MMURegion ExiCon{};
uint8_t ExiCon_d[4];
uint8_t ExiCon_d[4]{};
Ports(Emulator& emu) : Peripheral(emu) {
}
void Initialise() override {
Expand All @@ -208,16 +210,35 @@ namespace casioemu {
ExiSelect.Setup(
0xF048, 8, "Ports/ExiSelect", this,
[](MMURegion* reg, size_t offset) -> uint8_t {

auto pt = (Ports*)reg->userdata;
return pt->ExiSelect_d[offset & 0x7];
},
[](MMURegion* reg, size_t offset, uint8_t dat) {

auto pt = (Ports*)reg->userdata;
pt->ExiSelect_d[offset & 0x7] = dat;
},
emulator);
ExiCon.Setup(
0xF040, 4, "Ports/ExiCon", this,
[](MMURegion* reg, size_t offset) -> uint8_t {
auto pt = (Ports*)reg->userdata;
return pt->ExiCon_d[offset & 0x3];
},
[](MMURegion* reg, size_t offset, uint8_t dat) {
auto pt = (Ports*)reg->userdata;
pt->ExiCon_d[offset & 0x3] = dat;
},
emulator);
ExiCon.Setup(0xF040, 4, "Ports/ExiCon", this, );
}
bool PortExiSelect(int i) {
return 1;
for (size_t j = 0; j < 8; j++) {
if (
((ExiSelect_d[j] >> 4) == i) &&
((ExiSelect_d[j] & 0xf) == 0x8)) {
return 1;
}
}
return 0;
}
void* QueryInterface(const char* name) override {
if (strcmp(name, typeid(IPortProvider).name()) == 0) {
Expand All @@ -226,11 +247,29 @@ namespace casioemu {
return 0;
}
void PortTriggerInterrupt(int i) {
size_t k = -1;
for (size_t j = 0; j < 8; j++) {
if (((ExiSelect_d[j] >> 4) == i) &&
((ExiSelect_d[j] & 0xf) == 0x8)) {
emulator.chipset.MaskableInterrupts[7 + j].TryRaise();
}
}
}
void PortsTriggerInterrupt(int i, uint8_t Before, uint8_t After) {
for (size_t j = 0; j < 8; j++) {
if ((ExiSelect_d[j] >> 4) == i) {
auto d = ExiSelect_d[j] & 0xf;
if (d > 7)
continue;
auto rise = ExiCon_d[1], fall = ExiCon_d[0];
auto it = ((After & (After ^ Before) & rise) | (Before & (After ^ Before) & fall)) & (1 << d);
if (it)
emulator.chipset.MaskableInterrupts[7 + j].TryRaise();
}
}
}

// 通过 IPortProvider 继承
// 通过 IPortProvider 继承
void SetPortOutputCallback(int port, std::function<void(uint8_t new_output)> callback) override {
if (port >= 0 && port < 16 && ports[port]) {
ports[port]->SetOutputCallback(callback);
Expand Down
2 changes: 1 addition & 1 deletion CasioEmuMsvc/Peripheral/ML620Ports.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <Peripheral.hpp>
#include <functional>
namespace casioemu {
Expand Down

0 comments on commit 62fa758

Please sign in to comment.