Thursday, 20 September 2012

Sinclair Spectrum 128k +2 MINI

Sinclair Spectrum 128k +2 Mini!
The above image is a mock-up of what a sawed-off Sinclair Spectrum 128k +2 might look like. Read below to see how it turned out to be reality! The idea for this picture came from Marq, who suggested removing the ugly and unnecessary tape device in a rather brutal manner.

The original
The initial idea was that the cut would be aligned with the left edge of the cassette slot opening, giving a very straight line from which to begin. The whole operation ought to be simple, as the tape recorder is not really very integrated to the other stuff inside the casing. The motherboard is entirely contained at the left side.

128+2 insides: With the cut, the heat sink would have to be re-arranged and the casing would lose one support.
Still, the cut suggested in the first image may not be quite as straightforward. There are some parts beside the tape recorder that extend beyond the cutting line. This could be covered by having some kind of addition to the right side, perhaps something that resembles the original 128k Spectrum. Another option might be to use a couple of centimeters of the +2 casing itself! But this would probably leave a visible seam.

Preparing for the cut


Removing the cassette recorder proved to be simple. Also, the computer appears to work just as well without the tape recorder, which comes as no big surprise. In this process the power LED has come off, and I think someone else will have to figure out how to rewire it.


The now revealed plastic protrusions and screw holders can hinder the cut, so some re-thinking is in order at this stage. On the plus side the heat sink (A strange L-shaped contraption) may indeed be possible to turn around to the front side. However, it is unlikely to fit without at least some changes.

Cutting


About that re-thinking... Nah, I just decided to go with the original line. I first used a sharp paper knife to cut as deep as possible along the side of the tape recorder opening. Using a ruler, I also made careful lines using the opening as a guideline. When it came to actually cutting the plastic, the paper knife turned out to be surprisingly poor, so for the rest of the project I only used it for initiating points for sawing.

Some care needs to be taken when sawing the front. I used a straightedge and the paper knife before sawing.

I used a "Japanese" style back saw, meant for wood cutting. I probably ruined the blade but it had seen its best days anyway. This saw took to the plastic surprisingly well, and I felt encouraged to just push violently through the screw holders and other protrusions. However as I progressed I realised the casing would loose most of its support at the same time, and the part remaining to the right side of the keyboard became quite fragile. So I did away with the protrusions with some more care, trying to saw them sideways from below when possible.

The tape recorder part could be made into a unique, stand alone, Spectrum-themed tape unit. But who cares?

It might have been a wiser move to saw first the bottom half, leaving the more visible parts for later stage. Then I could have used the "gained experience" for the more important parts. But this way, I can use the existing cut for lining up the bottom half of the casing. Had the bottom been cut first, the resulting alignment might have been unsuitable. 

But really, I just could not resist getting first at the meat of the matter!

And now, what at first was just a mock-up, is rapidly becoming a reality...
The resulting edge is surprisingly straight given it is hand sawn and my sawing skills are a bit rusty. The success is mostly thanks to the existing tape recorder opening edge. The face certainly needs sanding, but perhaps not as much as I had feared.

Cutting the bottom half posed no problems, but making the end part from the remaining plastic and solving the heat sink placement is a bit tricky.

Closing the case


I have bent the heat sink from the L-shape to a formless blob. It does not quite go into a neat U-shape, at least without sawing the piece. I'm hoping to avoid that work phase, yet it may come to that.

Yet another decision to make...
The seam looks worrying at the moment, and at this stage I am tempted to cap off the end with a flat plastic plane cut from the former case bottom. This would diminish the effect of the seam and make the computer look very neat (from front and above) and much like the original mock-up image. However this would buy very little room for the heatsink and would maybe not look so nice from the side.

Adding the pictured end piece gives some more length to the computer, a bit like the original 128k Spectrum. The bent heat sink would fit easily. This direction means that there will be nearly endless sanding of the two parts and still the seam will probably be somewhat visible.

So, which ever route will be chosen, there will be work. But then again so far everything has gone quite smoothly.

(Continued to Part Two)

Saturday, 15 September 2012

8-bit CAD attack

In the following, I will shortly discuss the phenomenom of 3-D modelling on 8-bit computers. I'll also give a little example in Sinclair BASIC that makes use of 3-D graphics and perspective foreshortening. This gives some idea of how the topic of 3-D graphics appeared to the hobbyist programmer at the 1980s.

This kind of software allowed the definition of shapes in three mathematical dimensions. Then these objects would appear from an angle. It's a far cry from today's modellers, where it is possible to sculpt an object directly on the screen as it appears. Also, these little programs are not really Computer Aided Design packages by any means, but it's still interesting that these were ever made.

VU-3D on the Spectrum

