Jump to content
IGNORED

Intellivision Keyboard Component pics


y-bot

Recommended Posts

Software emulation of the tape drive is at least partially supported. It can load BASIC programs. That feature has not been put into MAME yet. The above work is helpfull if someone wanted to build a modern hardware replacement using flash memory.

Link to comment
Share on other sites

This is cool! Does this mean that emulation is becoming easier or a possibility soon?

 

As you will see, our focus at the moment is primarily in getting RonTheCat's KC as operational as possible. A side benefit of this is that we can write up our experiences in the hope that it is helpful to others when doing the same, or inspires people to give it a go. Longer term, this may lead to other things, such as trying to demonstrate KC software or help with emulators. However, this is not guaranteed and others, most noteably FrankP, are way further along in those endeavours than we are.

 

I thought there was already emulation available. It just is useless without the data from the tapes or carts... I could be wrong, though, but I believe Joe Z. once said he had KC emulation ready.

 

I don't believe there is a version of JzIntv that supports the KC at the moment.

 

Software emulation of the tape drive is at least partially supported. It can load BASIC programs. That feature has not been put into MAME yet. The above work is helpfull if someone wanted to build a modern hardware replacement using flash memory.

 

MAME does partially suport the KC. The BASIC cartridge (a ROM image of which can be found on the interwebnets) will run and it is possible to write and run programs. However, I'm not sure that the tape drive is emulated in the public versions. Frank has been working tape support and archiving the released software on and off for some time, I believe it is difficult and very time consuming.

 

There also seem to be some errors in MAME's emulation. For example, the CPU clock seems to be incorrect and it looks as though the hardware scrolling of the video chip does not match with actual behaviour. Personally, whilst it can be useful for reference purposes, I find MAME's source code to be filled with strange and powerful magic; too powerful for the time I can put into mastering it. :dunce:

 

OK, moving on, since our last video RonTheCat has acquired a couple of blank KC BASIC data storage cassettes which has allowed us to start investigating them and their behaviour.

 

The obvious first question is, do they work? Unfortunately, the answer to that is no at the moment. Currently, Ron's KC is unable to either save or load from the tapes, this is something we are working on. We don't understand the behaviours we see yet, so we want to get a handle on them before trying to describe them.

 

Given the tapes don't work, what can we say? Well, as we suspected the leaders are clear, but perhaps not as obviously clearer as you might expect. Here is a comparison of the pukka BASIC tape (white shell) with the audio tape from our last video (black shell) that the KC could not detect:

 

post-46336-0-92921600-1533911173.jpg

 

In the flesh, the leader of the Mattel tape is slightly more transparent and has a milky tinge to it, but there is not much in it. We suspect they are just made of different polymers. If we have time during the next lab visit, we will run some tests with an IR remote to see if we can demonstrate the difference in IR transparency.

 

The BASIC tapes are 30 minutes long and, whilst they may have four tracks, it is possible to play them using a standard audio recorder. Here are the first two minutes for your listening pleasure:

 

 

You know what comes next :)

 

Can we understand what is on the tape? and if so, is it anything interesting? To which the answers are yes, and not really.

 

Although the two tapes Ron has were not sealed, they don't appear to have been used. The data we can hear seems to be the formatting pre-coded by Mattel "for fast, automatic storage & retrieval!"

 

The tape format used is well documented on page 33 & 34 of this document from Papa Intellivision and with some additional details from JoeZ and FrankP (hat tip as always gentlemen :thumbsup:) we can put together a pretty good description. Here are the very gory details...

 

Each 30 minute data tape contains 100 "records" of data. Each record is approximately 17 seconds long with a 1 second gap in between. According to Frank the data on the tape is encoded using Differential Manchester Encoding with a fundamental frequency of 1.5KHz. This means that in a rough and ready sense each long half cycle at 1.5KHz is binary 0, each short full cycle at 3KHz is binary 1 as we can see here:

 

post-46336-0-70981700-1533911174.png

 

Notice how each bit's slice of time is the same duration and whether it represents binary 1 or 0 depends upon whether there is a zero crossing in the middle of the period.

 

As Frank has observed, the digital data has a DC bias to it, our initial measurements of the tape drive suggest this might be approximately 0.2V, but given we haven't managed to get anything useful out of the KC tape drive, this is unconfirmed. This bias would not normally be visible in the recording because audio recorders like the one Ron used have AC coupling of the signals. However, its impact can briefly be seen at the start of each record, where the centre of the tone initially has a negative offset or bias. The AC coupling capacitor then recovers from the transient and the centre of the signal returns to 0V, as shown by the green line:

 

post-46336-0-45978600-1533911175.png

 

Looking at the tape amplifier circuit we documented above, it is not clear that the digtial bias is required when reading from the tape as all the amplifiers used during playback from tape look to be AC coupled by the capacitors C10, C990, C997 and C999. If correct, this might make usable, if slightly less authentic, tapes somewhat easier to create.

 

Armed with this information and the description from Papa Intellivision it is possible to write some scripts to decode the data from Ron's recording.

 

