The Acorn DFS Osword commands - by - Gordon Horsington ---------------------------------------------------------- Module 3. Formatting single density discs ----------------------------------------- +----------------------------------------------------------+ | All the DFS modules in this series use programs which | | experiment with the format and contents of discs. These | | experiments may have disasterous effects if you use any | | of the programs on discs which store programs or data | | which you cannot afford to lose. You should first try | | out the programs using discs that have either been | | duplicated or, better still, have not been used at all. | +----------------------------------------------------------+ Writing your own disc formatting program can be quite a useful exercise because it will give you the opportunity to optimise the speed at which data can be written to and read from a disc. You might think that all disc formatting programs are the same but, if you do, then you are quite wrong. The time taken to write to and read from a disc is affected by the settings on the keyboard DIL switches and the logical sector offsets created during formatting. If you have a DIL switch block on your keyboard you might like to experiment with the settings to increase the performance of your disc drives. Figure 1 shows the effect of switching links 3 and 4 on the keyboard DIL switch block, but do remember that some disc drive manuals specify the settings to be used and these should not be altered. If you do not have a switch block fitted on you keyboard the effect of using these switches can be simulated using Osbyte &FF. Osbyte &FF takes effect after a soft Break and remains active until a hard Break. All but the slowest disc drives can be operated with link 3 open (off) and link 4 closed (on) and many modern disc drives can be used with both links 3 and 4 closed (on). If the settings for links 3 and 4 have not been specified for your disc drive you should experiment and use the fastest reliable speed. +---+---+-----------+-------------+-----------+---------------+---------+ | 3 | 4 | Step time | Settle time | Load time | Osbyte &FF | Speed | +---+---+-----------+-------------+-----------+---------------+---------+ |on |on | 4 | 16 | 0 | *FX 255,0,207 | Fastest | |on |off| 6 | 16 | 0 | *FX 255,0,223 | Faster | |off|on | 6 | 50 | 32 | *FX 255,0,239 | Fast | |off|off| 24 | 20 | 64 | *FX 255,0,255 | Slow | +---+---+-----------+-------------+-----------+---------------+---------+ Figure 1. The effect of keyboard switches 3 and 4 on disc access times ---------------------------------------------------------------------- The Acorn DFS uses discs with either 40 or 80 tracks and with 10 sectors of 256 bytes per track. The physical and logical track numbers must be the same so that, for example, the ten ID fields on track &01 must all use logical track number &01. The 10 sectors on each track must use the logical sector numbers &00 to &09 but the logical and physical sector numbers do not have to be the same. Logical sectors &00 and &01 on physical track &00 store the disc catalogue. The catalogue uses the structure shown in figure 2 and an empty catalogue must be created by the disc formatting program. Sector &00 Track &00 -------------------- &00 - &07 First 8 bytes of the 12 byte disc title. &08 - &0E First file name. &0F Directory of first file name. &10 - &16 Second file name. &17 Directory of second file name. &18 - &FF and so on for the 31 files. Sector &01 Track &00 -------------------- &00 - &03 Last 4 bytes of the 12 byte disc title. &04 Disc cycles (BCD number 0-99). &05 8 * (Number of catalogue entries). &06 (bits 0 and 1) Most significant two bits of the number of sectors on the disc. (bits 4 and 5) The boot up option set using *OPT4,n. &07 The least significant 8 bits of the (10 bit) number of sectors on the disc. The most significant bits are in bits 0 and 1 of byte &06. &08 - &09 Load address of first file, least significant 16 bits. &0A - &0B Execution address of first file, least significant 16 bits. &0C - &0D Length of first file, least significant 16 bits. &0E (bits 0 and 1) Startsector of first file, most sig. 2 bits. (bits 2 and 3) Load address of first file, most sig. 2 bits. (bits 4 and 5) Length of first file, most sig. 2 bits. (bits 6 and 7) Execution address of first file, most sig. bits. &0F Start sector of first file, least significant 8 bits. &10 - &FF Load address, execution address, file length, and sector number for every other file on the disc (8 bytes per file). This is the information given by the *INFO call. Figure 2. The structure of the DFS catalogue -------------------------------------------- Although there is a lot of information stored in a disc catalogue nearly all this information is written by the DFS when the disc is being used. An Acorn single density formatting program must fill the catalogue with null bytes (&00) with the exception of bytes &06 and &07 of sector &01. These bytes must store the number of sectors made available on the disc by the formatting program. When a single density formatter is used with an eighty track disc drive it will create &320 sectors on a disc. Bits 0 and 1 of byte &06 on logical sector &01 must store the number &03 (%11), and byte &07 of logical sector &01 must store the number &20. When the program is used with a fourty track disc drive it will create &190 sectors. Bits 0 and 1 of byte &06 on logical sector &01 must then store the number &01 (%01), and byte &07 of logical sector &01 must store the number &90. Figure 3 shows a part of a sector dump made with a newly formatted eighty track disc. The only information stored in the empty catalogue is the number of available sectors on the disc. Track: 00 Logical Sector: 00 0 1 2 3 4 5 6 7 00 0 0 0 0 0 0 0 0 ........ 08 0 0 0 0 0 0 0 0 ........ 10 0 0 0 0 0 0 0 0 ........ 18 0 0 0 0 0 0 0 0 ........ 20 ... Track: 00 Logical Sector: 01 0 1 2 3 4 5 6 7 00 0 0 0 0 0 0 3 20 ....... 08 0 0 0 0 0 0 0 0 ........ 10 0 0 0 0 0 0 0 0 ........ 18 0 0 0 0 0 0 0 0 ........ 20 ... Figure 3. Part of the catalogue of a newly formatted 80 track disc ------------------------------------------------------------------ The most efficient operation of an Acorn single density disc occurs if physical sector &00 does not store logical sector &00 on every track. The optimum distribution of logical sectors with respect to physical sectors for most disc drives is shown in figure 4. Figure 4 shows that, on track &00, the physical and logical sector numbers are the same. On track &01, physical sector &00 stores logical sector &07, physical sector &01 stores logical sector &08, and so on. This is known as a logical sector offset. Physical sector numbers | 00 01 02 03 04 05 06 07 08 09 ---+------------------------------ T 00 | 00 01 02 03 04 05 06 07 08 09 r 01 | 07 08 09 00 01 02 03 04 05 06 Logical a 02 | 04 05 06 07 08 09 00 01 02 03 sector c 03 | 01 02 03 04 05 06 07 08 09 00 numbers k 04 | 08 09 00 01 02 03 04 05 06 07 s 05 | 05 06 ... Figure 4. The logical sectors numbers for optimum speed ------------------------------------------------------- The logical sector numbers are offset because the disc drive head takes a predictable amount of time to step from one track to the next when writing to or reading from a disc. Consider what will happen if you use the *LOAD command to read a file which is stored in 10 sectors starting with sector &02 on track &00. This hypothetical file will be stored on logical sectors &02 to &09 on track &00, and on logical sectors &00 and &01 on track &01. The sectors on track &00 will be loaded from sector &02 to sector &09 and then the head will step in to track &01. This step will take a predictable amount of time which is long enough for most disc drives to miss logical sector &00 if it is stored on physical sector &00. The disc would then have to make a complete revolution before sector &00 reappears. Using the offset illustrated in figure 4 would ensure that, for most disc drives, sector &00 on track &01 would become immeadiatly available as the head steps in from track &00 to &01. All the tracks in figure 4 use the same sector offset with respect to each other to give an optimum distribution of logical sectors. Not all disc drives take the same amount of time to step the head from one track to another and for this reason the amount of offset used to produce an optimally formated disc will vary from one disc drive to another. The distribution of logical sectors shown in figure 4 uses an offset of 3 sectors. That is, sector &00 is offset 3 sectors with respect to sector &09 on the preceding track. A modern fast disc drive might only require an offset of 2 sectors so that the physical logical sector &00 on track &01 will be logical sector &08. An old disc drive liberated from the local junk shop might require an offset of 4 or even 5 sectors. The program OFFSET can be used to experiment with the amount of offset given to the logical sector numbers. It can format both 40 and 80 track discs with any offset from 0 to 9 sectors. To find the amount of offset needed with a particular disc drive you should create a set of 10 discs with the offset varying from 0 to 9 sectors. Each disc should be used to measure the time taken to store a very large file a large number of times within a program loop. It is a good idea to store the same large file 20 or 30 times and to use a stop watch rather than the computer to measure the time taken. If you start with an offset of 9 sectors and work down to zero offset you should find that the time decreases with each disc until, with one disc, there is an increase in the time taken to store the files. If, for example, the increase is with a disc using an offset of 2 sectors then an optimum offset of 3 sectors is needed for your disc drive. Most disc drives need an offset of 3 sectors. 10 REM: OFFSET 20 DIM mcode &400 30 oswrch=&FFEE 40 osnewl=&FFE7 50 osword=&FFF1 60 osbyte=&FFF4 70 FORpass=0 TO 2 STEP 2 80 P%=mcode 90 [ OPT pass 100 JSR osnewl 110 .loop 120 LDA &FF \ poll escape flag 130 BPL noescape \ bit 7 set if Escape pressed 140 .escape 150 LDA #&7E 160 JSR osbyte \ acknowledge Escape 170 BRK 180 BRK 190 EQUS "Escape" 200 BRK 210 .noescape 220 LDA track \ load physical track number 230 STA block+7 \ store physical track number 240 BEQ endoffset \ don't offset track zero 250 LDX #36 \ logical track index 260 LDY #38 \ logical sector index 270 .inloop 280 LDA track \ load physical track number 290 STA table,X \ store logical track number 300 LDA shear \ load logical sector offset 310 BEQ zero \ branch if no offset 320 STA temp \ temporary store 330 .offsetloop 340 SEC 350 LDA table,Y \ load logical sector number 360 SBC #1 \ subtract 1 370 BPL positive 380 LDA #9 390 .positive 400 STA table,Y \ store logical sector number - 1 410 DEC temp \ decrement sector offset 420 BNE offsetloop \ offset again 430 .zero 440 DEX 450 DEX 460 TXA 470 TAY \ subtract 4 from Y register 480 DEX 490 DEX \ subtract 4 from X register 500 BPL inloop \ branch if less than 10 sectors 510 .endoffset 520 LDA #&7F 530 LDX #block MOD 256 540 LDY #block DIV 256 550 JSR osword \ format track 560 LDA block+12 \ load result byte 570 BNE error \ format OK if result = 0 580 JSR printtrack \ print track number 590 INC track \ increment track number 600 LDA track \ load track number 610 CMP finish \ is that the last track? 620 BCC loop \ branch if more tracks to format 630 LDA #&7F 640 LDX #catblock MOD 256 650 LDY #catblock DIV 256 660 JSR osword \ store empty catalogue 670 LDA catblock+10 \ check result byte 680 BNE error \ branch if not saved 690 RTS \ return to BASIC 700 .error 710 BRK 720 BRK 730 EQUS "Format error" 740 BRK 750 .printtrack 760 LDA track \ load track number 770 LSR A 780 LSR A 790 LSR A 800 LSR A \ isolate MS nybble 810 JSR nybble \ print MS nybble 820 LDA track \ load track number 830 JSR nybble \ print LS nybble 840 LDA #ASC(" ") 850 JSR oswrch \ print space 860 JMP oswrch \ print space 870 .nybble 880 AND #&0F 890 SED 900 CLC 910 ADC #&90 920 ADC #&40 930 CLD 940 JMP oswrch \ print nybble and return 950 .block 960 EQUB &00 \ drive number 0-3 970 EQUD table \ sector table 980 EQUB &05 \ 5 parameters 990 EQUB &63 \ format track 1000 EQUB &00 \ physical track number 0-79 1010 EQUB &15 \ gap 3 1020 EQUB &2A \ 10 sectors of 256 bytes 1030 EQUB &00 \ gap 5 1040 EQUB &10 \ gap 1 1050 EQUB &00 \ result byte 1060 .table 1070 EQUD &01000000 1080 EQUD &01010000 1090 EQUD &01020000 1100 EQUD &01030000 1110 EQUD &01040000 1120 EQUD &01050000 1130 EQUD &01060000 1140 EQUD &01070000 1150 EQUD &01080000 1160 EQUD &01090000 1170 .catalogue 1180 OPT FNfill(262) 1190 \ store 262 zeros 1200 .sectors 1210 EQUW &2003 \ &320 sectors (80 tracks) 1220 OPT FNfill(248) 1230 \ store 248 zeros 1240 .catblock 1250 EQUB &00 \ drive number 0 - 3 1260 EQUD catalogue \ address of buffer 1270 EQUB &03 \ number of parameters 1280 EQUB &4B \ write data multi-sector 1290 EQUB &00 \ logical track 1300 EQUB &00 \ start logical sector 1310 EQUB &22 \ 2 sectors of 256 bytes 1320 EQUB &00 \ result byte 1330 .track 1340 EQUB &00 \ physical track number 1350 .finish 1360 EQUB &00 \ number of tracks 1370 .shear 1380 EQUB &00 \ sector offset 1390 .temp 1400 EQUB &00 \ sector offset 1410 ] 1420 NEXT 1430 REPEAT 1440 INPUT"Drive number (0-3) "D% 1450 UNTIL D%>-1 AND D%<4 1460 ?block=D% 1470 ?catblock=D% 1480 REPEAT 1490 INPUT"Number of tracks (40/80) "T% 1500 UNTIL T%=40 OR T%=80 1510 ?finish=T% 1520 IF T%=40 THEN ?sectors=&01 : sectors?1=&90 1530 REPEAT 1540 INPUT"Logical sector offset (0-9) "L% 1550 UNTIL L%>-1 AND L%<10 1560 ?shear=L% 1570 INPUT"Ready to format? (Y/N) "yes$ 1580 IF LEFT$(yes$,1)="Y" THEN CALL mcode 1590 INPUT'"Another disc? (Y/N) "yes$ 1600 IF LEFT$(yes$,1)="Y" THEN RUN 1610 END 1620 DEF FNfill(size) 1630 FOR count = 1 TO size 1640 ?P%=0 1650 P%=P%+1 1660 NEXT 1670 =pass The logical sector offsets produced by the program OFFSET can be demonstrated by using the program IDSDUMP introduced in module 0. The formatted discs it produces can be verified using any DFS verification program including the program VERIFY, also intorduced in module 0.