;FORMAT2/ASM - Format Initialization Code ; ; FORMAT routine entry point ; FORMAT @@CKBRKC ;Check for break JR Z,FORMATA ;Continue if no break LD HL,-1 ; else abort RET ; FORMATA LD (SPSAV+1),SP ;Save the stack pointer PUSH HL ;Save cmdline ptr @@DSPLY HELLO$ ;Hello message CALL GETSYS2 ;Load SYS2 overlay ; ; Read config sector & extract DCT # cyls ; IF @MOD4 LD DE,2 ;Track 0, sector 2 LD C,D ;Drive 0 ENDIF ; IF @MOD2 LD C,0 ;Drive 0 @@GTDCT ;Fetch DCT LD A,(IY+3) ;Get dct data AND 28H ;Bit 5/3 CP 20H ;8" floppy? JR NZ,SETSYS1 ;Go if not LD A,(IY+4) ;Get data AND 50H ;Bit 6/4 CP 40H ;DD not alien? JR NZ,SETSYS1 ;Go if not LD HL,HITBUF ;Init buffer LD D,(IY+9) ;Get dir cyl LD E,0 ;Init GAT table @@RDSEC ;Read GAT table CP 6 ;Directory read? JP NZ,IOERR ;Go on disk error LD A,(HITBUF+0CDH) ;Get data byte BIT 7,A ;System disk? SETSYS1 LD DE,0<8+2 ;Init cyl 0 JR NZ,$+3 ;Go if not system INC D ;Else on cyl 1 LD C,0 ;Drive 0 ENDIF ; LD HL,HITBUF ;Set disk buffer @@RDSEC ;Read sysinfo sector JP NZ,IOERR ;Quit on read error LD L,70H+6 ;Pt to default DCTs ; ; Establish the default BOOT step rate ; PUSH HL ;Pt IY to the POP IY ; start of the DCTs LD A,(IY+3-6) ;P/u DCT$ default step AND 3 ; & strip off LD (STEPARM+1),A ;Keep for Step parm ; ; Keep cyl count on all 8 drives ; LD B,8 LD IX,DCTCYL ;Pt to where to stuff LD DE,10 ; 10-byte increments DCTLP1 LD A,(HL) ;P/u default # CYL LD (IX),A ;Save in table INC IX ADD HL,DE DJNZ DCTLP1 ;Loop for 8 DCTs ; POP HL ;Rcvr ptr to cmdline FMT1 LD A,(HL) ;Ignore spaces INC HL CP ' ' JR Z,FMT1 CP ':' ;Colon drive indicator? JR Z,FMT2 ;Go on drive entry ; ; Drive not entered, prompt for it ; DEC HL ;Backspace command line DEC HL ; & adjust for next INC PUSH HL ;Save pointer WHDRV @@DSPLY WHDRV$ ;"which drive... LD HL,HITBUF ;Input buffer for now LD BC,1<8 ;Max 1 char @@KEYIN ;Get a 1-char line JP C,FMTABT ;Quit on Break LD A,(HL) ;P/u the entry SUB '0' ;Cvrt to binary CP 8 ;Error if > 7 JR NC,WHDRV POP HL ;Rcvr command pointer JR FMT2A ; ; Drive entered ; FMT2 LD A,(HL) ;P/u drive # SUB '0' ;Cvrt to ASCII CP 8 ;Make sure not > 7 JP NC,PRMERR FMT2A LD (FMTDRV+1),A ;Stuff drive INC HL ;Bump cmdline ptr LD DE,PRMTBL$ ;Parse any parameters @@PARAM JP NZ,PRMERR ;Jump on parm error ; ; Test if any other parm was entered ; SDPARM LD DE,0 ;Single density parm LD A,D OR E ;Merge all theses parms DDPARM LD DE,0 ;Double density parm OR D OR E SIDES LD DE,0 ;Sides parm OR D OR E CPARM LD DE,0 ;Cylinder parm OR D OR E STEPARM LD DE,0FF00H ;Init to show if entry INC D ;Did user enter it? OR D ;0=no user entry LD (PRMMRG+1),A ;Set to non-zero if any ; ; If Q-parm, then set NAME & MPW if not entered ; LD DE,(QPARM+1) ;P/u Query parm LD HL,(NPARM+1) ;P/u Name parm LD A,H OR L JR NZ,$+6 ;Go if user entered name LD (NPARM+1),DE ; else use Q-parm value LD HL,(MPARM+1) ;P/u Password parm LD A,H OR L JR NZ,$+6 ;Go if user entered password LD (MPARM+1),DE ;Set to Q-parm entry ; LD A,(FMTDRV+1) ;P/u drive LD C,A ;Set in drive register LD HL,DCTCYL ;Find default # cyls ADD A,L ;Index the DCTCYL table LD L,A ; according to drive # ADC A,H SUB L LD H,A LD A,(HL) ;P/u cylinder count INC A ;Offset from 1 LD (PCYL2+1),A ;Stuff default for 5" @@GTDCT ;Find the DCT pointer PUSH IY POP HL ;Xfer DCT to HL LD DE,SYSDCT ;Save the system's DCT LD BC,10 ; for the drive since LDIR ; we are altering it LD A,(SYSPRM+1) ;Check if "SYSTEM" parm INC A ; entered JR NZ,FMT2B ;Go if not BIT 3,(IY+3) ;Check if hard drive JP Z,NOTHARD ;Can't "SYSTEM" floppy FMT2B CALL DRVNOP ;Test if drive enabled JP NZ,IOERR NPARM LD HL,0 ;NAME parm entered? LD A,H OR L INC A ;Was it just NAME? JR Z,DSKNAM ;Prompt if so DEC A ;If entered, use it JR NZ,$+5 DFTNAM LD HL,PAKNAM$ LD DE,GATBUF+0D0H ;Yes, move name to field LD B,8 ;8-chars max MOVNAM LD A,(HL) ;P/u a char CP '"' ;Closing " JR Z,CKNAME ;Exit if end of parm CP 20H ;Permit all but controls JP C,CKNAME CP 'a' ;If char is lower case, JR C,MOVNAM1 CP 'z'+1 JR NC,MOVNAM1 XOR 20H ; make it UC MOVNAM1 LD (DE),A ;Put char in buffer INC HL ;Bump both ptrs INC DE DJNZ MOVNAM ;Loop til complete JR CKNAME ;Check if valid name ; ; Prompt user for name parameter ; DSKNAM @@DSPLY DSKNAM$ ;"diskette name? CALL GET8 ;Get 8 chars, make UC JR Z,DFTNAM ;Use default if no entry LD C,B ;Only move to name field LD B,0 ; how many were entered LD DE,GATBUF+0D0H LDIR CKNAME LD DE,GATBUF+0D0H ;Now check if illegal CALL CKMPW0 ; chars in name JP NZ,BADNAM ; & quit if so GETDAT LD HL,GATBUF+0D8H ;Get today's date & stuff @@DATE ; ; Master Password handling ; MPARM LD HL,0 ;Did user enter the MPW? LD A,H OR L INC A ;If only MPW, then prompt JR Z,MPW ;Go prompt if not DEC A JR NZ,$+5 ;If entered, use it DFTMPW LD HL,PAKMPW$ ; else use ours LD DE,MPWBUF ;Shift to pswd field LD B,8 MOVMPW LD A,(HL) CP 30H ;No spaces permitted JR C,PRSMPW ;End also on closing " CP 'a' ;Need cvrt to UC? JR C,MOVMPW1 CP 'z'+1 JR NC,MOVMPW1 XOR 20H ;Cvrt to UC MOVMPW1 LD (DE),A ;Store the char and INC DE ; bump the buffer ptrs INC HL DJNZ MOVMPW JR PRSMPW ;Check if valid password ; ; Prompt for master password ; MPW LD HL,MPW$ ;"master... CALL INPMPW JR NC,DFTMPW ;Use default on ; ; Parse the password & stuff into GAT sector buffer ; PRSMPW LD DE,MPWBUF CALL CKMPW ;Check for valid MPW JP NZ,IOERR LD (GATBUF+0CEH),HL ;Stuff it BIT 4,(IY+4) ;Jump if alien controller JP NZ,CALCGPC LD HL,TBLDATA ;Pt to config tables LD DE,6 ;Index the table BIT 5,(IY+3) ;8" drive? JR Z,INITDEN ;Bypass if not ADD HL,DE ; else move to 8" configs ADD HL,DE INITDEN LD (SETSDEN+1),HL ; & stuff for SDEN option EX DE,HL ;6->HL, SDEN->DE ADD HL,DE ;Pt to DDEN index table LD (SETDDEN+1),HL ;Stuff DDEN config ptr EX DE,HL ;HL=SDEN, DE=DDEN RES 6,(IY+3) ;Set DCT to SDEN BIT 6,(IY+4) ;Test if DDEN capability JR Z,SETSTD ;Go if single EX DE,HL ;HL->DDEN table SET 6,(IY+3) ;Set DCT to DDEN SETSTD CALL SETUP ;Init to std config RES 4,(IY+3) ;Set i/o to front side RES 5,(IY+4) ;Set to 1-sided PRMMRG LD A,0 ;<>0 if config parms OR A ; in command line JR NZ,GETDEN QPARM LD DE,-1 ;Prompts? Default=Y LD A,D OR E JP Z,PSTEP1 ;Go if no prompting GETDEN BIT 6,(IY+4) ;Bypass DDEN request msg JR Z,PMTSIDE ; if no DDEN capability LD A,(PRMMRG+1) ;Also, don't prompt if OR A ; any config parm was JR NZ,GDDEN1 ; entered with command LD HL,DEN?$ ;Density ... CALL GET3 JR Z,PMTSIDE ;Go on LD A,(HL) ;P/u respsonse CP 'S' ;Single Density? JR Z,SETSDEN CP 'D' ;Double density? JR Z,SETDDEN JR GETDEN ;Redo if bad response GDDEN1 LD A,(DDPARM+1) ;Not prompted, was DDEN XOR -1 ; set in command line? JR NZ,GSDEN1 ;Bypass if not SETDDEN LD HL,$-$ ;P/u DDEN index table SET 6,(IY+3) ;Set DCT to DDEN JR CHGDEN GSDEN1 LD A,(SDPARM+1) ;Was SDEN parm XOR -1 ; on command line? JR NZ,PMTSIDE ;Go if not SETSDEN LD HL,$-$ ;P/u SDEN index table RES 6,(IY+3) ;Set DCT to SDEN CHGDEN CALL SETUP ;Init #CYLs & alloc PMTSIDE LD A,(PRMMRG+1) ;Config parms entered OR A ;On command line? JR NZ,PMTS1 ;Bypass if yes PUSH IY ;P/u flag table @@FLAGS ; and check if BIT 5,(IY+'L'-'A') ; 2-side inhibit? POP IY JR NZ,PMTS1 ;If set, use 1 side LD HL,SIDES$ ;"double sided...? CALL GET3 ;Get # sides wanted JR Z,PMTCYL ;Go on LD A,(HL) ;P/u response char CP '1' ;1 is ok JR Z,PMTCYL CP '2' ; and so is 2 JR NZ,PMTSIDE ; but redo on anything else JR TSTSID ; ; Check side parm from command line ; PMTS1 LD A,(SIDES+1) ;How many sides? CP 2 TSTSID JR NZ,PMTCYL ;DCT ok if not 2 SET 5,(IY+4) ;Set 2-sided drive PMTCYL LD A,(IY+3) ;No cylinder request AND 28H ; if either hard drive JR NZ,PMTSTEP ; or 8" drive PCYL1 LD A,(PRMMRG+1) ;P/u config test byte & OR A ; bypass cyl req if user JR NZ,PCYL4 ; entered cmd line parms LD HL,NUMCYL$ ;"number of cyls..? CALL GET3 PCYL2 LD A,0 ;P/u default # cyls CALL NZ,CVBIN ;Get # of cyls on CR IF @BLD631 CALL CHKCNT ;<631> JR C,PCYL1 ;<631>Anything out of range JR PMTSTEP ;<631> CHKCNT: CP 96+1 ;<631>System cannot support CCF ;<631> anything over 96 (95) RET C ;<631> CP 35 ;<631>Must be 35 or more RET C ;<631> DEC A ;<631>Adjust to zero offset LD (IY+6),A ;<631> & stuff in DCT RET ;<631> ELSE PCYL3 CP 96+1 ;System cannot support JR NC,PCYL1 ; anything over 96 (95) CP 35 JR C,PCYL1 ;Must be 35 or more DEC A ;Adjust to zero offset LD (IY+6),A ; & stuff in DCT JR PMTSTEP ENDIF ; ; User entered config parms with command line ; PCYL4 LD A,(CPARM+1) ;Was cyl= one of them? OR A IF @BLD631 CALL NZ,CHKCNT ;<631>Check for valid range JP C,PRMERR ;<631>Parm error if too big PMTSTEP:BIT 4,(IY+4) ;<631>Alien controller? JR NZ,CALCGPC ;<631>No adjustable rate if so ELSE JR Z,PMTSTEP ;Bypass if not CP 96+1 JP NC,PRMERR ;Parm error if too big CP 35 JP C,PRMERR ; or too small DEC A ;Adjust to zero offset LD (IY+6),A ; & stuff into DCT PMTSTEP BIT 4,(IY+4) ;Alien controller? JR NZ,PMTSIDE ;No adjustable step rate if so ENDIF ; ; If step rate parm wasn't entered, prompt ; for it but first determine 8" or 5" drive ; LD A,(PRMMRG+1) ;Did user enter config OR A ;Parms on command line? JR NZ,PSTEP1 ;Go to step prompt if yes ; PUSH IY ;P/u flag table and @@FLAGS ; check if BIT 0,(IY+'L'-'A') ; step prompt inhibited POP IY JR NZ,PSTEP1 ;Bypass if set ; BIT 5,(IY+3) ;Need prompt, 8"? JR NZ,STEP8 ;Jump if 8" ; ; 5" drive step rate parsing ; STEP5 LD HL,STEP5$ ;"...step rate - 5" IF @BLD631 LD DE,L3574 ;<631> CALL DOITALL ;<631> JR NZ,STEP5 ;<631> JR C,PSTEP1 ;<631> JR GOTSTEP ;<631> ELSE CALL GET3 CALL CVBIN ;Get 5" step rate OR A ;Use default? JR Z,PSTEP1 ;Go if parm not entered LD B,0 ;Init key to 0 CP 6 JR Z,GOTSTEP LD B,1 ;Init key to 1 CP 12 JR Z,GOTSTEP LD B,2 ;Init key to 2 CP 20 JR Z,GOTSTEP LD B,3 ;Init key to 3 CP 30 JR Z,GOTSTEP CP 40 JR Z,GOTSTEP JR STEP5 ;Re-request, bad value ENDIF ; ; 8" drive step rate parsing ; STEP8 LD HL,STEP8$ ;"step rate - 8"... IF @BLD631 LD DE,L3579 ;<631> CALL DOITALL ;<631> JR NZ,STEP8 ;<631> JR NC,GOTSTEP ;<631> ELSE CALL GET3 CALL CVBIN ;Get 8" step rate OR A ;Use default? JR Z,PSTEP1 ;Go if not entered LD B,0 ;Init key to 0 CP 3 JR Z,GOTSTEP LD B,1 ;Init key to 1 CP 6 JR Z,GOTSTEP LD B,2 ;Init key to 2 CP 10 JR Z,GOTSTEP LD B,3 ;Init key to 3 CP 15 JR Z,GOTSTEP CP 20 JR Z,GOTSTEP JR STEP8 ;Bad entry, re-request ENDIF PSTEP1 LD A,(STEPARM+1) ;P/u step parm entry AND 3 ;Keep 2 lo-order bits JR $+3 GOTSTEP LD A,B ;Stuff boot step rate key LD (STEPDFT),A ; ; Routine to calculate the # of grans per logical ; cylinder so that the GAT byte can be constructed ; CALCGPC LD A,(IY+8) ;P/u # of grans per cyl RLCA ;Rotate to bits 0-2 RLCA RLCA AND 7 ;Strip off other data INC A ;Adj for zero offset ; ; If double siding (cylindering), double the count ; BIT 5,(IY+4) ;Test if 2-sided drive JR Z,$+3 ;Bypass if only 1-sided ADD A,A ;Double the grans/cyl LD BC,0FFFFH ;Init GAT byte to ones CGPC1 SLA B ;Now keep removing low DEC A ; order bits , 1 bit for JR NZ,CGPC1 ; each available granule LD HL,GATBUF ;Pt to GAT buffer area LD A,(IY+6) ;P/u highest # cylinder CGPC2 LD (HL),B ;Stuff the GAT byte into INC L ;Each position of the GAT CP L ;One byte per cylinder JR NC,CGPC2 ; ; Test if we are at 202 first by ignoring the ; first two instructions with LD DE,xxxx ; LD A,0CBH ;Continue to stuff GAT DB 11H ; until cyl 202 CGPC3 LD (HL),C ;Use FFH to show unused INC L CP L ;First test here for JR NZ,CGPC3 ; match against 202 ; ; Prompt for destination disk & prepare it ; LD A,(FMTDRV+1) ;P/u drive OR A JR NZ,PFMT1 ;Bypass if other than 0 PMTDST @@DSPLY PMTDST$ ;"load dest disk... PUSH IY ;Save DCT pointer @@FLAGS ;Point to flags BIT 5,(IY+'S'-'A') ;Check for JCL active POP IY ;Restore pointer JP NZ,FMTABT ;Abort if in JCL LD HL,HITBUF LD BC,0 ;Zero characters means @@KEYIN ;Enter or Break only JP C,FMTABT ;Abort if Break PFMT1 PUSH IY ;Xfer DCT ptr to HL POP HL ; & move DCT again LD DE,TMPDCT ; to store tempy LD BC,10 LDIR IF @MOD2 CALL SELECT JP NZ,IOERR ;Go on error ENDIF CALL RESTOR ;Restore to cyl 0 JP NZ,IOERR ;Go on error CALL RSELCT ;Reselect drive JP NZ,IOERR ;Go on error BIT 4,(IY+4) ;Jump if alien controller JR NZ,PFMT3 LD HL,NOTRDY$ ;Init "drive not ready BIT 7,A ;Test FDC status for READY JP NZ,EXTERR ;Quit if not ready LD HL,NODRV$ ;Init "drive not in... BIT 2,A ;Test FDC status for TRACK-0 JP Z,EXTERR ; & error if not at track 0 CALL CKDRV ;Ck if floppy not present JR NZ,PMTDST LD HL,CANTWR$ ;Init "write protected.. RLCA ;Align to bit 7 OR (IY+3) ;Combine with soft WP AND 80H ;WP error? JP NZ,EXTERR ;Can't format over WP LD A,(SYSPRM+1) ;Don't check space needed OR A ; if SYSTEM info only JR NZ,PFMT3 LD HL,FORMAT ;Start of format buffer PFMT2 LD DE,0 ;P/u format space needed ADD HL,DE ;Pt to last addr needed LD D,H ;Xfer to reg DE LD E,L LD HL,0 ;Set up for HIGH$ fetch LD B,L @@HIGH$ ;Make sure it won't wrap XOR A SBC HL,DE ; into protected memory LD HL,NOMEM$ ;Init "insufficient mem.. JP C,EXTERR ;Quit if no memory available PFMT3 LD DE,0 ;Init to cyl 0, sect 0 CALL VERSEC ;Verify BOOT JP NZ,PFMT6 ;Assume unformated if err ; ; Appears formatted, is there SYSTEM information? ; LD A,(SYSPRM+1) ;Ignore data if SYSTEM OR A ; info only JP NZ,PFMT6 LD HL,HITBUF ;Pt to i/o buffer CALL RDSEC ;Now try to read BOOT JP NZ,IOERR ;Jump on error @@LOGOT HASDAT$ ;Show "disk contains data LD HL,NOFMT$ ;Init "non-std format ; ; BOOT was read, is there a valid directory pointer ; LD A,(HITBUF+2) ;P/u dir cyl # (possible) CP (IY+6) ;Check against max cyl # JR NC,PFMT5 ;Go if bigger (or =) ; ; Read the assumed GAT & test it ; LD HL,HITBUF LD E,L LD D,A ;Pt to assumed GAT sector LD HL,HITBUF ;Pt to buffer CALL RDSEC ;Read the sector CP 6 ;Dir errcod returned? JR Z,PFMT4 ;Jump if yes & grab data LD HL,CANTRD$ ;Init "unreadable dir... JR PFMT5 PFMT4 LD HL,NODIR$ ;Init "non-init dir LD A,(HITBUF+0DAH) ;Check if date field CP '/' ; is present JR NZ,PFMT5 ;Jump if no ; ; The directory is readable - request its MPW ; LD HL,HITBUF+0D0H LD DE,PACKID$+5 ;Move name & date into LD BC,8 ; display message field LDIR LD DE,PACKID$+14H LD C,8 LDIR ; ; If MPW = "PASSWORD", just ck ABS ; LD HL,(HITBUF+0CEH) ;P/u disk MPW LD DE,PASSWORD ;Password=PASSWORD XOR A SBC HL,DE ;Is it password? LD HL,PACKID$ ;Init"Name=, Date= JR Z,PFMT5 ;If match, go check ABS IF @BLD631 PUSH IY ;<631> @@FLAGS ;<631> BIT 7,(IY+0DH) ;<631> POP IY ;<631> JR NZ,PFMT5 ;<631> ENDIF @@LOGOT ;Log the ID field PUSH IY ;Abort if in JCL @@FLAGS BIT 5,(IY+'S'-'A') ;Test if "DOing" POP IY JP NZ,FMTABT ;Can't get PW if in JCL ; ; User must enter Current Pack's MPW to proceed ; OLDMPW LD HL,OLDMPW$ ;"What's the old MPW? CALL INPMPW ;Grab user input to match JR NC,OLDMPW LD DE,MPWBUF CALL HASHMPW ;Hash user entry ; ; Routine to test master password for match ; EX DE,HL ;Xfer hashed MPW to DE LD HL,(HITBUF+0CEH) ;Else grab pack MPW XOR A ;Clear carry flag SBC HL,DE ;Did user enter pack MPW? JP NZ,BADMPW ;Abort if no match JR PFMT6 ; ; The directory was not readable - req assurance ; PFMT5 @@LOGOT APARM LD DE,0 ;ABS parameter INC E JR Z,PFMT6 ;Go if ABS used PUSH IY @@FLAGS BIT 5,(IY+'S'-'A') ;Test if "DOing" POP IY JP NZ,FMTABT ;Abort if JCL but no ABS LD HL,SURE?$ ;"are you sure...? CALL GET3 ;Get response LD A,(HL) CP 'Y' ;If not Yes, abort JP NZ,FMTABT PFMT6 PUSH IY ;Move drive code table POP DE ; back into place LD HL,TMPDCT ; into system slot LD BC,10 LDIR CALL RESTOR ;Restore to cylinder 0 JP NZ,IOERR ;Go on error JP GOFMT ;Go and format it ; ; Routine to set up the DCT for format ; SETUP LD A,(PCYL2+1) ;P/u the highest # cyl BIT 5,(IY+3) ;If 8" drive, use 77 JR Z,$+4 ;Go if only 5" LD A,77 ;8" drives are 77 cyls DEC A LD (IY+6),A ;Stuff in our DCT LD E,(HL) ;Grab address to INC HL ; master formatting table LD D,(HL) INC HL LD (FMTTBL+1),DE ;Stuff for later use LD E,(HL) ;P/u DCT+7 data INC HL ;Max sector, # of heads LD D,(HL) ;P/u DCT+8 data, # of INC HL ; sectors/gran & grans/cyl LD (IY+7),E ;Stuff these values into LD (IY+8),D ; our DCT LD E,(HL) ;P/u space needed for INC HL ; the formatting buffer LD D,(HL) LD (PFMT2+1),DE ; & stuff that for later RET IF @BLD631 DOITALL:PUSH DE ;<631> CALL GET3 ;<631> CALL CVBIN ;<631> POP HL ;<631> OR A ;<631> SCF ;<631> RET Z ;<631> LD B,0 ;<631> CP (HL) ;<631> RET Z ;<631> INC HL ;<631> INC B ;<631> CP (HL) ;<631> RET Z ;<631> INC B ;<631> INC HL ;<631> CP (HL) ;<631> RET Z ;<631> INC HL ;<631> INC B ;<631> CP (HL) ;<631> RET Z ;<631> INC HL ;<631> CP (HL) ;<631> RET ;<631> L3574: DB 06H,0CH,14H,1EH,28H ;<631> L3579: DB 03H,06H,0AH,0FH,14H ;<631> ENDIF ; ; Convert decimal ASCII to binary ; CVBIN LD E,0 ;Init value to 0 CVB1 LD A,(HL) ;Get a character INC HL ;Bump buff ptr SUB 30H ;Make binary LD B,A CP 0AH ;Was it a decimal digit? LD A,E RET NC ;Return if not ADD A,A ;Mult previous value X 10 ADD A,A ADD A,E ADD A,A ADD A,B ;Add in new digit LD E,A ;Put results in E JR CVB1 ;Loop ; INPMPW @@DSPLY LD HL,MPWBUF ;Use this buffer LD B,8 ;8 chars max CALL GET8A ;Input the pswd RET Z ;Go if Enter only EX DE,HL ADD A,E ;Find where the X'0D' was LD L,A ; stuffed & cover it LD A,D ADC A,0 LD H,A LD A,8 ;If 8 chars entered, SUB B SCF ; done RET Z LD B,A ; else pad the buffer FILLBLK LD (HL),' ' ; w/spaces INC HL DJNZ FILLBLK SCF RET ; CKMPW CALL CKMPW0 RET NZ ; ; Hash a diskette password ; HASHMPW LD A,0E4H ;Use SYS2 routine RST 40 ; CKMPW0 LD B,8 ;8 char to check PUSH DE ;Xfer start of PW POP HL ; to HL LD A,(HL) ;P/u 1st char JR CKMPW2 ; & check CKMPW1 INC HL ;Advance to next char LD A,(HL) ;P/u the char CP ' ' JR Z,CKMPW7 ;Go on space CP '0' JR C,INVMPW ;Bad if less than o CP '9'+1 ; or greater than 9 JR C,CKMPW3 CKMPW2 CP 'A' JR C,INVMPW ; but less than A CP 'Z'+1 JR NC,INVMPW ;More than Z also bad CKMPW3 DJNZ CKMPW1 ;Char ok, do another XOR A ;Set Z, PW good RET ; CKMPW5 INC HL ;Next char position CP (HL) ;No imbedded spaces JR NZ,INVMPW CKMPW7 DJNZ CKMPW5 ;Loop til 8 checked XOR A ;Set Z = PW good RET ; INVMPW LD HL,INVMPW$ ;Init "Invalid PW LD A,63 ;Indicate extended error OR A ;Set NZ condition RET ; ; Brief routine to check a drive for availability ; CKDRV LD HL,HITBUF @@TIME ;P/u the timer pointer EX DE,HL ;TIME$ to HL DEC HL ;TIMER$ to HL LD A,(HL) ;P/u current timer value ADD A,15 ;Set timeout to 500ms LD D,A ;Save for test later ; ; Test for diskette in drive & rotating ; CKDR1 CALL CKDR6 ;Test index pulse JR NZ,CKDR1 ;Jump on index CKDR2 CALL CKDR6 ;Test index pulse JR Z,CKDR2 ;Jump on no index CKDR2A CALL CKDR6 JR NZ,CKDR2A ;Jump on index RET CKDR6 EI ;Make sure they're ON LD A,(HL) ;P/u latest TIMER$ value SUB D ;500ms passed? JR Z,CKDR7 CALL RSELCT ;Select & wait not busy BIT 1,A ;Test index RET CKDR7 POP DE ;Pop the ret address OR 1 ;Set "Illegal drive # RET ;With NZ ; ; Temporary storage space for format drive DCT ; TMPDCT DS 10 DCTCYL DS 8 ;Default # cyls ; ; Config table for single density 5" ; TBLDATA EQU $ DW S5TBL,2409H,3381 ; ; Config table for double density 5" ; DW D5TBL,4511H,6506 ; ; Config table for single density 8" ; DW S8TBL,270FH,5464 ; ; Config table for double density 8" ; DW D8TBL,491DH,10673 ; ; Parm error exit ; BADNAM LD HL,BADNAM$ DB 0DDH BADMPW LD HL,INVMPW$ DB 0DDH NOTHARD LD HL,HARD$ JP EXTERR PRMERR LD A,44 ;Init Parm ERROR JP IOERR ; ; Load SYS2 overlay ; GETSYS2 LD A,84H RST 28H ; MPWBUF DB ' ' PRMTBL$ VAL EQU 80H SW EQU 40H STR EQU 20H SGL EQU 10H DB 80H DB SW!STR!SGL!4,'NAME',0 NRESP EQU $-1 DW NPARM+1 DB SW!STR!SGL!3,'MPW',0 MRESP EQU $-1 DW MPARM+1 DB SW!4,'SDEN',0 DW SDPARM+1 DB SW!4,'DDEN',0 DW DDPARM+1 DB VAL!5,'SIDES',0 DW SIDES+1 DB VAL!SGL!3,'CYL',0 DW CPARM+1 DB VAL!4,'STEP',0 DW STEPARM+1 DB SW!SGL!3,'ABS',0 DW APARM+1 DB SW!SGL!5,'QUERY',0 DW QPARM+1 DB SW!6,'SYSTEM',0 DW SYSPRM+1 DB VAL!SGL!4,'WAIT',0 DW WAITPRM+1 DB VAL!SGL!3,'DIR',0 DW DIRPARM+1 NOP ; HELLO$ DB 'FORMAT' *GET CLIENT:3 HARD$ DB 'Cannot "SYSTEM" a floppy',CR IF @BLD631 NOMEM$ DB 'Out of memory',CR ;<631> ELSE NOMEM$ DB 'Insufficient memory for ' DB 'specified format',CR ENDIF WHDRV$ DB 'Which drive is to be used ? ',3 DSKNAM$ DB 'Diskette name ? ',3 MPW$ DB 'Master password ? ',3 NUMCYL$ DB 'Number of cylinders ? ',3 IF @BLD631 STEP5$ DB 'Boot strap step rate ' ;<631> ELSE STEP5$ DB 'Boot strap stepping rate ' ENDIF DB '<6, 12, 20, 30 msecs> ? ',3 IF @BLD631 STEP8$ DB 'Bootstrap step rate ' ;<631> ELSE STEP8$ DB 'Bootstrap stepping rate ' ENDIF DB '<3, 6, 10, 15/20 msecs> ? ',3 SIDES$ DB 'Enter number of sides <1,2> ? ',3 DEN?$ DB 'Single or Double density ? ',3 NOTRDY$ DB 'Drive not ready',CR CANTWR$ DB 'Write protected disk',CR NODRV$ DB 'Drive not in system',CR PMTDST$ DB 'Load destination diskette ',CR HASDAT$ DB 'Disk contains data -- ',3 NOFMT$ DB 'Non-standard format',CR CANTRD$ DB 'Unreadable directory',CR NODIR$ DB 'Non-initialized directory',CR PACKID$ DB 'Name=XXXXXXXX Date=MM/DD/YY',CR OLDMPW$ DB ' Enter its Master Password' DB ' or to abort: ',3 LASTMSG DB '*** The target drive is a hard disk ***',LF SURE?$ DB 'Are you sure you want to format it ? ',3 INVMPW$ DB LF,'Invalid Master Password',LF,CR BADNAM$ DB 'Invalid Disk Name',CR PAKNAM$ DB 'DATADISK' PAKMPW$ DB 'PASSWORD'