The first record (record #0) does not contain any data, as Mattel were concerned the tape in this region would be subject to excessive wear. It just contains a 1.4KHz?! tone. All the other records contain the structure described in the document, as follows...

 

Each record starts with 600 bits of binary 0, used to synchronise the electronics (the Phase-Locked-Loop) of the tape drive.

 

This tone is immediately followed by a header pattern $0000007e, $000000bd, $000000db, $000000e7, which is checked by the tape drive. Joe pointed out that if you write this sequence out slightly differently in binary it creates an arrow of 0s pointing down, pretty cool:

 

$000000 %01111110
$000000 %10111101
$000000 %11011011
$000000 %11100111

From here the record is broken into a sequence of "chunks".

 

Each chunk is further partitioned into what I will call "lines" (Mattel does not provide a name for this structure). Each chunk is made up of 15 lines. Every line starts with 5 sync bits %11101, followed by the data for one bit of 32 decles. These are arranged a little bizarrely because the bit 9s for all 32 decles come first, in one line. These are followed by all the bit 8s in the next line, etc, finishing up with the bit 0s in the last line. Now I've deliberately missed out a little step here. Before the lines containing the actual bits of the stored data there are 5 additional lines, each containing one bit of a 5 bit error correction code. These can be used to fix errors in the data in the event of noise on the tape.

 

So reading across, then down, a chunk might look like this in binary:

 

Chunk: 1                     decle# 00000000001111111111222222222233
                                    01234567890123456789012345678901

Line  1 (Bit 14s) sync: 11101 data: 00000001100010001100010000000001
Line  2 (Bit 13s) sync: 11101 data: 10000001110010001110010000000001
Line  3 (Bit 12s) sync: 11101 data: 10000000010000000010100000000001
Line  4 (Bit 11s) sync: 11101 data: 00000000000000000000100000000000
Line  5 (Bit 10s) sync: 11101 data: 10000000010000000010000000000000
Line  6 (Bit  9s) sync: 11101 data: 00000000000000000000000000000000
Line  7 (Bit  8s) sync: 11101 data: 00000000000000000000000000000000
Line  8 (Bit  7s) sync: 11101 data: 00000000000000000000000000000000
Line  9 (Bit  6s) sync: 11101 data: 00100000000000000000000000000001
Line 10 (Bit  5s) sync: 11101 data: 00000000000000000000000000000001
Line 11 (Bit  4s) sync: 11101 data: 00100000000000000000000000000001
Line 12 (Bit  3s) sync: 11101 data: 00100000000000000000100000000001
Line 13 (Bit  2s) sync: 11101 data: 00000001100010001100010000000001
Line 14 (Bit  1s) sync: 11101 data: 00100000000000000000000000000000
Line 15 (Bit  0s) sync: 11101 data: 10000001110010001110110000000000

 

You read the data for a decle by looking down a column with lines 6-15 (bits 9-0) being the actual data making up a decle and lines 1-5 (bits 14-10) being the error correction code for the decle.

 

This transposition of the data on the tape was another noise protection mechanism. If there was a drop out or other problem of less than 10msec in length it would only corrupt one bit of each of the 32 decles and the data could be recovered. If the bits associated with a single decle were stored consecutively on the tape such a dropout would nuke the data in a single decle beyond the repair of error correction.

 

You will notice that the data in the example above is not blank. This pattern is taken from the recording and seems to be normal. The first decle contains the chunk number (so the example above is chunk #1 - remember the data is in bits 0-9, bits 10-14 are error correction and can be ignored when trying to understand the data). Chunk numbers within a particular record start at the record number and increment with each chunk. So the chunks in record #7 would start with a chunk number of 7 in the first chunk and go up from there.

 

The data in the next 30 decles seems to be constant for a blank storage cassette. We don't know what, if anything, it signifies. It does not seem to relate to Microsoft BASIC language tokens or create any nice visual patterns like the record header, but all the chunks on both of Ron's tapes contain the same data:

 

$00, $5A, $00, $00, $00, $00, $05, $05
$01, $00, $00, $05, $00, $00, $00, $05
$05, $01, $00, $09, $05, $00, $00, $00
$00, $00, $00, $00, $00, $00

This is why we believe that his tapes are unused, and why we are confident that our attempts to save anything have failed thus far (well that, and the fact we found one of the wires to the erase head had come detached during our last lab session :ponder:)

 

The final decle in each chunk also appears to be some kind of check. In record #1, chunk #1 this has the value of 124, it is unclear why. In each subsequent chunk this value is increased by 255 and it wraps at 1024. So chunk #5 of record #1 has a value of 120 ((124 + 4 * 255) mod 1024). The check value of chunk #1 of subsequent records, say record #n, is the same value as chunk #n in record #1. So record #2, chunk #1 will have a value of 379 (379 = 124 + 255, the same as the value in record #1, chunk #2) and record #5, chunk #1 will have a value of 120, like record #1, chunk #5 (get it? :ponder:). From these initial starting values the numbers in this final decle again increment by 255.

 

There would seem to be 90 chunks in each record, just butted up against each other. Assuming the first and last decle are not used, this means that each record holds 2700 decles of data and gives a total tape capacity of 267K decles, stored at about 150 decles/sec. Therefore, an 8K game would take about 60 seconds to load into memory, after it had been located on the tape.

 

Overall a record looks a bit like this:

 

 

 

Sync: 600 bits of 0
Header: 7e 00 00 00 bd 00 00 00 db 00 00 00 e7
Chunk: 1
Bit 14 sync: 11101 data: 00000001100010001100010000000001
Bit 13 sync: 11101 data: 10000001110010001110010000000001
Bit 12 sync: 11101 data: 10000000010000000010100000000001
Bit 11 sync: 11101 data: 00000000000000000000100000000000
Bit 10 sync: 11101 data: 10000000010000000010000000000000
Bit  9 sync: 11101 data: 00000000000000000000000000000000
Bit  8 sync: 11101 data: 00000000000000000000000000000000
Bit  7 sync: 11101 data: 00000000000000000000000000000000
Bit  6 sync: 11101 data: 00100000000000000000000000000001
Bit  5 sync: 11101 data: 00000000000000000000000000000001
Bit  4 sync: 11101 data: 00100000000000000000000000000001
Bit  3 sync: 11101 data: 00100000000000000000100000000001
Bit  2 sync: 11101 data: 00000001100010001100010000000001
Bit  1 sync: 11101 data: 00100000000000000000000000000000
Bit  0 sync: 11101 data: 10000001110010001110110000000000
Chunk: 2
Bit 14 sync: 11101 data: 10000001100010001100010000000000
Bit 13 sync: 11101 data: 10000001110010001110010000000000
Bit 12 sync: 11101 data: 00000000010000000010100000000000
Bit 11 sync: 11101 data: 10000000000000000000100000000001
Bit 10 sync: 11101 data: 00000000010000000010000000000000
Bit  9 sync: 11101 data: 00000000000000000000000000000000
Bit  8 sync: 11101 data: 00000000000000000000000000000001
Bit  7 sync: 11101 data: 00000000000000000000000000000000
Bit  6 sync: 11101 data: 00100000000000000000000000000001
Bit  5 sync: 11101 data: 00000000000000000000000000000001
Bit  4 sync: 11101 data: 00100000000000000000000000000001
Bit  3 sync: 11101 data: 00100000000000000000100000000001
Bit  2 sync: 11101 data: 00000001100010001100010000000000
Bit  1 sync: 11101 data: 10100000000000000000000000000001
Bit  0 sync: 11101 data: 00000001110010001110110000000001
Chunk: 3
Bit 14 sync: 11101 data: 10000001100010001100010000000000
Bit 13 sync: 11101 data: 00000001110010001110010000000001
Bit 12 sync: 11101 data: 10000000010000000010100000000000
Bit 11 sync: 11101 data: 10000000000000000000100000000001
Bit 10 sync: 11101 data: 10000000010000000010000000000000
Bit  9 sync: 11101 data: 00000000000000000000000000000001
Bit  8 sync: 11101 data: 00000000000000000000000000000000
Bit  7 sync: 11101 data: 00000000000000000000000000000000
Bit  6 sync: 11101 data: 00100000000000000000000000000001
Bit  5 sync: 11101 data: 00000000000000000000000000000001
Bit  4 sync: 11101 data: 00100000000000000000000000000001
Bit  3 sync: 11101 data: 00100000000000000000100000000001
Bit  2 sync: 11101 data: 00000001100010001100010000000000
Bit  1 sync: 11101 data: 10100000000000000000000000000001
Bit  0 sync: 11101 data: 10000001110010001110110000000000

...one, two, miss a few...

Chunk: 89
Bit 14 sync: 11101 data: 10000001100010001100010000000000
Bit 13 sync: 11101 data: 00000001110010001110010000000000
Bit 12 sync: 11101 data: 10000000010000000010100000000001
Bit 11 sync: 11101 data: 10000000000000000000100000000001
Bit 10 sync: 11101 data: 10000000010000000010000000000000
Bit  9 sync: 11101 data: 00000000000000000000000000000000
Bit  8 sync: 11101 data: 00000000000000000000000000000000
Bit  7 sync: 11101 data: 00000000000000000000000000000000
Bit  6 sync: 11101 data: 10100000000000000000000000000000
Bit  5 sync: 11101 data: 00000000000000000000000000000001
Bit  4 sync: 11101 data: 10100000000000000000000000000000
Bit  3 sync: 11101 data: 10100000000000000000100000000000
Bit  2 sync: 11101 data: 00000001100010001100010000000001
Bit  1 sync: 11101 data: 00100000000000000000000000000000
Bit  0 sync: 11101 data: 10000001110010001110110000000000
Chunk: 90
Bit 14 sync: 11101 data: 00000001100010001100010000000001
Bit 13 sync: 11101 data: 00000001110010001110010000000001
Bit 12 sync: 11101 data: 00000000010000000010100000000000
Bit 11 sync: 11101 data: 00000000000000000000100000000000
Bit 10 sync: 11101 data: 00000000010000000010000000000000
Bit  9 sync: 11101 data: 00000000000000000000000000000000
Bit  8 sync: 11101 data: 00000000000000000000000000000001
Bit  7 sync: 11101 data: 00000000000000000000000000000000
Bit  6 sync: 11101 data: 10100000000000000000000000000000
Bit  5 sync: 11101 data: 00000000000000000000000000000001
Bit  4 sync: 11101 data: 10100000000000000000000000000000
Bit  3 sync: 11101 data: 10100000000000000000100000000000
Bit  2 sync: 11101 data: 00000001100010001100010000000000
Bit  1 sync: 11101 data: 10100000000000000000000000000001
Bit  0 sync: 11101 data: 00000001110010001110110000000001

 

 

 

And there you go, that is what we know at the moment. With this lot, and some tape stock with suitably IR clear leaders, it should theoretically be possible to construct blank KC BASIC tapes using a doctored four track recorder (or possibly even just a standard stereo recorder - the KC might read the BASIC digital track even if its data is unbiased and spills onto one of the other tracks as well). So there is the challenge, go for your life! :party:

 

 

Cheers

 

decle

Edited by decle
  • Like 2
Link to comment
Share on other sites

That is a lot of great information, thanks for sharing!

 

I'm curious as to which tracks have data and which do not on a blank tape. A programmed tape (ex: Conversational French) has 2 digital tracks (one is read-only) and 2 analog tracks (one is read-only). I would expect the analog tracks to blank but wonder whether both digital tracks have data or only one of them.

  • Like 1
Link to comment
Share on other sites

In reviewing the data presented and taking the formula you presented, I can tentatively say the following. The caveat is that these statements could be wrong but happened to get lucky with the small amount of data above. Could you add a TXT file that contains the entirety of record 1, 90, and the last record? Anyways...

  • Each column of bits has even-parity (i.e. there is always an even number of bits that are 1)
  • Decle number 31 is a checksum for other decles in the chunk. The 32 decles are regarded as valid when the following formula is satisfied: 255 * (sum of the 32 decles ) == 0xFF [modulo 255].

My suspicion is that one of the lines 1-5 is the even-parity bit. My weaker suspicion is that the remaining 4 lines are using a Hamming Code (https://en.wikipedia.org/wiki/Hamming_code) but does not appear to be a straight-forward match. If it is using a Hamming Code, then the 4 ECC bits means 11 data bits can be protected, which means that Mattel simply dropped one of the data bits to slightly compact the data.

 

Edit: adjusted the formula to accommodate corrections.

  • Like 2
Link to comment
Share on other sites

I'm curious as to which tracks have data and which do not on a blank tape. A programmed tape (ex: Conversational French) has 2 digital tracks (one is read-only) and 2 analog tracks (one is read-only). I would expect the analog tracks to blank but wonder whether both digital tracks have data or only one of them.

 

This is an excellent question, my apologies for not including the information. If we record side "A" of the tape, we see that, with the exception of the tone in record #0, the the data track is predominantly in the right channel:

 

post-46336-0-15976900-1533991071.jpg

 

There is nothing on side "B" of the tape. Unfortunately I don't think this is consistent with Frank's slide at 39mins in:

 

 

So I'm not too sure what is going on there. I think the data track must be on side "A". If it was on side "B", I believe our recording would come out backwards when we recorded using a standard tape machine (everything is on side A as far as the KC is concerned - if you see what I mean).

 

In reviewing the data presented and taking the formula you presented, I can tentatively say the following. The caveat is that these statements could be wrong but happened to get lucky with the small amount of data above. Could you add a TXT file that contains the entirety of record 1, 90, and the last record?

 

Sure. It should be noted that the transcriptions by my scripts are not perfect. Here is record #1:

 

record001.txt

 

Hang on a minute. From record #12 there are steadily more and more chunks at the end with no data in them at all. Not even chunck numbers:

 

record012.txt

record013.txt

 

Weird. I did not notice this as I was mainly focussed on the start of the records. Ahh, the biggest chunk number with data looks to be 100! Surely no coincidence. So by record #50 only the first 51 chunks have data in them:

 

record050.txt

 

Looking at the recording this does seem to be correct although I've only counted the empy lines in records 12 and 13 :). Obviously this significantly curtails the "interesting" data on the tape.

 

Anyways...

  • Each column of bits has even-parity (i.e. there is always an even number of bits that are 1)
  • Decle number 31 is a checksum for other decles in the chunk. The 32 decles are regarded as valid when the following formula is satisfied: 255 * (sum of the 32 decles ) == 0xFF [modulo 255].
My suspicion is that one of the lines 1-5 is the even-parity bit. My weaker suspicion is that the remaining 4 lines are using a Hamming Code (https://en.wikipedia.org/wiki/Hamming_code) but does not appear to be a straight-forward match. If it is using a Hamming Code, then the 4 ECC bits means 11 data bits can be protected, which means that Mattel simply dropped one of the data bits to slightly compact the data.

 

Edit: adjusted the formula to accommodate corrections.

 

 

This is a great piece of detective work. Yes, I believe that the codes are Hamming based as mentioned by Joe. I've not been able to find the code he refers to on Papa Intellivision, perhaps he is recalling something from his personal stash :).

 

Working with the data available I think we can piece together most of the ECC scheme. As you say it looks to be even-parity. I believe this is found to work when trying to generate the ECC codes seen:

  • Line 1 - bits 1, 2, 4, 5, 8, 9
  • Line 2 - bits 0, 1, 3, 8, 9
  • Line 3 - bits 0, 2, 4, 6, 8
  • Line 4 - bits 1, 3, 4, 5, 6
  • Line 5 - bits 0, 2, 3, 5, 6, 9

It should be noted that this algorithm is not complete. You will see that bit 7 does not figure in any ECC line. The reason for this is that none of the data available on the blank BASIC tape exercises bit 7 of a decle!? Therefore, we cannot be certain of its influence on the ECC by inspection. I'm sure Frank or Joe know the details, or we could look at a non-blank, or non-BASIC tape, or we could look through a disassembly of the KC EXEC and work out the algorithm. Anyway, this subset should work for creating blank KC tapes.

 

Edit: Doh! I've just realised, all the other bits contribute to three ECC lines and only lines 2, 3 and 4 are one contribution short with five bits. I suspect bit 7 will contribute to these three lines, completing the pattern.

 

Speaking of creating blank tapes, if you want one, I think the following perl script should do a reasonable job of generating a tape image (although the result is 345meg) . It is based on the Audio::Wav module and will construct what I think is a correctly formatted track in the right channel of a wav file. It would be interesting if someone was to record this onto side A of a blank C60 with some nice IR transparent leaders and give it a whirl. For obvious reasons I've not been able to test the results.

 

kcBlankTapeWriter.txt

 

Couple of notes on the implementation. I've used pure sine waves rather than the "interesting" waveform seen on Ron's tapes. This might cause a problem, but could be changed pretty easily. And I've put in what I think is a similar DC bias (this will be stripped out when recording with a bog standard tape machine):

 

post-46336-0-52501900-1533994518.jpg

 

The amplitude and bias of the recording can be adjusted with a couple of variables at the top.

 

If someone gives it a go, let me know the results.

 

 

Cheers

 

decle

Edited by decle
  • Like 1
Link to comment
Share on other sites

If side A is read only and side B is read/write. Perhaps the formatting information is on side A and user data is written to side B. But shouldn't data be on the left channel?

 

Does that mean a Basic tape is only using one quarter of the tape capacity?

Link to comment
Share on other sites

Here's a few thoughts on the blank tape:

I suspect that only the 1st chunk in a record is meaningful. Papa Intellivision documents refer to this special 1st chunk of each records as a "rib". The other 89 chunks that follow are probably garbage / ignored on blank tapes. Keeping in mind that digital space was expensive in 1980, Mattel likely generated a master sequence of of chunks from 1 to 100. When the blank tape was created, they just played back the sequence starting at the record number and then padded with zeros. This might explain why every record is the following sequence of chunks: 1st chunk contains the record number, all chunks that follow increment their first decle until it reaches 100, after this all remaining chunks are 0s. This is just a theory.


The middle 30 decles appear to have structure to them. If the 1st decle is the special "rib" chunk, then it makes sense that it's payload would be used for other information as well. If you re-write it as decles in the following format


index: decles...
0x01: $000, $05A, $000, $000, $000, $000,
0x07: $005, $005, $001, $000, $000, $005, $000, $000, $000,
0x10: $005, $005, $001, $000, $009, $005, $000, $000, $000,
0x19: $000, $000, $000, $000, $000, $000

Then it looks like the red number is the tape's capacity. This number is 100 which happens to match the total number of records on the tape. Most programmers tend to put fields like this at the start of a data structure as well. This would also allow Mattel to either save money shipping smaller, cheaper tapes or use larger tapes for huge programs. Lastly, considering how long it can take to fast-forward from one end of a tape all the way to the other, it makes sense to encode the max number of records so that the KC knows not to waste the user's time going to the end of a programmed tape that is only 1/2 full or less (how much KC software would have contained 260K decles on a machine that only had 16K decles of RAM in the initial software releases).

The blue numbers starting at index 0x07 and 0x10 are mostly identical (except for 1 decle) which I doubt is coincidence. I have don't have any good guesses as to their meaning. Note that due to leading zeros, there are other indexes this comparison would also work for (i.e. 0x04 and 0x0D, 0x05 and 0x0E, and 0x06 and 0x0F).

I agree with @mr_me that the track with all the data we're looking at is very likely the Read-Only Digital track. It would be a poor Mattel design decision to allow users to write over the records since a user's Keyboard Component whose tape drive was slightly out of alignment might screw up the PLL timing that is pre-encoded on the tape (phase shifts, frequency shifts, frequency wow and flutter due to belt wear, etc). It would be better to leave these records as read-only and only allow writing on a different track entirely. That doesn't mean that is what they actually did, but that would be my suspicion.

If this is the read-only track, then one of the fields likely indicates what type of read-only data the rest of the record contains. Since this is a blank tape, one of the values means the rest of the record contains no data. I would expect some of these values to change on a programmed tape (ex: Conversational French) to indicate that some of the records contain CP1610 code. Maybe other records could indicate they contain BASIC or 6502 code (wildly guessing)?

Thanks for sharing kcBlankTapeWriter.txt. I'm not a Perl programmer but I code reviewed it and it looks great.

  • Like 2
Link to comment
Share on other sites

This is a great piece of detective work. Yes, I believe that the codes are Hamming based as mentioned by Joe. I've not been able to find the code he refers to on Papa Intellivision, perhaps he is recalling something from his personal stash :).

 

 

Yeah, I just scoured my downloads from Papa Intellivision and found nothing. Oh well.

Link to comment
Share on other sites

  • ...
  • Decle number 31 is a checksum for other decles in the chunk. The 32 decles are regarded as valid when the following formula is satisfied: 255 * (sum of the 32 decles ) == 0xFF [modulo 255].

 

Just an FYI that I double-checked the math for my formula. Looks like there is likely a math error in since ( 255 * (sum of the 32 decles ) % 256 == 10 for all 100 unique chunks and not the 0xFF I mentioned earlier. This formula is likely on the right track, though since there are 10 non-zero values between the 1st and 32nd columns.

 

Your formula is correct, of course.

  • Like 1
Link to comment
Share on other sites

If side A is read only and side B is read/write. Perhaps the formatting information is on side A and user data is written to side B. But shouldn't data be on the left channel?

 

Does that mean a Basic tape is only using one quarter of the tape capacity?

 

There are 4 tracks in a KC cassette:

  • RO analog
  • RO digital
  • RW analog
  • RW digital

The RO analog has recorded voices, music, whatever. The RO digital has program code and data, or for the bits in parallel with recorded audio, there's an unusual "timecode" pattern that we think PicSee uses to synchronize animations with the audio. (These time-sync blocks have a different structure than the normal data blocks.) David Rolfe has mentioned PicSee and this sync issue elsewhere in interviews.

 

The BASIC tapes, from what I remember, had a fixed block structure on the RO digital side to provide a "hard formatted" set of blocks for BASIC to address. This is in contrast with more general data islands on non-BASIC application tapes. So, BASIC programs can access up to 100 blocks of storage on the RW digital side of the tape. That's 1/4th of the tape's total capacity (1 out of 4 tracks), but 100% of the RW digital, as there's only 1 RW digital track.

 

 

My weaker suspicion is that the remaining 4 lines are using a Hamming Code (https://en.wikipedia.org/wiki/Hamming_code) but does not appear to be a straight-forward match. If it is using a Hamming Code, then the 4 ECC bits means 11 data bits can be protected, which means that Mattel simply dropped one of the data bits to slightly compact the data..

The code is a SECDED code developed by Dean Inada, but it's not exactly a Hamming code. It's a 15-bit code with 10 data bits and 5 ECC bits. It looks hand-rolled when I look at the bit patterns. It uses 2 separate 5-bit patterns with 3 1 bits set, and rotates them through all 5 rotations to generate the syndromes for the 15 bits. (Don't bug Dean. Frank and I already asked. He doesn't remember the details himself.)

 

(SECDED = Single Error Correct; Double Error Detect)

 

The ECC logic also uses the carrier detect signal from the tape unit to enhance the error correction capability. Basically, the decode logic first tries a standard 1-bit error correction. If that fails (2-bit error or worse), it tries flipping data bits wherever the carrier had dropped out, and tries again.

 

Here's the portion of the 6502 code that generates and decodes the SECDED code:

.

;;=============================================================================
;;  Error-correct encoded tape data.
;;-----------------------------------------------------------------------------
DA7B  A6 B6     LDX $B6         ; get index
DA7D  A5 F7     LDA $F7         ; Get ?
DA7F  5D 00 02  EOR $0200,X     ; Merge with low half of 15-bit word
DA82  85 94     STA $94         ; save lower half to $94
DA84  85 96     STA $96         ; save lower half to $96
DA86  BD 01 02  LDA $0201,X     ; Get upper half of 15-bit word
DA89  29 7F     AND #$7F        ; Make sure it's 15 bits
DA8B  85 95     STA $95         ; save upper half to $95
DA8D  85 97     STA $97         ; save upper half to $97
DA8F  29 03     AND #$03        ; Keep only bits 8, 9 of word
DA91  85 91     STA $91         ; save to $91
DA93  20 F6 DA  JSR $DAF6       ; Error-correct 10-bit word + 5-bit parity
DA96  85 F4     STA $F4         ; Store A (syndrome) to $F4
DA98  AA        TAX             ; \__ Use A to index into table at $DBA1
DA99  BD A1 DB  LDA $DBA1,X     ; /   (this is the "number of errors" table)
DA9C  85 F5     STA $F5         ; store number of errors to $F5
DA9E  F0 51     BEQ $DAF1       ; If it came up zero, all done, so return?

                ; there was an error or incomplete word?
DAA0  A6 B6     LDX $B6         ;\
DAA2  BD 02 02  LDA $0202,X     ; |
DAA5  45 94     EOR $94         ; |__ Try toggling bits in the places
DAA7  85 94     STA $94         ; |   where we had loss of carrier.
DAA9  BD 03 02  LDA $0203,X     ; |   
DAAC  45 95     EOR $95         ; |
DAAE  85 95     STA $95         ;/
DAB0  29 03     AND #$03        ; keep only bits 8, 9 of word
DAB2  85 91     STA $91         ; save to $91
DAB4  20 F6 DA  JSR $DAF6       ; Decode merged word
DAB7  85 F6     STA $F6         ; store new syndrome to $F6
DAB9  AA        TAX             ;
DABA  BD A1 DB  LDA $DBA1,X     ; how many errors according to syndrome?
DABD  F0 32     BEQ $DAF1       ; if it came up zero, all done, so return?

                ; error correction.
DABF  C5 F5     CMP $F5         ; fewer errors in second version?
DAC1  30 0E     BMI $DAD1       ; Yes: Keep second version.
DAC3  A5 F4     LDA $F4         ;\
DAC5  85 F6     STA $F6         ; |
DAC7  A5 96     LDA $96         ; |
DAC9  85 94     STA $94         ; |-- No: copy original to working buffer
DACB  A5 97     LDA $97         ; |
DACD  85 95     STA $95         ; |
DACF  A5 F5     LDA $F5         ;/

DAD1  C9 02     CMP #$02        ; can we fix it?
DAD3  10 1D     BPL $DAF2       ; no, incr unfixed error count and leave?
DAD5  EE 20 BE  INC $BE20       ; yes, incr corrected error count
DAD8  A6 F6     LDX $F6         ; get syndrome from $F6
DADA  A5 94     LDA $94         ; Get data for lower half to fix
DADC  5D 81 DB  EOR $DB81,X     ; Fix the broken bits in lower half
DADF  85 94     STA $94         ; Store it.
DAE1  A5 95     LDA $95         ; get upper half
DAE3  E0 19     CPX #$19        ;\
DAE5  D0 02     BNE $DAE9       ; |-- if syndrome == 0x19, then toggle bit 9.
DAE7  49 02     EOR #$02        ;/
DAE9  E0 1C     CPX #$1C        ;\
DAEB  D0 02     BNE $DAEF       ; |-- if syndrome == 0x1C, then toggle bit 10.
DAED  49 01     EOR #$01        ;/
DAEF  85 95     STA $95         ; store upper half.
DAF1  60        RTS

DAF2  EE 21 BE  INC $BE21       ; increment tape unfixable error count?
DAF5  60        RTS

;;=============================================================================
;;  Check the checksum of a 15-bit number and return a syndrome
;;-----------------------------------------------------------------------------
                                ;      C  7  6  5  4  3  2  1  0
DAF6  A5 95     LDA $95         ;      x  - WE WD WC WB WA W9 W8
DAF8  4A        LSR A           ;      x  -  - WE WD WC WB WA W9
DAF9  4A        LSR A           ;      x  -  -  - WE WD WC WB WA
DAFA  85 90     STA $90         ;      x  -  -  - WE WD WC WB WA
DAFC  A5 94     LDA $94         ;      x W7 W6 W5 W4 W3 W2 W1 W0 
DAFE  29 1F     AND #$1F        ;\     x  -  -  - W4 W3 W2 W1 W0 
DB00  AA        TAX             ; |- Look up ECC code for lower 5 bits
DB01  BD 41 DB  LDA $DB41,X     ;/   
DB04  45 90     EOR $90         ; add it to bits 12 thru 15
DB06  85 90     STA $90         ; and store it in $90 temporarily
                                ;      C  7  6  5  4  3  2  1  0
DB08  A5 94     LDA $94         ;      x W7 W6 W5 W4 W3 W2 W1 W0 
DB0A  29 E0     AND #$E0        ;      x W7 W6 W5  -  -  -  -  -
DB0C  0A        ASL A           ;     W7 W6 W5  -  -  -  -  -  -
DB0D  05 91     ORA $91         ;     W7 W6 W5  -  -  -  - W9 W8 
DB0F  2A        ROL A           ;     W6 W5  -  -  -  - W9 W8 W7
DB10  2A        ROL A           ;     W5  -  -  -  - W9 W8 W7 W6
DB11  2A        ROL A           ;      -  -  -  - W9 W8 W7 W6 W5
DB12  AA        TAX             ; \   
DB13  BD 61 DB  LDA $DB61,X     ;  |- Look up ECC code for upper 5 bits
DB16  45 90     EOR $90         ; /   
DB18  60        RTS             ; and return
;;=============================================================================

;;=============================================================================
;;  Generate the checksum for a 10-bit number, returning a 15-bit number.
;;-----------------------------------------------------------------------------
DB19  A5 94     LDA $94         ; \
DB1B  29 1F     AND #$1F        ;  |
DB1D  AA        TAX             ;  |-- Bits 0..4 into X, 
DB1E  45 94     EOR $94         ;  |   Bits 5..7 into $91
DB20  85 91     STA $91         ; /
DB22  BD 41 DB  LDA $DB41,X     ; Get checksum for bits 0..4 into A
DB25  85 90     STA $90         ; Store initial cksum to $90
                                ;      C  7  6  5  4  3  2  1  0
DB27  A5 95     LDA $95         ;      0  0  0  0  0  0  0  W9 W8
DB29  4A        LSR A           ;      W8 0  0  0  0  0  0  0  W9
DB2A  05 91     ORA $91         ;      W8 W7 W6 W5 0  0  0  0  W9
DB2C  2A        ROL A           ;      W7 W6 W5 0  0  0  0  W9 W8
DB2D  2A        ROL A           ;      W6 W5 0  0  0  0  W9 W8 W7
DB2E  2A        ROL A           ;      W5 0  0  0  0  W9 W8 W7 W6
DB2F  2A        ROL A           ;      0  0  0  0  W9 W8 W7 W6 W5
DB30  AA        TAX
DB31  BD 61 DB  LDA $DB61,X     ; Get checksum for bits 5..9 into A
                                ;      C  7  6  5  4  3  2  1  0
DB34  45 90     EOR $90         ; Merge w/ initial cksum into A
                                ;      0  0  0  0  WE WD WC WB WA
DB36  0A        ASL A           ;      0  0  0  WE WD WC WB WA 0
DB37  0A        ASL A           ;      0  0  WE WD WC WB WA 0  0
DB38  05 95     ORA $95         ;      0  0  WE WD WC WB WA W9 W8
DB3A  18        CLC             ;      
DB3B  26 94     ROL $94         ; shift lower-half left, bring in 0
DB3D  2A        ROL A           ;      0  WE WD WC WB WA W9 W8 W7
DB3E  85 95     STA $95         ; store upper half to $95
DB40  60        RTS             ; WE thru W0 are in upper 15 bits of $94-$95
;;=============================================================================

; Data from $DB41 to $DBC0 (128 bytes)
DB41  .byte $00, $0D, $1A, $17, $15, $18, $0F, $02
DB49  .byte $0B, $06, $11, $1C, $1E, $13, $04, $09
DB51  .byte $16, $1B, $0C, $01, $03, $0E, $19, $14
DB59  .byte $1D, $10, $07, $0A, $08, $05, $12, $1F

DB61  .byte $00, $13, $07, $14, $0E, $1D, $09, $1A
DB69  .byte $1C, $0F, $1B, $08, $12, $01, $15, $06
DB71  .byte $19, $0A, $1E, $0D, $17, $04, $10, $03
DB79  .byte $05, $16, $02, $11, $0B, $18, $0C, $1F

DB81  .byte $00, $00, $00, $00, $00, $00, $00, $40
DB89  .byte $00, $00, $00, $08, $00, $01, $80, $00
DB91  .byte $00, $00, $00, $20, $00, $04, $10, $00
DB99  .byte $00, $00, $02, $00, $00, $00, $00, $00

DBA1  .byte $00, $01, $01, $02, $01, $02, $02, $01
DBA9  .byte $01, $02, $02, $01, $02, $01, $01, $02
DBB1  .byte $01, $02, $02, $01, $02, $01, $01, $02
DBB9  .byte $02, $01, $01, $02, $01, $02, $02, $02

.

The data at DB41 and DB61 are the syndrome tables for bits [4:0] and [9:5] of the data, respectively. They compute the syndrome 5 bits at a time. To see what the syndromes are for each individual bit, you need to look at offsets 1, 2, 4, 8, and 16 in each table:

 

  • Bit 0: 01101
  • Bit 1: 11010
  • Bit 2: 10101
  • Bit 3: 01011
  • Bit 4: 10110
  • Bit 5: 10011
  • Bit 6: 00111
  • Bit 7: 01110
  • Bit 8: 11100
  • Bit 9: 11001

 

Notice the first 5 bits are just 5 rotations of 01101, while the next 5 bits are just 5 rotations of 10011. These are the only 5 bit patterns with 3 bits set. 5C3 (5 choose 3) is 10. (Everyone here remember the C and P operators from combinatorics? No?) 3 1 bits in each syndrome is what you need to generate a distance 4 code, and distance 4 is what you need for SECDED.

 

That gives you the first two sets of syndromes (for bits 0 through 9). The ECC bits themselves have syndromes. SECDED covers the full 15 bit codeword, just as in a Hamming code. I'll present the ECC syndromes for bits 10 - 14, and let you guess why they are what they are.

  • Bit 10: 00001
  • Bit 11: 00010
  • Bit 12: 00100
  • Bit 13: 01000
  • Bit 14: 10000

;-)

 

OK, the answer is pretty simple:

 

 

The syndrome for a parity bit in a Hamming-like code is always just the parity bit itself. If the syndrome residue you see when you decode only has a single parity bit set, you know you have a 1 bit error and it's in the parity bit itself.

 

 

On PapaIntellivision, look for the PDF that has this in it:

 

post-14113-0-86274900-1534178069_thumb.png

 

There are at least two PDFs with it, IIRC. The screen cap above is from "documents.pdf"; however, it also appears in CCF10232011_00020.pdf. Elsewhere, Frank dug up some BLISS16 code (we think it's BLISS16) that generates the ECC code. I can't find that snippet right now. That said, it's interesting only for historical purposes I think, as the 6502 code is pretty clear.

 

We should drag Frank in here, as he has some tape tools of his own, and lots more information.

 

I don't remember if we worked out what the fixed fields are in the RO digital part of the tape. It may be instructive to compare against a BASIC application such as the Financial Planning tape.

 

  • Like 5
Link to comment
Share on other sites

So back in 1982 if you wanted to double the capacity of your Basic tape, all you had to do was flip the tape over. But I'm guessing the other side is not formatted and KC Basic does not format tape. But if you have one formatted tape all you need is audio tape recording equipment to format another. On the revolution forums a guy wrote about doing just that.

 

The KC Basic book says each record stores up to 2kB. So with 100 records that's 200kB on one track, 400kB on two tracks, and if it wrote to all four (which it doesn't) that's 800kB. Sounds like a lot.

  • Like 1
Link to comment
Share on other sites

So back in 1982 if you wanted to double the capacity of your Basic tape, all you had to do was flip the tape over. But I'm guessing the other side is not formatted and KC Basic does not format tape. But if you have one formatted tape all you need is audio tape recording equipment to format another. On the revolution forums a guy wrote about doing just that.

 

The KC Basic book says each record stores up to 2kB. So with 100 records that's 200kB on one track, 400kB on two tracks, and if it wrote to all four (which it doesn't) that's 800kB. Sounds like a lot.

 

I would imagine had this gone into actual production and become a staple of Mattel Electronics catalogue, we would have seen the eventual release of pre-formatted, double-sided tape cassettes. You're right, it would make sense since a BASIC tape wouldn't have any use for the Read-Only tracks, so flipping the tape and making them available could have been an option.

 

Alas, it was not meant to be.

 

In any case, every time I read more on the underlying technology, I get more impressed by what they were trying to accomplish, and more saddened at the fact that they didn't succeed in bringing it to market in a practical manner. Yay! :) then Boo! :(

 

-dZ.

Link to comment
Share on other sites

They probably would have sold those at near double the price. It's like single sided floppies, punch a hole, and flip it over. Actually, flipping a kc basic tape would make use of the audio tracks.

 

Had this taken off and they started releasing games on tape, people would have figured out how to copy kc tapes at home. Even if it just used one track, 160k would have been a large game. I'm surprised there was no attempt at copy protection.

Link to comment
Share on other sites

They probably would have sold those at near double the price. It's like single sided floppies, punch a hole, and flip it over. Actually, flipping a kc basic tape would make use of the audio tracks.

 

Yes, unless you format the Read-Only Audio track (#1) on the other side as a Read-Write track, and it becomes track #4 when you flip the cassette. I'm saying that someone would have released a cassette that looked like:

  1. latigiD etirW-deaR
  2. --
  3. --
  4. Read-Write Digital

With the first track on "Side A" just being track #4 formatted as read-write on "Side B."

 

Of course if there was software available to format the cassette appropriately, the consumer could have done this himself at home by just flipping the cassette.

 

That is, assuming that formatting was required to begin with. If no formatting was required, then there's even less barriers.

 

Had this taken off and they started releasing games on tape, people would have figured out how to copy kc tapes at home. Even if it just used one track, 160k would have been a large game. I'm surprised there was no attempt at copy protection.

 

I think it was very early days in the industry. The heyday of copy-protection didn't come until later in the early to mid 1980s. The Keyboard Component was still the child of the 1970s. That is not to say that there was no copy protection anywhere, just that it wasn't as prevalent in the industry in the late 1970s.

 

Notice that early cassette tapes for micro-computers also didn't have copy protection in software. The most common protection was mastering using weak signals which would not be properly reproduced by consumer-level recorders of the time. There was a rather large differential between the quality of commercial and consumer hardware recording equipment.

 

-dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

It was a couple years later but coleco put extra holes in their adam cassettes. So if you wanted to use regular audio casettes you had to drill them into the shell. Not really copy protection, adam tapes were easily copied with audio recorders. Mattel Electronics spent a bit of time coming up with copy protection for their IBM/Apple floppies but that was 1983.

Link to comment
Share on other sites

My understanding is that the read-only digital track was preformatted so that the the KC could find the record locations on the tape. When it came time to write to the tape, data was written to the read/write digital track (and not the read-only digital track). Thus, flipping the tape over wouldn't work. However, this is mainly conjecture at this point.

 

As for dubbing a copy, it is theoretically possible. The only issue is that you need to find a blank tape whose leader tape (the part that comes before the magnetized tape) is permeable to infrared light since the KC uses such a sensor to find the start of the tape.

Link to comment
Share on other sites

My understanding is that the read-only digital track was preformatted so that the the KC could find the record locations on the tape. When it came time to write to the tape, data was written to the read/write digital track (and not the read-only digital track). Thus, flipping the tape over wouldn't work. However, this is mainly conjecture at this point.

 

That's a good point. I wasn't considering that both the read-only and read-write tracks were used in conjunction to maintain the state of recording of records. If so, then you're right that flipping the cassette won't work.

 

 

As for dubbing a copy, it is theoretically possible. The only issue is that you need to find a blank tape whose leader tape (the part that comes before the magnetized tape) is permeable to infrared light since the KC uses such a sensor to find the start of the tape.

Using modern equipment could work, but what I recall is that the noise, bias, speed, and quality tolerances of consumer equipment built for listening and recoding music were a lot more liberal than those required by some digital applications, especially during that time.

 

A lot of variance was added to microcomputer implementations to compensate for the flakiness and bad quality of typical music cassette recordings. The KC, having a dedicated tape machine may not have such tolerances built in.

 

dZ.

Link to comment
Share on other sites

Using modern equipment could work, but what I recall is that the noise, bias, speed, and quality tolerances of consumer equipment built for listening and recoding music were a lot more liberal than those required by some digital applications, especially during that time.

 

A lot of variance was added to microcomputer implementations to compensate for the flakiness and bad quality of typical music cassette recordings. The KC, having a dedicated tape machine may not have such tolerances built in.

 

dZ.

Good point, I hadn't considered that.

Link to comment
Share on other sites

There was a guy that did it using audio cassettes and, at the latest, 1980s audio equipment. I don't know exactly what tape recorder he used.

I'm sure it is possible, I just don't know if it would be reliable and scalable for widespread piracy, for it to be a concern at the time.

Link to comment
Share on other sites

My understanding is that the read-only digital track was preformatted so that the the KC could find the record locations on the tape. When it came time to write to the tape, data was written to the read/write digital track (and not the read-only digital track). Thus, flipping the tape over wouldn't work. However, this is mainly conjecture at this point.

 

...

Without formatting the flip side, it wouldn't work. Why couldn't you format both sides? And by format I mean copying from a preformatted tape.
Link to comment
Share on other sites

Without formatting the flip side, it wouldn't work. Why couldn't you format both sides? And by format I mean copying from a preformatted tape.

 

Oh, I see now, I misread the order of the tracks. I thought the pairs were 1/4 and 2/3, but actually intvnut's comment says the analog and digital tracks are interspersed as 1/3, 2/4. That means that it could work. For example:

 

 

Side A:

  1. ...
  2. Read-Only (sync)
  3. ...
  4. Read-Write (data)

Then when you flip, it'll look like this:

 

Side B:

4. ...

3. Read-Only (sync)

2. ...

1. Read-Write (data)

 

I thought they would overwrite each other, but they actually land on the opposite ones.

 

-dZ.

Link to comment
Share on other sites

Without formatting the flip side, it wouldn't work. Why couldn't you format both sides? And by format I mean copying from a preformatted tape.

 

Flipping might or might not work since at the moment it's unclear what the track order on a KC blank tape is at the moment. Depending on the order, it may be possible to dub a preformatted to side A and again to side B to get 2X the data.

 

However, this would sacrifice both Audio tracks which may or may not matter. Assuming the user doesn't care about audio (they just want to store data), there might be a 2nd issue. There is a tone at the beginning of the Read Only Audio track and I don't know if that is important to the KC reading the tape or not (I am guessing it doesn't matter but I'm not sure).

 

 

 

Just so everyone here is in sync on how tracks are laid onto a cassette tape, here are the order of tracks as reported from various sources. Obviously, the Tascam and Standard Cassette track orders are definitive. The only grey area is what is the KC track order.

 

Tascam Standard Cassette Frank's Joe's decle's

Recorder Presentation Bullet Order recording

1 Side A / left RO Data RO Audio RO Audio

2 Side A / right RO Audio RO Data RO Data

3 Side B / right RW Audio RW Audio --

4 Side B / left RW Data RW Data --

 

post-37124-0-18152300-1534616679.png

 

post-37124-0-83111500-1534616697_thumb.png

 

Note that the directional arrows are for the direction the tape goes when you have side A of the tape facing you with the openings that expose the cassette's tape facing down. In other words, like this rewound and ready-to-play tape:

 

post-37124-0-07110600-1534616949_thumb.jpg

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...