BBS

A 3-post collection

Even more connected

By apam |  Jun 10, 2020  | rc2014, retro-computer, z80, bbs, cp/m, esp-12

I just finished my second knock off of the official RC2014 ESP8266 module, and finally it works!

The first go, I had the wrong voltage regulator so the ESP module wasn’t receiving 3.3 volts. It was only getting 1.2 volts or something, so the whole thing didn’t work. There was also some tweaks to make to the first version of my PCB (the capacitor footprints were too small and I had the RX2-RX1 selection jumper thing around the wrong way).

So I ordered the correct voltage regulators and some new refined PCBs, and soldered it together.

The first thing I saw when I plugged in my programmer was the ESP module’s light blink, which meant it was powered up - I didn’t get that before. Next I programmed it with Zimodem, and fired it up and it just printed garbage on the screen.

So back to the code, there were a few tweaks I had to do.. but my Arduino IDE had stopped working. For whatever reason, 1.8.12 no matter which computer I tried wouldn’t work anymore with the ESP board definitions installed. Eventually I tried a nightly build and that worked, so on to the tweaks.

I needed to turn off “RS232_INVERTED” change the default BAUD to 115200 and add a delay to the serial port writing (ATS44=1)

After that it worked like a charm and I can dial out to my BBS … WITHOUT WIRES!!

Connected! Part Two

By apam |  Apr 28, 2020  | rc2014, retro-computer, z80, bbs, cp/m

Last post I got my RC2014 connected to my BBS using an Arduino Mega connected to a Laptop running tcpser. I could use QTerm to “dial” telnet BBSes and connect to them.

However, I wanted to remove the laptop running tcpser from the equation, and I have a WizNet ethernet shield, I thought I could use to have the arduino connect to the BBS itself.

It took a little while, but I eventually got it to work, with this attached sketch. It could probably be adapted for an UNO, just change the Serial1 to Serial.

I think it dropped characters because I’m not using CTS/RTS pins, I got around it by adding a 1ms delay between characters. It’s probably a bit slower, but then that’s part of the nostalgic feel…

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };


void setup() {
  // put your setup code here, to run once:
  Serial1.begin(115200);
  Ethernet.begin(mac);
}

EthernetClient client;
int gotIAC = 0;
int count = 0;
bool commandMode = true;
char tmpbuffer[64];
int bufferpos = 0;
char happyland[] = "magickabbs.com";
uint16_t happyland_port = 2023;

void writeser(char *str) {
  while (*str) {
    Serial1.write(*str);
    delay(1);
    Serial1.flush();
    str++;
  }
}
  
void loop() {

  if (commandMode) {
    count = Serial1.available();
    while (count--) {
       char inbyte = Serial1.read();
       if (inbyte == '\r' || inbyte == '\n') {
        if (inbyte == '\r' && Serial1.peek() == '\n') inbyte = Serial1.read();
        writeser("\r\n");
        if (bufferpos > 2) {
          if (toupper(tmpbuffer[0]) == 'A' && toupper(tmpbuffer[1]) == 'T') {
            if (toupper(tmpbuffer[2]) == 'Z') {
              bufferpos = 0;
              writeser("OK\r\n");
            } else
            if (toupper(tmpbuffer[2]) == 'D') {
              if (bufferpos > 3) {
                if (tmpbuffer[3] == '1') {
                  if (client.connect(happyland, happyland_port)) {
                    bufferpos = 0;
                    writeser("CONNECTED\r\n");
                    commandMode = false;
                  } else {
                    bufferpos = 0;
                    writeser("BUSY\r\n");
                  }
                } else if (toupper(tmpbuffer[3]) == 'T') {
                  uint16_t port = 23;
                  if (bufferpos > 4) {
                    for (int z = 4; z < bufferpos;z++) {
                      if (tmpbuffer[z] == ':') {
                        port = atoi(&tmpbuffer[z+1]);
                        tmpbuffer[z] = '\0';
                        break;
                      }
                    }
                    if (client.connect(&tmpbuffer[4], port)) {
                      bufferpos = 0;
                      writeser("CONNECTED\r\n");
                      commandMode = false;
                    } else {
                      bufferpos = 0;
                      writeser("BUSY\r\n");
                    }
                  } else {
                    bufferpos = 0;
                    writeser("ERROR\r\n");
                  }
                }
              }
            } else {
              bufferpos = 0;
              writeser("ERROR\r\n");
            }
          } else {
            bufferpos = 0;
            writeser("ERROR\r\n");
          }
        }
       } else {
        if (inbyte == '\b') {
          if (bufferpos > 0) {
            bufferpos--;
            tmpbuffer[bufferpos] = '\0';
            Serial1.write(inbyte);
          }
        } else {
          tmpbuffer[bufferpos++] = inbyte;
          tmpbuffer[bufferpos] = '\0';
          Serial1.write(inbyte);
        }
       }
    }
  } else {
    if (!client.connected()) {
      writeser("\r\n\r\nDISCONNECTED\r\n");
      commandMode = true;
      return;
    }
    
    count = client.available();
  
    if (count > 0) {
      while (count--) {    
        int inByte = client.read();
        if (gotIAC == 0) {
          if (inByte == 255) {
            gotIAC = 1;
          } else {
            Serial1.write(inByte);  
          }
        } else if (gotIAC == 1) {
          if (inByte == 255) {
            Serial1.write(inByte);
            gotIAC = 0;
          } else if (inByte == 240) {
            gotIAC = 3;
          } else {
            gotIAC = 2;
          }
        } else if (gotIAC == 2) {
          gotIAC = 0;
        } else if (gotIAC == 3) {
          if (inByte == 250) {
            gotIAC = 0;
          }
        }
        delay(1);
      Serial1.flush();
      }
    }
    count = Serial1.available();
    if (count > 0) {
       while (count--) {
          int inByte = Serial1.read();
          if (inByte == 255) {
            if (client.connected()) {
              client.write(inByte);
            }
          }
          if (client.connected()) {
            client.write(inByte);
          }
        }
    }
  }
}

Connected!

By apam |  Apr 25, 2020  | rc2014, retro-computer, z80, bbs, cp/m

Last night I started an attempt to connect to my BBS via an arduino mega. The first step was to get the second serial port on the SIO/2 module to communicate with the arduino so the arduino could communicate with the computer. I connected the RX and TX pins to the TX1 and RX1 of the mega respectivley and the ground to the ground. I then uploaded a simple sketch that would relay data from serial1 of the mega to serial0.

It didn’t work. I didn’t have a terminal capable of talking to the SIO/2 chip and had no idea where to find one.

The retro-comp google group came to the rescue with QTerm which had been modified to work with the SIO/2, once I had that it worked - almost first go. I did have to adjust the baud rate between the computer and the mega, as having it on 115200BPS resulted in dropped characters.

The next step was to install tcpser which acts like a modem, but instead you give it telnet addresses instead of phone numbers. Here it is all working:

Connected!

You can see the main menu of the BBS on the TV, which is connected to the Pi Serial Terminal of the RC2014. The laptop is connected to the mega and is running tcpser.

Here is the arduino sketch:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(38400);
  Serial1.begin(115200);
  
}

void loop() {
  // put your main code here, to run repeatedly:
 // read from port 1, send to port 0:
 int count = Serial1.available();
  while (count--) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);
    Serial1.flush();
  }
}

This sketch was taken from the arduino website, but I modified it a bit. I added the count loop and the flush, I’m not sure if it’s necessary or not as I was experimenting when I was losing characters.