Thursday, 17 August 2017

Model 100 micro SD Card reader, the MyTeSed

After the initial testing with a full sized SD card reader shield and Ardunio Uno, I wanted to know how easy it would be to shrink the TRS-80 Model 100 SD card interfaces size down to something a little more acceptable. I thought about building the whole design from the ground up, in the end the abundance of cheap modules from China can't be beaten on price (or convenience).

Before getting into the excitement of the details, the other major half of the fun of building these projects is naming them, so I'm calling this interface the 'MyTeSed', standing for My Model 'T' Serial Drive. Now that out of the way, on with where I'm up to with the project to date.

Testing the functionality of the MyTeSed on a Breadboard 

The Hardware


I've gone with a Arduino Nano for the heart of the project, the footprint of the Nano is barely larger than a atmega328p chip and far smaller if including the ancillary components. The Nano also nicely takes care of power regulation, has a USB port for easy re-programming, and behaves identically to a Uno. Thus making the Nano one of the most inclusive of the reduced sized Arduinos' to use.

Micro SD Card Reader Module
The revised hardware also substitutes the full sized SD card shield with an all in one micro USB card module. The SD module accommodates either 5v or 3.3v signals, making it an ideal choice for use with the Nano. It's a standard module avaliable from just about anywhere, including Ebay and various online Chinese merchants of all things electronica.

