Friday, 29 January 2016

Demo video

So, here is the video of the emulator running. I start it up, it boots straight into MINOL (it autodetects the ROM image and boots there).


I then immediately exit, disassemble and list some memory to show the monitor ROM, and boot MINOL back with G 9000.

Then the Star Trek program is listed and run - it does take a few seconds to create the galaxy, and then I fly about a bit, shoot up some Klingons and exit to the MINOL command line.

All very primitive :)

Executable rebuilt, RC/2016 pretty much done.

In what will probably the final thing I do for Retrochallenge 2016/1 ,

I've rebuilt the executables and the hardware version so that Star Trek will run automatically, e.g. it is loaded into memory.

All you have to do is run the executable, press F5 to run it, and type RUN and it should start. Slowly :)

I might put a screengrab/video up a bit later on.

This is a picture of Star Trek just having started and being run on the hardware "replica".

Trek complete

Yes, it's finished and working, coming in at 3,227 bytes.

This is the (probably) final listing. The next (and probably last) thing I will do is rig the emulator up so this is loaded by default.

I didn't actually write this ; it's pretty incomprehensible. The commented version with full variable names, which is about 5 times as long is on github.

A peculiarity of the original MINOL is you have to write it like this (except you can have comments) - most of the time the interpreter does not allow spaces so you can't write "PR C" it has to be "PRC". I removed the spaces in the preprocessor primarily to save space.

Though I have just noticed it has the superfluous 'A' command which invites the Klingons to attack you (which was for debugging). Still, maybe a Ferengi will play the game, it might be useful ?

The main thing that is missing that I might add, but probably won't as it's nearly time out and the weekend, is the phaser damage does not take distance into account.

But overall I'm quite pleased with it. It does have most of the proper features of Star Trek BASIC, which the other tiny versions (<4k) I have seen don't.

It may be technically wrong. The original MINOL claims a line length of 70 odd characters max but this is more to do with the keyboard buffer than internal structure. With 700 bytes left, I could stretch it out so no line is more than 70 characters long, but I won't :)

   2 (14,254)=12:(14,255)=0:PR$(14,254),"STAR TREK V1.0":PR"(C) PSR 2016":PR:(14,240)=0:(14,241)=7:(14,242)=8
   3 (14,243)=9:(14,244)=255:(14,245)=0:(14,246)=1:(14,247)=0-9:(14,248)=0-8:(14,249)=0-7
   4 PR"SKILL 1-9 ?";:IND:IFD=0;D=5:K=0:I=0
   5 N=0:IF!<2*D+35;N=N+!/80+1:K=K+N:IF!<16;N=N+100:(14,I)=!/50+1*10+N:I=I+1:IFI<64;GOTO5
   6 E=250:T=4:Q=!/4:(14,Q)=163:PRK,"KLINGONS"
  10 I=64:PR"IN QUADRANT ";:N=Q/8*8:(14,254)=Q-N+48:PR$(14,254),",";:(14,254)=Q/8+48:PR$(14,254)
  11 (14,I)=0:I=I+1:IFI#128;GOTO11:N=(14,Q):J=1:O=0:(14,J+151)=255:(14,J+152)=255:(14,J+153)=255:(14,J+154)=255
  12 IFN/10*10=N;GOTO14
  13 I=!/4+64:IF(14,I)#0;GOTO13:(14,I)=J:N=N-1:IF9<J;GOTO12:(14,J+150)=I-64:(14,J+160)=!/10+12:J=J+1:O=O+1:GOTO12
  14 N=N/10:J=J+1:IFJ<9;J=10:IFN#0;GOTO12
  15 S=!/4:IF(14,S+64)#0;GOTO15:(14,S+64)=12
  20 IFK=0;GOTO245:I=(12,128):PR" ",E;:(12,128)=I:PR"E:";:(12,128)=I+5:(14,254)=T+'0';:PR" T:",$(14,254),">";:INI
  21 IFI='A';GOTO200
  22 IFI<33;GOTO30:IFI='S';GOTO30:IFI='L';GOTO40:IFI='W';GOTO50:IFI='M';GOTO60:IFI='Q';GOTO70:IFI='T';GOTO80:IFI='P';GOTO90
  23 PR"CMD: SLWMPTQ":GOTO20
  30 (14,254)=12:PR$(14,254):I=0
  31 N=(14,I+64):IFN=0;GOTO34:IFN<9;N=9:N=N-9*2+224:(0,I*2)=N:(0,I*2+1)=N+1
  34 I=I+1:IFI#64;GOTO31:CALL(0,5):PR$(14,254);:GOTO20
  40 I=7
  41 J=0:PR"  ";
  42 N=I+J:N=(14,240+N):N=N+Q
  43 IFN<64;GOTO44:N=N-64:GOTO43
  44 N=(14,N):M=N/100*100:N=N-M:PRN;:(12,128)=(12,128)-4
  45 (14,254)=M/100+'0':PR$(14,254);:(12,128)=(12,128)+2:IFJ#2;PR"!";:J=J+1:IFJ#3;GOTO42
  46 I=I-3:PR:IFI<7;PR"  ---+---+---":IFI<7;GOTO41:GOTO20
  50 IFE-1<8;GOTO53:PR"DIR:";:INI:IF9<I;GOTO20:Q=Q+(14,240+I):E=E-8
  51 IFQ<64;GOTO52:Q=Q-64:GOTO51
  52 GOTO10
  53 PR"ENERGY!":GOTO20
  60 PR"DIR : ";:INI:IF9<I;GOTO20:I=(14,240+I):IFI=0;GOTO20:PR"WARP: ";:INJ:IF8<J;GOTO20:(14,S+64)=0
  61 IFJ=0;GOTO65:IFE-1<2;GOTO65:J=J-1:E=E-2:S=S+I
  62 IFS<64;GOTO63:S=S-64:GOTO62
  63 N=(14,S+64):IFN=0;GOTO61:IFN<10;GOTO240:IFN=10;GOTO241:PR"STARBASE DOCK":E=250:T=4:(14,Q)=(14,Q)-100
  65 (14,S+64)=12:GOTO200
  70 PR"SURE ?";:INI:IFI='Y';GOTO242:GOTO20
  80 IFT=0;GOTO20:PR"DIR : ";:INI:IF9<I;GOTO20:I=(14,240+I):IFI=0;GOTO20:J=7:N=S:T=T-1
  81 IFJ=0;GOTO200:J=J-1:N=N+I
  82 IFN<64;GOTO83:N=N-64:GOTO82
  83 M=(14,64+N):IFM=0;GOTO81:IFM=10;GOTO200:IFM=11;GOTO243:IFM=12;END:I=M:GOTO120
  90 IFO=0;GOTO20:PR"LVL : ";:INI:IFI=0;GOTO20:IFE-1<I;GOTO20:E=E-I:N=I/O+3:N=N-D+5:IF200<N;N=0:I=1
  91 IF(14,150+I)=255;GOTO94:J=(14,160+I)-N:(14,160+I)=J:IF200<J;GOTO120
  94 I=I+1:IFI#5;GOTO91:GOTO200
 120 PR"KLINGON DOWN !":J=(14,I+150):IFJ=255;END:N=(14,J+64):IFN#I;END:K=K-1:PRK,"LEFT"
 121 O=O-1:(14,J+64)=0:(14,I+150)=255:(14,Q)=(14,Q)-1:IFK=0;GOTO245:GOTO200
 200 IFO=0;GOTO20:I=0:PR"KLINGONS ATTACK"
 201 I=I+1:IFI=5;GOTO20:IF(14,I+150)=255;GOTO201:GOTO220
 210 N=!/32+1:IFN=6;N=9:N=(14,N+240):J=(14,I+150)+N:IF(14,(14,I+150)+64)#I;END
 211 IFJ<64;GOTO212:J=J-64:GOTO211
 212 IF(14,J+64)#0;GOTO201:(14,(14,I+150)+64)=0:(14,I+150)=J:(14,J+64)=I:GOTO201
 220 N=(14,I+160):N=N+D-5:M=!/64+1:N=N*M/4:IFN=0;GOTO201:IFE<N;N=E
 221 E=E-N:PRN,"DAMAGE":IFE=0;GOTO244
 222 M=(14,I+160):N=N/3:IFM-1<N;N=M-1:(14,I+160)=M-N:GOTO201
 240 PR"YOU HAVE COLLIDED WITH A KLINGON.":END
 241 PR"YOU HAVE BURNED UP IN A STAR.":END
 242 PR"YOU HAVE RESIGNED FROM STARFLEET.":END
 243 PR"YOU HAVE DESTROYED A STARBASE AND BEEN ARRESTED.":END
 244 PR"A KLINGON SHIP DESTROYED YOU":END
 245 PR"CONGRATS - YOU WON !":END

