10
20
30
40
50
60
70
80
90
100
110 :
120 PRINT "Assembling S.HADFS8"
130 O%=P%-Block%+mcode%
140 [OPT0
150 :
160 \ ------------------------
170 \ Check if command enabled
180 \ ------------------------
190 .CheckEnable
200 BIT ENABLE:BVC NotEnabled:RTS
210 .NotEnabled
220 TYA:PHA:TXA:PHA
230 JSR PrText:EQUS "Go? (Y/N) ":BRK
240 LDA #21:LDX #0:JSR OSBYTE
250 PLA:TAX:PLA:TAY
260 JSR OSRDCH:BCS NotEnab2
270 AND #&DF:CMP #ASC"Y":BNE NotEnab2
280 JSR OSWRCH:JMP OSNEWL
290 .NotEnab2
300 JSR errors:EQUB 189:EQUS "Not enabled":BRK
310 :
320 :
330 \ ================
340 \ *Install routine
350 \ ================
360 .InstHelp
370 LDX #CommInstall-CommTable :\ Point to "INSTALL" text
380 LDY #HelpInstall-HelpText :\ Point to *Install help text
390 JSR HelpLp2 :\ Print a single *Help entry
400 JSR PrText
410 EQUS "<size> can be:":EQUB 13
420 EQUS "L... : Large Disk even if <16M":EQUB 13
430 \EQUS "D... - data disk":\EQUB 13
440 EQUS "<dec> : tracks":EQUB 13
450 EQUS "<dec>K|M : bytes":EQUB 13
460 EQUS "&<hex> : sectors":EQUB 13
470 BRK
480 :]:IF _NoInsHlp%:z%=P%-InstHelp:P%=P%-z%:O%=O%-z%
490 RTS
500 :
510 \ ----------------
520 \ *Install command
530 \ ----------------
540 .Install
550 LDA CSD+d:STA drive :\ Assume using current drive
560 JSR GetChar:BEQ InstDrive :\ No parameters, do default action
570 CMP #ASC"?":BNE P%+5:JMP InstHelp :\ Print out *Install help text
580 INY:LDA (&F2),Y:DEY :\ Get char after current char
590 CMP #ASC"!":BCS InstDrive :\ If not separator, use current drv
600 JSR GetDrive
610 .InstDrive :\ DRIVE now holds drive to use
620 JSR ReadFSM :\ EQ=HADFS disk, NE=blank
630 CLC:PHP :\ CC=new install
640 JSR SkipSpc :\ Look for next parameter
650 INY:CMP #ASC"$":BEQ InstRoot :\ '$' -> create new disk
660 DEY:PLP:BEQ P%+5:JMP NotHADFSDisk :\ Update must be of HADFS disk
670 SEC:PHP :\ CS=update existing disk
680 :
690 .InstRoot
700 \ On entry here, pushed flags
710 \ NE=not HADFS disk (ie blank) EQ=HADFS disk
720 \ CC=do new install ($) CS=update disk
730 :
740 JSR SkipSpc:BEQ InstNoTitle :\ No new disk title
750 LDX #0
760 .InstTitle
770 STA FSM,X:INY:LDA (&F2),Y :\ Copy new disk title in
780 CMP #ASC"!":BCC InstPad :\ End at space or <cr>
790 INX:CPX #16:BNE InstTitle :\ Loop for 16 characters
800 JMP errBadFilename :\ This disallows titles exactly 16 characters long
810 .InstPad
820 LDA #ASC" "
830 .InstSpc
840 INX:STA FSM,X :\ Pad title with spaces
850 CPX #16:BNE InstSpc :\ Title length is 16 chars
860 .InstJGH
870 LDA JGHName-16,X:STA FSM,X:INX :\ Put validity string in
880 CPX #24:BNE InstJGH
890 :
900 .InstNoTitle
910 LDA #0 :\ Prepare cleared flags
920 PLP:BCC P%+5:JMP InstUpdate :\ Jump ahead to update existing disk
930 PHP:BNE InstBlank :\ New install on blank disk
940 LDA FSM+31:ASL A:BPL InstOverwrite :\ New install on existing unlocked disk
950 JMP errLocked :\ Can't overwrite locked disk
960 .InstOverwrite
970 LDA #&C1 :\ Keep BigDisk+Locked+NoDFS flags
980 .InstBlank :\ **** FAILING SOMEWHERE ****
990 AND FSM+31:STA FSM+31 :\ Clear disk flags
1000 :
1010 \ Overwriting disk - Creating new disk
1020 \ ------------------------------------
1030 JSR SkipSpc:AND #&DF :\ Get next character
1040 CMP #ASC"@":BCC P%+3:INY
1050 PLP:PHA:PHP :\ Save any prefix character
1060 :
1070 \ From here on,
1080 \ Pushed A='S','L','D', <cr>, etc
1090 \ Pushed flags
1100 \ NE=not HADFS disk (ie blank) EQ=HADFS disk
1110 \ CC=do new install ($)
1120 :
1130 JSR SkipSpc:BNE InstSize :\ Disk size given, parse it
1140 PLP:BEQ InstEnable :\ Use existing disk size
1150 : :\ If no size given, allow GetNumber
1160 : :\ to generate error later on
1170 .InstSize
1180 PLP:INY:CMP #ASC"&":BEQ InstNum :\ Drop NE/EQ flag, check for §ors
1190 DEY:CLC :\ CC=decimal, CS=hex
1200 .InstNum
1210 PHP:JSR GetNumber :\ Read size parameter
1220 PLP:BCS InstSectors:AND #&DF :\ &xxxx is actual sector size
1230 :
1240 LDY #2:CMP #ASC"K":BEQ InstNumLp :\ Convert xxxxK to sectors
1250 CMP #ASC"M":BNE InstTrk:LDY #12 :\ xxxx is number of tracks
1260 .InstNumLp
1270 JSR TimesTwo:DEY:BNE InstNumLp :\ Convert K or M to sectors
1280 BEQ InstSectors :\ TimesTwo returns flags preserved
1290 :
1300 .InstTrk
1310 JSR Times10 :\ Multiply tracks by 10 to get sectors
1320 :
1330 .InstSectors
1340 CLC:LDA numstore+3 :\ Flag ENABLE not yet checked
1350 BEQ P%+5:JMP errBadNumber :\ If 4G+, error, disk too big
1360 :
1370 .InstFormat
1380 \ When *FORM enters here, ENABLE already checked
1390 \------------------------------------------------
1400 \ On entry here,
1410 \ TITLE, JGHNAME set, numstore holds SIZE
1420 \ pushed A=disk type character
1430 \ CC Check ENABLE CS Don't check ENABLE
1440 \------------------------------------------------
1450 PLA:PHA:EOR #ASC"L":BEQ InstBig :\ Force to BigDisk if L<size>
1460 LDA #&7F:AND FSM+31:\STA FSM+31 :\ Remove BigDisk flag
1470 LDX numstore+2:BEQ P%+4 :\ If <16M, leave set to SmallDisk
1480 .InstBig
1490 ORA #&80:STA FSM+31:LDX #2 :\ Set DiskSize flag
1500 .InstLp1
1510 LDA numstore,X:STA FSM+&1C,X :\ Put sector count into SIZE
1520 DEX:BPL InstLp1
1530 :
1540 .InstEnable
1550 BCS P%+5:JSR CheckEnable :\ Is command enabled?
1560 LDA #0:STA fptr+0
1570 LDA #FSM DIV 256:STA fptr+1 :\ Point to disk creation date
1580 SEC:JSR SetCrDateFSM :\ Set disk creation date
1590 :
1600 LDA &296:LDX #30 :\ Seed disk ID with part of TIME
1610 .MakeID
1620 PHA:TYA:EOR FSM+0,X :\ Hash the disk info into an ID
1630 TAY:PLA:ADC FSM+1,X
1640 DEX:DEX:BPL MakeID:STA FSM+&18 :\ Set DiskID
1650 EOR &295:STA FSM+&19 :\ Merge in another part of TIME
1660 :
1670 LDX #32:LDA #0
1680 .InstEmptyFSM :\ Create an empty FSM
1690 STA FSM,X:INX:BNE InstEmptyFSM :\ Blank all entries
1700 LDA FSM+31:ASL A:BCS InstEmptyBig :\ Empty BigDisk
1710 DEX:LDA #1:STA FSM+30 :\ Make SmallDisk a Data disk
1720 .InstEmptyBig
1730 INX:LDA #2:STA FSM+32 :\ First FSM entry start is &0002
1740 LDA #68:STA FSM+34,X :\ First FSM entry length is &0044
1750 TXA:PHA:BCC P%+3:INX :\ Save pointer to first entry
1760 LDA #74:STA FSM+36,X :\ Second entry &004A+xxxx
1770 BCC P%+3:INX:SEC
1780 LDA FSM+&1C:SBC #74:STA FSM+38,X
1790 LDA FSM+&1D:SBC #00:STA FSM+39,X
1800 LDA FSM+&1E:SBC #00:STA FSM+40,X :\ Length is to end of disk
1810 PLA:TAX :\ Get pointer to first entry
1820 BNE P%+5:STA FSM+40 :\ Clear SmallDisk end of FSM byte
1830 PLA:CMP #ASC"S":BNE InstNew
1840 LDA #4:STA FSM+34,X:LDA #0 :\ System disk, reduce space for ROM image
1850 .InstNew
1860 CLC :\ CC=overwrite, NE=Data, EQ=Syst
1870 :
1880 \---------------------------
1890 \ InstUpdate - Update a disk
1900 \---------------------------
1910 \ On entry here,
1920 \ TITLE, JGHNAME, DATE, DSKID, SIZE, FLAGS set
1930 \ P -> CS=update, CC=overwrite
1940 \ NE/EQ=xxx NE=Data, EQ=Syst
1950 \----------------------------------------------
1960 .InstUpdate
1970 PHP
1980 LDA #0:STA VFLG:JSR SaveFSM :\ Clear names, save the new or updated FSM
1990 :
2000 \ We always update so old versions can understand, even if we lose some space
2010 \ Update SmallData -> dual boot, 16-bit FSM, update any $.HADFSROM file
2020 \ Update SmallSyst -> dual boot, 16-bit FSM, update embedded ROM
2030 \ Update BigDisk -> dual boot, 24-bit FSM, update any $.HADFSROM file
2040 \
2050 \ We always create as disk with dual boot
2060 \ Create SmallData -> dual boot, 16-bit FSM
2070 \ Create SmallSyst -> dual boot, 16-bit FSM, save $.HADFSROM file
2080 \ Create BigDisk -> dual boot, 24-bit FSM, save $.HADFSROM file
2090 :
2100 LDA FSM+31:AND #&41:BNE InstNoDFS :\ Don't overwrite sectors 0/1
2110 .InstDFS
2120 JSR ClearDIR:JSR dirInit :\ Use DIR buffer, fptr=>DIR, Y=0
2130 STY sect+0:STY sect+1:STY sect+2 :\ Set SECT to &000000
2140 LDA #BootCode AND 255:STA addr+0
2150 LDA #BootCode DIV 256:STA addr+1
2160 JSR InstCopyMem :\ Save data to disk
2170 :
2180 .InstNoDFS
2190 LDA #6:STA sect+0
2200 LDA #0:STA sect+1:STA sect+2 :\ Pre-assume HADFSROM is at &0006 for OldSyst
2210 PLP:PHP:BCC InstROMUpd :\ Create ROM at &0006 for new disk
2220 LDA FSM+31:BMI InstROMFind :\ BigDisk, look for $.HADFSROM
2230 LDA FSM+30:LSR A:BCC InstROMUpd2 :\ SmallDisk, SystDisk, embedded ROM at &0006
2240 :
2250 \ BigDisk or SmallData, look for $.HADFSROM
2260 .InstROMFind
2270 LDA #ROMName AND 255:STA &F2
2280 LDA #ROMName DIV 256:STA &F3
2290 LDY #0:JSR LookFromRoot2 :\ Look for $.HADFSROM on current drive
2300 CMP #1:BNE InstNoROM :\ $.HADFSROM doesn't exist as a file
2310 CLC:JSR GetLength
2320 JSR GetSectAddr :\ sect=file start
2330 LDA len+1:CMP #&40:BNE InstNoROM :\ Length not &xx40xx
2340 LDA len+2:ORA len+0:\BNE InstNoROM :\ Length not &00xx00
2350 :
2360 \ sect=start of $.HADFSROM file or start of embedded ROM
2370 .InstROMUpd
2380 BNE InstNoROM :\ Create Data disk
2390 .InstROMUpd2
2400 JSR ClearDIR :\ Use DIR buffer, A=0
2410 STA addr+0:LDA #&80 :\ addr=&8000, ROM start
2420 .InstROMlp
2430 STA addr+1:PHA :\ Save source address
2440 JSR dirInit:JSR InstCopyMem :\ Copy two pages from addr to fptr, and save it
2450 PLA:CLC:ADC #2 :\ Update addr
2460 CMP #&C0:BCC InstROMlp :\ Loop to end of ROM
2470 :
2480 \ Any required $.HADFSROM or embedded ROM updated
2490 \ Now, install blank root directory if needed
2500 \ pushed P -> CS=update, CC=overwrite
2510 \ NE/EQ=xxx NE=Data, EQ=Syst
2520 \------------------------------------------------
2530 .InstNoROM
2540 PLP:BCS InstDone:PHP :\ Updating, so no new root needed
2550 JSR ClearDIR:JSR dirInit:TYA :\ Use DIR buffer, fptr=>DIR, Y=0
2560 .InstRootLp1
2570 CPY #9:BNE P%+4:LDA #32 :\ First 10 bytes are spaces
2580 STA (fptr),Y:DEY:BNE InstRootLp1 :\ Blank out directory
2590 LDA #ASC"$":STA (fptr),Y :\ Set directory name
2600 LDA FSM+24:LDY #16:STA (fptr),Y
2610 LDA FSM+25:INY:STA (fptr),Y :\ Set DiskID
2620 LDA FSM+31:AND #&80 :\ Get BigDisk flag
2630 LDY #12:STA (fptr),Y :\ If BigDisk, also BigDir
2640 LDY #10:TAX:BPL P%+4:LDY #&1C :\ Y=>Parent
2650 LDA #71:STA (fptr),Y :\ Set Parent=$
2660 PLP:BNE InstRootSave :\ Data disk, no $.HADFSROM file
2670 LDY #12:LDA #1:STA (fptr),Y :\ Entries=1
2680 JSR dirNext :\ fptr=>first directory entry, Y=0
2690 .InstRootLp2
2700 LDA ROMName,Y:STA (fptr),Y :\ Copy 'HADFSROM' filename into dir
2710 INX:INY:CPY #10:BNE InstRootLp2
2720 LDA #&40:LDY #&13:STA (fptr),Y :\ Length=&004000
2730 LDA #&06:LDY #&16:STA (fptr),Y :\ Sector=&000006
2740 .InstRootSave
2750 JSR SectRoot:JMP PutDirNoHdr :\ Save the root directory and exit
2760 .InstDone
2770 RTS :\ All finished
2780 :
2790 \ Copy data from (addr) to DIR buffer
2800 \ -----------------------------------
2810 .InstCopyMem
2820 LDX #2:LDY #0:STX num :\ Copy two pages, two sectors to save
2830 .InstCopyMemLp
2840 LDA (addr),Y:STA (fptr),Y :\ Copy code to DIR buffer
2850 INY:BNE InstCopyMemLp
2860 INC addr+1:INC fptr+1 :\ Point to next page
2870 DEX:BNE InstCopyMemLp
2880 DEX:STX action :\ action=&FF - Write
2890 JMP DiskAccDIR :\ Write from DIR, sect updated
2900 :
2910 \------------------------------------------
2920 \ Boot sector code - 512 bytes of code with
2930 \ DFS catalogue and !Boot boot code
2940 \------------------------------------------
2950 .BootCode:]:BootOff=BootCode-&900
2960 :]:BootOsw7F=&08C0:BootAddr=BootOsw7F+1
2970 :]:BootZP=&A8:BootROM=&AA:BootNum=&AC:BootOS=&AD
2980 EQUS "HADFS"+CHR$0+" D"
2990 .BootCmd
3000 EQUS "!Boot "+CHR$164
3010 EQUD 13:EQUD 0 :\ Disk Parameter Table
3020 EQUS "$ ":EQUW &20A0 :\ Fake entry for '$'
3030 .ROMName
3040 EQUS "HADFSROM "
3050 EQUW &0000:EQUW &0047 :\ Sector of '$'
3060 :
3070 .BootGo%
3080 LDY #0:JSR Osbyte90_6-BootOff :\ Get HADFS status
3090 TXA:BPL BootUp :\ HADFS present, boot it
3100 LDX #1:AND #&40:BNE BootLdROM :\ No HADFS, load it
3110 LDA #143:LDY #&E:JSR OSBYTE :\ Redeclare shared workspace
3120 LDX #2:JSR OSBYTE:STY &244 :\ Redeclare private workspace
3130 .BootUp
3140 LDY #2 :\ *FX90,6,2 - Boot from HADFS
3150 :
3160 .Osbyte90_6 :\ Generic Osbyte 90,6,y routine
3170 LDX #6
3180 .Osbyte90 :\ Generic Osbyte 90,x,y routine
3190 LDA #90:JMP OSBYTE
3200 :
3210 .BootLdROM:\ X=1 when here
3220 LDA #0:JSR OSBYTE:TXA:BNE BootLd1
3230 LDA #&05:STA RomSelOne+3-BootOff:\ Change RomSelect for Electron
3240 .BootLd1
3250 LDX #15 :\ Look for a bank of RAM
3260 .BootLp
3270 JSR RomSelect-BootOff :\ Select ROM number X
3280 LDA &8008:INC &8008:CMP &8008 :\ Test if RAM
3290 BNE BootRAMFound :\ RAM found
3300 DEX:BPL BootLp :\ Loop for all 16 banks
3310 INX:JMP BootPrText-BootOff :\ No RAM found
3320 :
3330 .BootRAMFound
3340 LDA #0:LDX #&47:LDY #3 :\ Read 3 sectors from &0047
3350 JSR BootRd-BootOff:LDX #6 :\ Load '$' directory, BootZP=&3000, default sector=6
3360 .BootNxtName
3370 LDY #0:CLC
3380 LDA BootZP+0:ADC #24:STA BootZP+0 :\ Step through SmallDir entries
3390 LDA BootZP+1:ADC #00:STA BootZP+1 :\ Tweek to allow BigDir entries
3400 CMP #&33:LDA #0:BCS BootEndOfDir :\ End of directory, try embedded ROM at &AAXX=&0006
3410 .BootChkChr
3420 LDA (BootZP),Y:AND #&5F :\ Get filename character
3430 CMP ROMName-BootOff,Y
3440 BNE BootNxtName :\ Not 'HADFSROM', step to next
3450 INY:CPY #8:BNE BootChkChr :\ Check 8 characters
3460 :
3470 LDY #22:LDA (BootZP),Y:TAX :\ X=sector low byte
3480 INY:LDA (BootZP),Y :\ A=sector high byte
3490 .BootEndOfDir
3500 LDY #&40:JSR BootRd-BootOff :\ Read &40 sectors from &AAXX, returns Y=0
3510 :
3520 LDX #&40:STY BootROM+0 :\ &40 pages to copy
3530 LDA #&80:STA BootROM+1 :\ BootROM=>&8000
3540 .BootCopyLp
3550 LDA (BootZP),Y:STA (BootROM),Y:\ Copy byte to ROM
3560 INY:BNE BootCopyLp :\ Loop for 256 bytes
3570 INC BootZP+1:INC BootROM+1 :\ Update pointers
3580 DEX:BNE BootCopyLp :\ Loop for &40 pages
3590 \ NB, doesn't actually check if loaded data is a ROM
3600 :
3610 .BootROMReset
3620 LDA #3:STA &190+200 :\ *FX200,3
3630 TXA:INX:JSR OSBYTE :\ Read host
3640 CPX #5:BCS BootReset :\ Compact - don't power reset
3650 JSR ChkMOS350-BootOff
3660 BEQ BootReset :\ MOS 3.50 - don't power cycle
3670 .BootPower
3680 LDA #151:LDX #78:LDY #127:JSR OSBYTE:\ Power reset
3690 .BootReset
3700 BIT &27A:BMI BootNoReset :\ If Tube, stall
3710 JMP (-4) :\ Otherwise, vector to reset code
3720 .BootNoReset
3730 LDX #BootBreak-BootText :\ Point to 'Press BREAK' text
3740 .BootPrText
3750 LDA BootText-BootOff,X:BEQ P% :\ End of text, stall
3760 JSR OSASCI:INX:BNE BootPrText
3770 :
3780 EQUS STRING$(&A00-(P%-BootOff),CHR$0)
3790 EQUS "ISK "+CHR$0+CHR$8+CHR$&20+CHR$&02
3800 EQUW &900:EQUW BootGo%-BootOff:EQUW &0200:EQUB &CC:EQUB 0
3810 :
3820 .ChkMOS350
3830 LDX &EED5:CPX #ASC"M":BNE ChkMOS350a
3840 LDX &EEDB:CPX #ASC"5"
3850 .ChkMOS350a
3860 RTS
3870 :
3880 .BootRd
3890 STX BootZP+0 :\ SectorLo
3900 STA BootZP+1 :\ SectorHi
3910 STY BootNum :\ Number
3920 LDX #&00:STX BootAddr+0 :\ Load to &xx00
3930 LDA #&30:STA BootAddr+1 :\ Load to &3000
3940 DEX:STX BootOsw7F+0 :\ Drive=-1 - Current drive
3950 STX BootOsw7F+3:STX BootOsw7F+4 :\ Addr high word
3960 LDA #&03:STA BootOsw7F+5 :\ Params=3
3970 LDA #&53:STA BootOsw7F+6 :\ READ
3980 :
3990 .BootDiv10
4000 INX:SEC
4010 LDA BootZP+0:SBC #10:STA BootZP+0
4020 LDA BootZP+1:SBC #00:STA BootZP+1
4030 BCS BootDiv10:LDA BootZP:ADC #10 :\ X=Trk, A=Sec
4040 STX BootOsw7F+7:STA BootOsw7F+8 :\ Trk, Sec
4050 :
4060 .BootRdNxt
4070 LDA BootNum:TAY
4080 CLC:ADC BootOsw7F+8:CMP #11 :\ Spans past end of track?
4090 BCC BootNoSpan
4100 LDA #10:SEC:SBC BootOsw7F+8:TAY :\ Number to end of track
4110 .BootNoSpan
4120 TYA:ORA #&20:STA BootOsw7F+9 :\ Num
4130 :
4140 .BootRetry
4150 LDX #9:.BootSvLp
4160 LDA BootOsw7F,X:PHA:DEX:BPL BootSvLp
4170 LDX #BootOsw7F AND 255:LDY #BootOsw7F DIV 256
4180 LDA #&7F:JSR OSWORD
4190 LDX #0:.BootRestLp
4200 PLA:STA BootOsw7F,X:INX:CPX #10:BNE BootRestLp
4210 AND #&1F:TAX:STA BootOsw7F+9 :\ Num
4220 LDA BootOsw7F+10:BNE BootRetry
4230 :
4240 STA BootOsw7F+8:INC BootOsw7F+7 :\ Sec=0, Trk=Trk+1
4250 TXA:CLC:ADC BootAddr+1:STA BootAddr+1 :\ Update address
4260 LDA BootNum:SEC:SBC BootOsw7F+9 :\ Update length
4270 STA BootNum:BNE BootRdNxt :\ Read from next track
4280 :
4290 TAY:STY BootZP:LDX #&30:STX BootZP+1 :\ BootZP=&3000, Y=0
4300 RTS
4310 :
4320 .RomSelect
4330 LDA #12:JSR RomSelOne-BootOff:TXA:STA &FF30,X
4340 .RomSelOne
4350 STA &F4:STA &FE30:RTS
4360 :
4370 \.\BootWantSystem
4380 \\LDX #BootSystem-BootText
4390 \\JSR BootPrText-BootOff
4400 \\CLI:\JSR &FFE0:\JSR &FFE7
4410 \\LDX #(BootCmd-BootOff) AND 255
4420 \\LDY #(BootCmd-BootOff) DIV 256:\JMP &FFF7
4430 :
4440 .BootText
4450 EQUS "No SRAM":BRK:\ No sideways RAM
4460 .BootBreak
4470 EQUB 22:EQUB 7:EQUB 13:EQUS "Press BREAK":BRK:\ to reset
4480 \\.BootSystem
4490 \\EQUS "Not a system disk":\BRK
4500 :
4510 \\.BootRWrite
4520 \\EQUS "RWRITE E.":\EQUB 13
4530 EQUS "v"+ver$:BRK
4540 :
4550 :
4560 \ ===============
4570 \ *Format routine
4580 \ ===============
4590 .Form
4600 CLC:JSR GetNumber:LDA numstore :\ Get decimal number
4610 CMP #10:BCS P%+5:JMP errBadNumber
4620 PHA:JSR SkipSpc:BNE FormDsk3
4630 .FormBadDrv
4640 JMP errBadDrive
4650 .FormDsk3
4660 CMP #ASC"0":BCC FormBadDrv :\ <'0' - Bad drive
4670 CMP #ASC"4":BCS FormBadDrv :\ >'3' - Bad drive
4680 AND #3:CMP #2:BCC FormDsk4 :\ <'2' - Valid drive number
4690 JSR ChkROM:BEQ FormBadDrv :\ >'1' and HADFS, Bad drive
4700 .FormDsk4
4710 JSR GrabAbs:STA &F90:STA &F91 :\ &F90=current drive, &F91=start drive
4720 JSR ClearFSM:LDA #0:STA &F92 :\ &F92=&00 for single-sided
4730 STA &F94:PLA:STA &F95 :\ &F94=current track, &F95=tracks per side
4740 STA &F96:CMP #103:BCC FormDsk5 :\ &F96=total tracks, 102 tracks is biggest DFS size
4750 LSR &F95:DEC &F92 :\ Double sided, half number of tracks, &F92=&FF
4760 .FormDsk5
4770 LDA &F90:CMP #2:BCC FormDsk6
4780 LDA #0:STA &F92 :\ Drive 2/3, set to single-sided
4790 .FormDsk6
4800 JSR PrText:EQUS "Format drive ":BRK
4810 LDA &F90:JSR PrNyb:JSR OSNEWL :\ Print current drive number
4820 JSR ChkROM:BEQ FormDsk1 :\ HADFS, check ENABLE flag
4830 JSR NotEnabled:JMP FormDsk2 :\ Not HADFS, ask to be enabled
4840 .FormDsk1
4850 JSR CheckEnable
4860 :
4870 .FormDsk2
4880 LDA #7:STA &F93 :\ &F93=Set initial skew
4890 .FormDskLoop
4900 LDA &F90:JSR FormTrack :\ Format a single track
4910 BIT &FF:BPL P%+5:JMP FormExit :\ Quit if Escape pressed
4920 INC &F94:LDA &F94:CMP &F95 :\ Increment current track
4930 BNE FormDskLoop :\ Loop back until all done
4940 BIT &F92:BPL FormDsk7a :\ Single-sided -> create blank disk
4950 LDA &F90:CMP #2:BCS FormDsk7a :\ Drive 2/3 -> create blank disk
4960 ORA #2:STA &F90 :\ Set to drive 2/3 for side 1
4970 LDA #0:STA &F94:BEQ FormDskLoop :\ Reset to track zero, do second side
4980 :
4990 .FormDsk7a
5000 JSR OSNEWL:LDA &F91:STA drive :\ Set drive
5010 LDA &F96:STA numstore:LDA #0:LDX #3 :\ numstore?0=tracks
5020 .FormDsk7b
5030 STA numstore,X:DEX:BNE FormDsk7b :\ numstore=tracks
5040 JSR Times10:LDA #0:TAX :\ numstore=tracks*10
5050 .FormZero
5060 STA FSM,X:INX:BNE FormZero :\ Fill sector with zeros
5070 JSR ChkROM:BNE FormDFS:LDX #23 :\ HADFS not selected, install DFS
5080 .FormJGH :\ Put blank HADFS data in
5090 LDA JGHName-16,X:STA FSM,X:DEX:BPL FormJGH
5100 LDA #1:STA FSM+30 :\ Flag as OldData disk
5110 PHA:SEC :\ Pushed A=NotSyst, CS=ENABLE already checked
5120 JMP InstFormat :\ Create disk, CS=don't check ENABLE
5130 :
5140 .FormDFS
5150 STA sect+0:STA sect+1:STA sect+2 :\ Sector &0000
5160 LDA drive:PHA:AND #1:STA drive :\ Set drive to 0/1
5170 PLA:AND #2:BEQ FormDFSb :\ Jump to save to drive 0/1
5180 LDA #&20:STA sect+0
5190 LDA #&03:STA sect+1 :\ Drive 2/3 - sect=&320 for side 1
5200 .FormDFSb
5210 JSR SavePageF :\ Save empty sector, sect updated to &0001
5220 LDA numstore+0:STA FSM+7
5230 LDA numstore+1:STA FSM+6 :\ Set disk size
5240 JMP SavePageF :\ Save sector &0001
5250 :
5260 .ChkROM
5270 LDX XFILEV+2:CPX &F4:RTS :\ Is HADFS current filing system?
5280 :
5290 \ FormTrack - format a track
5300 \ --------------------------
5310 \ On entry, A=DFS drive number
5320 .FormTrack
5330 STA &F80:PHA:LDA #13:JSR OSWRCH
5340 JSR PrText:EQUS "Formatting ":BRK
5350 PLA:JSR PrNyb:LDA #ASC":":JSR OSWRCH
5360 LDA &F94:JSR PrHex
5370 .FormTrkLp
5380 LDX #10:BIT &FF:BPL FormSectLp1
5390 .FormExit
5400 RTS
5410 .FormSectLp1
5420 LDA FormTable,X:STA &F81,X
5430 DEX:BPL FormSectLp1
5440 LDA &F94:STA &F87:\ track
5450 LDX #0:\ Set up sector table
5460 .FormSectLp2
5470 LDA &F94:STA &F00,X
5480 LDA #0:STA &F01,X
5490 LDA &F93:STA &F02,X:INC &F93
5500 CMP #9:BCC FormSect2
5510 LDA #0:STA &F93
5520 .FormSect2
5530 LDA #1:STA &F03,X
5540 INX:INX:INX:INX:CPX #40
5550 BNE FormSectLp2
5560 LDA &F93:SBC #3:BPL FormSect3
5570 ADC #10:.FormSect3:STA &F93
5580 :
5590 \ Wrap this in SelectDFS ?
5600 LDX #&80:LDY #&F:LDA #&7F
5610 JSR OSWORD
5620 :
5630 LDA &F8C:BEQ FormExit
5640 CMP #&12:BCC FormTrkLp
5650 BNE P%+5:LDA #&12:JMP DiskErrors :\ Read only
5660 CMP #&14:BEQ FormTrkLp
5670 LDA #ASC"?":JSR OSWRCH:JMP OSNEWL
5680 .FormTable
5690 EQUD &FFFF0F00:\ =sectab
5700 EQUB &5:EQUB &63:\ =format
5710 EQUB 0:\ track
5720 EQUB &10:\ gap3
5730 EQUB &2A:\ sector num + size
5740 EQUB &00:\ gap5
5750 EQUB &10:\ gap1
5760 :]:IF _NoFormat%:z%=P%-Form:P%=P%-z%:O%=O%-z%
5770 :
5780 :
5790 \\\ Overlap dummy module headers with code:
5800 \\EQUW NullKbd_Lnk :\ x-2
5810 \\.DummyHeader
5820 \\:
5830 \\.PutInInfo :\ Five bytes overlapped here
5840 \\STA &F00,Y:\INY:\RTS
5850 \\:
5860 \\.DummyFinal
5870 \\EQUW &0000 :\ x+5 \\two spare bytes
5880 \\EQUB JGHName-DummyHeader :\ x+7
5890 \\BRK :\ x+8
5900 \\EQUS "NullKeyboard":\BRK:\EQUS "0.12 (01 Aug 1998)"
5910 \\BRK
5920 \\:
5930 \\.NullKbd_Lnk
5940 \\EQUW DummyFinal :\ x-2
5950 \\.NullKbd_0
5960 \\.GetChn
5970 \\LDY #0:\LDA (blk),Y
5980 \\RTS:\BRK:\BRK
5990 \\\.DummyCopy
6000 \\\BRK:\EQUS "(C)JGH" :\ x+0, \\DummyCopy-NullKbd_0 = 0
6010 \\\.DummyFinal
6020 \\EQUB JGHName-NullKbd_0:\BRK:\ x+7, x+8
6030 \\EQUS "SoftRTC":\BRK:\EQUS "0.10 (23 Nov 1992)"
6040 \\BRK
6050 \\:
6060
6070 \\ New module header layout
6080
6090 .PutInInfo
6100 STA &F00,Y:INY:RTS
6110 .GetChn
6120 LDY #0:LDA (blk),Y
6130 .NULL
6140 RTS
6150 :
6160 \EQUW Dummy2-2:\ For compatability with old *SMList command
6170 .Dummy1
6180 JSR Service:JMP Dummy2
6190 EQUB 0:EQUB JGHName-Dummy1:EQUB 0
6200 EQUS "NullKeyboard":EQUB 0
6210 EQUS "0.12 (01 Aug 1998)":EQUB 0
6220 :
6230 \EQUW Dummy2-4:\ For compatability with old *SMList command
6240 .Dummy2
6250 JSR NULL:JMP NULL
6260 EQUB 0:EQUB JGHName-Dummy2:EQUB 0
6270 EQUS "SoftRTC":EQUB 0
6280 EQUS "0.10 (23 Nov 1992)":EQUB 0
6290 :
6300 \\\
6310
6320 .Trk_70
6330 EQUS "(Untitled_Disk) "
6340 .JGHName
6350 EQUB 0:EQUS "(C)JGH":EQUB 0
6360
6370 ]
6380 PRINT CHR$11;STRING$(20,CHR$9);O%-mcode%;" bytes"
6390 >"S.HADFS9"