Difference between revisions of "NorthStar 10-sector formats"
(fix error in DD format (thanks to Bob Pryor for reporting this)) |
|||
(9 intermediate revisions by the same user not shown) | |||
Line 36: | Line 36: | ||
The check character is computed iteratively by setting it to zero and then exclusive ORing each successive data byte value with the current value of the check character and left cycling the result. | The check character is computed iteratively by setting it to zero and then exclusive ORing each successive data byte value with the current value of the check character and left cycling the result. | ||
+ | This source code (from [http://www.hartetechnologies.com/manuals/Northstar/NSDOS.ASM Barry Watzman's disassembly of NS-DOS]) makes it a little more obvious what's really happening: | ||
+ | <nowiki>READ MOV B,C ;MOVE 0 TO B | ||
+ | READ1 LDAX D ;THIS IS THE ACTUAL DATA READ | ||
+ | MOV M,A ;STORE DATA IN MEMORY | ||
+ | XRA B ;I THINK THIS ADDS TO CKSUM | ||
+ | RLC ;THIS TOO | ||
+ | MOV B,A ;MOVE PARTIAL CKSUM TO B | ||
+ | INX H ;SET H FOR NEXT BYTE | ||
+ | DCR C ;GOING TO READ 256 BYTES & CKSUM | ||
+ | JNZ READ1 ;READ MORE DATA | ||
+ | LDAX D ;READ THE CHECKSUM FROM DISK | ||
+ | XRA B ;COMPARE IT WITH CALCULATED CKSUM | ||
+ | JZ LE9C4 ;IF THEY ARE SAME GO ON</nowiki> | ||
+ | |||
+ | There's also a disassembly of the Northstar boot PROM: http://www.sol20.org/northstar/nsboot.asm. | ||
+ | There are some other interesting Northstar files on the same site: http://www.sol20.org/programs.html#Northstar. | ||
+ | |||
+ | What we can take away from this is: | ||
+ | |||
+ | * The check character is initialised to zero when reading the sector | ||
+ | * Every data byte in the payload is first XORed with the current checksum, then the checksum is barrel-rotated left. See the explanation of the RLC instruction in [http://neil.franklin.ch/Info_Texts/Instruction_Set_8080 Neil Franklin's 8080 instruction set reference] -- note that [http://www.textfiles.com/programming/CARDS/8080a Jonathan Bowen's 8080A Reference Card] describes RLC as "Rotate Left, Circular", which is a bit of a giveaway. | ||
+ | |||
+ | Thus the C implementation of this algorithm would be something along the lines of: | ||
+ | <nowiki> | ||
+ | // UNTESTED code to calculate the cyclic check code for a Northstar disc sector | ||
+ | unsigned char northstar_crc(unsigned char last_crc, unsigned char data) { | ||
+ | unsigned char crc = last_crc; | ||
+ | crc += data; | ||
+ | crc = ((crc << 1)&0xfe) | ((crc >> 7)&1); | ||
+ | return crc; | ||
+ | }</nowiki> | ||
== Double-density format == | == Double-density format == | ||
Line 49: | Line 80: | ||
* 32 bytes, zeroes. These allow the PLO to synchronise itself to the incoming data stream | * 32 bytes, zeroes. These allow the PLO to synchronise itself to the incoming data stream | ||
* 2 synchronisation bytes. Always 0xFB. | * 2 synchronisation bytes. Always 0xFB. | ||
− | * | + | * 512 bytes of data (payload) |
* 1 byte check character | * 1 byte check character | ||
The check character is computed as per the Single-Density NorthStar format. | The check character is computed as per the Single-Density NorthStar format. |
Latest revision as of 23:13, 13 March 2012
Contents
Description and common features
10-sector hard-sectored formats used by NorthStar NSDOS and CP/M systems (e.g. NorthStar Horizon and NorthStar Advantage).
Two variants are known:
- Single Density (FM)
- Double Density (MFM)
Both formats have 35 tracks, and 10 hardware-defined sectors.
Things still unknown:
- Bit order of data -- is it LSB first, or MSB first?
- Byte order of data -- little or big endian? Does this matter?
- Description of check character computation is ambiguous. Need to find some example code e.g. Boot PROM to figure this out.
Single-density format
References: NorthStar MDS-A-D Manual (p. 33)
Encoding method
Frequency Modulation. Two transitions per bit-cell, one clock (always present), one data (present if data bit is a '1', otherwise skipped). Data rate unknown.
Track format
Each track consists of ten sectors, whose position is specified by hardware (hard-sector index pulses). The NorthStar hardware triggers off of the leading edge of an index pulse, then waits for 96 microseconds to pass before enabling the read/write circuitry (this is the post index gap).
Each sector contains, in order:
- 16 bytes, zeroes. These allow the PLO to synchronise itself to the incoming data stream
- 1 byte synchronisation character. Always 0xFB.
- 256 bytes of data (payload)
- 1 byte check character
Check character computation
From the NorthStar MDS-A-D Manual:
The check character is computed iteratively by setting it to zero and then exclusive ORing each successive data byte value with the current value of the check character and left cycling the result.
This source code (from Barry Watzman's disassembly of NS-DOS) makes it a little more obvious what's really happening:
READ MOV B,C ;MOVE 0 TO B READ1 LDAX D ;THIS IS THE ACTUAL DATA READ MOV M,A ;STORE DATA IN MEMORY XRA B ;I THINK THIS ADDS TO CKSUM RLC ;THIS TOO MOV B,A ;MOVE PARTIAL CKSUM TO B INX H ;SET H FOR NEXT BYTE DCR C ;GOING TO READ 256 BYTES & CKSUM JNZ READ1 ;READ MORE DATA LDAX D ;READ THE CHECKSUM FROM DISK XRA B ;COMPARE IT WITH CALCULATED CKSUM JZ LE9C4 ;IF THEY ARE SAME GO ON
There's also a disassembly of the Northstar boot PROM: http://www.sol20.org/northstar/nsboot.asm. There are some other interesting Northstar files on the same site: http://www.sol20.org/programs.html#Northstar.
What we can take away from this is:
- The check character is initialised to zero when reading the sector
- Every data byte in the payload is first XORed with the current checksum, then the checksum is barrel-rotated left. See the explanation of the RLC instruction in Neil Franklin's 8080 instruction set reference -- note that Jonathan Bowen's 8080A Reference Card describes RLC as "Rotate Left, Circular", which is a bit of a giveaway.
Thus the C implementation of this algorithm would be something along the lines of:
// UNTESTED code to calculate the cyclic check code for a Northstar disc sector unsigned char northstar_crc(unsigned char last_crc, unsigned char data) { unsigned char crc = last_crc; crc += data; crc = ((crc << 1)&0xfe) | ((crc >> 7)&1); return crc; }
Double-density format
References: NorthStar MDS-A-D Manual (p. 33)
Encoding method
Modified Frequency Modulation. Two transitions per bit-cell, one clock (only present if the previous and current data bits are both zero), one data (present if data bit is a '1', otherwise skipped). Data rate unknown.
Track format
Each track consists of ten sectors, whose position is specified by hardware (hard-sector index pulses). The NorthStar hardware triggers off of the leading edge of an index pulse, then waits for 96 microseconds to pass before enabling the read/write circuitry (this is the post index gap).
Each sector contains, in order:
- 32 bytes, zeroes. These allow the PLO to synchronise itself to the incoming data stream
- 2 synchronisation bytes. Always 0xFB.
- 512 bytes of data (payload)
- 1 byte check character
The check character is computed as per the Single-Density NorthStar format.