.

Wednesday, 27 January 2016

And more commands

Well, the program is now up to 2,338 bytes - I can scrape back a few if necessary - and it's mostly, not entirely there.

The two outstanding parts are firing phasers, and the Klingons firing (and , if I have space, I might make them move as well)

So today I have added the in-quadrant movement, and torpedo firing - but this also includes a lot of the code to 'clear up' dead Klingons, so it really should fit in the 1700 odd bytes remaining.

The actual source code - the stuff with all the macros and comments - is about 14k, so the output code does look rather like it went through one of those programs that compressed BASIC that used to be available.

Tuesday, 26 January 2016

More Commands

Well, I'm a bit more optimistic than yesterday about program size, at present it is 1,336 bytes and since yesterday I've added the long range scan - this is messier because MINOL doesn't really handle the requirement to print 42 as 042 well, and the annoying printing of spaces before and after (I didn't write its spec) which you can't suppress. You can see the long range scan on the right. (It shows the contents of adjacent quadrants).

I've also added the warp command - this Trek has two moves, one in a quadrant, and one between quadrants. It just warps to an adjacent quadrant using the directional aspect of a PC numeric keypad.

So that leaves Move, Firing Phasers and Torpedoes, getting the Klingons to fire back, and end game stuff. I'm reasonably confident of getting that into 2.5k or so.

Out of interest, I ran it in normal speed - I've been developing in a version of the emulator that runs flat out - and it is actually not so bad. It takes maybe 3 seconds to create the galaxy, and a couple of seconds to create a quadrant. Short and Long range scans take a second or two. It's a bit slow, but playable - it's actually reminiscent of playing it on a teleprinter, or a machine like an Apple 1 or a similar TV Typewriter device.

Or over a modem. Which reminds me.

I used to work in Halifax (its in Yorkshire), for a company making vertical market software for property management. We wanted to set up a machine in Edinburgh , a unix box. We had an old audio coupler modem - one of those things you plugged the old phones into physically, which was supposed, I think to run at 300 baud. (This was in the late 1980s)

It was rubbish. I couldn't even type ls<return> half the time, and when I did I just got gobbledegook back. Nothing we did made it better. We were part of a big

On the upside, I did get sent up there with a box of backup tapes and did it the hard way. Well actually I spent most of a couple of days waiting for the compiler. So a free holiday. Unfortunately it chucked it down every night, so I didn't see much of Edinburgh.

Halifax is a wierd place. It's a small Yorkshire town. Well actually it's really dull .... except if you approach it from Leeds.

Then your first view is this ridiculously futuristic road layout with overpasses and all sorts of wierd junctions. It completely threw me the first time, it's like finding a motorway built in someone's back garden. Apparently, in the 1970s they had this idea for this super-duper ultra-modern town road system, but it ran out of money half way through - so getting out of the south end of town was (and apparently still is) dreadful.

More here

Monday, 25 January 2016

Short range scanner


Having had a little time to tinker with it, I now have a working short range scanner.

The * are stars, the +++ are Klingons (this is TOS Star Trek .....), >!< are starbases and <*> is the Enterprise.

I hope it's going to fit ; so far this occupies 899 bytes of program memory. This is a little unnerving as I only have 4096 bytes, slightly over 20% used.

If it doesn't fit ; I'll implement "Hunt the Wumpus" instead :)

Building a galaxy, one atom at a time.


Primarily for reasons of space , I'm not going to directly port Tiny BASIC Trek. I had a look at various small Treks and concluded they were all too big, so I decided to write it from scratch and use the Computing Today as a base for ideas.


Minol isn't very compact - it doesn't have any tokenising so keywords like PRINT, which is stored in one byte in most BASIC interpreters, is stored in 2 (it is PR). It doesn't sound like much but over time it does get a bit cramped.
I think though that I will get most of the features in - it might be a bit rough and ready, but it will work. So far, I've done all the set up - the creation of the initial galaxy, and the creation of the new 'quadrant' from that galaxy data, which means I can start to work on the movement routines next.

Thursday, 21 January 2016

Adding some preprocessor stuff

Image result for macrosHaving done a bit of testing, I've decided to add a sort of very basic Macro processor for writing MINOL code.

Instead of everything being upper case, which I always think is horribly unreadable, I've made everything lower case.

Anything in upper case is a macro, which has a straight text substitution.

This allows me to write code like

:Energy e

To define a macro which is a variable, and then write

Energy = Energy + 1

which the system converts into e = e + 1 automatically. This should improve readability no-end, even though it is very primitive.

For development, I'm also going to cheat slightly and speed the emulated CPU up a lot, just to make running it quicker. The first thing the program does is to set up the quadrants and so on, which would take long enough to be annoying each time I run it.

Tuesday, 19 January 2016

Font changes for Trek

Over the years, there has arisen a standard set of graphics for text star trek, derived from David Ahl's version.

These are things like +++ for Klingons and <*> for the Enterprise.

To keep these (the Tiny Basic Trek actually has slightly different ones, but I prefer the classics) I've made some amendment to the font, adding eight font characters, 2 per graphic.

I have to do this because at some point I will show the short range scan which is an 8 x 8 grid. On a 16 x 8 screen, this gives (obviously) 2 characters per 'cell', and the graphics are three characters per cell.

So as you can see (in the top left of the snap) I have "Poked" 224 and 225 into the first two bytes of display memory, and it shows a <*> which will be the Enterprise.

Release 2


Well, sort of. The current release is the one with 2 2k ROMs in it (effectively) which boots into MINOL (you can access the monitor via the OS command, and return using G 9000). The zip contains the executable and the SDL DLL if you don't have it.

The hardware version is updated to match ; both should be version 0.94


Of ROMs, PROMs and EPROMs....