VU-3D was created in 1982, released pretty much alongside the release of the Spectrum. Psion made some of the most competently programmed software of the early Spectrum days. To my knowledge, since then nobody has really attempted to create a three-dimensional object modeller and solid renderer on the Spectrum. 3D Construction Kit (1991) from Domark might be closest to the description.

The VU wineglass, the Spectrum equivalent of the tea kettle!

At least to me, the VU-3D wine glass and box image was one of the early "iconic" images associated with the Spectrum. The screenshot was the basis for the cassette inlay of the package.

The three-dimensional shape is created by adding sections from bottom to top.
The editing is quite slick, but does not have any functions for modifying the existing points (that I know of). Nor is there any grid snap that would have made it easier to align the points. When viewing the object, there seemed to be some limitations to the angles from which it can be viewed. So, when devising the object, one needs to be careful to think which way it will be positioned, as this fundamental angle cannot be changed afterwards.

Viewing the created object.
So, it's pretty much a toy program, but the shading renderer is pretty impressive for its time. I found it quite difficult to do anything that would compare with the complexity of the wine-glass object, though.

ORIC CAD

Curiously, a very similar program exists for the Oric home computer, produced by Tansoft. After about 10 minutes of loading (in the slow speed) the user is greeted with a screen of text. Everything appears to have been written in BASIC. The demo object is a kind of round object made from an extruded pentagon, not as impressive as the wine glass on VU-3d.


A complete 8-bit CAD workstation!
The shape addition is not that different to the VU-3D. However, it is possible to go through existing points in the shape and adjust their coordinates. This makes it much more simple to correct any distortions that might have occurred.

Outlining the shape plan with ORIC-CAD.

One question is whether the Oric program is just a straight copy of the VU-3D, or whether there exists a common precedent that they both attempted to emulate. Perhaps there is some precedent on the bigger computers or turnkey CAD systems. Possibly it was something that was featured on a TV show, so the programmers might not even have had real first-hand experience of these bigger programs. But then again, Psion programmers for the early Sinclair software appear to have been quite competent so who knows.

3-D objects in Sinclair BASIC

Given the simplicity of the above programs, it might be just as useful (or useless) to write a program of your own. So, of course I could not resist the idea of doing something very quickly.

The example below gives some idea how such a program could be started, although it has many limitations compared to the above software packages. Back in the day, 3-D programming was quite a difficult topic. Then I could not really work my head around it at all, as oftentimes the examples were quite impenetrable. Yet, after getting how the objects are defined as coordinate lists, it really comes down to two things: perspective foreshortening and transformation (rotation), which are applied to all the coordinates.

I only cover the foreshortening in the following, although one could argue the rotation would be just as important. The foreshortening is simply a matter of proportioning X and Y coordinates of a point with its depth coordinate. (In principle, X=X/Z and Y=Y/Z for each defined point.) Of course the depth coordinate needs to be proportioned to something that gives a working result on screen.


The proportioning is done within lines 210-232 in the listing below. In line 200, the next point coordinate set (X=-50,Y=-50,Z=-50) is grabbed from the data list, and the following lines will mangle the numbers.

210 LET D=(Z+400)/300

First, the "eye" is set back 400 units so that the object coordinates will all be positive. (This adjustment might have been done in the coordinate list, but it's clearer to define the object along it's own coordinate centre.)

The Z coordinate is divided with 300. Here it is a rather arbitrary number. It is meant to give a ratio that shows the object in good size on the TV screen. There's no "right" number as it depends also on the distance and the size of the object, and ultimately what the program is meant to do. Here I'm just interested in getting a sizeable object on screen and 300 seemed to do the trick.

Then the X and Y coordinates (horizontal and vertical) are divided with the proportioned Z coordinate, stored in the D variable. (Line 220) The line 232 moves the coordinates in relation to the middle of the screen. (Remember, Spectrum has 256*192 pixel screen)

Here's the code. Go on, type it on your Spectrum!

By the way, if the eye needs to be moved to the side, a LET X=X+75 (or whatever) after line 200 will do the trick. If this number is too great, the object is drawn out of screen and the program will fail.

There's some added trickery that makes the program use the previously calculated point as a basis for drawing a continuos line through the coordinates. Hence, the DRAW x2-x,y2-y thing at line 40. This helps me avoid making a separate coordinate and point connection list.

The limits of the presented program are obvious. As it is not possible to rotate the coordinates in relation to the eye, the program output is confined to frontal views. Well, one could insert coordinates for a pre-rotated, diagonal cube, but it would be more effective to have the transformation within the program. This would be done after the line 200. 

Some "fun" with the above program.

However, as Spectrum BASIC does not allow lines to cross the screen boundaries, there's only so little that can be done with the above example. Furthermore, if I wanted to extend this program for viewing objects and spaces from the inside, the lines would need to be "clipped" also in relation to the picture depth plane, which is an added complication. Including all required line clipping and transformation routines woud also slow the drawing speed.

Thursday, 23 February 2012

Panasonic JR200 insides

