Saturday, 4 January 2014

Coda to the Hughes LCD Driver.....

I've been pondering the questions in the wiring.

Looking at the Hughes Data sheet
Arduino Shield with 84 x 48 Pixel LCD
two things spring to mind. The numbering of D0-D3 is backwards to how these things are normally done - D0 is normally the least significant bit, but in this its the most significant bit - this matches up with the TMS1100 'O Register' interface, as Dan Boris has it, where O0 is connected to D3 and O3 is connect to D0 (on a TMS1100 O0 is the least significant bit). It is also consistent with section 10 - "Data 0" is put in R1 (e.g. the first row), which would be horribly messy  if this was actually a least significant bit - so the first nibble is R1/R2/R3/R4 and the second R5/R6/R7/R8 etc.

Also the rows and columns are numbered from 1 to 16. If they were numbered 0-15 it is not implausible that these are bit numbers (e.g. R0 is the least significant bit), but the document appears to have been done 'counting' left to right - so D0 is on the left of the nibble, R1 on the left of the LCD, and C1 at the top of the nibble.

So, having said all that, I'm fairly sure that :


  • (R1,C1) is the top left pixel on the LCD.
  • D0 is the most significant data bit.


The latter actually doesn't matter. The TMS1100 has an instruction TDO that outputs a 5 bit word composed of the Status Latch (1 bit) and the Accumulator (4 bits).

This doesn't however, go straight onto the output lines O0-O4 - a TMS1100 has a built in 32 x 8 mask  ROM, and what happens is the TDO 5 bit value is an address into this ROM, and the data is output on O0-O7. This comes from its early use as a calculator chip - the idea being that you put a digit value using TDO and it outputs a 7 segment bit pattern on O0-O7. So it operates a bit like a 7447. This on the TMS1100 used in the Microvision is probably a 1-1 thing, so putting a value n in the accumulator produces n on O0-O3 irrespective of the Status Latch (O4-O7 aren't connected). If it is backwards, and it is not likely IMO, then you could just reprogram the Mask ROM to reverse the nibble bits anyway.

I did wonder about using the 32 x 8 ROM to hold digit data, but there just isn't enough space to fit it in.

So, next thing is to write the interface code between the CPU emulation and the physical emulation of the keyboard, beeper and LCD, and write some basic code to test it. This means that porting it to an Arduino just involves compiling the interface code and the processor code, leaving the physical emulation, obviously different on an Arduino, to be written.

(I've found somewhere that will sell me one of these (see picture) cheaply - its an 84x48 LCD and a little joystick, which I can make do the same job as buttons - maybe :)  which will minimise the wiring and make me feel less bad about using a TFT LCD)

All about the Hughes LCD Driver

So, this morning's little bit of light reading is my rewriting/explanation of the Datasheet of the Hughes 0488 LCD Chip.

Hopefully it's a bit more readable than the Datasheet itself, which isn't the clearest document I've ever read, and has at least one significant error in it, I think :)

I have also revised the tms1100.def file as it had some errors in it - when I first put it up it hadn't actually been generated / compiled.

The Hughes Document is at http://www.studio2.org.uk/mv/HughesNotes.pdf

NB: I have just noticed that on Dan Boris's document and the Hughes data sheet the pins are the same but in the reverse order - so what is marked as "Row 1" (pin 39 on the Datasheet) is R15 on Dan's (the bottom one). I will need to give this some consideration.

Friday, 3 January 2014

Which Processor to use ?

This is a fairly serious issue for this machine.
The huge gap is because of LibreOffice's
vector graphics export

The display hardware is basically what is drawn on the right. There are 32 latches, 2 lots of 16 for rows and columns, one latch for each row and column of the display, each composed of 4 lots of 4 bit latches* (because the interface is 4 bit)

Lighting a pixel on the display involves loading these latches with bit patterns. Any pixel which has its row latch set, and its column latch set, is lit (e.g. darkened as its an LCD display).

If you want to write something different on each row (and the row has at least one pixel on), then you have to fill these latches 16 times - one for each row, or if you prefer, one for each column - mentally it's probably easier to do it as a row by row, but there's no technical reason I can see why you can't do it column by column.

Lines that are empty don't need to have anything done to them, and lines that are duplicate can be done together (by setting the column bits to the pattern and one or more row bits).

The TMS1100 microprocessor does 50,000 instructions a second. The recommended refresh rate is 30-50Hz.

Let's say 30Hz as a workable rate, which means each frame is 1,667 cycles.

To do a full screen needs 16 write sessions, so that's about 100 each per line. Each of those lines requires 8 writes to the display, which gives you 12 or 13 instructions per write. This isn't a lot for a TMS1100 as its instructions are pretty basic.

This is probably the reason a lot of Microvision games only have the odd pixel displayed, or maybe a line or two.  Connect Four I recall has a pretty full screen,but then it's not an action game.

Using an Intel 8021 gives you double the speed more or less automatically, plus it is a more powerful 8 bit processor.

But still, what would a challenge be if it wasn't a challenge. So I've decided to stick with the TMS1100 and put the i8021 code in abeyance unless I find it is just too slow. But I think it is doable. It was only about 30 minutes to convert it, and to make it useable won't take much longer.

One issue is I don't know how much you can bully it. I did some programming for TI Calculators and you could get a lot more out of those by ignoring the TI stuff and telling the LCD Driver to do things directly.

The LCD has this rather odd thing about "DC Build Up" which I don't fully understand yet. Every frame you "switch the polarity of the LCD" and if this isn't 50-50 then DC static builds up with presumably hilarious consequences. It says 'exactly' but this isn't possible. I'm a bit loathe to start torturing real Microvision hardware :)