So…. Looking at the resulting MINOL ROM, it’s about 2,500 bytes or thereabouts in total.

Thinking in hardware terms, how you would actually put this on a machine - this isn’t good. I’m wasting 1/2k of ROM here – now, that isn’t much in 2016 terms, but in 1975 terms it is a heck of a lot.

So I have decided on some reorganisation.

Out from the monitor ROM go the Mathematics routines – which now aren’t used by anything – and into the monitor ROM goes the scrolling screen handler.

I’ve tweaked it a bit so there are vectors at 3 (Print Char/String) 5 (Get Char) 7 (Get String) and obviously changed MINOL so it calls these routines directly. This is also handy in that I can call these routines from MINOL if required.

The monitor ROM now has two sets of screen drivers – the roll to the top and the scrolling version. It also has two keyboard input routines, but this isn’t really worth fixing.

There’s one problem ; I fixed up the integer printer so when it is left it sets P3 to the Print routine, so this can’t happen any more – the Print routine is elsewhere – so this is set up manually after the three calls to this routine.

It works quite nicely, and each ROM image (both 2 x 1k ROMs) has about 128 bytes of free program space, which is handy if there are any messy bugs.

Minol Completed


Well, it’s sort of finished and working, probably. I added the final bits this morning.

  1. I added a marker in RAM (a 32 bit value) that if present indicated memory already had a MINOL program in there – if this isn’t present it does a NEW on start, otherwise it leaves it alone. You can switch back and forth from MINOL and the Monitor at will. 
  2. Ctrl+C now interrupts at Print statements. 10 PR "HELLO WORLD":GOTO 10 previously could only be got out of using the RESET button.
  3. It looks for the stack top rather than assuming it’s there (it was previously hard coded to $0FF8). It should run with only 2 x 6810 RAM chips (e.g. $C00-$CFF) in the main board, except that a long typed in instruction won't work (the keyboard buffer and stack will collide). It really needs at least three ($C00-$D7F)
  4. The current line number is cleared when you type in a keyboard command. (this was a bug), meant that if you typed PR 1/0 in the command line the number given was the last line number executed.

I will update the released version so it has both ROM images in it sometime soon, e.g. it boots into MINOL, you can type MINOL programs into it and so on. It's not bad, the original code was 1.75k this is about 2.5k but most of the difference is because of the screen driver.

The next bit is to write the code to translate a text file to MINOL format – may do something automatic with line numbers ? – and get that loading in.  You can type in programs like we used to with C64 and Speccys, it does work, but it's not a good idea on a beta langiage. I remember writing about my experiences with such earlier.

Then, once that’s done, look at Star Trek. I think there are three Star Trek related retrochallenges this half-year :)



Monday, 18 January 2016

Benchmarking an interpreter

Back in the dim and distant past, the first thing that magazines would do with the latest home computer is benchmark its internal ROM BASIC.

Virtually every machine released over a period of about 1978-1988 ish had a built in ROM BASIC, with a few exceptions – I owned a Sharp MZ-80K where it had to be loaded in from tape, and the Jupiter Ace had FORTH – but most had BASIC.

When the machines arrived that had floppy disks as standard – primarily the Amiga and Atari ST – the BASIC interpreter became something provided on a floppy disk.

The UK magazine Personal Computer World had its own set of benchmarks, which were BASIC programs that were run and measured to see how long they took. The simplest one was this :

100 FOR I = 1 TO 1000
110 NEXT I

I’ve actually found them here http://www.geocities.ws/peterochocki/computers/pcwbm.html 

To give some idea ; a ZX81 4.5s, a Speccy 4.4s, a C64 1.2s,a BBC Micro 0.8s. The slowest machine would be a ZX81 in slow mode which would be about 18s or so (estimate).

The variation is quite surprising. The first thing on the list is a 68000 at 8Mhz (HP Integral PC) which takes 1.9s ; it is quite remarkable that the BBC Micro (6502 at 2Mhz) should be over twice as fast given that both are operating in floating point. The ZX Spectrum BASIC is based on Nine Tiles original ZX80 BASIC which is designed to operate with 1k of RAM and doesn’t care about speed – a typical Z80 machine of the time clocked at 3.5-4Mhz would probably run the first benchmark in about a second.

So, I have benchmarked it. I can’t actually run Benchmark 1 – no FOR/NEXT loop, but I can run Benchmark 2, which is the same thing with an IF … GOTO instead , in MINOL, if I reduce the count to 250.

100 LET A = 0
110 LET A = A + 1
120 IF A#250; GOTO 110

Which runs in about 19 seconds (when wrapped in a loop running it four times).
This isn’t bad, really – it’s a slow processor, it’s running at a quarter of its actual speed anyway (just sticking an SC/MP 2 in and clocking it up to 4Mhz will get that down to 5 seconds) and it’s not written for efficiency by any means, it’s written more with clarity in mind (honest – an optimised one would look like spaghetti – and it wouldn’t be that much quicker anyway).

By comparison : ZX81 6.9s, Speccy 8.2s, C64 9.3s, Atari 800 7.3s

So not too bad really. If I conveniently forget they are all doing it in floating point and I’m doing it in 8 bit integer

The SC/MP is a notoriously slow processor though – having attempted to emulate processors on an Arduino, it can cope with 4004/4040/8008, the RCA1802 and the SC/MP and that’s about it. I wrote an Apple 1 emulator (more as a protest than anything else) and it ran at about 15-20% of the speed of the real thing (which didn’t matter in most cases because of the slooooow TV Typewriter output).

For depressing comparison ; 2400Mhz Celeron, running QBASIC, 0.011s. I have reduced this PC to a wreck of its original finery.

MINOL on Hardware

So, this is a sort of actually working BASIC program here.

Okay, so it’s not exactly the most complex code ever written, but it is working as it should, and it picks up errors a bit better than the original

Sunday, 17 January 2016

Running programs, after a fashion ....

Well, we sort of have it running MINOL. Very shoddily, but it does work, and as defined by the document from DDJ.

Admittedly you do have to type it into the assembler  directly , well, with a macro anyway – but it does sort of work and seem to do what it’s supposed to. It's junk code, just testing various things.

 1 "START:CLEAR:INA:PR A,A,A,A:GOTO240
 10 HELLO WORLD
 20 GOTO 20
 30 LETB=69:LETA=42:C=A+B:END
 120 D=D+1:(0,4)=D:(12,130)=69:GOTO120
 130 A=!:B='@':C=42:D=0-1:GOTO130
 140 IF1#255;A=A+1:B=B+1
 150 IF255#255;C=C+1:D=D+1
 200 LETA=0
 210 LETA=A+1:IFA#250;GOTO210
 240 PR42,69,Y
 241 PR "A:",A,"STAR TREK"
 242 PR "(",$(144,33),")"

Next up, the console stuff – editing programs, running commands from the keyboard and so on.

MINOL Commands

I seem to have written a lot since the last post in terms of the project moving forward. It is now executing code, albeit not in an interactive environment, and the GOTO RUN NEW CLEAR END OS CALL LET and IF commands are coded, leaving PR, IN and LIST.

Then I have to write the code so you can actually edit programs using the keyboard. At present the “program” is put in using Assembler Macros which works fine for testing but isn’t any good for the final thing.