Here are photographs from the board inside the Panasonic JR200UP. At the centre, little to the left, the MN1800 processor can be seen, a clone of Motorola 6802. Another very important chip is the MN1544, a 4-bit co-processor with its own memory, located in the bottom right section.

Click on the images to see the high resolution versions, or open them in a new tab to download the full-size originals. I have photographed these images myself and they can be used freely.

Panasonic JR200 board from above.

The board from below.

Monday, 13 February 2012

Graphics on the Panasonic JR200U


This image was converted from a jpg of a photograph, posterized into 8 colours in the paint program Gimp, converted into a character set and laid out according to the video/attribute memory of Panasonic with a separate program written in Processing. The output binaries were transferred into CJR files using bin2cjr programmed by Markku Reunanen. The CJR files were then converted into WAV files, and loaded into a real Panasonic JR200 with Audacity. The image is taken with a camera and brought back to the mac for some editing before posting it on the blog. So, the image has made quite a journey!

What you see here is a redefined character set on a character display with attributes, not a bitmap. 256 characters of the ordinary character set plus the user-defined 64 characters gives a total of 320 characters. (The shown image uses 275 unique characters) The attributes in the video memory determine whether a character is composed of the normal character set, the user-defined set, or the crude pseudo-bitmap graphics.

Dithering is a possibility when converting images from high color and high resolution, but it can drastically increase the number of unique characters needed. Especially Floyd-Steinberg dithering will result in too much variation, so a flat pattern dithering is recommended. Personally I think dithering easily looks ugly so it is better used sparingly.


Dynamite Dan on the Panasonic?
Apart from the character display, the Panasonic graphics capabilities very much resemble the ZX Spectrum. Here is a mock-up made out of a screenshot grabbed from Dynamite Dan running on a Spectrum emulator and transferred to the Panasonic. Many 8-bit games make use of repetitive background graphics, so the limitation in the character set would not necessarily prevent making games similar to the Spectrum.

Accessing the screen and attribute memory

What follows is rather detailed information about character displays, using the Panasonic as an example. The character displays are blissfully simple to program, and it shows the kind of directness nowadays missing from computer programming. Fiddling around with the character memory is is also a neat visual way into understanding the workings of the old computers.

This will be painfully thorough, and is likely to be uninteresting to an expert!

A classic 8-bit computer has a bunch of memory that appears to the user as a series of address locations, like 65536 bytes. For convenience, the memory represents everything that is in some ways accessible to the user. Portion of this memory would be reserved for the video. Changing the contents of those memory addresses would have a direct effect on screen.

The Panasonic screen layout is at the memory positions ranging from $C100 to $C3FF. As the screen grid has 32 x 24 characters, this makes exactly 768 bytes. The attribute memory is located in positions between $C500-$C755, again 768 bytes. This indicates the colours for each of the 32 x 24 cells on screen.

What is visible on the Panasonic display is dictated by the contents of the screen memory, the attribute memory and the character graphics memory. The attribute memory and the screen memory are in clear correspondence with each other. For each cursor grid location on the screen there is a memory location in screen memory and the attribute memory. The character memory is from where the pixel patterns for the character are derived.

All the memory can of course be accessed from the BASIC. The POKE command is used to change memory contents, so...

POKE $C100,$41

...would result the character 'A' appearing at the top left corner of the screen, as this memory area is reserved for the screen memory. Furthermore,

POKE $C500,$16

...makes that character appear yellow on a red background.

The attribute memory contents dictate what colour the corresponding characters have on the screen. But there's more to it. Now, as each byte can denote a value of 0-255, this would mean the Panasonic can display 256 unique characters on screen. Yet because of the additional features in the attribute memory, it is possible to have more. The attribute cells not only determine the colour of the characters, but they tell how the screen memory contents will be interpreted.

Sadly, this does not mean there are 512 or 768 characters, as the practical number of additional characters is 64, making up the total of 320. This is likely because the video memory would have exceeded 4 kilobytes, something the computer designers apparently wanted to avoid. 

Defining the characters

$D000 begins the memory portion reserved for the appearance of the 256 standard characters themselves. As the characters are made from 8x8 pixel, each takes up eight bytes. 256 characters takes 2048 bytes of memory, or $800 in hex.


A detail of how the bitmap is divided into different characters. Each cell refers to a 8x8 pixel character and has its own attributes, background and foreground colour.
It's not granted that every computer that has character graphics has user-definable character graphics. For instance, Mattel Aquarius only has a fixed character set and no bitmap graphics. Defining the graphics is a matter of changing the memory contents in the reserved area.
So, again in BASIC,

POKE $D000,$FF

changes the first byte in the first character into $FF (255). This has an immediate visible effect on the Panasonic screen, as clear background is made up of this first character. The screen will be filled with horizontal lines. POKEing the location back to zero will rid of the line.