* it's a bit more complicated than this but not much.

The Joys of Code Reuse

An Intel 8021 MCU
Was up early this morning. I wanted the emulator to emulate both the TMS1100 and the Intel 8021, and I already had a Java i8021 emulator, so I've retrofitted that to the emulator and converted it to 'C'.

There's already a nice assembler (Alfred Arnold's "AS") which is free and portable for this MCU.

There is a freeware TMS1x00 assembler but it's broken because it doesn't fix up the LDP/CALL/BR addresses properly - long branches and calls (e.g. out of page) in one of these controllers are done with two (or sometimes three) instructions, one to set the page, one to do the branch or call.


Thursday, 2 January 2014

Hardware version

The bits of hardware that will go (hopefully) to make a Hardware version of the Microvision Emulator - An Arduino Leonardo, A 3 x 4 keypad, and a 128x160 TFT Screen.

Seems a shame to take a Colour LCD Screen and reduce it to 16 x 16 monochrome, but that's what I had in the box, I'd probably be better off with one of those Nokia LCDs.

Missing ; a Piezoelectric Buzzer. There's a couple in my junk box somewhere :)


Now working......

Well, partly. The TMS1100 emulator is up and running and seems to be working okay, and you can control it from the keyboard - set breakpoints, single step and so on.

It has been running this code.

start
ldx 0
nextdigit
tcy 0 // point to start
carryforward
imac // increment and load digit
tam // write it back
ac6ac // add 6
br carryout // if carry set, then carry out
br nextdigit // else start again.
carryout
cla // clear the current one
tam 
iyc // increment Y
cla // in case of carry out, unlikely !
br carryforward

All this does is increment each memory location one at a time till 10, carrying forwards, so it works like a giant counter with one digit in each memory location.

The point of this is to speed test (alternatively, to check it runs at the right speed). On my machine it was executing about 0.96 million loops a second, which equates to about 6.4Mhz clock speed (on the TMS series 1 instruction = 1 clock cycle*) . The TMS1100 runs at 50Khz or so, so it's going to be quick enough :)

It doesn't emulate any of the other hardware - LCD, Keyboard and Speaker (I'm not going to code for the rotary controller) - yet.

* note: for the pedantic, the clock speed is six times this, and it runs at 300Khz, every instruction being 6 clock cycles in length.

Emulator in Progress .....

Microvision Emulator main Screen
An in-progress shot of the emulator under development - on the left side, the currently empty 2k ROM, the lower right is the R-output latches and the 128 nibbles of memory, the upper right is the Microvision display (faked up) and upper Middle, the processor registers (BP is the Break point and some of them are helpers (e.g. XY, LS and M).

Whilst the code is written though, the emulator commands aren't implemented yet, so it doesn't do anything at all.

It uses the SDL2 library so it should port to Linux and Windows. The alert reader will note I'm now developing on a Macintosh.