I have also written a separate integer printing routine, so actually none of the math routines are now used that I wrote ages ago (well a few days ago anyway).

Part of the reason is this is a bit of a swine in SC/MP. You have four pointer registers. One is the program counter, one is used for subroutines (P3) and one for the stack (P2) – this is just convention.
This leaves you with one pointer register, P1. In this code it is normally pointing at the program code.

My original integer to ASCII routine (a 16 bit one) used this as a pointer to memory to store the result in. In the end I decided it was simpler just to write a simple byte only one that used subtraction not division – it only does decimal, and 0-255, but that doesn’t actually matter, and it is simpler to use – it just prints the number in ‘E’.

Saturday, 16 January 2016

Half time - state of play

Well, so far, I'm quite pleased with progress. I have:
Related image
  1. Digitised the circuit diagrams
  2. Written an Emulator, running on the PC and "replica" hardware.
  3. Debugged the original monitor
  4. Written a Machine code monitor with a simple assembler
  5. Written a fair chunk of a "High Level" language


to finish ....

  1. complete the Language and test it a bit.
  2. write some sort of text -> MINOL translator - I whilst I could physically type the code into the emulator, well, that's the plan any way, it would be much easier to have it as a text file and convert it into MINOL format and load it straight in.
  3. write Star Trek - and testing the language
The Star Trek I was going to base it on was the one by Ian Powell published in Computing Today (a UK Magazine) in 1979 ; the reason is I have already ported this (it's for an obscure machine, the Transam Triton) to whatever computer I had at the time (Sharp MZ80K I think ....), so it seems appropriate.

Writing a program in a partly tested language is no fun. I've actually done it before, professionally, it was a BASIC owned by a Dutch company (but written by an Englishman). It was, well, interesting. You would enter GOSUB 3000 and it didn't. Variables would occasionally disappear or the program would crash altogether. I don't know what happened to that project (Hotel Management package) but it had disaster written all over it.... I did my best. On the up side, I did get to spend several months in Dordrecht in the Netherlands, which was fun. Even if all the girls (bar one) were taller than me. In fact everyone was taller than me. Even the five year olds.


Expressions in MINOL

So, having been tinkering for a bit, I’ve written the functions to calculate expressions for MINOL. 

This is considerably simpler than BASIC , because there is no order of precedence, and only five possible terms:
  • integer constant
  • variable A-Z
  • a random number - ! (e.g. !*2)
  • quoted character value (‘a’) 
  • memory access (4,1) (which reads $0401). 

Plus, they are all one byte which means I can return them easily in E rather than use the stack.


The code is actually just the expression and the test code, which is python generated expressions which are then run and compared with the calculated answer – this kind of thing for example 

(4,(2,(((7,'O'),Z),70)))-6-90+D-4/50+D 

which is, incidentally, 23 (on the current version of the monitor, which is used for memory reads).

Obviously I don't use random numbers in a unit test but this is the Galoisian LFSR again, which is quite a decent random number generator.

Friday, 15 January 2016

MINOL

I was originally going to use VTL-2 as my High Level Language, but I discovered this Tiny BASIC ish language while poking around, it was published in an old edition of Dr Dobbs Journal.

I’d already written the screen driver (see previous post) and some evaluation stuff for VTL-2 but this looked more interesting to program in.

In some ways it’s appropriate. It was designed by someone in their “Third year of High School” (Erik Mueller, who I think is the guy pictured – not aged 13) in 1976, which means he is about the same age as me plus or minus a year.

It’s slightly odd as Tiny BASICs go ; for a start it has 1 byte values, both variables and line numbers – this means that my work on 2 byte maths routines is pretty much to pot. It does support strings, sort of and it also supports direct access to memory both for data and code.

It’s pretty impressive for a 13/14 year old and fits in under 2k of memory. This is what the code looks like :-

10 " *** NUMBER- A NUMBER GUESSING GAME (NUM05) 
20 PR:PR" WHAT IS YOUR NAME";:IN$(14,1) 
30 X=!:S=0:PR"HI, " ;$(14,1);" . WELCOME TO THE GAME OF NUMBER" 
40 PR" I'M THINKING OF A NUMBER FROM 0 TO 255" 
50 PR" GUESS MY NUMBER !!" 
60 PR: PR "YOUR GUESS": ING: S=S+1 
65 IFG=X; GOTO90 
70 IFG<X; PR" TOO SMALL. TRY A BIGGER NUMBER." 
80 IFX<G; PR"TOO BIG. TRY A SMALLER NUMBER." 
85 GOTO60 
90 PR " THAT’S RIGHT, ";$(14,1);" I ! YOU GOT IT IN";S; "GUESSES" 
100 PR" PLAY AGAIN" ; : INA: IFA=’Y';GOTO30 
110 PR " OK HOPE YOU HAD FUN . " : END 

This is (of course) the very common Hi Lo game.

  • $(14,1) is the string at H = 14, L = 1 e.g. $0E01, 
  • ! is a random number from 0-255. 
  • Lines beginning with a “ are comments (e.g. 10)

Other than that it should be fairly clear. I will probably be a bit more syntactically friendly, skipping spaces and so on - looking at the original code (8080 assembler) it could get a bit confused running program if you aren't fairly straight with syntax - so mine will support IF G=X ; GOTO 90 rather than IFG=X; GOTO90

Thursday, 14 January 2016

New Screen Driver

The picture is a thing called Curses. It was (or is) a sort of terminal driver / text ui library  that allowed the use of completely different terminals with the same code, it worked with termcap or terminfo to provide device independence.

I used to work at a place that used it ; it was a really cheap place to work. Not only did we use a version of curses we typed in ourselves from a book – wrongly, which we didn’t know until I tried to do a vertical menu with it and it crashed all the time. When allocating memory for the window we’d used w * w rather than h * w, which worked fine provided w was greater than h, which it isn’t in some drop down menus.

The hardware we developed on was on loan from someone or other – a huge 386 box about the size of a fridge. We kept having to concoct reasons why we were still ”testing” this gear …… this company was a subset of a big commercial organisation too. If the owners had wanted it back we would have been stuffed….. we were running Xenix/386 on it and we wouldn’t have had a machine to develop on.

I also worked at a place where I was given an original IBM PC to work on, the 4.77Mhz one, with a specialised BASIC interpreter. I got an upgrade when I pointed out the machine could not keep up with my typing – type LIST and it took about 5 seconds to appear. Not awfully good for productivity (this same place I was ridiculed for suggesting DBASE III type screen painters …. this was in the late 1980s ….)

Anyway, the point of this is I have released, hopefully, a new screen driver for the HLL – this one does proper scrolling unlike the rolling of the monitor, which means it needs 128 bytes of RAM all to itself – because the design does not allow you to read video ram, you have to keep a shadow copy of everything. I wanted the Monitor ROM to be able to operate in one 128 x 8 RAM.

It’s about 400 bytes and provides string and character input and output. There’s a program testing it that just inputs a line and echos it again.


Wednesday, 13 January 2016

Working Release

Something actually downloadable and runnable, at last :)
Image result for release software
I've added a link to the release directory, which contains a zip with two further files (click on the file then RAW to open it.... I think) one of which is SDL.dll, the SDL dynamic link library, and the other is the emulator.

All you can do is run it at the moment.

