Skip to content

Commit

Permalink
[i8048] Detect MSM80C48 variant
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Jun 11, 2024
1 parent 5b268af commit bf1d614
Show file tree
Hide file tree
Showing 15 changed files with 133 additions and 113 deletions.
2 changes: 2 additions & 0 deletions debugger/i8048/inst_i8048.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
namespace debugger {
namespace i8048 {

struct InstI8048 Inst;

namespace {

constexpr uint8_t E(uint8_t len, uint8_t cyc, uint8_t flags) {
Expand Down
31 changes: 18 additions & 13 deletions debugger/i8048/inst_i8048.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,17 @@
#define __INST_I8048_H__

#include <stdint.h>
#include "pins_i8048.h"

namespace debugger {
namespace i8048 {

struct InstI8048 final {
enum CpuFlags : uint8_t {
F_80C39 = 0x2,
F_MSM39 = 0x4,
F_X8048 = 0x8,
F_I8039 = 0x1,
F_I80C39 = F_I8039 | F_80C39,
F_MSM80C39 = F_I8039 | F_80C39 | F_MSM39,
F_I8048 = F_X8048 | F_I8039,
F_I80C48 = F_X8048 | F_I8039 | F_80C39,
F_MSM80C48 = F_X8048 | F_I8039 | F_80C39 | F_MSM39,
};
InstI8048() : _flags(F_MSM80C39) {}

InstI8048(CpuFlags flags) : _flags(flags) {}
void setSoftwareType(SoftwareType type) {
_flags = (type == SW_I8048) ? F_I8039 : F_MSM80C39;
}

uint8_t instLength(uint8_t inst) const;
uint8_t busCycles(uint8_t inst) const;
Expand All @@ -41,12 +34,24 @@ struct InstI8048 final {
static constexpr uint8_t mb(uint16_t addr) { return (addr >> 11) & 1; }

private:
const CpuFlags _flags;
enum CpuFlags : uint8_t {
F_80C39 = 0x2,
F_MSM39 = 0x4,
F_X8048 = 0x8,
F_I8039 = 0x1,
F_I80C39 = F_I8039 | F_80C39,
F_MSM80C39 = F_I8039 | F_80C39 | F_MSM39,
F_I8048 = F_X8048 | F_I8039,
F_I80C48 = F_X8048 | F_I8039 | F_80C39,
F_MSM80C48 = F_X8048 | F_I8039 | F_80C39 | F_MSM39,
} _flags;

static constexpr uint8_t SEL_MB0 = 0xE5;
static constexpr uint8_t SEL_MB1 = 0xF5;
};

extern struct InstI8048 Inst;

} // namespace i8048
} // namespace debugger
#endif
Expand Down
9 changes: 5 additions & 4 deletions debugger/i8048/mems_i8048.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace debugger {
namespace i8048 {

struct ProgI8048 ProgMemory;
struct DataI8048 DataMemory;

uint16_t DataI8048::read(uint32_t addr) const {
Expand All @@ -28,7 +29,7 @@ uint16_t ProgI8048::get(uint32_t addr, const char *space) const {
if (space == nullptr || toupper(*space) == 'P')
return raw_read(addr);
if (toupper(*space) == 'M')
return _regs.read_internal(addr);
return Regs.read_internal(addr);
if (toupper(*space) == 'X')
return DataMemory.read(addr);
return 0;
Expand All @@ -38,7 +39,7 @@ void ProgI8048::put(uint32_t addr, uint16_t data, const char *space) const {
if (space == nullptr || toupper(*space) == 'P') {
raw_write(addr, data);
} else if (toupper(*space) == 'M') {
_regs.write_internal(addr, data);
Regs.write_internal(addr, data);
} else if (toupper(*space) == 'X') {
DataMemory.write(addr, data);
}
Expand All @@ -47,15 +48,15 @@ void ProgI8048::put(uint32_t addr, uint16_t data, const char *space) const {
#ifdef WITH_ASSEMBLER
libasm::Assembler *ProgI8048::assembler() const {
static auto as = new libasm::i8048::AsmI8048();
as->setCpu(_regs.cpu());
as->setCpu(Regs.cpu());
return as;
}
#endif

#ifdef WITH_DISASSEMBLER
libasm::Disassembler *ProgI8048::disassembler() const {
static auto dis = new libasm::i8048::DisI8048();
dis->setCpu(_regs.cpu());
dis->setCpu(Regs.cpu());
return dis;
}
#endif
Expand Down
4 changes: 1 addition & 3 deletions debugger/i8048/mems_i8048.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@ namespace i8048 {
struct RegsI8048;

struct ProgI8048 final : DmaMemory {
ProgI8048(RegsI8048 &regs) : DmaMemory(Endian::ENDIAN_BIG), _regs(regs) {}
ProgI8048() : DmaMemory(Endian::ENDIAN_BIG) {}

uint32_t maxAddr() const override { return 0xFFF; }
uint16_t get(uint32_t addr, const char *space = nullptr) const override;
void put(uint32_t addr, uint16_t data,
const char *space = nullptr) const override;

protected:
RegsI8048 &_regs;

#ifdef WITH_ASSEMBLER
libasm::Assembler *assembler() const override;
#endif
Expand Down
49 changes: 35 additions & 14 deletions debugger/i8048/pins_i8048.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
namespace debugger {
namespace i8048 {

struct PinsI8048 Pins;

// clang-format off
/**
* P8048 bus cycle.
Expand Down Expand Up @@ -174,6 +176,24 @@ inline void xtal1_cycle() {

} // namespace

void PinsI8048::checkSoftwareType() {
static constexpr uint8_t DETECT_MSM[] = {
0x23, 0x01, // MOV A, #1
0xA8, // MOV R0, A
0xA9, // MOV R1, A
0xC0, // DEC @R0
0x00, // NOP
0xF9, // MOV A, R1
0x90, // MOVX @R0, A
};
uint8_t r1;
Inst.setSoftwareType(SW_MSM80C48);
captureWrites(DETECT_MSM, sizeof(DETECT_MSM), nullptr, &r1, sizeof(r1));
_type = r1 ? SW_I8048 : SW_MSM80C48;
Inst.setSoftwareType(_type);
Regs.restore();
}

void PinsI8048::reset() {
// Assert reset condition
pinsMode(PINS_LOW, sizeof(PINS_LOW), OUTPUT, LOW);
Expand All @@ -189,7 +209,8 @@ void PinsI8048::reset() {
xtal1_cycle();
Signals::resetCycles();
// #SS=L
_regs.save();
Regs.save();
checkSoftwareType();
}

Signals *PinsI8048::prepareCycle() {
Expand Down Expand Up @@ -224,7 +245,7 @@ Signals *PinsI8048::prepareCycle() {
xtal1_lo();
delayNanoseconds(xtal1_lo_control);
if (signal_ale() != LOW)
break; // found next cycle
break; // found next cycle
const auto valid = s->getControl(); // #PSEN
if (valid) {
// t7
Expand All @@ -243,7 +264,7 @@ Signals *PinsI8048::completeCycle(Signals *s) {
// t8
xtal1_hi();
if (s->readMemory()) {
s->data = _mems.raw_read(s->addr);
s->data = ProgMemory.raw_read(s->addr);
delayNanoseconds(xtal1_hi_memory);
} else {
delayNanoseconds(xtal1_hi_inject);
Expand Down Expand Up @@ -286,7 +307,7 @@ Signals *PinsI8048::completeCycle(Signals *s) {
xtal1_cycle();
xtal1_cycle();
xtal1_cycle_lo();
while (signal_rd() == LOW) // ensure tDR
while (signal_rd() == LOW) // ensure tDR
;
busMode(DB, INPUT);
} else if (s->write()) { // external data write
Expand Down Expand Up @@ -381,14 +402,14 @@ void PinsI8048::loop() {
}

void PinsI8048::run() {
_regs.restore();
Regs.restore();
Signals::resetCycles();
saveBreakInsts();
loop();
assert_ss();
restoreBreakInsts();
disassembleCycles();
_regs.save();
Regs.save();
}

void PinsI8048::injectJumpHere(Signals *s) {
Expand All @@ -413,8 +434,8 @@ void PinsI8048::injectJumpHere(Signals *s) {
bool PinsI8048::rawStep(bool step) {
negate_ss();
auto s = prepareCycle();
const auto inst = _mems.raw_read(s->addr);
const auto len = _inst.instLength(inst);
const auto inst = ProgMemory.raw_read(s->addr);
const auto len = Inst.instLength(inst);
if (inst == InstI8048::HALT || len == 0) {
injectJumpHere(s);
Signals::discard(s);
Expand All @@ -428,7 +449,7 @@ bool PinsI8048::rawStep(bool step) {
}
return true;
}
const auto cycles = _inst.busCycles(inst);
const auto cycles = Inst.busCycles(inst);
completeCycle(s);
for (auto i = 1; i < cycles; ++i) {
completeCycle(prepareCycle())->clearFetch();
Expand All @@ -438,13 +459,13 @@ bool PinsI8048::rawStep(bool step) {

bool PinsI8048::step(bool show) {
Signals::resetCycles();
_regs.restore();
Regs.restore();
if (show)
Signals::resetCycles();
if (rawStep(true)) {
if (show)
printCycles();
_regs.save();
Regs.save();
return true;
}
return false;
Expand All @@ -459,7 +480,7 @@ void PinsI8048::negateInt(uint8_t name) {
}

void PinsI8048::setBreakInst(uint32_t addr) const {
_mems.put_inst(addr, InstI8048::HALT);
ProgMemory.put_inst(addr, InstI8048::HALT);
}

void PinsI8048::printCycles() {
Expand All @@ -477,8 +498,8 @@ void PinsI8048::disassembleCycles() {
for (auto i = 0; i < cycles;) {
const auto s = g->next(i);
if (s->fetch()) {
const auto len = _mems.disassemble(s->addr, 1) - s->addr;
const auto cycles = _inst.busCycles(s->data);
const auto len = ProgMemory.disassemble(s->addr, 1) - s->addr;
const auto cycles = Inst.busCycles(s->data);
for (auto i = len; i < cycles; ++i)
s->next(i)->print();
i += cycles;
Expand Down
16 changes: 11 additions & 5 deletions debugger/i8048/pins_i8048.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ struct RegsI8048;
struct ProgI8048;
struct InstI8048;

enum SoftwareType : uint8_t {
SW_I8048 = 0,
SW_MSM80C48 = 1,
};

struct PinsI8048 final : Pins {
PinsI8048(RegsI8048 &regs, ProgI8048 &mems, const InstI8048 &inst)
: Pins(), _regs(regs), _mems(mems), _inst(inst) {}
void reset() override;
void idle() override;
bool step(bool show) override;
Expand All @@ -78,14 +81,15 @@ struct PinsI8048 final : Pins {
uint8_t captureWrites(const uint8_t *inst, uint8_t len, uint16_t *addr,
uint8_t *buf, uint8_t max);
Signals *cycle(uint8_t data);
SoftwareType softwareType() const { return _type; }

private:
RegsI8048 &_regs;
ProgI8048 &_mems;
const InstI8048 &_inst;
SoftwareType _type;

void setBreakInst(uint32_t addr) const override;

void checkSoftwareType();

Signals *prepareCycle();
Signals *completeCycle(Signals *signals);
void loop();
Expand All @@ -98,6 +102,8 @@ struct PinsI8048 final : Pins {
void disassembleCycles();
};

extern struct PinsI8048 Pins;

} // namespace i8048
} // namespace debugger
#endif /* __PINS_H__ */
Expand Down
Loading

0 comments on commit bf1d614

Please sign in to comment.