Compare commits

...

3 Commits

Author SHA1 Message Date
Daniele Verducci (ZenPenguin)
17153486a6 Merge branch 'master' into TerminalWithCommands 2021-01-03 08:49:07 +01:00
Daniele Verducci (ZenPenguin)
ff4823b3ad WIP Terminal interface with commands 2021-01-02 07:56:11 +01:00
Daniele Verducci su MatissePenguin
4d9fd83cdd WIP Terminal interface with commands 2021-01-01 23:09:42 +01:00
2 changed files with 39 additions and 11 deletions

View File

@ -5,6 +5,12 @@
* The Python Terminal Monitor or the Arduino IDE serial monitor is used to send
* and receive commands to/from the Z80.
*
* Seen from the PC, the terminal receives two bytes: a command byte and a value byte.
* Commands:
* 0x00 WRITE: The next byte is sent as-is to Pat80. If the terminal interface buffer
* is not empty, the new byte will replace the older one.
* 0x01 BUFFER: The terminal interface returns the number of bytes waiting to be sent.
*
* Seen from the Pat80, the terminal interface has two registers:
* DATA Register at addr 0x00 (\RS) contains the last received byte from the pc
* DATA_AVAILABLE Register at addr 0x01 (RS) contains the number of bytes in the buffer,
@ -17,6 +23,9 @@
// RS 12 // Input, low = DATA register, high = DATA_AVAILABLE register
// DATA BUS (Input/Output, active high): 3, 4, 5, 6, 7, 8, 9, 10;
const byte COMMAND_WRITE = 0x00;
const byte COMMAND_BUFFER = 0x01;
byte incomingBuffer = 0; // Incoming from computer, to the Pat80
byte outgoingBuffer = 0; // Outgoing to computer, from the Pat80
byte availableBytes = 0; // Available bytes in the incoming buffer (for the DATA_AVAILABLE register)
@ -32,10 +41,19 @@ void setup() {
}
void loop() {
if (Serial.available() > 0) {
if (Serial.available() > 1) {
switch (Serial.read()) {
case COMMAND_WRITE:
while (Serial.available() < 1) {} // Waits for the second byte
incomingBuffer = Serial.read();
availableBytes = 1; // TODO: Implement a 256 byte buffer and store the avail bytes number in this var
break;
case COMMAND_BUFFER:
Serial.write(availableBytes);
break;
}
}
if (outgoingBuffer != 0) {
if ((outgoingBuffer >= 8 && outgoingBuffer <= 13) || (outgoingBuffer >= 32 && outgoingBuffer <= 127)) {
// Printable character

View File

@ -31,7 +31,6 @@ import os
class TerminalEmulator:
SYNC_SLEEP = 0.001
def __init__(self, w, ser):
w.clear()
@ -48,8 +47,7 @@ class TerminalEmulator:
key = w.getch()
if key == 10 or (key > 31 and key < 256):
# Is a character
time.sleep(self.SYNC_SLEEP)
ser.write(bytes([key]))
self.sendByte(bytes([key]))
elif int(key) == 1: # CTRL+A, enter ADB mode
# Save cursor position
(xPos, yPos) = w.getyx()
@ -82,10 +80,8 @@ class TerminalEmulator:
w.refresh()
# Send the two heading bytes (most significant first)
ser.write(header[0:1])
time.sleep(self.SYNC_SLEEP)
ser.write(header[1:2])
time.sleep(self.SYNC_SLEEP)
self.sendByte(header[0:1])
self.sendByte(header[1:2])
# Send the actual binary stream
with open(path, "rb") as f:
@ -105,6 +101,20 @@ class TerminalEmulator:
curses.noecho()
stdscr.nodelay(True)
# Sends a byte checking if the interface is busy
def sendByte(self, b):
busy = True
while busy:
# check if busy
ser.write(b'\x01') # send COMMAND_BUFFER
while not ser.inWaiting():
# wait for answer from interface
pass
busy = ser.read() != 0
# interface is free: write byte
ser.write(b'\x00') # send COMMAND_WRITE
ser.write(b) # send byte
if __name__ == '__main__':
import argparse