After a little experimentation I've also decided to set up software serial on pins D8 and D9 of the Nano. Using software serial as the conduit to the T100 / T102 / T200 leaves the Nanos' standard serial pins D1 and D2 free to use as a pass-through (actually via the Nanos' USB) which will be used as direct connections to a PC. As in the previous version (blog entry Using SD Cards with the TRS-80 Model 100) a MAX323 IC handles the RS232 to TTL serial conversion.

The when complete the MyTeSeD can be powered from a 6v to 9v battery supply (like most Arduino projects), in addition usage of the Nano conveniently provides a means to power the interface via the mini USB port, allowing battery packs or a USB power source etc.


MyTeSed Circuit Diagram

Arduino Code


This is not by any measure the final code to be using with the interface, for the moment it serves as proof of concept. I'm still yet to go back a write up a more permanent solution, it does however work for now, just expect some drastic changes for the foreseeable future.

In essence the current idea is for MyTeSed to listen for instructions in plain text over the serial line, 'LOAD' and 'SAVE' for example, then either send data back or shift files around on the SD card. Regardless there is a lot left to implement, such as file deletion, access to directories and error checking.
// **************************************************************************
// **** MyTeSed: T100 SD Card Reader for Arduino Nano and SD Card Reader ****
// **************************************************************************
// ** David Stephenson 2017-08-23  **
// ** Version 0.01                 **
// **********************************
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>

enum SERIAL_MODE {FREE, COMMAND, DATA_IN, DATA_OUT, FILES_OUT};

const byte LF=10;
const byte CR=13;
const byte EF=26;

SoftwareSerial mySerial(12, 13); // RX, TX

class CardReader {
 private:
  SERIAL_MODE eSerialMode = FREE;
  //DRIVE_COMMAND eDriveMode = NONE;

  File MyFile;
  
  String sFileName;
  String sInString;
  
  unsigned long TimeLastUpdate = 0;
  
  // Class Private Functions
  void LoadBas() {
   
   char cRead, cLast;

   if(eSerialMode == DATA_OUT){
    MyFile = SD.open(sFileName);

    if(MyFile){
     while(MyFile.available()){
      cRead=MyFile.read();
      if (cRead== LF){
       if (cLast != CR){
        mySerial.write(CR);
       }
       mySerial.write(LF);
      } else {
       mySerial.write(cRead);
       cLast = cRead;
      }
     }
    }
    MyFile.close();
    mySerial.write(EF);
    eSerialMode = FREE;
   }
  }

  void SaveBas(char cInChar) {
   
   if(eSerialMode == DATA_IN){
    if(cInChar != EF){
     MyFile.print(cInChar);
    } else { 
     MyFile.close();
     eSerialMode = FREE;
    }
   }  
  }
  
  void FilesOut() {
   
  }
  
  
  void commandIn(){
   String KEYWORDS[7] = {"LOAD","SAVE","KILL","FILES","MOVE","CP2SD","CP2R"};
   String sInSubString;

   sInString.trim();

   Serial.print(sInString);

   if (sInString.length() >= 3){
    for (byte bKeyword = 0 ; bKeyword < 8 ; bKeyword++){
     sInSubString = sInString.substring(0,KEYWORDS[bKeyword].length() );
     sInSubString.toUpperCase();
     if (sInSubString.indexOf(KEYWORDS[bKeyword])!=-1){
      if (KEYWORDS[bKeyword] == "LOAD") {
       sFileName = sInString.substring(4);
       sFileName.trim();
       delay(500);
       eSerialMode = DATA_OUT;
       LoadBas();
      }

      else if (KEYWORDS[bKeyword] == "SAVE" || KEYWORDS[bKeyword] == "CP2D") {
       sFileName = sInString.substring(4);
       sFileName.trim();
       if (SD.exists(sFileName)) {
        SD.remove(sFileName);
       }
       MyFile = SD.open(sFileName, FILE_WRITE);
       eSerialMode = DATA_IN;
      }
      
      else if (KEYWORDS[bKeyword] == "FILES") {
       eSerialMode = FILES_OUT;
       FilesOut();
      }
     }
    }
   }

   //sInCommand = false;
   sInString = "";
   
  }
 
 public:
 
 void SerialIn(char cInChar){
  switch(eSerialMode) {
   case FREE:
    if(cInChar == CR){
     eSerialMode = COMMAND;
     commandIn();
    } else {
     sInString += cInChar;
    }
    break;
   case DATA_IN:
     SaveBas(cInChar);
    break;
  }
 }

};

CardReader MyCard;

void setup()

{
  // Open serial communications and wait for port to open:
  Serial.begin(1200);
    //57I1D
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // set the data rate for the SoftwareSerial port
  mySerial.begin(1200);

  if(!SD.begin(10)){
   mySerial.println("fail");
    return;
  } else {
 mySerial.println("mango");
 Serial.println("mangos");
  }
}



void loop()
{
 char cInChar;
 if (mySerial.available()) {
  cInChar = (char)mySerial.read();
  //sInString += cInChar;
  MyCard.SerialIn(cInChar);
  Serial.write(cInChar);
 }
}

Talking With a Model 100


Saving, loading and copying files from the micro SD card requires first sending a command and a filename to the serial port, then engaging the normal BASIC save / load to serial command. The COM port should be set to 1200 Baud, 7 Bit Word length, Ignore parity.

For example, saving the active BASIC file:
OPEN "COM:57I1D" FOR OUTPUT AS 1: PRINT #1,"SAVE MYFILE.BA": CLOSE 1: SAVE "COM:57I1D"

Or loading a BASIC file from the Interface:
OPEN "COM:57I1D" FOR OUTPUT AS 1: PRINT #1,"LOAD MYFILE.BA": CLOSE 1: LOAD "COM:57I1D"

Possibly the easiest method to save or load  BASIC program is to add some of the below lines to a program listings. Alternatively an option once the code base is a little more on the stable side would be the development of a menu-ing  system, but that's for latter.

Save a BASIC file to SD Card

900 OPEN "COM:57I1D" FOR OUTPUT AS 1
910 PRINT #1,"save testme.ba"
920 CLOSE 1
930 SAVE "COM:57I1D"

Load BASIC file to SD Card

10 OPEN "COM:57I1D" FOR OUTPUT AS 1
20 PRINT #1,"load testme.ba"
30 CLOSE 1
40 LOAD "COM:57I1D"

Copy a RAM Text File to the SD Card

10 MAXFILES=2
20 OPEN "RAM:TXT2RD.DO" FOR INPUT AS 1
30 OPEN "COM:57I1D" FOR OUTPUT AS 2
40 PRINT #2, "SAVE TXTFIL.DO"
50 LINE INPUT #1, Z$
60 PRINT #2,Z$
70 IF EOF(1) THEN GOTO 90
80 GOTO 50
90 PRINT #2, CHR$(26)
100 CLOSE 1: CLOSE 2

Copy a File from the SD Card to a RAM Text File

10 MAXFILES=2
20 OPEN "RAM:TXT2RD.DO" FOR OUTPUT AS 1
30 OPEN "COM:57I1D" FOR OUTPUT AS 2
40 PRINT #2, "LOAD TXTFIL.DO"
50 LINE INPUT #2, Z$
60 PRINT #1,Z$
70 IF EOF(1) THEN GOTO 90
80 GOTO 50
90 PRINT #1, CHR$(26)
100 CLOSE 1: CLOSE 2

Next Time


The next stage of proceedings is to design a circuit board, should be a simple enough task. Unlike all the other projects in this blog I'm planning on getting the PCB produced by a fabrication house, and hopefully all that will go well.


Monday, 14 August 2017

ZX81 Video Monitor Perfection?

A while ago now I fitted the very cool and reasonably priced ZXCCB composite video mod into a ZX81, yielding a much improved video experience, yet this is only half the story in the quest for retro ZX81 video perfection.

There is many a web page or YouTube video devoted to video outputs on retro computers and gaming consoles. Mostly these deal with the somewhat later computing or console incarnations such as the Sega Mega Drive, Nintendo NES or Commodore 64s. There are some excellent write ups on the subject, and you can't go past RetroRGB.com for some solid information well beyond the scope of this article. The ZX81s video demands though are rather less unassuming than most, requiring only the display of a (hopefully) clear black and white image.

What kind of perfection are we after? I say video perfection, this is a perhaps a little misleading, as what I'm really after is a video experience, an experience that captures the heart of ZX81 usage. This is of course a rather esoteric requirement, if perhaps partially at the heart of using the real deal instead of a emulator to start with.

Below are some of the variations on a theme I've tried, this is not an extensive list of every possible configuration available. So this is not a guide, more of a primer before launching your own quest down the rabbit hole of ZX81 monitor selection.


To CRT or LCD?


Back in the 80s the best monitor for a stock ZX81 was a black and white television. The perfect monitor for a ZX81 with a composite mod in 2017 is probably a black and white monitor with composite inputs. Simply put, the ZX81 does not output a chomiance (colour) signal, only a luminance (black and white) signal, any colour induced into the picture is by pure accident. There are not a great deal of black and white monitors available these days, so what easily available monitor options are available in 2017 and beyond?

There are a whole host of options available these days, from old CRTs to video converter boxes and new LCD televisions. The choice is only limited user preferences and in some cases by the constraints of the ZX81s video signal and it's interaction with modern devices. My personal preference varies, on the whole though I'm rather taken by Sony Broadcast monitors as these induce that all important retro feeling.


Option 1: An LCD TV


ZX81 with LCD television as monitor.
Most (I'm not going to say all as there are weird regional variances) LCD TVs still have Composite video ports. The ZXCCB video mod, the ZXVid and others, are designed to take full advantage of the Composite inputs, outputting a stable and clear image to modern LCD TVs. Frankly the clarity of the ZX81s output on a decent TV is astounding, even on low rent LCD TVs the image quality is far sharper anything you've ever experienced on an unmodified ZX81.

At this point, If you're happy with LCD displays you can stop right here, your never going to get a clearer display out of a ZX81, still there are minor issues with the display, and your personal preferences play a part in the ultimate monitor selection.

It's difficult to find an LCD TV with a 4:3 aspect ratio, meaning that text and therefor the underlying pixels are always going to look elongated. This may or many not be a worry, certainly the enhanced video quality more than makes up for the distortion.  Then again anyone after retro video purity may well take some offence at lack of near squareness in the aspect ratio. Of course an LCD monitor may already fall into the abyss of impure horrors for those with high retro tastes.

I have found that some LCD televisions play up a little when loading tape, loading from the ZXpand or going into fast mode. Anytime the Sync signal is dropped by the ZX81 an LCD televisions may revert to a blue or black screen momentarily, where most CRT monitors will retain the greyish background or display the loading bars normally associated with a ZX81.


Option 2: The CRT Colour TV


Late model TV with the ZX81 using RF out.
The best part about these is that they are (at the time of writing) cheap, though a slowly disappearing resource. I was lucky enough to find a late model 32cm (14inch) xxxx on the side of the road a couple of months ago, I was initially quite happy about that. I say initially as while the general image clarity falls in the okay-ish zone, the refresh rate on the monitor is headache inducing.

Refresh rate is probably misleading here as technically speaking all PAL TVs and monitors are refreshed at 50htz. This may really be a phosphor persistence rating problem. The rating of particular coating thi inside particular model seems to be just high enough to mostly maintain an image between refresh cycles. Doubtlessly this is not the only reason for this units headache producing flaws.

On the positive side, the TV has AV inputs for a very clear image, though more interestingly it also has no issues in picking up a ZX81s RF signal, producing one of the clearest images I think I've ever seen RF wise. So if you're not keen on modifying a ZX81 for composite out a late model CRT TV might be the best video output option.

Regardless of the positives, using a standard TV as a computer monitor in 2017 is just plain awful, even if you're after that retro CRT experience. Sitting up close to a standard flickering television is underwhelming, did we really do this 30 years ago?


Option 3: A Professional / Broadcast CRT Video Monitors


Sony 9inch PVMs
Broadcast and Professional monitors are without doubt one of the better go ways to go if you're after an old school CRT feel without compromising high legibility. These monitors are designed for people who's job it is to make, view and breath Television 24 x 7, so the clarity gained, particularly from the high end editions of these monitors is breath taking for CRT.

Presently being discarded by the TV industry, PVMs and BVMs are highly coveted by many a serious retro gamer. Sought after PVMs are typically 20 inches plus, with extensive features including Composite, S-Video, RGB and YCbCr inputs. All this providing an expansive, high quality retro gaming experience suitable for most retro consoles. Of course a ZX81 in no way needs all the higher end features, we're just after a clear picture.

A ZX81 isn't going to be used from the couch or armchair, most likely it'll be desk based, so clarity is probably the foremost factor in choosing the monitor. Sizes over 14 inches aren't going to add much to experience, and RGB and YCbCr are nice to haves but not important unless using you're also planning on using the monitor with more advanced micros.

Nicely I have 2 Sony PVM monitors, a PVM-9040ME a PAL only monitor that has S-Video and Composite ports and a PVM-9042QM monitor with a full spectrum of video inputs available. Both monitors have screen sizes of 9inchs, a small size by today's standards but not so tiny by the standards of the day. These monitors provide a beautiful viewing experience.


Option 4: Video Upscalers and Converter Boxes


Given the vast supply of LCD VGA and HDMI monitors in circulation, video converter boxes seem like an obvious usage case. But, and this is a big but, not all converters are created equal. Finding a converter box that worked with my ZX81 has proven problematic at best, though individual mileage may vary considerably.

The ZX81s video output, even with a ZXCCB installed is dependent on the version of ULA inside. While the signal can be corrected for missing back porch, the underlay signal generation may not be exactly to PAL standards. I'm not am expert on the subject, but given the lack lustre results using various converter boxes which for all intensive purposes work fine other conversion duties I'd guess this is the cause of the problems I've encountered.

The best converter box I've found is a rather ancient one, an Aver Media TV Box 5. It's unfortunate that the maximum resolution this will pump out is 1024x800, somewhat below the capabilities current generation LCD VGA monitors. For this the TV Box suffers, as monitors perform best at their own native resolutions and the resulting image is a little blurry.

I've put up a little video that highlights the problems or successes of various converter boxes at my disposal. The best I can say is buy one at your own risk, and at the end of the day a cheap LCD television seems by far a better option.




What is Monitor Perfection?


The choice of monitor really comes down to personal preferences. If after a clean and sharp emulator like quality, I've found even the least expensive LCD television is capable of delivering a stunning image (for a ZX81). For a that fuzzy feel good retro experience my preference falls defiantly in favour of PVMs and other broadcast monitors. Just remember that most of these video options are only available once the ZX81 is fitted with a composite modification such as the ZXCCB or ZXVid, both of which are regularly obtainable from the Sell My Retro web site.