The Acorn DFS Osword commands - by - Gordon Horsington ---------------------------------------------------------- Module 5. Creating discs compatible with both 40 and 80 track drives -------------------------------------------------------------------- +----------------------------------------------------------+ | 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. | +----------------------------------------------------------+ In this module I will examine the problem of modifying eighty track discs so that they work properly on both forty and eighty track disc drives. I will demonstrate how this can be done on an unswitched eighty track disc drive using an Osword &7F based program and a disc formatting program. I will then describe how the same dual format disc can be created with only a disc formatting program if a 40/80 track switchable disc drive is available. Forty track discs have a track density exactly one half of that used by eighty track discs. Track &00 of both forty and eighty track discs share the same physical position as the outer track on the disc. Track &01 on a forty track disc is in the same physical position as track &02 on an eighty track disc, track &02 is in the same position as track &04, and so on. The relative position of the physical tracks on forty and eighty track discs is shown in figure 1. 40T> 00 01 ... 09 0A 0B ... 13 14 15 ... 25 26 27 80T> 00 01 02 ... 12 13 14 15 16 ... 26 27 28 29 2A ... 4A 4B 4C 4D 4E 4F Figure 1. The relative position of tracks on 40 and 80 track discs ------------------------------------------------------------------ All the numbers in figures 1 and 2 are in hexadecimal and I have used the term track density refers to the physical proximity of the tracks (which are closer together on 80 track discs). Because the track density of an eighty track disc is twice that of a forty track disc, an eighty track disc is sometimes refered to as double density even if it uses a single density format. I will not refer to 80 track discs as double density because this can be confused with the double density ADFS, which can use 80 track discs in a double density format. Figure 2 illustrates one method of formatting a single density disc so that the same disc can be used with either a forty or an eighty track disc drive. 00 01 02 ... 12 13 14 15 16 ... 26 27 14 15 16 ... 25 26 27 | \-------------/ \----------------/ \-------------------------------/ | &01-&13 unused &14-&27 &14-&27 | 80 track density 80 track density 40 track density | Track &00, common to both track densities Figure 2. The format for 40/80 track discs ------------------------------------------ The disc can be divided into four regions. 1) Track &00, which is common to both forty and eighty track densities. 2) Tracks &01 to &13 (1 to 19 decimal) in eighty track density are unused. 3) Tracks &14 to &27 (20 to 39 decimal) used in eighty track density. 4) Tracks &14 to &27 (20 to 39 decimal) used in forty track density. The data stored on this type of dual format disc are stored on track &00 and tracks &14 to &27. The data on tracks &14 to &27 are stored twice, once in forty track density and once in eighty track density. Sectors &00 and &01 of track &00 are used to store the catalogue for the disc. The remaining sectors on track &00 give a total of 2k available for data. Tracks &14 to &27 have 50k available for data. This dual format disc makes 52k available for programs and data. This type of disc can be created on an eighty track disc drive by using a forty track disc formatting program to format the first forty tracks on a disc in an eighty track disc drive. You can use the program OFFSET introduced in module 3 if you want to optimise the logical sector offset. Store a 2k (&800 bytes) dummy !BOOT file to fill track &00 and a large (47.5k), locked dummy file to fill tracks &01 to &13. These files can be created with the following commands: *SAVE :0.$.!BOOT 1900+400 *SAVE :0.D.DUMMY 1900+BE00 *ACCESS :0.D.DUMMY L Up to 50k of data can then be stored on tracks &14 to &27 using the DFS star commands. Do not use the filenames $.!BOOT or D.DUMMY. When all the data, except the real !BOOT file, are stored on the disc then the dummy !BOOT file can be deleted and the real !BOOT file (which must not be longer than 2k) can be stored. Do not delete the dummy file D.DUMMY because this file is making sure that tracks &01 to &13 inclusive remain unused (see figure 2). When all the programs and data have been copied onto the disc then logical tracks &14 to &27 should be copied from the eighty track density physical tracks to the forty track density physical tracks. Physical track &14 (eighty track density) will be copied onto physical track &28 (eighty track density), physical track &15 will be copied onto physical track &2A and so on as shown in figure 3. Read physical track -> Format and write physical track &14 -> &28 &15 -> &2A &16 -> &2C &17 -> &2E . . . &25 -> &4B &26 -> &4C &27 -> &4E Figure 3. The required copying of physical tracks ------------------------------------------------- This copying will produce the format shown in figure 2. The following algorithm can be used to implement this idea using a disc which has had the first forty tracks formatted in an eighty track disc drive. It is important to format only the first forty tracks so that the DFS recognises the disc as a forty track disc even though it is used in an eighty track disc drive. Use *FORMAT 40 0 (or whatever is appropriate with your system). Do not use *FORMAT 80 0 and press Escape after forty tracks have been formatted because, if you do, the DFS will still recognise the disc as an eighty track disc even though only the first forty tracks have been formatted. 1) Start with physical track number &14 (decimal 20). 2) Read the sector IDs on the current physical track. These will be used to create the sector data for formatting the forty track copy. 3) Read all the data on the current track into a buffer. 4) Seek the current physical track * 2. This will be where the forty track copy will be written. 5) Write the physical track number (&14-&27) into the track register (number &12). This will allow the eighty track disc drive to write the data onto a track in the position it would use on a forty track disc drive. 6) Format the track found in step 4) using the sector data from step 2). 7) Write the contents of the buffer onto the newly formatted track. 8) Write the physical track number * 2 (&28-&4E) into the track register (number &12). This takes the disc controller back to the eighty track status. 9) Increment the track number. If it is less than &28 (decimal 40) then go back to 2) to duplicate the next track. This algorithm has been implemented in the program DUALDFS. You must use the program DUALDFS with an eighty track disc drive (drive &00) to convert a disc formatted as described above into a 40/80 track disc. The program will not work with copy-protected discs and you should only use it after you have made a backup copy of all the files on the disc you intend to convert. If you use DUALDFS and press the Escape key before it has finished the conversion you will only be able to use the disc on an eighty track disc drive. Do not attempt to use the program to make the conversion using a forty track disc drive. You have been warned to be careful with all the programs used to illustrate this series. Whatever modifications you make to this or any other of the programs used to ilustrate the DFS modules of the series, don't ignore the warning about the potentially disasterous effects these programs can have on your discs. After using DUALDFS to create a dual format disc you must not use the command *COMPACT with the disc. It is a good idea stick a write-protect tab on all dual format discs. 10 REM: DUALDFS 20 osnewl=&FFE7 30 oswrch=&FFEE 40 osword=&FFF1 50 osbyte=&FFF4 60 DIM table &50 70 DIM mcode &500 80 DIM buffer &1000 90 FOR pass=0 TO 2 STEP 2 100 P%=mcode 110 [ OPT pass 120 JSR osnewl 130 .mainloop 140 JSR escape \ check escape flag 150 JSR sectorids \ read all sector ids 160 JSR read \ read all sectors 170 JSR seektwo \ seek source track * 2 180 LDA track \ source track number 190 JSR register \ write track register 200 JSR format \ format 2 * source track 210 JSR write \ write all sectors 220 LDA track \ load source track 230 ASL A \ *2 = physical track number 240 JSR register \ write track register 250 JSR printbyte \ print track number 260 INC track \ increment source track number 270 LDA track \ load source track number 280 CMP #40 \ all done? 290 BNE mainloop \ if not read next track 300 JSR osnewl 310 RTS \ return to BASIC 320 .escape 330 LDA &FF \ escape flag 340 BMI pressed \ bit 7 set if pressed 350 RTS 360 .pressed 370 LDA #&7E 380 JSR osbyte \ acknowledge Escape 390 BRK 400 BRK 410 EQUS "Escape" 420 BRK 430 .seektwo 440 LDA track \ source track number 450 ASL A \ *2 460 STA seekblock+7 \ physical track number 470 LDA #&7F 480 LDX #seekblock MOD 256 490 LDY #seekblock DIV 256 500 JSR osword 510 LDA seekblock+8 \ result 520 BNE seekerror \ = 0 if OK 530 RTS 540 .seekerror 550 BRK 560 BRK 570 EQUS "Seek error" 580 BRK 590 .format 600 LDA track \ source track number 610 STA formblock+7 \ store physical track 620 JSR register \ write track register 630 LDA #&7F 640 LDX #formblock MOD 256 650 LDY #formblock DIV 256 660 JSR osword 670 LDA formblock+12 \ result 680 BNE formerror \ = 0 if OK 690 RTS 700 .formerror 710 BRK 720 BRK 730 EQUS "Format error" 740 BRK 750 .register 760 STA regblock+8 \ value to put in register 770 LDA #&7F 780 LDX #regblock MOD 256 790 LDY #regblock DIV 256 800 JSR osword 810 LDA regblock+9 \ result 820 BNE regerror \ = 0 if OK 830 RTS 840 .regerror 850 BRK 860 BRK 870 EQUS "Special register error" 880 BRK 890 .sectorids 900 LDA track \ source track number 910 STA idsblock+7 \ store physical track 920 LDA #&7F 930 LDX #idsblock MOD 256 940 LDY #idsblock DIV 256 950 JSR osword 960 LDA idsblock+10 \ result 970 BNE idserror \ = 0 if OK 980 RTS 990 .idserror 1000 BRK 1010 BRK 1020 EQUS "Sector ID Error" 1030 BRK 1040 .read 1050 LDA track \ source track number 1060 STA copyblock+7 \ logical track number 1070 LDA #&53 \ read data multi-sector 1080 STA copyblock+6 1090 LDA #&7F 1100 LDX #copyblock MOD 256 1110 LDY #copyblock DIV 256 1120 JSR osword 1130 LDA copyblock+10 1140 BNE readerror 1150 RTS 1160 .readerror 1170 BRK 1180 BRK 1190 EQUS "Read error" 1200 BRK 1210 .write 1220 LDA #&4B \ write data multi-sector 1230 STA copyblock+6 1240 LDA #&7F 1250 LDX #copyblock MOD 256 1260 LDY #copyblock DIV 256 1270 JSR osword 1280 LDA copyblock+10 \ result 1290 BNE writeerror \ = 0 if OK 1300 RTS 1310 .writeerror 1320 BRK 1330 BRK 1340 EQUS "Write error" 1350 BRK 1360 .printbyte 1370 LDA track \ print source track number 1380 PHA 1390 LSR A 1400 LSR A 1410 LSR A 1420 LSR A 1430 JSR nybble \ print MS nybble 1440 PLA 1450 JSR nybble \ print LS nybble 1460 LDA #ASC(" ") 1470 JSR oswrch \ print space 1480 JMP oswrch \ print space 1490 .nybble 1500 AND #&0F 1510 SED 1520 CLC 1530 ADC #&90 1540 ADC #&40 1550 CLD 1560 JMP oswrch \ print nybble and return 1570 .seekblock 1580 EQUB &00 \ drive 0 1590 EQUD &00 \ does not matter 1600 EQUB &01 \ 1 parameter 1601 EQUB &69 \ seek command 1602 EQUB &00 \ physical track number 1603 EQUB &00 \ result 1610 .regblock 1620 EQUB &00 \ drive 0 1630 EQUD &00 \ does not matter 1640 EQUB &02 \ 2 parameters 1641 EQUB &7A \ write special register 1642 EQUB &12 \ track register, drive 0/2 1643 EQUB &00 \ value to be put in register 1650 EQUB &00 \ result 1660 .idsblock 1670 EQUB &00 \ drive 0 1680 EQUD table \ address of buffer 1690 EQUB &03 \ 3 parameters 1691 EQUB &5B \ read sector IDs command 1692 EQUB &00 \ physical track number 1693 EQUB &00 1700 EQUB &0A \ number of IDs 1701 EQUB &00 \ result 1710 .copyblock 1720 EQUB &00 \ drive 0 1730 EQUD buffer \ address of buffer 1740 EQUB &03 \ 3 parameters 1741 EQUB &57 \ read data multi-sector 1742 EQUB &00 \ logical track number 1743 EQUB &00 \ start logical sector number 1750 EQUB &2A \ 10 sectors of 256 bytes 1751 EQUB &00 \ result 1760 .formblock 1770 EQUB &00 \ drive 0 1780 EQUD table \ address of sector table 1790 EQUB &05 \ 5 parameters 1791 EQUB &63 \ format command 1792 EQUB &00 \ physical track number 1793 EQUB &15 \ gap 3 size 1800 EQUB &2A \ 10 sectors of 256 bytes 1801 EQUB &00 \ gap 5 size 1802 EQUB &10 \ gap 1 size 1803 EQUB &00 \ result 1810 .track 1820 EQUB 20 \ use tracks 20-39 1830 ] 1840 NEXT 1850 PRINT'"Place 40 track formatted 80 track disc" 1860 PRINT"in drive 0, and press Spacebar" 1870 REPEAT 1880 UNTIL GET = 32 1890 CALL mcode If you have a switched 40/80 track disc drive it is quite easy to produce dual format discs without using a conversion program such as DUALDFS. To produce a dual format disc you need to use a forty track formatter and to be very careful about the order in which files are saved on the dual format disc. The following algorith will produce dual formatted discs. 1) Switch the disc drive to 40 track mode. 2) Format a disc using a forty track formatter. 3) Switch the disc drive to 80 track mode. 4) Format the same disc again using the same forty track formatter. 5) Fill track &00 with a dummy !BOOT file using *SAVE !BOOT 1900+800 6) Fill tracks &01 to &13 with a locked dummy file. use the commands: *SAVE D.DUMMY 1900+BE00 *ACESS D.DUMMY L 7) Copy up to 50k of programs onto the disc. Don't use the filenames $.!BOOT or D.DUMMY. 8) Switch the disc drive to 40 track mode. 9) Copy the same files copied in step 7) onto the disc in exactly the same order. It is important that the order should be exactly the same. 10) Delete the dummy !BOOT file and store the real !BOOT file on the disc. The !BOOT file must not be longer than 2k. This method will produce exactly the same dual format disc as that produced by the program DUALDFS but it does require the use of a switched disc drive and a great deal of care in storing the files in the same order on both formats.