The commands are (apart from assembler ones)


  • A [aaaa] set current address
  • B [bb] [bb] [bb] ... enter bytes at current address
  • C clear screen
  • D [aaaa] disassemble from current address
  • G aaaa run program
  • GET [aaaa] read tape to addresss aaaa
  • L nn set label nn to current address
  • M [aaaa] memory dump
  • PUT [nnnn] write nnnn bytes from current address to tape I/O


All the source and so on should be up to date ; also the hardware version source is released, this requires platformio to build it.



Britain's Dumbest Coder Episode 94

Confession time.

I spent about 20 minutes finding a bug this morning. For a complex bug, that’s not so terrible, but this wasn’t a complex one.

The emulator uses different storage for the Windows version (RAM arrays) and the Arduino version (Flash memory) because the 2650 just doesn’t have very much RAM memory, so the ROM images are permanent in Flash.

So I wrote some Macros in ‘C’ to create and access these.

When I added support for ROM at $9000-$9FFF into the emulator, this involved putting these macros in and amending the Read() inline function to cope with reading from this space.
Worked perfectly in the emulator version, didn’t work at all on the Arduino one.

Lots of headscratching.

Eventually it dawned on me that I’d written something like :

MB = extendedROMMemory[MA-0x9000]

on the Read inline function.

This is why it didn’t work ; I was always using the static RAM access in either version, whereas to access Arduino flash you have to use a function pgm_read_byte_far() or something like that.

This was despite writing a Macro to do this automatically (so you just put in ROM(extendedROMMemory,MA-0x9000) and it did the work for you) and having an example immediately above (reading from the Monitor ROM space) to copy.

I felt very dim when I realised it…..

Answer to the question in the last post:

VTL-2 allows punctuation to be used for variables, including ‘=’ so ===== becomes, if we replace the = that refers to the variable '=' with 'E'  it becomes

E = E = E

