Skip to content

Commit

Permalink
[TMS7000] Add TMS700x Serial handler
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Jun 26, 2024
1 parent 0689943 commit bfac338
Show file tree
Hide file tree
Showing 17 changed files with 1,292 additions and 11 deletions.
13 changes: 13 additions & 0 deletions debugger/tms7000/devs_tms7000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ DevsTms7000 Devs;
void DevsTms7000::reset() {
ACIA.reset();
ACIA.setBaseAddr(ACIA_BASE);
if (_serial)
_serial->reset();
}

void DevsTms7000::begin() {
Expand All @@ -21,6 +23,11 @@ void DevsTms7000::loop() {
ACIA.loop();
}

void DevsTms7000::setIdle(bool idle) {
if (_serial)
_serial->setIdle(idle);
}

bool DevsTms7000::isSelected(uint32_t addr) const {
return ACIA.isSelected(addr);
}
Expand All @@ -36,15 +43,21 @@ void DevsTms7000::write(uint32_t addr, uint16_t data) const {
Device &DevsTms7000::parseDevice(const char *name) const {
if (strcasecmp(name, ACIA.name()) == 0)
return ACIA;
if (_serial && strcasecmp(name, _serial->name()) == 0)
return *_serial;
return Devs::nullDevice();
}

void DevsTms7000::enableDevice(Device &dev) {
ACIA.enable(&dev == &ACIA);
if (_serial)
_serial->enable(&dev == _serial);
}

void DevsTms7000::printDevices() const {
printDevice(ACIA);
if (_serial)
printDevice(*_serial);
}

} // namespace tms7000
Expand Down
8 changes: 8 additions & 0 deletions debugger/tms7000/devs_tms7000.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,31 @@
#define __DEVS_TMS7000_H__

#include "devs.h"
#include "serial_handler.h"

#define ACIA_BASE 0x01F0 // P240

namespace debugger {
namespace tms7000 {

struct DevsTms7000 : Devs {
DevsTms7000() : Devs(), _serial(nullptr) {}
void begin() override;
void reset() override;
void loop() override;
void setIdle(bool idle) override;
bool isSelected(uint32_t addr) const override;
uint16_t read(uint32_t addr) const override;
void write(uint32_t addr, uint16_t data) const override;

Device &parseDevice(const char *name) const override;
void enableDevice(Device &dev) override;
void printDevices() const override;

void setSerialHandler(SerialHandler *serial) { _serial = serial; }

private:
SerialHandler *_serial;
};

extern struct DevsTms7000 Devs;
Expand Down
10 changes: 9 additions & 1 deletion debugger/tms7000/pins_tms7000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
#include "mems_tms7000.h"
#include "regs_tms7000.h"
#include "signals_tms7000.h"
#include "tms7002_serial_handler.h"

namespace debugger {
namespace tms7000 {

using tms7002::SerialH;

struct PinsTms7000 Pins;

// clang-format off
Expand Down Expand Up @@ -48,6 +51,7 @@ constexpr auto clk2_hi_ns = 500;
constexpr auto clk2_lo_ns = 500;
constexpr auto clk4_hi_ns = 250;
constexpr auto clk4_lo_ns = 250;
constexpr auto clk4_hi_serial = 200;

inline void clkin_hi() {
digitalWriteFast(PIN_CLKIN, HIGH);
Expand Down Expand Up @@ -124,6 +128,7 @@ inline void clkin_cycle() {

void clk2_hi() {
clkin_hi();
SerialH.loop();
}

void clk2_lo() {
Expand All @@ -132,7 +137,8 @@ void clk2_lo() {

void clk4_hi() {
clkin_lo();
delayNanoseconds(clk4_hi_ns);
delayNanoseconds(clk4_hi_serial);
SerialH.loop();
clkin_hi();
}

Expand Down Expand Up @@ -239,6 +245,8 @@ void PinsTms7000::checkHardwareType() {
_hardType = port19->external() ? HW_TMS7002 : HW_TMS70C02;
}
Regs.restoreA();
SerialH.setTms7001(_hardType == HW_TMS7001);
Devs.setSerialHandler(_hardType == HW_TMS7000 ? nullptr : &SerialH);
}

Signals *PinsTms7000::prepareCycle() const {
Expand Down
61 changes: 61 additions & 0 deletions debugger/tms7000/tms7002_serial_handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "tms7002_serial_handler.h"
#include "debugger.h"
#include "pins_tms7000.h"
#include "regs_tms7000.h"

namespace debugger {
namespace tms7002 {

struct Tms7002SerialHandler SerialH;

using tms7000::Regs;

const char *Tms7002SerialHandler::name() const {
return "Serial";
}

const char *Tms7002SerialHandler::description() const {
return Regs.cpuName();
}

uint32_t Tms7002SerialHandler::baseAddr() const {
return 0x0111; // SMODE/SCTL0/SSTAT
}

void Tms7002SerialHandler::assert_rxd() const {
digitalWriteFast(PIN_PA5, LOW);
}

void Tms7002SerialHandler::negate_rxd() const {
digitalWriteFast(PIN_PA5, HIGH);
}

uint8_t Tms7002SerialHandler::signal_txd() const {
return digitalReadFast(PIN_PB3);
}

void Tms7002SerialHandler::resetHandler() {
pinMode(PIN_PA5, OUTPUT);
pinMode(PIN_PB3, INPUT);
// TMS7002/TMS7001 Serial:
// fosc: XTAL frequency
// CLK: system clock; fosc/2 (/2 clock option), fosc/4 (/4 clock option)
// PR: Timer 3 prescaler reload value
// TR: TImer 3 reload value
// Serial Clock (SCLK) = (CLK / 2) / (PR + 1) / (TR + 1) / 2
// Asynchronous baud rate; SCLK/8 (TMS7002), SCLK/16 (TMS7001)
constexpr auto PR = 0;
constexpr auto TR = 12;
_pre_divider = (PR + 1) * (TR + 1) * 4 * 2;
_divider = _tms7001 ? 16 : 8;
}

} // namespace tms7002
} // namespace debugger

// Local Variables:
// mode: c++
// c-basic-offset: 4
// tab-width: 4
// End:
// vim: set ft=cpp et ts=4 sw=4:
39 changes: 39 additions & 0 deletions debugger/tms7000/tms7002_serial_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef __TMS7002_SERIAL_HANDLER_H__
#define __TMS7002_SERIAL_HANDLER_H__

#include "serial_handler.h"

namespace debugger {
namespace tms7002 {

struct Tms7002SerialHandler final : SerialHandler {
Tms7002SerialHandler() : SerialHandler(), _tms7001(false) {}

const char *name() const override;
const char *description() const override;
uint32_t baseAddr() const override;

void setTms7001(bool tms7001) { _tms7001 = tms7001; }

protected:
void resetHandler() override;
void assert_rxd() const override;
void negate_rxd() const override;
uint8_t signal_txd() const override;

private:
bool _tms7001;
};

extern struct Tms7002SerialHandler SerialH;

} // namespace tms7002
} // namespace debugger
#endif

// Local Variables:
// mode: c++
// c-basic-offset: 4
// tab-width: 4
// End:
// vim: set ft=cpp et ts=4 sw=4:
3 changes: 2 additions & 1 deletion samples/tms7000/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ ASM=asm

.PHONY: clean

all: echo.hex echoir.hex echoitr.hex arith.hex mandelbrot.hex
all: echo.hex echoir.hex echoitr.hex arith.hex mandelbrot.hex \
serial.hex serialir.hex serialitr.hex

%.hex: %.asm
$(ASM) -l $*.lst -o $@ $^
Expand Down
43 changes: 43 additions & 0 deletions samples/tms7000/serial.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
;;; -*- mode: asm; mode: flyspell-prog; -*-
cpu tms7000
include "tms7001.inc"

org VEC_RESET
data initialize

org >1000
initialize:
orp %?1000, BPORT Pass through TXD (PB3=1)
movp %0, SMODE Select SCTL0
movp %UR_bm, SCTL0 Select SMODE by reset
movp %CMODE_bm|CHAR8_bm|ASYNC_bm, SMODE 8 bits asynchronous
movp %RXEN_bm|TXEN_bm, SCTL0 Rx/Tx enable
movp %12, T3DATA 9600 bps (TR)
movp %CLK_bm, SCTL1 Enable internal clock, PR=0

loop: call @getchar
tsta
jeq halt_to_system
echo: call @putchar
cmp %>0D, A
jne loop
mov %>0A, A
jmp echo
halt_to_system:
idle

getchar:
btjzp %RXRDY_bm, SSTAT, getchar
movp RXBUF, A
rets

putchar:
btjzp %TXRDY_bm, SSTAT, putchar
movp A, TXBUF
rets

*** Local Variables:
*** mode: asm
*** mode: flyspell-prog
*** comment-start: "*"
*** End:
4 changes: 4 additions & 0 deletions samples/tms7000/serial.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:20100000A40806A20011A24011A24E11A20511A20C14A240158E1027B0E20B8E102E2D0D9E
:15102000E6F3220AE0F501A70211FC80160AA70111FC82170A32
:02FFFE001000F1
:00000001FF
Loading

0 comments on commit bfac338

Please sign in to comment.