The following POKEs give a nice brick effect:

POKE $D000,$FF
POKE $D001,$4
POKE $D002,$4
POKE $D003,$4
POKE $D004,$FF
POKE $D005,$40
POKE $D006,$40
POKE $D007,$40

This is a bit painful. The classic way of inputting user defined graphics would be something like this:

10 FOR A=0 TO 7
20 READ B
30 POKE $D000+A,B
40 NEXT A
50 DATA $FF,$4,$4,$4,$FF,$40,$40,$40

Saturday, 11 February 2012

Panasonic JR200u tape wave generation


I've previously described the contents of a CJR file and the structuring of the Panasonic JR200U tape format. Here I'll go into converting binaries into WAV audio files that work as JR200 tape input. The purpose is to produce similar audio files as would result when an output from the actual machine is recorded. It's pretty straightforward except for the fact that the tape audio consists of data encoded both in 600 and 2400 baud speeds, and the way of encoding for the two is a bit different.

I'll take a very brutal and practical approach and merely tell how to construct a wave file that can be played back to the Panasonic from an audio software such as Audacity. This is just a crude task of appending bytes into a file in a correct order, and the finer points about signal processing can and will be ignored. First I will describe how bytes are composed in an audio file both in the 600 baud format and the 2400 baud format and how to append them into the WAV as waveform data points. Only after then the overall layout of the wave file with all the necessary "filler" will be given.

The following will work with the assumption that the file consists of a 600 baud header and 2400 baud data blocks. The logic of a full 600 baud file is slightly different, and simply using 600 baud binary with the below description will not work. For completeness sake, this may be addressed in the future, but as the 2400 baud format is the more useful the lower speed is ignored for now.

If you just need a tool for converting CJR files, head to this page.

The header bytes

Looking in detail at a tape audio wave in Audacity, it can be seen the data is encoded in a square wave.



This is the beginning of a header block after a lead in. A block in a normal file always seems to begin with a 2 and 42. (See the previous blog entry for the composition of the CJR files.)

The bytes are of course built out of bits, and these bits are represented in the header wave as a group of longer and shorter waves. The longer wavelength is 1 and the shorter is 0.

So, the above wave will translate into bits like this:

...11111110010000001110010101001110...

The highlighted parts are the same as are highlighted in the image above. The "nybbles" of 1110 are byte markers that precede all actual data bytes. They are not part of the stored data content. The lead-in and all in-between sounds are long series of 1's without the nybbles.

I have previously illustrated the composition of a byte in the header, and here it is again. The format is little-endian binary. This is the composition for the Ascii character 's' (Decimal 115):



The following byte marker actually belongs to the next byte already, which is not visible. Building the header as a wave with this information is then quite simple. For each data byte, the byte marker bits and the data bit waves are appended to the wave file.

But how many audio samples does each bit result in the actual wave file?

I'm assuming a 44100hz sample rate for the WAV, as to simplify the practical task of constructing the file. Note that what follows is not ideal, for reasons given later in the text.

This is the procedure for making the bits:

Do 0: Make the datapoints for a 0-bit:

Write 8 data points of negative signal
Write 1 data point of neutral signal
Write 8 data points of positive signal
Write 1 data point of neutral signal
Write 8 data points of negative signal
Write 1 data point of neutral signal
Write 8 data points of positive signal
Write 1 data point of neutral signal
Write 8 data points of negative signal
Write 1 data point of neutral signal
Write 8 data points of positive signal
Write 1 data point of neutral signal
Write 8 data points of negative signal
Write 1 data point of neutral signal
Write 8 data points of positive signal
Write 1 data point of neutral signal

Do 1: Make the datapoints for a 1-bit:

Write 17 data points of negative signal
Write 1 data point of neutral signal
Write 17 data points of positive signal
Write 1 data point of neutral signal
Write 17 data points of negative signal
Write 1 data point of neutral signal
Write 17 data points of positive signal
Write 1 data point of neutral signal

Both take 72 data points in the wave file. In an 8-bit wave, this would be the actual number of bytes, whereas in a 16-bit wave, the amount will be double. I have myself used 16-bit waves, although 8-bit (or even less) might suffice.

Just to reiterate the obvious, using the above logic the character 's' as in the previous image would be built like this:

Do 1, Do 1, Do 1, Do 0. [The byte marker nybble]
Do 1, Do 1, Do 0, Do 0, Do 1, Do 1, Do 1, Do 0. [The character 's' in ascii]

The 2400 baud format

The 2400 baud format is slightly more difficult to illustrate. When visualized, the bits are not a set of consistently identical peaks and valleys.



The above image is a portion of the wave where the data begins in 2400 baud format. The construction of the short and the long wave does not differ, but the data is 4 times more dense than in 600 baud format.

