Sunday, 12 January 2014

A fairly quiet day

Not done a lot today - tweaked the assembler so the changes I made yesterday are the same - I've also made the assembler generate code in TMS1x00 PC order, rather than normal counter order so I don't have to maintain two lots of code, but it's still flattened in the emulator so it looks normal.

Thanks to Sean's scan of the output PLA I know that the mapping of O register -> O lines is 1:1 on Vegas Slots, need to check the physical wiring tomorrow - I do have a couple of Microvisions and most of the cartridges made.

Oddly MB seem to have made different cartridge designs rather than just two - a TMS1100 and an Intel8021 one.

Saturday, 11 January 2014

In which I make a stupid mistake.

Vegas Slots running
I've solved the puzzle of the difference between the manual and the code, and a couple of things that nearly but didn't quite work.

I noticed when running BlockBuster there appeared to be a second ball image running in parallel with the first one. I wondered if this was a feature of the rendering rather than the actual code, but it appears not.  So I did a review of the TMS1100 Code.

There's two dumb errors there. On TMS1100 with operands, some operands are reversed. So YNEC 4 is actually

0101 0010

where 0010 is the operand, backwards (e.g. 0100, 4 in binary). What I've only just noticed is that the bit test operands (RBIT, SBIT and TBIT1) and the Load X immediate LDX also have backwards 3 bit and 2 bit operands respectively. The only ones that aren't reversed at Branch and Call, with their 6 bit operands.

This explains much. I thought it strange that LDX 4 was used when according to the documentation it shouldn't work. But it was right, because LDX 4 was actually LDX 1 (e.g. it is 00101 100 - I interpreted 100 as 4 but it's actually 001 , e.g. 1) - so X was in the range 0-3, so the book is right (and the Microvision emulation in MESS is wrong).  Apart from this it didn't matter, it just put the rows in the wrong order because LDX is the only way you can load the X register, you can't increment it, decrement it, load it from memory or accumulator, all you can do is put a constant in it.

The bits were worse, it's remarkable anything worked at all. These are also reversed, so I was interpreting SBIT 1 (which is 001100 10) as SBIT 2 (e.g. the 10 should have been reversed), hence it set the wrong bit.

This was the cause of the spurious ball in Block Buster and also the weird cocked up display in MindBuster, which now looks right.

Of course there are still problems. Phaser Strike works perfectly except that the keypad is upside down - the setup keys are at the bottom rather than the top. It's possible that this might be because in Phaser Strike the cartridges are wired differently. Vegas Slots too works perfectly except it has the same problem that Block Buster did originally, viz. all the graphics or back to front and upside down. This might be simply because the 32 x 8 bit O mask ROM is wired differently. Or it might be another bug. I will have to investigate more closely.

Anyhow, I'm going to try to emulate the rotary control, then I will release another emulator so you can have a go at playing the Microvision games for real.

Friday, 10 January 2014

Sometimes real code works .......

BlockBuster working
So, following the last post, I decided to see if it worked.

I removed the test mentioned in the TMS1100 data sheet - only updating the R-Latches if the X Index register was less than four.

It partly worked - except it came out back to front and upside down. Turns out that the LCD input was reversed, which I fixed by reversing the bits on the LCD driver (equivalent to reprogramming the Parallel Output ROM to do it), and as you can see it works well enough.

