Day 33: 332 days left
Internet connection pickle. ..
Well my net connection is cursed, However with the replacement of multiple widgets on the main post things seem to be back in action.
In the interim things were productive.
1. Figured out how to read,write forth block files (a.k.a screens) this is the key to creating the macro cross assembler.
2. created a screen editor, no more manually MOVE input buffers to raw memory areas, has insert, delete, add line. I copied most of the ideas from se (a visual ed).
the whole editor is 2048 bytes. (two screens of memory). it operates completely in ram, until the file buffer is written to disk. - this improves the operating speed of the program and also reduces ware and tear on the hard disk. I am hoping to put all my crap tools onto a flash memory so its important to minimise the writes to flash. (that is the whole point of using blocks - you don't interact with the physical hard disk until its absolutely critical. )
With a more minimal feature set (just insert line, and page navigation) I could probably get it down to 1024 bytes.
I had forgotten just how nice forth is to use. The tools I can make with this will make creating my projects on the micro computers so much easier.
Next am at the stage where I can keep the different file formats for the various spectrum file types (tap and microdrive) I found the tzx format but not the tap or microdrive file format.
But having discovered some utilities for writing micro drives here from one kind soul - shout out to serbalgi
. I figure I can discover the file format by examining the utility.
What I am starting to do now is modularizing all of my code snippets that I use for the subroutines, then I will be able to do the copy pasta to a new file with graphics, and a few decisions have a new project generated.
There are a few things I still don't quite understand that I will need to straighten out but this has been a great learning experience - the added advantage of forth is its heavily dependent on stack manipulation to get anything done. In a round about way this should make me a better z80 assembly coder. I am guessing with more use of the stack my programs should get a lot faster.
Another discovery that will help my documentation of projects is Dijkstra diagrams. You can imagine my surprise having completed a software engineering course in the 90s to come across this method a few days ago and realise it never once came up in any of my lectures or books from what I can remember. But its a far superior way of illustrating program flow vs flowcharts.
I had began to become frustrated with the way flowcharts can start to look like a hot mess after a certain level of complexity/length. Especially with jumps, calls its a little confusing. However with the Dijkstra diagrams its a much better way of describing these processes. Everything flows down, you don't have to be looking all over the place when a loop or case occurs.
That said there is very little information about this technique besides an obscure article in an crusty forth users group circular.
You can read the article that sparked my interest here..
http://www.forth.org/fd/FD-V01N3.pdf its on page 30.
I am trying to track down Dijkstra's books/papers to see where the source was for the user-group article.
On to CrapChess, well following the discussion of the data format for encoding games into CrapChess I realised that this would be one area where it would really pay dividends to use a non-native solution to encode the data and then just transfer the binary blob when it was ready to the spectrum file.
Encoding a binary is pretty straight forward, keeping everything organized not so much. To save space information on the games, who played would be kept in a printed binder. This also acts as a kind of copy protection as you need the binder to have any idea what game you are reviewing on the microdrive.
One thing I am curious about is how many files you can have on a microdrive...
Having got the net back I was able to track down the file specifications I wanted,
DSK..
Luckly the waybackwhen machine helped out as the link had been dead for 20 years..
The format is the same used on the Amstrad CPC.
Disk image file format
This document describes the standard disk image format. It has the file extension ".DSK".
Disc Information block
This is at the start of all disk image files. Data for the first track immediately follows the Disc Information Block and is at offset &100 in the disc image file.
Code: Select all
offset comment
00-21 MV-CPCEMU Disk-File\r\nDisk-Info\r\n
"MV-CPC" must be present, because it is used to identify the
file as a disk image. It is sufficient to check this to identify
the file as being a disk image.
\r and \n are control character representations used by C
programming language. ASCII codes: \r = 13, \n = 10
22-2f DSK Creator (name of utility that made the disc image)
30 number of tracks in disk image (40,80,42...)
Do not rely on this being exactly 40 or 80 tracks. Some disc
images use the extra storage from extra tracks.
31 number of sides (1 or 2)
32-33 size of a track including &100 byte track information block
(stored low byte followed by high byte)
All tracks must be the same size.
34-ff not used (0)
Track Information Block
Each Track Block comprises a Track Information Block and sector data. The sector data is always at an offset of &100 bytes from the start of the track block. The data for the next track in the disc image immediately follows the data for the current track.
The first Track Block is located at offset &100 in the disk image file. The track block starts with the Track Information Block and has this form.
Code: Select all
offset comment
00-0c Track-Info\r\n
This is not essential. DO NOT CHECK FOR THIS. In a early
version of my disk image creation utility for the Amiga this
was incorrectly written into the track header.
0d-0f not used (0)
10 Track number (0 to number of tracks-1)
11 Side number (0 or 1)
Do not bother to check that these are correct. Some disc images
do not have these correct.
12-13 not used (0)
The following parameters are the same as are used in the format track
command in the fdc.
14 BPS (bytes per sector)
0 = 128 bytes
1 = 256 bytes
2 = 512 bytes
3 = 1024 bytes
This is used to calculate the sector data offset from the
Track Information Block.
15 SPT (sectors per track)
Number of sectors on this track. (normally 9, at the most 18)
16 GAP#3 (used in formatting, &4e)
17 Filler Byte (byte used to fill sectors, &e5;)
The two parameters above are not essential.
18-&ff; sector info list
Sector info
Code: Select all
offset comment
0 track number (C) - from FDC "READ ID" command
1 head number (H) - from FDC "READ ID" command
2 sector id number (R) - from FDC "READ ID" command
3 sector size (N) - from FDC "READ ID" command
4 FDC Status register 1 - from the result phase of FDC "READ DATA" command
5 FDC Status register 2 - from the result phase of FDC "READ DATA" command
6 not used (0)
7 not used (0)
General format
Single sided DSK images
Disc Information Block
Track 0 data
Track Information Block
Sector data
Track 1 data
Track Information Block
Sector data
. . . .
Track (number_of_tracks-1) data
Track Information Block
Sector data
Double sided DSK images
Disc Information Block
Track 0 side 0 data
Track Information Block
Sector data
Track 0 side 1 data
Track Information Block
Sector data
. . . .
Track (number_of_tracks-1) side 1 data
Track Information Block
Sector data
Notes
The first track must immediately follow the Disk Information Block.
The sector data must immediately follow the Track Information Block.
The sector data must be in the same order as in the sector info list.
In double sided formats the tracks are stored alternating:
e.g. track 0 side 0, track 0 side 1, track 1 side 0 etc..
To hold different size tracks and different size sectors in a disk image:
Size of one track should be set to the size of the track containing the most data. All tracks will use the same size, but some space will be wasted
All sectors must occupy the same space on a track. Take the sector with the largest data
8k Sectors are stored with 1800h bytes only. This is the maximum usable data on one of these sectors
Calculating Track Position and Sector Data Position
The following equation will give the offset to the Track Information Block for the track you want:
track_offset=(track_number*size_of_track*no_of_sides)+&100+(track_size if the DSK image has 2 sides and a request is made to read side 2) To get the sector data offset:
Make sure the correct Track Information Block has been loaded.
Set a counter to 0
Check the R value in the FDC command against the sector number in the sector info list.
If the value doesn't match then increment the counter.
If the value>18 then the sector doesn't exist.
When the sector has been found, the sector data is calculated as: sector_data_offset=track_offset+(sector_position*BPS)+&100
The size of the sector data to read is defined in bps in the sector info.
[\quote]
Also TAP format this time the page was still running.
The .TAP files contain blocks of tape-saved data. All blocks start with two bytes specifying how many bytes will follow (not counting the two length bytes). Then raw tape data follows, including the flag and checksum bytes. The checksum is the bitwise XOR of all bytes including the flag byte. For example, when you execute the line SAVE "ROM" CODE 0,2 this will result:
Code: Select all
|------ Spectrum-generated data -------| |---------|
13 00 00 03 52 4f 4d 7x20 02 00 00 00 00 80 f1 04 00 ff f3 af a3
^^^^^...... first block is 19 bytes (17 bytes+flag+checksum)
^^... flag byte (A reg, 00 for headers, ff for data blocks)
^^ first byte of header, indicating a code block
file name ..^^^^^^^^^^^^^
header info ..............^^^^^^^^^^^^^^^^^
checksum of header .........................^^
length of second block ........................^^^^^
flag byte ............................................^^
first two bytes of rom .................................^^^^^
checksum (checkbittoggle would be a better name!).............^^
Note that it is possible to join .TAP files by simply stringing them together, for example COPY /B FILE1.TAP + FILE2.TAP ALL.TAP
For completeness, I'll include the structure of a tape header. A header always consists of 17 bytes:
Code: Select all
Byte Length Description
---------------------------
0 1 Type (0,1,2 or 3)
1 10 Filename (padded with blanks)
11 2 Length of data block
13 2 Parameter 1
15 2 Parameter 2
The type is 0,1,2 or 3 for a Program, Number array, Character array or Code file. A SCREEN$ file is regarded as a Code file with start address 16384 and length 6912 decimal. If the file is a Program file, parameter 1 holds the autostart line number (or a number >=32768 if no LINE parameter was given) and parameter 2 holds the start of the variable area relative to the start of the program. If it's a Code file, parameter 1 holds the start of the code block when saved, and parameter 2 holds 32768. For data files finally, the byte at position 14 decimal holds the variable name.