Although the image highlights the nybbles very clearly, it is not so obvious how the data bytes are composed. The image shows bytes 2 and 42 as before, but they don't look quite the same. So, the difference between 600 and 2400 baud format is not simply a question of changed frequency.

The data is there in the same little-endian way, it is just that the waves representing ones and zeroes can be "upside down". Let's have a visual look at one of the bytes, the 42.



The illustration already makes things much clearer. The first '1' within the byte points "down", whereas the second one points "up". Also, the three one's in the nybble point to alternate directions. But, looking at the two last zeroes, they are identical. So it is the '1' that changes the phase.

Both the above images are misleading in that the nybble byte markers seem identical. They can also be inverted, depending on the previous bit phase, it just happens so the chosen images do not show this.

To cut the explanation, here's the procedure for making the bits in a 2400 baud format:

(The A-signal is initially negative, as the last 1-bit in the 600 baud format part implies.)

Do 0: Make the datapoints for a 0-bit:

Write 8 data points of A-signal
Write 1 data point of neutral signal
Invert the A-signal
Write 8 data points of A-signal
Write 1 data point of neutral signal
Invert the A-signal

Do 1: Make the datapoints for a 1-bit:

Write 17 data points of A-signal
Write 1 data point of neutral signal
Invert the A-signal

So, how each bit "looks like" in the wave depends on what the state of A was after the previous bit was written. So unlike in the 600 baud format, the wave writer needs to keep record of this phase.

A note about the approach

This method as described will not generate precisely same overall wave file lengths as recorded from the Panasonic. Some adjustment may be required to achieve this. In reality, the wavelength is not "72 bytes" long, but a frequency. The described approach is in a way inferior to one where a real frequency is used. This method does work, though, so it will suffice here. Also, this procedural approach is simpler to explain.

In my wave generator, I added a global time skip variable that can be used to adjust the overall synchronization of the wave. The time skip can be adjusted so that the overall audio file lengths would better correspond with those of the actual machine. This means that data points are counted as they are written into the WAV, and each hundredth (say) will not be written. Or if the audio file needs to be lengthened, every hundredth data point will be written twice, or something like that.

The overall wave generation

The more tricky stuff has been gone through and what is left is to give the recipe for generating the whole audio file. For the content of the Blocks, refer to the previous blog post.

600 baud header:

 Generate some silence
 Lead in: More than 800 bits of 1
 Header Block: 33 bytes in the 600 baud format above
 In-Betweener: 51 bits of 1

2400 baud data blocks and footer/tail:

 Data Block 1
 In-betweener: 196 bits of 1
 Data Block 2
 In-betweener: 196 bits of 1
 Data Block 3
 In-betweener: 196 bits of 1
 ...
 ...
 Last Data Block
 A "long 1", See *1
 In-Betweener: 188 bits of 1
 Footer Block (tail)
 Byte 255, See *2
 Lead out: some 150 bits of 1
 Generate some silence (5 seconds between tape parts for example)

*1: The Long 1 is an anomalous piece of waveform that seems to be added at this point. It can be treated as a 1 that has twice as long waveform. I'm not sure if Panasonic really requires this, but it's better to be precise.
*2: The byte 255 is not included in a CJR file.



The above image shows the anomalous waveform near the end of a file, before the footer. Looking the image closer will also reveal the number of samples used for the waves. (36 as opposed to the 17 in the following wave.)

The WAV format

Describing the actual wave file format is really outside the scope of this post, but I'll include the bare description for writing 16-bit, one channel, 44100hz sound files. So, again, the following is just for the purposes of generating the things discussed above, and it is not intended to be a full WAV specification. The alphabetic values are in Ascii.

An easy formula for the entire file size [offset 4-7] is 44+seconds*88200.

0    : R
1    : I
2    : F
3    : F
4-7  : 32 bit value for the entire file size
8    : W
9    : A
10   : V
11   : E
12   : f
13   : m
14   : t
15   : 32 [space]
16   : 16 [16-bit pcm]
17   : 0
18   : 0
19   : 0
20   : 1 [audioformat=1]
21   : 0
22   : 1 [numchannels=mono]
23   : 0
24-27: 44100 [32-bit value for sample rate]
28-31: 88200 [32-bit value for byte rate]
32   : 2 [block alignment]
33   : 0
34   : 16 [bits per sample]
35   : 0
36   : d
37   : a
38   : t
39   : a
40-43: [32 bit value for the wave chunk size]
44-  : [16 bit words for the single channel wave data.]




Monday, 30 January 2012

Panasonic JR200U tape file format


I have started to collect information about the tape format associated with Panasonic JR200, and the CJR format used in Panasonic emulators.

I will here produce what I have figured out so far, so this is not a comprehensive deciphering of CJR files. The information below is compiled mostly with a view to creating files that could be readable with emulators or with the machine itself. I have had some success in generating audio wave files from CJR, which will be a later topic.

Only a typical file will be discussed here, such as that could be outputted in JR-BASIC with the SAVE command.

