// (C) 2018 by Folkert van Heusden // // Released under Apache License v2.0 #include #if defined(ESP32) #include #else #include #endif #include #include #include "tty.h" #include "gen.h" #include "memory.h" #include "utils.h" #if !defined(ESP32) #include "terminal.h" extern NEWWIN *w_main; #endif const char * const regnames[] = { "reader status ", "reader buffer ", "puncher status", "puncher buffer" }; tty::tty(std::function poll_char, std::function get_char, std::function put_char) : poll_char(poll_char), get_char(get_char), put_char(put_char) { #if defined(ESP32) queue = xQueueCreate(10, sizeof(char)); if (queue == nullptr) Serial.println(F("Problem creating TTY queue")); #endif } tty::~tty() { } uint8_t tty::readByte(const uint16_t addr) { uint16_t v = readWord(addr & ~1); if (addr & 1) return v >> 8; return v; } uint16_t tty::readWord(const uint16_t addr) { const int reg = (addr - PDP11TTY_BASE) / 2; uint16_t vtemp = registers[reg]; if (!have_char) have_char = poll_char(); if (addr == PDP11TTY_TKS) { vtemp = have_char ? 128 : 0; } else if (addr == PDP11TTY_TKB) { if (have_char) { char c = get_char(); vtemp = c | (parity(c) << 7); have_char = false; } else { vtemp = 0; } } else if (addr == PDP11TTY_TPS) { vtemp = 128; } //D(fprintf(stderr, "PDP11TTY read addr %o (%s): %d, 7bit: %d\n", addr, regnames[reg], vtemp, vtemp & 127);) registers[reg] = vtemp; return vtemp; } void tty::writeByte(const uint16_t addr, const uint8_t v) { uint16_t vtemp = registers[(addr - PDP11TTY_BASE) / 2]; if (addr & 1) { vtemp &= ~0xff00; vtemp |= v << 8; } else { vtemp &= ~0x00ff; vtemp |= v; } writeWord(addr, vtemp); } void tty::writeWord(const uint16_t addr, uint16_t v) { const int reg = (addr - PDP11TTY_BASE) / 2; D(fprintf(stderr, "PDP11TTY write %o (%s): %o\n", addr, regnames[reg], v);) if (v == 0207 && testMode) { D(fprintf(stderr, "TestMode: TTY 0207 char\n");) #if !defined(ESP32) exit(0); #endif } // FIXME if (addr == PDP11TTY_TPB) { char c = v & 127; #if defined(ESP32) Serial.print(c); if (xQueueSend(queue, &c, portMAX_DELAY) != pdTRUE) Serial.println(F("queue TTY character failed")); #else put_char(c); #endif } D(fprintf(stderr, "set register %o to %o\n", addr, v);) registers[(addr - PDP11TTY_BASE) / 2] = v; }