Skip to content

Commit

Permalink
[TMS7000] Support TMS7000 /4 clock option variants
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Jun 12, 2024
1 parent 9ed2e61 commit 9a7509e
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 59 deletions.
169 changes: 116 additions & 53 deletions debugger/tms7000/pins_tms7000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ struct PinsTms7000 Pins;

namespace {

constexpr auto clkin_hi_ns = 500;
constexpr auto clkin_lo_ns = 500;
constexpr auto clkin2_hi_ns = 500;
constexpr auto clkin2_lo_ns = 500;
constexpr auto clkin4_hi_ns = 250;
constexpr auto clkin4_lo_ns = 250;

inline void clkin_hi() {
digitalWriteFast(PIN_CLKIN, HIGH);
Expand All @@ -60,7 +62,11 @@ inline auto signal_rw() {
return digitalReadFast(PIN_RW);
}

void negate_reset() {
inline void assert_reset() {
digitalWriteFast(PIN_RESET, LOW);
}

inline void negate_reset() {
digitalWriteFast(PIN_RESET, HIGH);
}

Expand Down Expand Up @@ -109,32 +115,91 @@ const uint8_t PINS_INPUT[] = {
PIN_PB3,
};

inline void clkin_cycle_lo() {
inline void clkin2_cycle() {
clkin_hi();
delayNanoseconds(clkin_hi_ns);
delayNanoseconds(clkin2_hi_ns);
clkin_lo();
delayNanoseconds(clkin2_lo_ns);
}

inline void clkin_cycle() {
clkin_cycle_lo();
delayNanoseconds(clkin_lo_ns);
inline void clkin4_cycle_hi() {
clkin_lo();
delayNanoseconds(clkin4_lo_ns);
clkin_hi();
}

} // namespace

void (*PinsTms7000::_clk_hi)();
void (*PinsTms7000::_clk_lo)();
void (*PinsTms7000::_clk_cycle)();

void PinsTms7000::clk2_hi() {
clkin_hi();
}

void PinsTms7000::clk2_lo() {
clkin_lo();
}

void PinsTms7000::clk4_cycle_hi() {
clkin4_cycle_hi();
}

void PinsTms7000::clk_cycle2() {
clkin2_cycle();
}

void PinsTms7000::clk_cycle4() {
clkin4_cycle_hi();
delayNanoseconds(clkin4_hi_ns);
clkin4_cycle_hi();
delayNanoseconds(clkin4_hi_ns);
}

void PinsTms7000::synchronize_clk() {
// CLKOUT works only when #RESET=H
negate_reset();
while (signal_clkout() != LOW)
clkin2_cycle();
assert_debug();
while (signal_clkout() == LOW)
clkin2_cycle();
// CLKOUT=H
clkin2_cycle(); // /2:CLKOUT=L, /4:CLKOUT=H
clkin2_cycle(); // /2:CLKOUT=H, /4:CLKOUT=L
negate_debug();
if (signal_clkout() != LOW) {
// /2 clock option
_clk_hi = clk2_hi;
_clk_lo = clk2_lo;
_clk_cycle = clk_cycle2;
} else {
// /4 clock option
_clk_hi = clk4_cycle_hi;
_clk_lo = clk4_cycle_hi;
_clk_cycle = clk_cycle4;
clkin_hi();
delayNanoseconds(clkin4_hi_ns);
}
// CLKOUT=H; Assert #RESET again
assert_reset();
}

void PinsTms7000::reset() {
// Assert reset condition
pinsMode(PINS_LOW, sizeof(PINS_LOW), OUTPUT, LOW);
pinsMode(PINS_HIGH, sizeof(PINS_HIGH), OUTPUT, HIGH);
pinsMode(PINS_INPUT, sizeof(PINS_INPUT), INPUT);

synchronize_clk();
// The RESET function is initiated when the #RESET line of the
// TMS7000 device is held at a logic zero level for at least five
// clock cycles.
for (auto i = 0; i < 100; i++)
clkin_cycle();
for (auto i = 0; i < 10; i++)
clk_cycle();
negate_reset();
clkin_cycle();
clk_cycle();
Signals::resetCycles();
// Clear IOCNT0 (>0100) to disable interrupts
cycle();
Expand Down Expand Up @@ -167,80 +232,80 @@ void PinsTms7000::checkHardwareType() {
Signals *PinsTms7000::prepareCycle() const {
auto s = Signals::put();
while (signal_alatch() == LOW)
clkin_cycle();
clk_cycle();
// CLKOUT=H, ALATCH=H
clkin_hi();
delayNanoseconds(clkin_hi_ns);
clk_hi();
delayNanoseconds(clkin2_hi_ns);
// CLKOUT=L
clkin_lo();
// assert_debug();
clk_lo();
assert_debug();
s->getAddress();
// negate_debug();
delayNanoseconds(clkin_lo_ns);
negate_debug();
delayNanoseconds(clkin2_lo_ns);
// CLKOUT=H
clkin_hi();
delayNanoseconds(clkin_hi_ns);
// assert_debug();
clk_hi();
delayNanoseconds(clkin2_hi_ns);
assert_debug();
s->getDirection();
// negate_debug();
negate_debug();
return s;
}

Signals *PinsTms7000::completeCycle(Signals *s) const {
if (s->read()) { // External read
clkin_lo();
clk_lo();
if (s->readMemory()) {
s->data = Memory.read(s->addr);
} else {
; // inject
}
delayNanoseconds(clkin_lo_ns);
delayNanoseconds(clkin2_lo_ns);
// CLKOUT=L
clkin_hi();
// assert_debug();
clk_hi();
assert_debug();
s->outData();
// negate_debug();
delayNanoseconds(clkin_hi_ns);
clkin_lo();
delayNanoseconds(clkin_lo_ns);
negate_debug();
delayNanoseconds(clkin2_hi_ns);
clk_lo();
delayNanoseconds(clkin2_lo_ns);
// CLKOUT=H
clkin_hi();
clk_hi();
while (signal_enable() == LOW)
;
// assert_debug();
assert_debug();
s->inputMode();
// negate_debug();
delayNanoseconds(clkin_hi_ns);
clkin_lo();
delayNanoseconds(clkin_lo_ns);
negate_debug();
delayNanoseconds(clkin2_hi_ns);
clk_lo();
delayNanoseconds(clkin2_lo_ns);
} else if (s->write()) { // External write
clkin_lo();
delayNanoseconds(clkin_lo_ns);
clk_lo();
delayNanoseconds(clkin2_lo_ns);
// CLKOUT=L
clkin_hi();
// assert_debug();
clk_hi();
assert_debug();
s->getData();
// negate_debug();
delayNanoseconds(clkin_hi_ns);
clkin_lo();
negate_debug();
delayNanoseconds(clkin2_hi_ns);
clk_lo();
if (s->writeMemory()) {
Memory.write(s->addr, s->data);
} else {
; // capture
}
delayNanoseconds(clkin_lo_ns);
delayNanoseconds(clkin2_lo_ns);
} else { // Internal cycle
clkin_lo();
delayNanoseconds(clkin_lo_ns);
// assert_debug();
clk_lo();
delayNanoseconds(clkin2_lo_ns);
assert_debug();
s->getData();
// negate_debug();
negate_debug();
}
// assert_debug();
assert_debug();
Signals::nextCycle();
// negate_debug();
negate_debug();
while (signal_alatch() == LOW)
clkin_cycle();
clk_cycle();
return s;
}

Expand Down Expand Up @@ -322,10 +387,8 @@ bool PinsTms7000::rawStep() {
const auto opc = Memory.raw_read(s->addr);
const auto cycles = InstTms7000::busCycles(opc);
if (opc == InstTms7000::IDLE || cycles == 0) {
assert_debug();
completeCycle(s->inject(InstTms7000::JMP));
inject(InstTms7000::JMP_HERE);
negate_debug();
Signals::discard(s);
return false;
}
Expand Down
25 changes: 23 additions & 2 deletions debugger/tms7000/pins_tms7000.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ enum HardwareType : uint8_t {
HW_TMS7002 = 2, // TMS7002
};

enum ClockType : uint8_t {
CLK_DIV2 = 0, // NL2
CLK_DIV4 = 3, // NL4
};

enum IntrName : uint8_t {
INTR_NONE = 0,
INTR_INT1 = 1,
Expand All @@ -84,18 +89,34 @@ struct PinsTms7000 final : Pins {
void captureWrites(const uint8_t *inst, uint8_t len, uint8_t *buf,
uint8_t max, uint16_t *addr = nullptr);
HardwareType hardwareType() const { return _hardType; }
ClockType clockType() const {
return _clk_cycle == clk_cycle4 ? CLK_DIV4 : CLK_DIV2;
}

private:
HardwareType _hardType;

static void (*_clk_hi)();
static void (*_clk_lo)();
static void (*_clk_cycle)();
static void clk2_hi();
static void clk2_lo();
static void clk4_cycle_hi();
static void clk_cycle2();
static void clk_cycle4();
static void clk_hi() { _clk_hi(); }
static void clk_lo() { _clk_lo(); }
static void clk_cycle() { _clk_cycle(); }

void setBreakInst(uint32_t addr) const override;

void synchronize_clk();
void checkHardwareType();
void loop();
Signals *prepareCycle() const;
Signals *completeCycle(Signals *signals) const;
Signals *completeCycle(Signals *s) const;
Signals *cycle() const;
Signals *inject(uint8_t data) const;
void loop();
bool rawStep();
void execute(const uint8_t *inst, uint8_t len, uint8_t *buf = nullptr,
uint8_t max = 0, uint16_t *addr = nullptr);
Expand Down
10 changes: 6 additions & 4 deletions debugger/tms7000/regs_tms7000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ struct RegsTms7000 Regs;

namespace {
constexpr const char *const CPU_NAMES[/*HardwareType*/] = {
"TMS7000",
"TMS7001",
"TMS7002",
"TMS7000NL2", // 0
"TMS7001NL2", // 1
"TMS7002", // 2
"TMS7000NL4", // 0+3
"TMS7001NL4", // 1+3
};
}

Expand All @@ -24,7 +26,7 @@ const char *RegsTms7000::cpu() const {
}

const char *RegsTms7000::cpuName() const {
const auto type = Pins.hardwareType();
const auto type = Pins.hardwareType() + Pins.clockType();
return CPU_NAMES[type];
}

Expand Down

0 comments on commit 9a7509e

Please sign in to comment.