The CJR format appears to be a comprehensive representation of the data in a file saved on a tape. Consider an audio recording of a file saved on a real Panasonic. Examining the audio file reveals that it has bytes encoded into a waveform. The CJR file contains all these bytes. Note that it does not represent the waveform. Also, it is not a full tape format, as each separate file has its own CJR file. (Such as the BASIC loader, loading screens and game data.)

The data in a CJR file is organized into blocks. In principle, the blocks have a similar structure, but they also differ. Each block begins by values 2 and 42, and except the final block, they are ended with a checksum. The checksum is particular to each block, an 8-bit value that is reached by adding all previous values together, including the 2 and 42. (Being 8-bit, the value will of course "roll over" after 255.)

I have chosen to call the first block the Identifier, the subsequent parts as Data blocks, followed by a Tail.

The Identifier:
  1. 2
  2. 42
  3. 0 (Block number. The ID block is #0)
  4. 26 (Length of data, fixed in a normal ID)
  5. 255
  6. 255
  7. Ascii (Filename, 16 characters)
  8. Ascii
  9. Ascii
  10. Ascii
  11. Ascii
  12. Ascii
  13. Ascii
  14. Ascii
  15. Ascii
  16. Ascii
  17. Ascii
  18. Ascii
  19. Ascii
  20. Ascii
  21. Ascii
  22. Ascii
  23. 0 (0=BASIC 1=BINARY)
  24. Baud Rate (0=2400 1=600)
  25. 255
  26. 255
  27. 255
  28. 255
  29. 255
  30. 255
  31. 255
  32. 255
  33. Checksum (8-bit number, all previous values added)
A Data Block (one or more):
  1. 2
  2. 42
  3. Block # (Block number, starting from #1)
  4. Length (Length of data. 0 means full 256 bytes)
  5. HI (Word: Block start address.)
  6. LO
  7. Binary data (Up to 256 bytes of binary data)
  8. ...
  9. ...
  10. ...
LAST. Checksum. All values in this block added together.
The Tail (After all data blocks):
  1. 2
  2. 42
  3. 255
  4. 255
  5. HI (Word: End address)
  6. LO
About the ID

The File identifier is quite straightforward. The 16 character filename, the two following values and the eight 255's make up the 26 bytes indicated by the length.

Data Block handling

Very short files, such as BASIC loaders for games can sometimes be less than 256 bytes, so they only have the Identifier, one Data Block and a Tail.

Files that exceed 256 bytes in length have multiple Data Blocks. In this case the Block length is denoted by a 0 (Really 256), meaning that there will be further blocks. The last block will then have a different length. Suppose you have saved a file that is 320 bytes long. The first Block length will be 0, whereas the second (and final) Data Block will be 64 bytes long.

The Block number will be incremented for each block. The Identifier is the block number 0, so the first actual Data Block has a value of 1.

The start address in each Data Block shows where the data "belongs". For example, a BASIC file has a start address of $0801. The start address in each data block is normally incremented by $100 (256), so a normal BASIC file would have $0901 as the next Block start address and so on.

Each Data Block has its own checksum, which is reset for each block. The Tail, as can be seen, does not have a checksum.

It is also possible to load files into a different start address on the Panasonic. A character set could be loaded directly over the normal character set or the user defined graphics memory area.

Wrapping it up

The end address in the Tail is the memory address after the file. So if 255 bytes are loaded to a start address of $D000, the end address in the Tail is $D100.

Edit

As has been commented, apparently the 24th byte in the header/identifier block indicates the baud rate of the subsequent data blocks. I suspected it to have some meaning! This and other information on the tape format is available on a Japanese language web page. The byte is not $64 or 64 though, but simply 0 or 1 for 2400 and 600 bauds respectively.



Sunday, 3 July 2011

Panasonic JR-200UP

The Panasonic JR200
Here's another machine that is nearly 30 years old. It is somewhat obscure, but apparently a few were imported to Finland around 1984. I'll go through some of my initial experiences with this computer, which has been previously unknown to me.

BASIC operation

The Panasonic has a very solid appearance. The casing is bigger than a ZX spectrum, yet considerably smaller than a VIC-20 or a C64. A seventies space typeface declares “Panasonic personal computer 32k memory”. A dry run on the keyboard did not impress, yet it works pretty well in action. The keyboard is not nearly as bad as Laser 200, a bit better than a ZX rubber. With full screen editing and well positioned cursor keys, it's okay for BASIC programming. A feature I like is the inclusion of the BASIC keywords on the keyboard as a kind of reference. It's possible to invoke the keywords with a combination of CTRL+key. Far from saying that this keyboard is comparable to modern keyboards, but it's not a torture.

For the hobbyist (both then and now), the computer is quite a nice treat. Everything works pretty smoothly and the editing is user friendly compared to some other computers at the time. The JR-BASIC is not far from Microsoft BASIC, and for those with previous programming experience it is easy to adapt to. The video and character memory is simply laid out and easy to use even from within BASIC.

Some neat touches make the life of a hobbyist easier. The BASIC interpreter accepts hexadecimal, and there's a built-in function for returning decimal in hex. The character set can be adjusted by directly POKEing into the character set memory space, starting from $D000. Contrast this to the C64, where the same action would have required multiple preparatory pokes plus duplicating the character set from ROM. For learning machine code the 6802-based processor is simple and straightforward.

An interesting feature is a built-in monitor, which can be invoked with the MON command. With the monitor it is possible to change memory contents by entering hex, or examine how the present BASIC program is tokenised, starting from address $0800. Sadly the monitor is somewhat lacking in features, as it does not do disassembly or cannot display the memory contents as characters. However, the 6802 has a clear instruction set and 16-bit addresses are stored in a readable high-low format, both factors which make a hex dump like this a bit more readable. What is a bit unclear that the commands, D, M and G have to be typed in capital letters, which can be a bit annoying as this is not required in BASIC and the hex input itself does not care about the case.

The BASIC line entry is a slightly more picky than some others. It really insists on putting a space before and after the commands. There are no shorthands to the commands, so typing ?1+1 does NOT work. Having to type PRINT each time means the Panasonic works less well as a calculator.

There are supposedly two ways to break into the program, using CTRL-C for exiting normal basic, and a single hard BREAK key which should be able to exit even a stuck machine code loop. In many situations, however, the machine had to be switched off and on. This was quite common practice back in the time, but nowadays it does not feel right to do this. The hard break had to be used when exiting program loops with the PICK keyboard input command. Use of the PICK command makes the loop impervious to the soft break.

The manual is quite sparse. Although it has some useful information on the BASIC instruction set and how to define characters and things like that, it does not have any real examples. The reader is assumed to have a good knowledge about how computers generally work. There's no sample machine code program or a list of 6802 instructions, but these can be found from the Internet.

Graphics

The first impression about the graphics capabilities bring into mind the Sinclair ZX Spectrum, but the presence of the character display points more towards other computers. The palette of Black, Blue, Red, Magenta, Green, Cyan, Yellow and White are very reminiscent of the ZX, and it's nice to see them here. As the Panasonic lacks the variable brightness of the Spectrum, there are only 8 colours available. There are no sprites or hardware scrolling, which is a bit sad, as the CPU is slow for throwing graphics around. The character display and user defined characters alleviates this somewhat, as character displays are very quick for rough graphics. The amount of definable characters is 256+64, enough to give a theoretical resolution of 256x192, comparable to the Spectrum. I can't see why games like Manic Miner could not be reproduced faithfully with some clever on-the-go modification of the character set.

The PLOT command can be used to create graphics with the resolution of 64x48. At first it appears that the computer merely sorts logically some of the characters included in the character set and prints them out as some kind of pseudo-graphics. But it's actually a bit more clever than that. The low resolution graphics is not made out of the character set at all, as it is possible to have four different colours on the same cursor area. Furthermore, there is no need to switch to a different display "mode", as each character on the display in a way has its own mode. Each screen character can be either a standard character, a user defined character, or a low resolution graphics cell. So the low resolution graphics and the normal graphics can coexist on the same display. However, the low resolution graphics has fairly limited uses.

Curiously, even though the BASIC has commands pretty much for any sensible operation, changing the border colour has to be done with POKE $CA00,n. Of course, learning this makes it easy to implement in machine code.

Loading tape files

The Panasonic uses a 8-pin DIN socket for tape input/output. This connection was quite common in machines like the MSX and apparently TRS-80. The pin assignment seems to be quite similar to an MSX, but I have not absolutely checked. As the computer did not come supplied with the standard tape lead, I had to improvise one. Here is how I did it:

The tape connector as seen behind the computer. The cable is not to scale.
GND=Ground, IN=Signal in for loading, OUT=Signal out for recording

I connected the ground to the bases of two microphone style jacks, and connected the signal pins to the jack tips. I connected both to the same ground and it seems to work. I connected the microphone jacks to my Mac Mini audio input and output, and used Audacity as a substitute for a tape recorder.

From the JR BASIC, LOAD is used for loading Basic files, whereas MLOAD is for binaries. A=USR($1000) would then execute the code starting from $1000. Also, the G1000 command within the monitor can also be used.

The Panasonic allows a choice between 600 baud and 2400 baud rates for storage. This can be changed from a switch below the computer. Apparently the 600 baud can be chosen for reliability whereas the 2400 should only be used with Panasonic's dedicated tape recorder. With this setup, the 2400 baud rate has worked fine. Just to be sure I use 44100khz sample rate with 16 bit accuracy. I have not made tests but I believe 8 bits would work just as fine, not so sure about compromising the sample rate though.

Looking at the saved files I started building an understanding on how the data is actually stored into the tape, with the hope of creating audio files from binaries on the Mac. The normal saved recordings are constructed from two parts, the header and the actual data. The header is pretty straightforward but the data part was a bit trickier. Both the header and the data have a checksum, which is built from adding up all the values into an 8-bit counter. Files larger than 255 bytes are divided into page-sized chunks each with their own checksum.

The above diagram depicts how header data is stored in the waveform. The data part uses a bit different format, depending on the chosen baud rate.

In the end I could generate the wave files and load them into the Panasonic. Mostly this was made by imitating the structure of the previously recorded output from the machine. I also spent time trying to find existing software for the Panasonic, and in the end found some .CJR files related to a virtual Panasonic emulator. (by “James the Animal Tamer” in 2002) I did not bother to fire up my PC to find out if the emulator works, as I'm only interested in using the actual machine. There may or may not exist a program called the CJR2WAV or something similar, which would apparently perform the function I was seeking. I did not search comprehensively but it seems to be currently unavailable. Besides, it was more interesting learning experience to try to make my own.

The software

The CJR files were a welcome find. Adjusting my wave generator program I could convert some of the CJR-based programs into wave files that actually could be loaded into the machine. So I was enjoying games like Solitaire, Vortex, Crazy Mazey and so on. There are several games (Junkman Joe, Galactic Chase, Mischievous Mansion) that have a different format and so far I have had no success loading them. Most of the ones I could load were written almost entirely in BASIC, possibly converted from some another computer. I’ll quickly go through some of the more interesting ones.

I loaded the Solitaire first and it is very addictive. The cards can be manipulated with simple keystrokes which is a refreshing change from mouse-based card games. The graphics are likewise very minimal and pleasantly laid out. The program offers four solitaire varieties. Sound is very sparse, with the occasional beep for an invalid move.

Mars Cars is a kind of a loose Pac Man variant, except the enemies do not behave in very intelligent fashion nor is there really a maze to speak of. Some sort of space car is moved in four directions and the player has to catch four treasures guarded by critters. After collecting the treasures the player proceeds to the next screen via the exit. The car can “eat” the obstacles on screen, which forms part of the game strategy. The critters have to be let out of their containment area before the treasure can be safely picked up. If the aliens moved in a less random way the concept could be quite interesting.

Vortex on the first sight appeared to be a fun arcade game. The player has to fire missiles to four directions to counter torpedoes that appear from different sides of the screen. Occasionally a “saucer” appears. Yet the game is devoid of any content or development throughout the game, it merely gets faster all the time until it becomes impossibly fast. There is never more than a single torpedo on screen.

Crazy Mazey is another maze game. This time the player guides a car in a city-like maze, collecting dollar signs and avoiding the pursuing cars. This game utilizes per-pixel moving graphics, not seen in the other games. On the faster level, the game runs pretty smoothly. The enemy cars pursue the player in a very determined and annoying manner!

Santa Paravia is one of those management/diplomacy games which where featured as magazine and book type-in listings in early 80s. You know, the player manages a mine, a city, a nation or a space variant of any of them. The player makes choices of resource allocation and at some point the player is killed randomly because there is a mutiny or plague or whatever. Santa Paravia has an occasional graphical screen that adds some charm to the otherwise text-based proceedings.

Judging from this small sample of games, the Panasonic does not really have that impressive catalogue. The arcade games are a bit lazily done and could have been more interesting with only very little additions. Then again at around 1983 there were really not that many good home computer games on any platform, even though the hardware was already up to it. So perhaps the games are kind of par for the course for this particular vintage. Reputedly the Disney games have more effort put into them, but there’s very little information about them available on the net.

Conclusion

The Panasonic JR-200 is an impressively simple and straightforward computer. In some ways it reminds me of the MSX, but without the video chip hassle. The 6802-based chip has a simple instruction set and although the monitor is not really a full monitor, it does give quick access to beginner level machine code.

Nowadays it has become a truism to say that a hardware is just as good as its' software catalogue. But these were different times. I don't feel right to blame the machine for not having a huge amount of great games, as home home computers at that time had other purposes too. In the 70s, home computers were the domain of hardware hackers and DIY electronics enthusiasts. As the audiences became wider in the beginning of the 80s, a home computer might still have been bought for hobbyist purposes, such as learning to program BASIC and then moving onto machine code. There may not have been so much thought put to whether the computer was able to do something "useful". Messing around and learning was (and is) fun in itself. I cannot imagine a much better introductory machine for this purpose than the JR200. Whereas many computers of that time have become very off-putting by the way of user experience, this computer is still quite neat for typing in programs and seeing how they work. It combines a good quality hardware with simple and usable BASIC and gives full 32K space to play with.

Panasonic JR-200 at Old-computers.com


My work on the tape generation.