E = E as an expression is 1 (VTL's "True") so it becomes

E = 1


Tuesday, 12 January 2016

Monitor Complete (again)

Well, pretty much. Should now be version 0.92. I’m hoping this is a fairly stable version now.

This one no longer has a random number generator, but has an integer to ASCII routine, which appears to work fine.

So I will upload this to github and sometime tomorrow upload the emulator and hardware source, so people can actually run this if they are so inclined.

After that, think through VTL-2 and get used to the language. It puts me in mind of APL a bit.

Actually what it is really is a sort of transport triggered architecture BASIC, where moving something from one place to another does something. There’s only one instruction (assignment statement), but if you assign to ? it prints the number, if you assign to $ it prints the character and so on. You “GOTO” (boo !) by assigning to #. Editing is done a la BASIC (e.g. line numbers) and you can execute from the command line like you do in BASIC.

It gives it a 87”*&£(*!”&(&(!*”&£( sort of look, which isn’t helped by the use of the 6 bit ASCII character set as variables, so you can use = as a variable, an operator, and an assignment.

So in VTL-2 you can write, as an instruction.

=====

Quiz of the day : what does this do ?



I was thinking about the implementation of VTL-2.


One thing that dawned on me was that the monitor and VTL-2 won’t share much code , except the Maths routines – VTL-2 will have its own i/o routines with proper scrolling rather than the rolly-to-the-top thing I have now.

VTL-2 will not have the requirement to operate with 128 bytes of RAM minimum (as the Monitor uses about 60 bytes, and the stack probably 20 or so , this doesn’t leave a huge amount of memory).

This is a problem for the random number generator ; out of all the routines, this is the only one that uses a fixed memory slot, 2 bytes (at $C1E) which is the current seed, the only static value in the mathematics routines. If I use this, I am beholden to the memory layout in the monitor.

So, I’ve decided to simply cut the routine altogether and replace it with an Integer -> ASCII routine which won’t have that problem – like the other routines it communicates via the stack and P1.

I could’ve passed a pointer to the seed in, but that just seems messy.

This might mean I have to lose the beep on start up, or the text message ; I can live without those .... just. Surely a beep is mandatory in a retrocomputer.

A bug, after a fashion.

Well, a bug popped up. Sort of.

When reading through the VTL-2 stuff I noticed it uses positive integers only 0-65535. The problem is my arithmetic routines only do -32768..32767.

So I sacrificed my in ROM message to have two divisions – forward slash (signed) and backward slash (unsigned). Multiply works for both.

Retesting revealed a bug in going from 15 to 16 bit division, checking the result sign rather than the Carry flag when doing the test subtraction, so I replaced that.  It almost doesn’t really count as a bug, because originally values were only going to be 15 bit.

But anyway, that one is fixed.

I’ve added, for no reason at all other than I can, a booting beep to the machine. It reminds me of my days with the BBC Micro, where it used to boot up with duuuuu--beep.

Monday, 11 January 2016

Monitor completed.

Definitely not a cheese-eating surrender monkey
Monitor is now at version 0.90, e.g. it is basically finished and works well enough.

Every byte is actually used, but I could easily scrape up about 80 bytes ; I put a text message in the ROM just to fill up space really, and there are things I could trim if I needed to.

The chap on the right is Evariste Galois, a French mathematical genius who died at the age of 20 as the result of a duel. The random number generator I have added comes from his work on feedback shift registers.

The other addition is an ASCII to Integer conversion routine, which takes a string of ASCII digits and converts it to a 16 bit integer.

It struck me that much of the code written in the last couple of days is basically FORTH – arithmetic operations on a stack, and I was quite tempted to use FORTH as a High Level Language.

The thing that has sort of taken my eye, though is a language called VTL-2 ; this was a very tiny language, a sort of cut down BASIC with some interesting features.

It originally came with an Altair 680B (the 6800 based follow up to the original Altair), and was designed to fit into 3 PROMs – these things were horribly expensive then, these are 256 x 8 byte PROMs.

I will spend a little time pondering what to use for Star Trek (the 680B manual actually has a Trek listing in it which would be cheating a bit …..)

Testing the arithmetic routines ....

Of course, we all love maths tests…..

I tested the arithmetic  - primarily multiply and divide a bit bluntly – putting sums in and comparing answers.

I thought this wasn’t good enough, so I wrote a program that resides in the machine’s RAM at $C40 that repeatedly tested multiply or divide against a set of inputs and outputs (including remainder for division).

I then created a little python script which generated the result. With a little bit of tweaking it worked ; there are issues with –ve numbers.

What I do is remove the signs, do integer division, and then put the sign back if the input signs are different. Python does it slightly differently ; it seems to depend whether you round the result down (on the number line) or round it back to zero. But I’m quite happy with my algorithm, and it passed several hundred tests with flying colours.

So the last two monitor bits are going to be ASCII to decimal conversion, and a Galois LFSR to generate some nice random numbers. This should fit (if necessary there are bytes that can be chopped).

Maths routines added.

Well, the arithmetic is done, though I do want to test it a bit more – at present it is only the four basic operations.

I’m considering adding a random number generator and ASCII to/from integer functions to it. Probably in the opposite order.

I want to write some code to test the arithmetic functions better , especially multiply and divide – they seem to work as far as they go (e.g. the 16 x 16 bit multiply only yields 16 bit results and so on.

Memory-wise I have 256 bytes left of the ROM monitor.

Though as you can see I’ve wasted 35 bytes of that on displaying a prompt when the machine first boots up, and it beeps to announce it has booted.  This is running on the replica , so far there seems to be no problems of consistency between the replica and the emulator at all, which is good.

Once I've played with it a bit more and finished the extra operations then I will release the source to the emulator(s) - they share the same source, mostly - the only differences are I/O, obviously, and things like ROM code is in Flash ROM on the hardware version and Byte Arrays in the PC version.

Question of the day: how can Microsoft with all the improvement in CPU speeds etc. still have a word processor that runs worse than Word 2.0 on a 386 ?

Sunday, 10 January 2016

Moving on apace ......

The monitor moves on apace.

Firstly the quiz question.

The problem was I had SIO working backwards. Instead of reading into bit 0, shifting the others left, and outputting bit 7, it works the other way round – bit 7 is the input bit, bit 0 goes to the SOUT latch and the data is shifted right.

So LDI 0x80 ; XAE ; SIO which is supposed to set the SOUT Flag (this is the start bit) wouldn’t do anything (well, it would clear SOUT…. which is connected to Bit 0)

Anyway, that is fixed and I have written the bulk of the arithmetic routines – addition and subtraction (easy) , multiplication (bit harder) and division (messy).  I prototyped them in python, this should be in the documents directory.

The missing bits ; division is unsigned at the moment and doesn’t test for division by zero.

I’ve got about 364 bytes left, plus some set-up-to-test code so its probably about 400 bytes or so, so looks like most of the goodies are going to fit. I might look at other mathematical operations.


We shall see.

and disassembling back again ......

Well, the monitor is now sort-of finished, really.  Well, beta ish anyway.

It has most of the functionality I wanted when I started. You can see the disassembler at work here (disassembling a chunk of the Tape I/O routine).

Like the assembler, it is primitive but works.
I still have plenty of space left in the ROM (620 bytes), so I think I will have some 16 bit routines in the ROM to do multiply and divide definitely, add, subtract maybe and so on, which will come in useful for any HLL I write (or indeed anything else).

This will probably be a FORTH sort of thing where it takes values off the stack and processes them.

Then after that, maybe a boot up message and sound f/x – this isn’t really much use but does have the advantage that if I need that space, for bugs for example, I can take it out again, or truncate it.
I have been surprised by the relative efficiency of the code ; I wasn’t even sure I’d get the assembler into the 2k of Monitor space I have. 

It’s partly learning the style of coding for these processors.

Competition of the Day

In the 7 lines of code shown there is a significant (read I’ve done something really dumb) bug which will stop the tape system (but nothing else) from working.


What is it ?

Saturday, 9 January 2016

An inline Assembler of sorts

Well, I now have a working inline assembler, which was fairly easy – a lot of the work had been done in the rest of the ROM.

I still have plenty of space. I was worried that what I’ve done to date – memory read/write/view/execute, tape i/o and the assembler would take up the whole ROM, as of the time of writing the space between 0x3CC and 0x751 is empty, which is 901 of the 2,048 bytes I have available.

A quick demo showing it running on the replica hardware.  I have written three lines of SC/MP assembler here which are a slightly modified version of full assembler. In a proper assembler it would look like :

Loop:   DLY 70
        ILD 0x45(P2)
        JNZ Loop

So you can see the correlation quite easily.
(DLY is software delay, the operand says how long, ILD is increment and load memory at address P2+$45 and JNZ is jump if not zero)

In the second picture I have typed C (to clear screen) and D C15 (Dump memory from C15 onwards) and you can see the results.

Note that the relative address calculation on the JNZ  has been calculated automagically from the C15 (the absolute target) to $FA (the 8 bit signed relative target).

It isn’t super intelligent, it doesn’t (for example) check the range on relative offsets, so if the actual offset is $105 not $005 it will still assemble it. But it’s only really intended for very simple programming.

The next thing to do is the labels (so you can do JNZ =7 rather than remembering addresses) and to work a disassembler. Then I will see how much space is left, and probably fill the rest with utility routines, maybe.

Friday, 8 January 2016

Monitor - in Progress

I’m quite pleased with progress on this. I was worrying about fitting the assembler in, but the other bits of the monitor are written and working properly – well, I haven’t tested the tape read :) but it probably works.

The monitor commands are built around the concept of current address – on the screen you can see this is currently $0020. The cursor is at the top of the screen because it loops round from the bottom rather than scrolling, part of my (rather unnecessary) requirement that the monitor does not require extra RAM beyond the 128 bytes.

It will probably end up using about half that 128 byte minimum in variables, input buffers, labels and the stack.

The current supported commands are:

A [aaaa]   Set current address to aaaa
B [bb] [bb] [bb] …. Enter bytes – as many as will fit on the line.
C Clear screen.
D [aaaa] Dump from current address, updating current 
                    address if aaaa is present
G aaaa Run program from aaaa – the address is
                    mandatory here ; XPPC P3 exits.
GET [aaaa] Read tape into memory at current address, 
                    updating current address if aaaa is present
PUT nnnn Write nnnn bytes starting at the current
                    address.

So the next bits are – adding in the micro assembler so you can type code straight in, then the label allocation code.

Then I’ll see if I can fit a disassembler in as well. It looks quite promising. If there is still space left I might put some 16 bit multiply and divide routines in.

Thursday, 7 January 2016

Thinking about Monitors....

The machine pictured is a UK machine called the “Nascom 1” from around the late 1970s.

Many of these machines hadn’t quite got as far as the built in BASIC interpreters of the Pet/Apple/Tandy era, they had ROM monitors. (The Nascom was a Z80 based m/c with a TV display). These allowed you to change memory, run programs, read and write to cassette tape etc.

I’ve done some work on a monitor, which hopefully I’ve remembered to upload to github. It is just basic I/O with the SC/MP's version of the DAA trick for converting binary to ASCII hexadecimal.

I thought I might do something a bit different, rather than just have simple commands to set bytes, run programs etc. if it will fit I will add in a sort of pseudo command line assembler so you can type things like:-

LD @P1 47

into the command line and it will assemble the code (C5 47) for you.

I got the idea from another British SC/MP machine, the Scrumpi 3, which had the option of setting label values, so you could calculate jump offsets etc. automatically. It’s a very basic assembler, obviously it doesn’t do forward references which is the big minus point. However, it would take a lot of the hassle out of entering programs in machine code ; it’s a kind of half way house between the Nascom1 or Apple 1 monitors and a proper assembler.

Much depends on the space. My original design only allowed 2k of ROM on the basic machine – the idea is that this machine should work with 2k ROM, 128 bytes of RAM and the video display, so it might not fit. I shall see.....

As a move towards this, I have written code to convert typed input into 15 bit numbers (representing up to 3 x 5 bit ASCII characters) which I can use in a look up table, which can direct the monitor either to execute code, or to assemble it. If the baby assembler doesn’t fit, it’s a rather long winded but harmless way of decoding the command line. e.g.

ASCII A L Z
Hex 41 4C 5A
5-Bit 01 0C 1A
Binary 00001 01100 11010

15 bit 000010110011010

So basically it takes the characters, converts them to a 15 bit equivalent, looks that up in a table and does whatever is there. Fortunately most of the opcodes on SC/MP are three letters and those that aren't are easily modified to suit (e.g. XPAH -> XPH). I can use a lot of the same code, because the @P1 stuff can be handled using a modifier byte, and the other instructions are faux opcodes so you might have G 1223 to run code at $1223 whereas JMP 1223 might assemble 90 xx where xx is a relative offset.

If I’ve got the space, I’ll create a little disassembler as well. But I suspect it won’t fit. Can’t have everything

When I come to write the HLL, I’ll have to rewrite the I/O as well. This one is designed for 128 bytes of RAM as a minimum – this is the minimum set up of the machine. This means, because of the write only VDU, I cannot have scrolling (I need to save all the characters output to scroll), so what the monitor does is jump back to the top from the bottom, keeping the current line clear as it goes.

All the code from here is original. I had a couple of sheets of code, one of which was the basic monitor which I copied and tweaked slightly. The other one is just the middle of something, the PILOT interpreter I think, and it’s useless on its own.

Basic Testing

So, before I actually write some code that might be slightly useful, two basic tests.

First up, the speed test. This displays a counter of the number of times a section of code is done, and the section of code is a pretty random cross section of SC/MP instructions , just enough thought to avoid crashes.

The purpose of this is to confirm that the replica can keep up with the software emulator, which it can.
Second up, a basic hardware test. This functions a bit like a teletype – whatever is typed in is displayed. At the same time, the lower three bits are sent to the sound system (system, seriously ?) to play the appropriate note.

This tests most of the hardware works as it should.

The exception is the cassette tape – as this is basically banging data out via SIO then I might code it, but there’s no real point in implementing it physically.

These two source files, plus the monitor (for the basic board, with 128 bytes of RAM and the video card, operated by the buttons a la Altair are in the software/miscellany directory.

These are assembled using Alfred Arnold's exceptional cross assembler AS, which as far as I know is the only SC/MP assembler except for my bodged TASM file of ten or more years ago.

I think the most up to date one is required as I have sent a couple of bug fixes in in the past.

Wednesday, 6 January 2016

How not to design a printer

The printer design….. okay, let’s start with the picture, which is where the idea for this printer came from. This is a 1970s Dymo Labeller – it works a bit like an old daisywheel printer, except you do it by hand – you rotate the round bit, pull the trigger, and the letter appears on the tape.

The printer design is a dot matrix version of the same sort of thing. There is an array of 7 pins that are actuated by the computer  (the interface is a couple of 7475s driving actuators via transistors basically so I haven’t bothered to convert this one), and these mark the paper through a piece of inked ribbon. 

The 8th pin pulls the paper strip through to do the next vertical line ... without using a stepper motor (that’s going to work well ….), and so on. 

So you get something like the Dymo output in dot matrix form. In a long strip of paper.


When I actually looked at this I was slightly embarrassed. But then, I remembered this.  This is from the CDC160 System Programmers guide, which lists the various routines provided with the minicomputer.

It’s basically exactly the same idea, except instead of using an Inkjet Ribbon.

So, I’m at least as smart as C.M. Atchison :-)

On designing a Video Card

Pass me a beer.

I’m quite impressed that as a teenager I had any idea how PAL video worked at all. I’m now in my 50s and I still haven’t really got it. I think NTSC is easier (even though the colours are bad)

I’ve only documented the main digital part of the video board (because the rest of it is a bit hopeless is the real reason), and this bit isn’t so bad.

The basics : IC9A and IC11A decode write to Video RAM (this shadows the lowest 2k of ROM from 0000-07FF).

IC1 and IC2 count horizontally, using IC2 pin Q3 to blank horizontally. IC3 and 4 do the same vertically.

The character positions (e.g. divide by 8 – note that IC3/4 divide by two initially e.g. IC3 pin Q0 is not connected, so each line of character data is repeated) are passed into address multiplexors IC5/6 which takes data from this on VRAM write. These are then fed into 128x8 RAM IC8 (Yay ! - Motorola – again) which can receive data from the bus gated via IC8 on VRAMWRITE.

This data out – the character – is fed into the character generator ROM IC10 (along with Q1-A3 of IC3) and multiplexed by IC12 (using Q0-Q2 of IC1), and the gated by the two blanking signals from the counters.

There’s one obvious mistake here (there’s probably half a dozen others !). There are no delays between the reset pulses (HSYNC and VSYNC) and video output. So No front porch time, no blanking period before vertical display starts. Oops. I also seem to have moved the whole blank area to the bottom, so the display occurs in the first 128 scan lines. Which means half of it will disappear.

I would probably fix it on this design by having them trigger a monostable multivibrator (each) which gates their clock inputs, thus effectively shoving the picture right and down – the outputs of these would have to be gated as well (so that when the monostable is blocking the clock the output is blanked). I do remember looking at an early video card which operated in this way.

But I have a spare 3 input NOR and ¾ of a 7400, so that probably means a couple of 555s – I think there’s a TTL dual monostable as well ? (The other way would be to use 74193 rather than 7493 and preset them to –ve values, though I’d need another /2 counter to clock the vertical position – gotta be able to count to 262 or 313.

Still nobody’s perfect…

What’s missing – well, at the end there is the mixing of the sync signals to produce composite video, and at that time there'd be an RF Modulator so you can plug it into a telly, and obviously there is no sync generation – these days the best way of doing this seems to be a microcontroller….. which would probably be more powerful than this computer.

Next up ; finish the emulator and replica versions, and write a test program for them which tests all the various bits and bobs.

The software emulator does actually emulate the bits on the ‘basic’ board – the buttons and LEDs and so on – and I have actually written a basic monitor for that system, but from now on I’m going to ignore those buttons, This monitor is the only bit of software that has survived, though it had a couple of bugs in it.

I think, in a real system the LEDs would go nuts in classic Blinkenlights style when you are writing to the video, because they are mapped onto the same space. What would an old computer be without Blinkenlights though ?

Tuesday, 5 January 2016

It lives !

This is the Mark 1 replica of the WP1 … and it seems to work, and it seems to work quickly enough.

It is, obviously, a faux replica like the Kim Uno - it is an emulator running on a hardware platform. Building the design isn't very practical at best - for a start all the Motorola ROMs and RAMs are probably almost unobtainable, and are expensive in quantity. The design is not actually bad given how old I was when I designed it, but it isn't robust enough to be built either.

The design is very simple. The display is an ST7920 SPI GLCD which is 128 x 64 resolution. It is connected to A0,A1 and A2 so it is bit banged rather than uses the built in SPI.

On the right, a piezo buzzer, and in the lower middle a PS/2 keyboard adaptor. You can’t buy PS/2 keyboards any more, so there’s a USB->PS/2 adaptor (which you can buy dirt cheap …..) plugged into it and an ordinary keyboard onto that. The Arduino’s power lead and programming connector is on the right, not plugged in.

The whole thing lives on a Mega 2560 board, which will probably give me about 6k – 7k of RAM when I have finished, which will be masses – most of the software will be ROM based, and the Trek program Is not that big.

The picture is rather odd, the bottom left looks like something weird is plugged in there, but its an artefact of the green proto board (which is an Arduino UNO one) and the black Arduino board underneath it.

Sound is not emulated yet, on either, so the next thing I will do is to code the sound interface for the real thing and the emulator, and write a better testing program than the current bodge.

The other thing I haven’t done yet is copied the Video display circuit and described my novelty printer design.

Once that is done, then I will do some testing of this hardware both for compatibility and for speed, and then write some original software. First up will be a ROM based Monitor.

Monday, 4 January 2016

The RAM/ROM Expansion board

Some 128 x 8 byte RAM Chips. 
The design for the expansion RAM/ROM board is fairly simple. Like many designs of its type, it’s also very repetitive.

The basic design allows for up to 4kb of ROM,  made up of up to 4 MCM6830 chips (there’s that Motorola thing again), and 32 128 x 8 MCM6810 chips (no prizes for guessing the manufacturer's name).

I probably should have designed them using 1k x 1 SRAMs as looking at 1970s prices they were a lot cheaper.  But that's thinking further down the line - for a machine that is programmed in assembler code, 128 bytes is actually quite a lot. Using 128x8 RAM chips means you could progressively add more and more RAM when you could afford it, 128 bytes at a time.

Against this, it could be designed with 256x4 chips which would be cheaper and fractionally expanded.

Probably would be better with 2708 EPROM rather than 6830 ROMs. This would actually require more logic for decoding, one of the advantage of the 68x0 series is they have quite a lot of chip select pins built in – the design makes use of this feature.

This design won’t work I think, because the processor couldn’t cope with all this without some buffering (this applies to the whole thing, I haven’t considered fanout at any time. I probably didn’t know it existed). But aside from that, it seems to be okay.

U1’s job is to latch the upper 4 address lines (A12-A15) on NADS strobe. IU4Aa detects this as being 0000 and this is the “ZeroPage” signal which is used to enable all the addresses on the CPU board.

In reality at this time though, this board would be horribly expensive to fill up with RAM, even if I redesigned it using cheaper 2102 1k x 1 SRAMs.

U4B selects the page this memory appears on. This is done using A12,A13 and A14 or their inverses, this is a handy by product of using the 7475. A15 = 1 is for the ROM, A15 = 0 is for the RAM.

So if your page selection gate (U4B) is set to page 5 (101) then :
  • The 4k of ROM will be at D000-DFFF (1 101 xxxx xxxx xxxx)
  • The 4k of RAM will be at 5000-5FFF   (0 101 xxxx xxxx xxxx)
The 4k of RAM is divided into 512 byte blocks of 4 x 128 x 8 each. One of these is shown. Their chip selects are : the current page signal, one of a combination of A7 and A8 and their inverses connected to chip selects (see the A7:x A8:x text above each RAM chip and track what the A7/A8 bus lines are connected to), and a page selection output from U3 decoded from A9,A10,A11. This itself is only enabled if A15 is low via U3 pin 5 (otherwise all the U3 outputs are driven high)
The ROM decoding is simpler. It uses for chip selects for each 1k ROM – the current page (e.g. A12,13,14), A15 must be logic 1, and a combination of A10 and A11 or their inverses. The same usage as A7 and A8 in the RAM area.

The schematic only shows 1k ROM and 512 bytes of RAM, but there are just 3 more ROMs and 7 more banks of 6810 RAM chips to fill it up, same connections, varying just on which output of U3 or which of A10/Not A10 A11/Not A11 is connected.

A slight oddity is because page zero already exists, the logical place to put the expansion board is in page 1 (so the RAM is 1000-1FFF which is continuous from the RAM on the CPU board, and the RAM is 9000-9FFF).  Though actually it doesn't matter as SC/MP memory is not continuous in the way (say) a 6800 or 8080 is. If you set HL or IX to $0FFF and increment it, it will become $1000. In an SC/MP, it becomes $0000. In the planned High Level Language, it will just probably use 1 page for RAM and 1 for ROM.

If you were like many computers of that time, where memory is continuous and you have (say) 48k RAM for BASIC code, you'd have messy code to put each line on the same page ; if you didn't pointer increments would be horribly messy - every time you bumped a pointer register you'd have to check it was cross page.

You can still get at the missing 4k of ROM (8000-8FFF) by putting the board to plug in at Page 0. This will work, but you can’t then put the RAM in as well, because it will collide with the 0000-0FFF ROM, RAM and I/O.

If you have multiple boards the design is a bit wasteful, the decoding and so on is repeated. I think to grasp this you have to look at chip prices then. 7400 et al weren’t far off the price they are now – they are cheaper but it’s the same sort of price (in 1978 a 7400 cost 13p).  RAM/ROM is incredibly expensive. A 62256 (32k x 8 SRAM, which is enough for the entire RAM memory of this machine, is about £10 or so. In 1978 a single 6810 RAM was £4.00), and money is now about 3.5 x the value then, so the single 128x8 RAM is more expensive than the 32k x 8 SRAM chip. This makes designs that worry about the odd 7400 chip here and there a bit pointless.

If we fully populate one of these boards and connect it to page 1 (e.g. the AND gate has A12, Not A13 and Not A14), we have the following memory map. (This is the standard layout because it makes the CPU Board RAM sort-of contiguous with the expansion RAM).

Address
Contents
0000-07FF
2k Monitor ROM (Write to Video circuitry and LED output)
0800-0BFF
Keyboard (or toggle switch) input
0C00-0FFF
CPU Board RAM
1000-1FFF
Expansion RAM
2000-8FFF
Unused
9000-9FFF
Expansion ROM
A000-FFFF
Unused

A dubious cassette interface

This is the bit that is probably completely wrong.
I think the idea behind it is plausible, but the execution isn’t quite right. I never was much of a one for analogue electronics, to be honest. Still aren’t.

The purpose is to convert a digital signal to a tape recordable one and back again.

This is how it is supposed to work.

Output side

U1 is a 555 configured to run as an astable multivibrator at about 1.5khz. The output is gated via D1 and D2 which form a diode AND gate – if SOUT is high the signal is output to the tape, if not, it isn’t. I suspect this signal needs rounding a bit to work.

Input side

R1/C1 form a 2.8khz Low band pass filter. Signals that get past this turn on Q1, triggering the 555 which is configured to run as a monostable multivibrator with a period of about 1khz. A 1.5khz signal should retrigger this before its period ends, providing a constant logic ‘1’ output when there is a signal coming in from the tape.

Notes

When I figured it out this design after god knows how many years, my first thought was, does a 555 retrigger like that ? The problem is, no it doesn’t, because it doesn’t discharge the timing capacitor (C5). So the circuit won’t work as it’s supposed to. It is fixable in various ways, apparently, including simply replacing the 555 with a 74123, and wiring a PNP transistor across the timing capacitor to discharge it rapidly.

The circuit is probably going to operate at about maybe 150 baud maximum – this is pretty slow, but then again, with 128 bytes of RAM, it matters less. I think my out frequency of 555 is rather low, but I suppose having an audible frequency makes sure it is in the recording range of a tape cassette. I was looking at some other circuits which were using 3khz waveforms, so I suppose this must be do-able with a bog standard recording tape.

Still not sure if it would work in practice with the adjustment made to the monostable circuit. Probably not, because the on cycle time of the square wave is half the frequency, so I probably need to bump that oscillator (U1) up to 2.3khz or thereabouts. Replace C4 with a 22nf capacitor But it’s not bad, and the output needs to be smoothed to something more akin to an audio signal rather than a direct square wave.