* * "REPAIR" a program to repair the contents of a Helios * diskette at the 'gut' level. (without using PTDOS) * * Entry has the format of: * * *REPAIR (no parameters) * *REPAIR 25 (track number desired) * *REPAIR /1 (disk number desired) * *REPAIR /1,25 (disk and track number) * * The program will ask for any data it needs. * If no disk number is specified on entry, the * default disk is selected. Note: only a Helios * II is supported in this version. (disks 0 & 1) * ORG 0100H XEQ START ASCF 0 * COPY NPTDEFS COPY DSKPORTS * * Read in any parameters typed at the PTDOS command * level. If none found issue prompt message and * accept input. Check parameters for legal value. * START LXI SP,STACK CALL INIT CALL INIT1 CALL CRLF CALL BZERO Zero buffer MVI A,PSOPT Delimited read LXI D,INBUF Point to buffer CALL PSCAN See if track # was entered CC RDERR Error, illegal character JZ NOARG No track info present PUSH PSW Save delimiter LDA INBUF See if disk was specified CPI '/' JNZ SDISK If not, must be track # LDA DISKNR Get disk number from buffer CPI 30H Less than 0? JC INERR CPI 32H More than 2? (0-1) JNC INERR STA DISK Store it POP PSW See if delimiter was a comma CPI ',' JNZ TKNBR If not, no track info MVI A,PSOPT Delimited read LXI D,INBUF CALL PSCAN Now get track info CC RDERR Illegal character JNZ TK1 Zero means no track info CALL BZERO JMP TKNBR * * If no arguments found in command line come here. * NOARG CALL BZERO Zero the buffers PUSH PSW SDISK POP PSW LXI D,GLUNI Set default disk number CALL SYST2 MOV A,L ADI 30H Make it ASCII STA DISK LDA INBUF If buffer has track info, ORA A bypass message. JNZ TK1 * TKNBR LXI D,MSG1 Put out track msg CALL WRITE CALL CHIN JC TKNBR Carry indicates input error TK1 CALL CONVT Convert ASCII to binary JC INERR Value error LDA TRACK Get binary value CPI 77 See if greater than 76 JNC TKERR Opps! not correct CALL CRLF CALL CRLF LXI D,MSG7 CALL WRITE LXI D,INBUF CALL WRITE LXI D,MSG8 CALL WRITE LXI D,DISK CALL PUTCH * * This routine positions the read head to the desired * track and loads the head on the selected disk unit. * TKRD LDA DISK SUI 30H RAR . Get disk number JC TR1 MVI A,SD0+NH1+DS1+DS2+DO+NSP Disk 0 JMP TR2 TR1 MVI A,NH0+DS1+DS2+DO+NSP Disk 1 TR2 OUT DCOM Send out restore command OUT DTADL Clear status PUSH PSW MVI A,-1 Send 'do nothing' command OUT DTCOM CALL SCCHK See if seek completed POP PSW ORI 10H Deactivate restore OUT DCOM PUSH PSW CALL DRCHK Get disk status LDA TRACK Get track # MOV B,A POP PSW OUT DCOM Send it out again ANI 0FDH Now switch step dir to in OUT DCOM ANI 0FEH Now switch on step INR B TR3 DCR B JZ TR4 OUT DCOM JMP TR3 Keep stepping TR4 CALL SCCHK See if seek compeleted * * This routine reads in up to 16 headers if there are * that many found on the track. Next it analyzes the * data to pass to the INFO module. If there is a read * error it issues a message. * MAIN LXI H,HDBUF-16 Set up target for read SHLD BUFER CALL SRCHK See if disk is ready CALL IXCHK Wait for index hole to come around MVI A,16 Load A with count STA COUNT Save it M1 CALL RDHDR Read in a header LDA COUNT DCR A Decrement count JZ INFO STA COUNT CALL DUPCK See if we have read same header before JZ INFO JMP M1 * * Now that the headers have been read in, analyze * the data and present it in the INFO block for * the user to act upon. * INFO LXI D,MSG9 CALL WRITE LXI D,INBUF CALL WRITE LXI D,MSG8 CALL WRITE LXI D,DISK CALL PUTCH LXI D,MSG10 CALL WRITE CALL BCALC LXI D,UBLKS CALL WRITE LXI D,MSG11 CALL WRITE LXI D,FBLKS CALL WRITE LXI D,MSG12 CALL PUTCH CALL CRLF LXI D,MSG13 CALL PUTCH LXI D,MSG14 CALL PUTCH CALL BOUT LXI H,HDBUF MOV A,M CALL ASCII JMP FINIS * * ASCII MOV C,A RRC RRC RRC RRC CALL AS1 MOV A,C AS1 ANI 0FH ADI 30H CPI 3AH JC OUTH ADI 7 OUTH JMP CONOUT * BCALC RET UBLKS DB 30H,37H,0 FBLKS DB 30H,32H,0 * RDHDR LXI B,16 Load buffer offset LXI D,13 Read 13 bytes of Header LHLD BUFER Point to Header buffer DAD B Add offset SHLD BUFER CALL TADTL Send out data MVI A,7 Load A with read header command OUT DTCOM CALL TRCHK JNZ ABORT Error! RET * DUPCK LDA FLAG CPI 0FFH See if flag set JZ D1 If so, this is 1st header read LHLD BUFER CMP M See if we're back at sector 0 yet RZ D1 XRA A STA FLAG ORI 1 RET * DATRD LXI H,TKBUF Point to track buffer DAD B Add offset SHLD BUFAD Store address LXI H,HDBUF Point to Header buffer LXI D,0AH Point to byte count DAD D Add it to HL DAD B Add offset SHLD DALEN Store address CALL TRDAT RET * TRDAT LHLD DALEN Get # of bytes to Xfer XCHG Pass it to DE INX D INX D Add 3 to count INX D LHLD BUFER Get target address in buffer CALL TADTL Send it out MVI A,3 Issue command OUT DTCOM CALL TRCHK Check transfer OK JNZ ABORT CALL CRCHK CRC OK? CALL SRCHK Now wait for status ready XRA A OUT DTADL Reset latch RET * NLST * TKERR LXI D,MSG4 CALL PUTCH JMP TKNBR * MSG1 ASCZ 'Track number:' MSG2 ASCZ ' Input too long.' MSG3 ASCZ ' Error' MSG4 ASCZ ' Track number must be between 0 - 76.' MSG5 ASCZ 'Argument error' MSG7 ASCZ 'Loading Track: ' MSG8 ASCZ ' of Unit: ' MSG9 DB 0AH,0DH ASCZ ' Information contained on track: ' MSG10 ASCZ ' Track contains ' MSG11 ASCZ ' blocks in use and ' MSG12 ASCZ ' free blocks.' MSG13 ASC 'SECTOR BLK SIZE DATA LENTH FILE NAME ' ASCZ ' PREV BLOCK NEXT BLOCK' MSG14 ASC '+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-' ASCZ '+-+-+-+-+-+-+-+-+-+-+-+' * INERR LXI D,MSG3 CALL PUTCH JMP TKNBR * CHIN LXI D,INBUF Point to buffer MVI C,3 Get ready to read in 2 char MVI A,' ' CALL CONOUT Put out a space CH1 CALL CONIN ANI 7FH JZ FINIS If a mode, exit CPI 0DH CR? RZ CPI 7FH Was it a delete? JZ DELT DCR C JZ LONG Input was too long STAX D INX D CALL CONOUT JMP CH1 * FINIS CALL SYST1 CALL SYS Short reset to PTDOS DB RETOP * DELT MVI A,3 CMP C JZ CH1 INR C DCX D MVI A,5FH CALL CONOUT JMP CH1 * LONG LXI D,MSG2 CALL PUTCH STC RET * PUTCH CALL WRITE JMP CRLF * WRITE LDAX D ORA A RZ CALL CONOUT INX D JMP WRITE * CRLF MVI A,0DH CALL CONOUT MVI A,0AH JMP CONOUT * BOUT MVI A,20H CALL CONOUT JMP CONOUT * BZERO MVI C,14H XRA A LXI D,INBUF Z1 STAX D INX D DCR C JNZ Z1 LXI B,1500H Space for 1 track LXI D,HDBUF Header buffer area Z2 XRA A STAX D DCX B INX D MOV A,B ORA C JNZ Z2 CMA STA FLAG RET * CONVT LXI H,INBUF LXI D,TRACK MVI A,0D5H MVI B,0AH CALL PSCAN RC XCHG SHLD TRACK RET * ABORT STA ERCODE POP H DCX H DCX H DCX H DCX H MOV A,M STA OPCODE PUSH H ABRT1 CALL SYST1 LXI H,MSG6 MVI A,2 CALL UTIL DB UXOP Output to console JMP ABRT2 * OPCODE DB 0FFH Op code (none) ERCODE DB 0FFH Error code (none) * ABRT2 CALL SYS DB ABTOP * MSG6 ASCZ 'REPAIR' * RDERR MOV A,E 0 if error ORA A JZ ARGER STA ERCODE JMP ABRT1 * ARGER LXI D,MSG5 CALL PUTCH CALL SYS DB RESOP Short reset * TADTL MOV A,L OUT DTADL MOV A,H OUT DTADH MOV A,E OUT DTLL MOV A,D OUT DTLH RET * SRCHK IN DSTAT ANI SR JZ SRCHK * TRCHK IN DSTAT ANI TC+SR+AB+CE JZ TRCHK ANI AB+CE RET * SCCHK IN DSTAT ANI SC JNZ SCCHK RET * DRCHK IN DSTAT ANI DR RZ OUT DTADL JMP DRCHK * IXCHK IN DSTAT RLC JC IXCHK RET * CRCHK IN DSTAT ANI CC RNZ IN DSTAT ANI CE+AB JZ CRCHK * INIT LXI D,GLERS Get error 2 addr CALL SYST2 SHLD ERR2 Store it LXI D,GLERM Get error 1 addr CALL SYST2 SHLD ERR1 Store it RET * INIT1 LXI D,GLERS LXI H,0FFFFH CALL SYST3 LXI D,GLERM LXI H,0FFFFH CALL SYST3 RET * SYST1 LXI D,GLERS LHLD ERR2 CALL SYST3 LXI D,GLERM LHLD ERR1 CALL SYST3 RET * SYST2 LHLD SYSGLO DAD D MOV A,M INX H MOV H,M MOV L,A RET * SYST3 PUSH H LHLD SYSGLO DAD D POP D MOV M,E INX H MOV M,D RET * DS 64 STACK EQU $ INBUF DS 1 DISKNR DS 19 ERR1 DS 2 ERR2 DS 2 TRACK DS 2 BUFER DS 2 BUFAD DS 2 DISK DS 1 TOP DB 0 FLAG DS 1 1st Header read flag COUNT DS 1 HDBUF EQU 0F00H Header buffer area FWPTR EQU HDBUF+3 BWPTR EQU FWPTR+2 FILID EQU BWPTR+2 BKLEN EQU FILID+1 DALEN EQU BKLEN+1 TKBUF EQU HDBUF+256 Track data buffer *.