Hitting a few keys at random it appears to do what the BlockBuster Cartridge does (haven't checked this properly yet), and it also starts up the game and displays the initial wall.

I wasn't, originally, going to emulate the Rotary Hardware, but perhaps I will now, just to see how it works.


Running real code is usually asking for trouble.

Self Portrait
Thanks to Sean, Kevin and the MESS team I've got some real code running. It's quite interesting.

One of the big issues with the TMS1000 is the instruction set is mask programmable. It's not like a 6502 when you know what you are getting or like a Pentium when you know 2 + 2 = 7, you can (I think !) order it with a reorganised instruction set. I kind of reckoned nobody ever bothered, I mean if you did that the development tools wouldn't work.

I've been running BlockBuster on the emulator (It's one of those knock the bricks out of the wall games) . One of the first things it does is display something like 7 ST (a bit like this http://home.comcast.net/~eichler2/microvision/MicroBlockSim.htm).

It sort of works. It displays something, but not what it should.

Looking at the code, I find this (note for people even more pedantic than me - code has been remapped from the LFSR PC to a standard counter PC. If you don't comprehend this this means you are a normal human being).

796   ldx 4          // set X index to 4
797   tma            // Load Memory(4,Y) to accumulator
798   tdo            // put A (pixel data) on output lines to LCD
799   tya            // save Y in A (this is the ptr to the data)
79A   tcy 7          // set Y to 7 (the data clock latch)
79B   rstr           // set data clock (latch 7) to 0
7BC   setr           // set data clock (latch 7) to 1
7BD   tay            // restore the pointer.

which is all very sensible. This should load a nibble into the accumulator (Y points to the pixel data at the start), put it on the LCD data bus and put a pulse on the data clock line to load it into the latches, it preserves the pixel data pointer whilst it does this).

However ....... it doesn't work.  Single stepping this code, it doesn't output the data to the LCD.

Because ... it shouldn't work

The reason it shouldn't work is in the TMS1x00 Programmer Guide.

It says (page 8-12) "The operation of the SETR and RSTR commands is possible for 0<=Y<=15 and 0<=X<=3. And it explicitly says - the X register must be <= 3.

(I note that the Microvision emulation for the TMS1x00 doesn't test this. This might be because they know more than I do, or because they are working from the TMS1000 which doesn't do this test, because X is always 0,1,2 or 3)

A brief perusal of the code above shows X isn't in the range 0-3. It's 4. So , according to the book - it shouldn't work.

Now the code is obviously - to me anyway - doing what it should. It makes logical sense, and it may well work without this test.

Whether the book is wrong (other lists don't mention this X requirement and it does seem a bit pointless !), or the chip is a special one, I don't know. The problem is, of course, if the chip is a special this is an entirely new issue. It doesn't seem to be, what I see of this code makes sense. So I'm going to fix it so it works irrespective of X is and see what happens.

From the challenge view point it doesn't matter as I'm writing a new game not an old one, but if I can get it working reasonably I know my emulation is okay. (If you do nothing it beeps three times to warn you which kinda makes sense). I do have a Microvision so I must see if it actually does this.

The display, we shall see.




Thursday, 9 January 2014

Other MB work

I'm still looking for the Microvision ROMs - hopefully I can get some of the early dumps that some of our technical geniuses have done.  Apparently the MESS Microvision emulation does work - to some extent anyway, and browsing that source my interpretation of the controller and theirs aren't that different.

There's two methods. The TMS1000 patent describes a method of testing the chips by dumping the ROMs serially. It was known this was possible, but not how to do it, but it seems it has been figured out.

The second is direct examination - taking the top off the chip, scanning it at high resolution and converting that to binary code - the picture is a TMS1100 die.

It would be great if the Microvision stuff was dumped - it's one of the few last old machines that hasn't been dumped yet. Not that anyone would really want to play the games, it's more of a preservation thing.

Reading the MESS source also revealed the clock speeds. I have had a problem with this, because whilst the TMS1000 data book is very informative on coding, it's not on the physical hardware, I couldn't find a clock speed descriptor (the clock circuit values are on Dan Boris' circuit).

In practice, it varies, there are 300Khz, 500Khz and 550Khz clock speeds, which correspond to 50Khz, 83Khz and 92Khz instructions per second (every TMS1x00 instruction takes 6 clocks).

An early example of over clocking. The data book says that fOsc (the clock) has a maximum speed of 350Khz,  on the previous page oddly it says that tc,  the instruction cycle time is 2.5us minimum (e.g. 400Khz).  I guess the Microvision coders had the same problems I did viz. simply getting LCD information to the display quickly enough uses up most of the coding time.

Though in my experiments if you only have 2 or 3 things on the screen, or a few lines, it is quick enough. The diagonal line drawing is slow because it's a pixel plot - effectively PLOT(X,Y) so for X and Y it has to convert it to a bit pattern ($8000 >> x) basically, and that's what takes the time up, not the writing to the LCD. If you have the nibble pattern already, I would reckon BlockBuster works like this for the 'wall' it's much quicker.

Wednesday, 8 January 2014

First Release

So, a first release.

There are two release files, and things are likely to stay this way.

The OSX one contains a Mac OSX executable (mvem) and all the source code. It does not contain the SDL library required to run it,  which can be downloaded from http://www.libsdl.org/download-2.0.php

The Windows one contains a 32 bit Windows executable, the SDL2 DLL, a Code:Blocks project file and a note on how to build it from the OSX source.

Both contain a file test.bin which is the assembled version of the test program. All it does is draw a diagonal line, sound the buzzer continually (the tone varies slightly because the emulator decides the frequency from the total transitions and time per frame, but it will be fine for beeps) and respond to the right column of keys (3 E D C) on the top row.

This is pretty much flogging the hardware to death.

You run it with ./mvem test.bin or mvem test.bin . The debugger commands are : 0-9A-F change code address, K set breakpoint, H home to program counter, S single step, V step over. G run. When running (the debug display will disappear) M returns to debug mode (the other key columns are 1QAZ and 2WSX - a Microvision has a 3 across by 4 down keypad). You can exit either using Escape or the Close button on the window.

It's very primitive, but it works fine.

Minor updates

I've updated three things on the right :

tms1100.def has been updated because of a minor bug

tmsasm.lua has been updated to add in "lcall"  and "lbr" pseudo operations that do a long call and a long branch (on a TMS1100 this takes two instructions, or three if you are changing chapter (don't ask))

test.asm has been replaced completely with the program that draws the diagonal line, responds to the keyboard and tests the beeper, it also has the beginnings of some utility functions.

Interesting comment from Sean Riddle about TMS1100 dumps. Let's hope there are some Microvision ones out there - if so then then after releasing the first version, I will get them working, if not on with the game coding, which will start with extending the utility routines.