Difference between revisions of "Th. Tempelmann format"
Line 271: | Line 271: | ||
>8:00f4 52 4d 4d 4a 52 79 4a 4d RMMJRyJM | >8:00f4 52 4d 4d 4a 52 79 4a 4d RMMJRyJM | ||
>8:00fc 4a 4d 4e 53 00 c9 00 00 JMNS.... | >8:00fc 4a 4d 4e 53 00 c9 00 00 JMNS.... | ||
+ | |||
+ | {| | ||
+ | | | ||
+ | {| class="wikitable" | ||
+ | |-class="hintergrundfarbe6" | ||
+ | ! Daten !! Code | ||
+ | |- | ||
+ | | 000000 || 10010110 | ||
+ | |- | ||
+ | | 000001 || 10010111 | ||
+ | |- | ||
+ | | 000010 || 10011010 | ||
+ | |- | ||
+ | | 000011 || 10011011 | ||
+ | |- | ||
+ | | 000100 || 10011101 | ||
+ | |- | ||
+ | | 000101 || 10011110 | ||
+ | |- | ||
+ | | 000110 || 10011111 | ||
+ | |- | ||
+ | | 000111 || 10100110 | ||
+ | |} | ||
+ | | | ||
+ | {| class="wikitable" | ||
+ | |-class="hintergrundfarbe6" | ||
+ | ! Daten !! Code | ||
+ | |- | ||
+ | | 001000 || 10100111 | ||
+ | |- | ||
+ | | 001001 || 10101011 | ||
+ | |- | ||
+ | | 001010 || 10101100 | ||
+ | |- | ||
+ | | 001011 || 10101101 | ||
+ | |- | ||
+ | | 001100 || 10101110 | ||
+ | |- | ||
+ | | 001101 || 10101111 | ||
+ | |- | ||
+ | | 001110 || 10110010 | ||
+ | |- | ||
+ | | 001111 || 10110011 | ||
+ | |} | ||
+ | | | ||
+ | {| class="wikitable" | ||
+ | |-class="hintergrundfarbe6" | ||
+ | ! Daten !! Code | ||
+ | |- | ||
+ | | 010000 || 10110100 | ||
+ | |- | ||
+ | | 010001 || 10110101 | ||
+ | |- | ||
+ | | 010010 || 10110110 | ||
+ | |- | ||
+ | | 010011 || 10110111 | ||
+ | |- | ||
+ | | 010100 || 10111001 | ||
+ | |- | ||
+ | | 010101 || 10111010 | ||
+ | |- | ||
+ | | 010110 || 10111011 | ||
+ | |- | ||
+ | | 010111 || 10111100 | ||
+ | |} | ||
+ | | | ||
+ | {| class="wikitable" | ||
+ | |-class="hintergrundfarbe6" | ||
+ | ! Daten !! Code | ||
+ | |- | ||
+ | | 011000 || 10111101 | ||
+ | |- | ||
+ | | 011001 || 10111110 | ||
+ | |- | ||
+ | | 011010 || 10111111 | ||
+ | |- | ||
+ | | 011011 || 11001011 | ||
+ | |- | ||
+ | | 011100 || 11001101 | ||
+ | |- | ||
+ | | 011101 || 11001110 | ||
+ | |- | ||
+ | | 011110 || 11001111 | ||
+ | |- | ||
+ | | 011111 || 11010011 | ||
+ | |} | ||
+ | | | ||
+ | {| class="wikitable" | ||
+ | |-class="hintergrundfarbe6" | ||
+ | ! Daten !! Code | ||
+ | |- | ||
+ | | 100000 || 11010110 | ||
+ | |- | ||
+ | | 100001 || 11010111 | ||
+ | |- | ||
+ | | 100010 || 11011001 | ||
+ | |- | ||
+ | | 100011 || 11011010 | ||
+ | |- | ||
+ | | 100100 || 11011011 | ||
+ | |- | ||
+ | | 100101 || 11011100 | ||
+ | |- | ||
+ | | 100110 || 11011101 | ||
+ | |- | ||
+ | | 100111 || 11011110 | ||
+ | |} | ||
+ | | | ||
+ | {| class="wikitable" | ||
+ | |-class="hintergrundfarbe6" | ||
+ | ! Daten !! Code | ||
+ | |- | ||
+ | | 101000 || 11011111 | ||
+ | |- | ||
+ | | 101001 || 11100101 | ||
+ | |- | ||
+ | | 101010 || 11100110 | ||
+ | |- | ||
+ | | 101011 || 11100111 | ||
+ | |- | ||
+ | | 101100 || 11101001 | ||
+ | |- | ||
+ | | 101101 || 11101010 | ||
+ | |- | ||
+ | | 101110 || 11101011 | ||
+ | |- | ||
+ | | 101111 || 11101100 | ||
+ | |} | ||
+ | | | ||
+ | {| class="wikitable" | ||
+ | |-class="hintergrundfarbe6" | ||
+ | ! Daten !! Code | ||
+ | |- | ||
+ | | 110000 || 11101101 | ||
+ | |- | ||
+ | | 110001 || 11101110 | ||
+ | |- | ||
+ | | 110010 || 11101111 | ||
+ | |- | ||
+ | | 110011 || 11110010 | ||
+ | |- | ||
+ | | 110100 || 11110011 | ||
+ | |- | ||
+ | | 110101 || 11110100 | ||
+ | |- | ||
+ | | 110110 || 11110101 | ||
+ | |- | ||
+ | | 110111 || 11110110 | ||
+ | |} | ||
+ | | | ||
+ | {| class="wikitable" | ||
+ | |-class="hintergrundfarbe6" | ||
+ | ! Daten !! Code | ||
+ | |- | ||
+ | | 111000 || 11110111 | ||
+ | |- | ||
+ | | 111001 || 11111001 | ||
+ | |- | ||
+ | | 111010 || 11111010 | ||
+ | |- | ||
+ | | 111011 || 11111011 | ||
+ | |- | ||
+ | | 111100 || 11111100 | ||
+ | |- | ||
+ | | 111101 || 11111101 | ||
+ | |- | ||
+ | | 111110 || 11111110 | ||
+ | |- | ||
+ | | 111111 || 11111111 | ||
+ | |} | ||
+ | |} | ||
===== Table 2 (Sparse Table) ===== | ===== Table 2 (Sparse Table) ===== |
Revision as of 14:55, 24 May 2021
As found on Wörter Rennen mit System
There are 4 sectors on track 18 in regular format on the disk:
Sector 0, 1, 8 and 11.
The rest of the tracks were written in speed 0. Each of these tracks contain a single additional regular sector header that was written with speed 3.
Contents
Initial code loaded to C64
The first file is linked to t18 s8 that loads auto start code to the C64 from $02d1 to $03cb. Execution entry point is at $0334.
.C:0334 A9 0B LDA #$0B .C:0336 20 B0 03 JSR $03B0 .C:0339 A9 2D LDA #$2D // "-" -> Send Memory Execute at $07b0 to floppy .C:033b 20 A8 FF JSR $FFA8 // Output byte to serial .C:033e A9 45 LDA #$45 // "E" .C:0340 20 A8 FF JSR $FFA8 // Output byte to serial .C:0343 A9 B0 LDA #$B0 // Address $07b0 .C:0345 20 A8 FF JSR $FFA8 // Output byte to serial .C:0348 A9 07 LDA #$07 // .C:034a 20 A8 FF JSR $FFA8 // Output byte to serial .C:034d 20 FE ED JSR $EDFE // Send UNLISTEN .C:0350 A2 FF LDX #$FF .C:0352 AD 00 DD LDA $DD00 .C:0355 A0 10 LDY #$10 .C:0357 CA DEX .C:0358 D0 FD BNE $0357 .C:035a 88 DEY .C:035b D0 FA BNE $0357 .C:035d A9 03 LDA #$03 .C:035f 8D 00 DD STA $DD00 .C:0362 AD 00 DD LDA $DD00 .C:0365 CD 00 DD CMP $DD00 .C:0368 F0 FB BEQ $0365 .C:036a 20 80 03 JSR $0380 .C:036d 85 D1 STA $D1 .C:036f 20 80 03 JSR $0380 .C:0372 85 D2 STA $D2 .C:0374 A0 00 LDY #$00 .C:0376 20 80 03 JSR $0380 .C:0379 91 D1 STA ($D1),Y .C:037b 88 DEY .C:037c D0 F8 BNE $0376 .C:037e F0 EA BEQ $036A .C:0380 78 SEI .C:0381 A9 27 LDA #$27 .C:0383 8D 00 DD STA $DD00 .C:0386 2C 00 DD BIT $DD00 .C:0389 50 FB BVC $0386 .C:038b A9 03 LDA #$03 .C:038d 8D 00 DD STA $DD00 .C:0390 A2 08 LDX #$08 .C:0392 CA DEX .C:0393 D0 FD BNE $0392 .C:0395 A2 04 LDX #$04 .C:0397 AD 00 DD LDA $DD00 .C:039a 0A ASL A .C:039b 08 PHP .C:039c 0A ASL A .C:039d 26 2D ROL $2D .C:039f 28 PLP .C:03a0 26 2D ROL $2D .C:03a2 CA DEX .C:03a3 D0 F2 BNE $0397 .C:03a5 A9 17 LDA #$17 .C:03a7 8D 00 DD STA $DD00 .C:03aa EA NOP .C:03ab EA NOP .C:03ac EA NOP .C:03ad A5 2D LDA $2D .C:03af 60 RTS .C:03b0 8D 11 D0 STA $D011 .C:03b3 A9 08 LDA #$08 .C:03b5 20 0C ED JSR $ED0C .C:03b8 A9 6F LDA #$6F .C:03ba 20 B9 ED JSR $EDB9 .C:03bd A9 4D LDA #$4D .C:03bf 4C A8 FF JMP $FFA8 .C:03c2 4C FE ED JMP $EDFE
Load Translation Table
The floppy has loaded the previous t18 s0 to the buffer at $0700. Aside from the disk title the sector also contains code at $0700 and $07b0.
.8:0700 A5 04 LDA $04 // $04 == #$E0 .8:0702 C9 E2 CMP #$E2 // is it #$E2? .8:0704 F0 27 BEQ $072D // send command find sector .8:0706 20 56 F5 JSR $F556 // wait for sync .8:0709 50 FE BVC $0709 .8:070b B8 CLV .8:070c AD 01 1C LDA $1C01 // check if first byte is #$6A .8:070f C9 6A CMP #$6A .8:0711 D0 F3 BNE $0706 // No? try next Sync .8:0713 A2 64 LDX #$64 // We are at the first data (6A) sector we found after changing to track 2 .8:0715 50 FE BVC $0715 // wait for byte from disk .8:0717 B8 CLV .8:0718 AD 01 1C LDA $1C01 // read byte from disk .8:071b 95 00 STA $00,X // read 156 bytes and put them to $64 to $ff .8:071d E8 INX .8:071e D0 F5 BNE $0715 .8:0720 55 64 EOR $64,X // run EOR checksum over all 156 bytes .8:0722 E8 INX .8:0723 E0 9C CPX #$9C // 156 .8:0725 D0 F9 BNE $0720 .8:0727 EA NOP .8:0728 29 7F AND #$7F // use lower 7 bits of checksum for error code, should be #$39 .8:072a 4C 69 F9 JMP $F969 // error entry disk controller -> user code execution continues in $078d .8:072d 4C CA F6 JMP $F6CA // send command find sector
.. disk title data
.8:07b0 A9 02 LDA #$02 <- The C64 does start execution in the floppy here .8:07b2 8D 78 02 STA $0278 // init some values for user file execute - number of file names .8:07b5 A9 2A LDA #$2A .8:07b7 8D 00 02 STA $0200 .8:07ba A9 01 LDA #$01 .8:07bc 8D 74 02 STA $0274 .8:07bf A9 00 LDA #$00 .8:07c1 85 7E STA $7E // last handled program .8:07c3 4C AB E7 JMP $E7AB // Execute USR file, loads t18 s11 into floppy at $0730 and executes it.
The upper routine loads t18 s11 to the floppy ram starting at $0730 to $07b5. Previously there was unused code space due to disk title space in t18 s0. Execution continues at $0730.
Check Track 3 Header / Load Translation Table / Create Sparse Table
From t18 s11
.8:0730 A2 03 LDX #$03 // Seek to track 3 .8:0732 86 0E STX $0E .8:0734 A9 00 LDA #$00 // Set sector 0 to look for .8:0736 85 0F STA $0F .8:0738 A9 B0 LDA #$B0 // Set new job: find sector header .8:073a 85 04 STA $04 .8:073c A5 04 LDA $04 .8:073e 30 FC BMI $073C // wait for result code .8:0740 C9 01 CMP #$01 // 1? .8:0742 F0 3A BEQ $077E // OK, go on, otherwise lockup loop .8:0744 EE FE 02 INC $02FE // 0 -> 1 .8:0747 AD FE 02 LDA $02FE // Lockup .8:074a D0 FB BNE $0747 // Loop .8:074c A9 B0 LDA #$B0 // not used .8:074e 85 04 STA $04 // not used .8:0750 A5 04 LDA $04 // not used .8:0752 30 FC BMI $0750 // not used .8:0754 C9 01 CMP #$01 // not used .8:0756 F0 26 BEQ $077E // not used .8:0758 CE FE 02 DEC $02FE // not used .8:075b AD FE 02 LDA $02FE // not used .8:075e D0 FB BNE $075B // not used .8:0760 CE FE 02 DEC $02FE // not used .8:0763 AD FE 02 LDA $02FE // not used .8:0766 D0 FB BNE $0763 // not used .8:0768 A9 B0 LDA #$B0 // not used .8:076a 85 04 STA $04 // not used .8:076c A5 04 LDA $04 // not used .8:076e 30 FC BMI $076C // not used .8:0770 C9 01 CMP #$01 // not used .8:0772 F0 0A BEQ $077E // not used .8:0774 EE FE 02 INC $02FE // not used .8:0777 AD FE 02 LDA $02FE // not used .8:077a D0 FB BNE $0777 // not used .8:077c F0 BA BEQ $0738 // not used .8:077e 20 F5 07 JSR $07F5 // check if we are on track 3 .8:0781 A9 22 LDA #$22 // set buffer 4, set track 2 .8:0783 85 0E STA $0E .8:0785 A9 E0 LDA #$E0 // Job: motor on, seek track and execute code at $0700 .8:0787 85 04 STA $04 // The code at $0700 loads the forward translation table to $A4 .8:0789 A5 04 LDA $04 .8:078b 30 FC BMI $0789 // wait for result .8:078d C9 39 CMP #$39 // was checksum result #$39 is good .8:078f D0 9F BNE $0730 // if not, go to track 3 sector header find again .8:0791 C6 31 DEC $31 // $31: #$07 -> #$06 this is our internal sector id for the next sector .8:0793 78 SEI .8:0794 A9 EE LDA #$EE // What does this do? Init PCR? .8:0796 8D 0C 1C STA $1C0C .8:0799 EA NOP .8:079a A2 00 LDX #$00 .8:079c B4 64 LDY $64,X .8:079e 8A TXA .8:079f 99 00 01 STA $0100,Y // [$100 + [$64 + X]] = X .8:07a2 E8 INX // this means, the loaded data at $64 are used as indices to a new sparse table at $0100. .8:07a3 E0 40 CPX #$40 // bytes at these indexed positions are filled counting upwards. See table 1 and table 2. .8:07a5 90 F5 BCC $079C // The counter here that is also written to table 2 is the actual 6 bit byte value .8:07a7 20 00 06 JSR $0600 // We have now our translation table, load first sector (id 6) to $0200 .8:07aa B9 00 02 LDA $0200,Y // copy to $0300 and execute .8:07ad 99 00 03 STA $0300,Y .8:07b0 C8 INY .8:07b1 D0 F7 BNE $07AA .8:07b3 4C 00 03 JMP $0300
.. remaining bytes .. From t18 s0, loads a custom sector header
.8:07c6 20 56 F5 JSR $F556 // wait for sync .8:07c9 50 FE BVC $07C9 // wait for data byte .8:07cb B8 CLV .8:07cc AD 01 1C LDA $1C01 // read data byte .8:07cf C9 73 CMP #$73 // #$73 is the code for a sector header .8:07d1 D0 F3 BNE $07C6 // no? then try again .8:07d3 50 FE BVC $07D3 // wait for data byte .8:07d5 B8 CLV .8:07d6 AD 01 1C LDA $1C01 // read a skip byte .8:07d9 50 FE BVC $07D9 // wait for data byte .8:07db B8 CLV .8:07dc AC 01 1C LDY $1C01 // read data byte .8:07df B9 00 01 LDA $0100,Y // translate to 6 bit byte through lookup table .8:07e2 C5 31 CMP $31 // $31 contains the wanted sector number (first one read is 6) .8:07e4 D0 E0 BNE $07C6 // no? then next sector header .8:07e6 20 03 06 JSR $0603 // Read sector data .8:07e9 E8 INX // with the correct checksum X is #$FF when $0603 returns .8:07ea D0 DA BNE $07C6 // wrong checksum? try read again .8:07ec A5 31 LDA $31 // set next sector id +2 (e.g. 8) .8:07ee 69 02 ADC #$02 .8:07f0 29 0F AND #$0F .8:07f2 85 31 STA $31 .8:07f4 60 RTS .8:07f5 A5 22 LDA $22 // current track .8:07f7 C9 03 CMP #$03 // are we on 3? .8:07f9 D0 94 BNE $078F // repeat, set track 3, find header .8:07fb 09 20 ORA #$20 // .8:07fd 85 22 STA $22 // #$23 -> $22 .8:07ff 60 RTS
Sector id translation: Mark for header is after snyc #$73, then a skip byte follow, typically #$4d, then the header byte follows:
#$4A -> $31 = 0x00 #$4B -> $31 = 0x01 #$4D -> $31 = 0x02 #$4E -> $31 = 0x03 #$52 -> $31 = 0x04 #$53 -> $31 = 0x05 #$55 -> $31 = 0x06 #$56 -> $31 = 0x07 #$57 -> $31 = 0x08 #$59 -> $31 = 0x09 #$5A -> $31 = 0x0A #$5B -> $31 = 0x0B #$5D -> $31 = 0x0C #$5E -> $31 = 0x0D #$65 -> $31 = 0x0E #$66 -> $31 = 0x0F
As one sees the same lookup is used as installed through table 1 in table 2.
Table 1 (Translation Table)
With the routine at $079a this table is translated to $0100 such that #$00 -> $014a, #$01 -> $014b, #$02 -> 014d a.s.o. The background is: The floppy can not store native bytes with more than two zeros in a row. The following table translates 6 bit wide numbers from #$00 to #$3f to native bytes in the floppy sector ($64 to $a3).
With the transfer to $0100 the new table at $0100 can be used as lookup to translate the native floppy bytes to 6 bit wide bytes. Such that [$0100 + native_floppy_byte] == translated_byte, where translated_byte is a 6 bit wide value from $00 to $3f.
>8:0064 4a 4b 4d 4e 52 53 55 56 JKMNRSUV >8:006c 57 59 5a 5b 5d 5e 65 66 WYZ[]^ef >8:0074 67 69 6a 6b 6d 6e 72 73 gijkmnrs >8:007c 75 76 77 79 7a 7b 7d 7e uvwyz{}~ >8:0084 95 96 97 9a 9b 9d 9e a5 ........ >8:008c a6 a7 a9 aa ab ad ae b2 ........ >8:0094 b3 b5 b6 b7 b9 ba bb bd ........ >8:009c be ca cb cd ce d2 d3 d5 ........ >8:00a4 57 4a 4a 4a 76 4b 52 4b WJJJvKRK >8:00ac 7b 76 4d 56 7a 4a 4a 4a {vMVzJJJ >8:00b4 4a 75 4e 56 4d 4d 55 4e JuNVMMUN >8:00bc 4e 56 7b 4d 77 77 4d 4a NV{MwwMJ >8:00c4 4a 53 55 53 4e 53 75 55 JSUSNSuU >8:00cc 7d 7b 56 76 4e 7b 52 4d }{VvN{RM >8:00d4 56 53 4d 4a 4e 4e 4a 75 VSMJNNJu >8:00dc 4e 76 77 75 75 4e 77 4a NvwuuNwJ >8:00e4 55 52 4d 4b 4d 53 7a 7a URMKMSzz >8:00ec 4b 4b 7e 4e 52 4b 55 4e KK~NRKUN >8:00f4 52 4d 4d 4a 52 79 4a 4d RMMJRyJM >8:00fc 4a 4d 4e 53 00 c9 00 00 JMNS....
|
|
|
|
|
|
|
|
Table 2 (Sparse Table)
sparse table for translating native_floppy_bytes to translated bytes, [$0100 + native_floppy_byte] == translated_byte
>8:0100 00 c9 00 00 00 00 00 00 ........ >8:0108 00 00 00 00 00 00 00 00 ........ >8:0110 00 00 00 00 00 00 00 00 ........ >8:0118 00 00 00 00 00 00 00 00 ........ >8:0120 00 00 00 00 63 f9 3a f5 ....c.:. >8:0128 10 63 7e fe 00 00 02 20 .c~.... >8:0130 7e fe 31 d1 31 d1 ba f4 ~.1.1... >8:0138 07 e0 77 f9 7e fe 00 03 ..w.~... >8:0140 e0 a1 89 07 fe eb 00 00 ........ >8:0148 00 00 00 01 00 02 03 00 ........ >8:0150 00 00 04 05 00 06 07 08 ........ >8:0158 00 09 0a 0b 00 0c 0d 00 ........ >8:0160 00 00 00 00 00 0e 0f 10 ........ >8:0168 00 11 12 13 00 14 15 00 ........ >8:0170 00 00 16 17 00 18 19 1a ........ >8:0178 00 1b 1c 1d 00 1e 1f 00 ........ >8:0180 00 00 00 00 00 00 00 00 ........ >8:0188 00 00 00 00 00 00 00 00 ........ >8:0190 00 00 00 00 00 20 21 22 ..... !" >8:0198 00 00 23 24 00 25 26 00 ..#$.%&. >8:01a0 00 00 00 00 00 27 28 29 .....'() >8:01a8 00 2a 2b 2c 00 2d 2e 00 .*+,.-.. >8:01b0 00 00 2f 30 00 31 32 33 ../0.123 >8:01b8 00 34 35 36 2f 37 38 9e .456/78. >8:01c0 fd e7 4e 52 9d a9 f9 52 ..NR...R >8:01c8 54 9d 39 3a 52 3b 3c a9 T.9:R;<. >8:01d0 f9 4b 3d 3e a9 3f 4b 54 .K=>.?KT >8:01d8 9d a9 f9 4a 54 9d a9 f9 ...JT... >8:01e0 4a 54 bc 9f 27 c9 4a 7a JT..'.Jz >8:01e8 ae d7 4f d3 9d a9 7a b5 ..O...z. >8:01f0 54 9d a9 7a b5 54 96 9b T..z.T.. >8:01f8 29 ef 5b 6d 95 29 5a d2 ).[m.)Z.
Load Custom Sector
Code at $0603 loads a custom format sector to $0200
.8:0600 4C C6 07 JMP $07C6 // this part loads a data sector .8:0603 20 56 F5 JSR $F556 //wait for sync // - load data from disk and decode .8:0606 50 FE BVC $0606 .8:0608 AD 01 1C LDA $1C01 // read data byte .8:060b B8 CLV .8:060c C9 6A CMP #$6A // #$6A is the code for a data sector .8:060e D0 F3 BNE $0603 .8:0610 98 TYA // Y is returned 0 from wait for sync .8:0611 AA TAX // now all registers are zeroed .8:0612 50 FE BVC $0612 .8:0614 B8 CLV .8:0615 AC 01 1C LDY $1C01 // Read 256 bytes to $0200 .8:0618 59 00 01 EOR $0100,Y // translate from table, data sector gets EORed .8:061b 9D 00 02 STA $0200,X // .8:061e E8 INX .8:061f D0 F1 BNE $0612 // loop .8:0621 A2 55 LDX #$55 // Read 85 bytes more and put from $F9 to $A4 .8:0623 50 FE BVC $0623 .8:0625 B8 CLV .8:0626 AC 01 1C LDY $1C01 .8:0629 59 00 01 EOR $0100,Y // translate from table .8:062c 95 A4 STA $A4,X .8:062e CA DEX .8:062f 10 F2 BPL $0623 .8:0631 50 FE BVC $0631 .8:0633 B8 CLV .8:0634 AC 01 1C LDY $1C01 // Read byte 86. .8:0637 59 00 01 EOR $0100,Y // translate from table .8:063a AA TAX // if checksum is correct, then A should be 0 here, A -> X
Translate 6-bit to 8-bit
The following loop takes #$55 bytes with 6 bit values from $A4 - $FF and add two bits each to bytes in groups of 3 at $0200. Y counts 1 each from the part at $A4 (downwards)
X counts 3 each for the part at $0200 (upwards)
.8:063b A0 55 LDY #$55 // 85 .8:063d B9 A4 00 LDA $00A4,Y // get lower bits from $F9 to $A4, e.g. pattern --543210 .8:0640 4A LSR A // pattern 0 -> Carry .8:0641 3E 02 02 ROL $0202,X // [$0200 + 3 * X + 2] -bbbbbb0 .8:0644 4A LSR A // next bit to carry .8:0645 3E 02 02 ROL $0202,X // [$0200 + 3 * X + 2] bbbbbb01 .8:0648 4A LSR A // .8:0649 3E 01 02 ROL $0201,X // .8:064c 4A LSR A // .8:064d 3E 01 02 ROL $0201,X // [$0200 + 3 * X + 1] bbbbbb23 .8:0650 4A LSR A // .8:0651 3E 00 02 ROL $0200,X .8:0654 4A LSR A .8:0655 3E 00 02 ROL $0200,X [$0200 + 3 * X + 0] bbbbbb45 .8:0658 E8 INX // step 3 bytes .8:0659 E8 INX .8:065a E8 INX .8:065b 88 DEY // do that 0x55 times (0x55 * 3 = 0xFF) == 0x2FF .8:065c D0 DF BNE $063D .8:065e A5 A4 LDA $A4 // lowest two bit from start $A4 to 0x2FF .8:0660 4A LSR A .8:0661 2E FF 02 ROL $02FF .8:0664 4A LSR A .8:0665 2E FF 02 ROL $02FF .8:0668 18 CLC // If checksum at $063a was correct then X is here 3 * 0x55 = 0xFF .8:0669 60 RTS .8:066a 55 00 EOR $00,X
The code at $0300 gets loaded from custom sector id 6 and loads remaining code for the 'second stage loader'. At the start the next sector to load is id 8.
.8:0300 A2 FF LDX #$FF // reset stack .8:0302 9A TXS .8:0303 20 00 06 JSR $0600 // load sector id 8 and move to $0400 .8:0306 A2 00 LDX #$00 .8:0308 BD 00 02 LDA $0200,X .8:030b 9D 00 04 STA $0400,X .8:030e E8 INX .8:030f D0 F7 BNE $0308 .8:0311 20 00 06 JSR $0600 // load sector id a and move to $0500 .8:0314 A2 00 LDX #$00 .8:0316 BD 00 02 LDA $0200,X .8:0319 9D 00 05 STA $0500,X .8:031c E8 INX .8:031d D0 F7 BNE $0316 .8:031f E6 31 INC $31 .8:0321 E6 31 INC $31 .8:0323 20 00 06 JSR $0600 // load sector id e and move to $0700 .8:0326 A2 00 LDX #$00 .8:0328 BD 00 02 LDA $0200,X .8:032b 9D 00 07 STA $0700,X .8:032e E8 INX .8:032f E0 98 CPX #$98 .8:0331 90 F5 BCC $0328 .8:0333 20 00 06 JSR $0600 // load sector id 0 to $0200 .8:0336 A2 00 LDX #$00 .8:0338 4C 00 07 JMP $0700 // start second stage
Example Sectors
Sectors decoded with g64conv mode 5.
Sector with Translation Table
Sector loaded for the forward translation table. Routine at $0700:
Header sector 5 (not evaluated):
sync 64 ; Following raw bytes: 73 4d 53 56 55 55 55 55 55 55 55 55 52 bf ; Following raw bits: 111
Data:
sync 23 ; Following raw bytes: 6a 4a 4b 4d 4e 52 53 55 56 57 59 5a 5b 5d 5e 65 66 67 69 6a 6b 6d 6e 72 73 75 76 77 79 7a 7b 7d 7e 95 96 97 9a 9b 9d 9e a5 a6 a7 a9 aa ab ad ae b2 b3 b5 b6 b7 b9 ba bb bd be ca cb cd ce d2 d3 d5 57 4a 4a 4a 76 4b 52 4b 7b 76 4d 56 7a 4a 4a 4a 4a 75 4e 56 4d 4d 55 4e 4e 56 7b 4d 77 77 4d 4a 4a 53 55 53 4e 53 75 55 7d 7b 56 76 4e 7b 52 4d 56 53 4d 4a 4e 4e 4a 75 4e 76 77 75 75 4e 77 4a 55 52 4d 4b 4d 53 7a 7a 4b 4b 7e 4e 52 4b 55 4e 52 4d 4d 4a 52 79 4a 4d 4a 4d 4e 53 4b 53 76 4a 7b 52 53 4b 7b 76 4a 53 56 4e 4e 53 7d 4a 4a 4a 57 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 6e 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 53 69 ad b2 b7 b3 ce 77 72 b7 9a b2 66 75 76 4e 95 a6 7d 7b 5e d2 57 6e 6e 95 b5 be 79 4b 6d 5a 6a d3 59 67 59 95 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4d 55 55 55 55 55 55 55 55 55 55 55 55 5f ; Following raw bits: 1111
Sector with Code
Sector 6, contains the routine loaded to $0300 in the floppy. Routine is called at $07a7
sync 64 ; Following raw bytes: 73 4d 55 57 55 55 55 55 55 55 55 56 52 bf ; Following raw bits: 111
sync 23 ; Following raw bytes: 6a a6 73 76 ae 57 4b a7 a6 b2 b2 4a a5 a5 4b cd 65 59 ba 57 4b a7 a6 b2 b2 4a a5 a5 4b cd 65 59 52 ba ba ba 52 57 4b a7 a6 b2 b2 4a a5 a5 4b cd 4d 7d 4d 76 ba 57 4b a7 a6 6b 6b 4b 4b 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 7b 7a 6b 6d 55 5d 59 5e 67 be 72 ae 7b 5e 67 a6 b6 4e 69 7a 5d 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4a 4b 4a aa aa aa aa aa aa aa aa aa aa aa bf ; Following raw bits: 111