home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / HARDDISK / ADJUST.ZIP / ADJUST.ASM next >
Encoding:
Assembly Source File  |  1988-02-10  |  31.6 KB  |  1,395 lines

  1. ;
  2. ;
  3. ;
  4. TITLE    * PARAMS.ASM *
  5. ;
  6. IF1
  7. %OUT [PASS1]
  8. ELSE
  9. %OUT [PASS2]
  10. ENDIF
  11. ;
  12. COLUMNS    EQU    79
  13. CR    EQU    0DH
  14. LF    EQU    0AH
  15. CREATE    EQU    3CH
  16. WRITEF    EQU    40H
  17. CLOSEF    EQU    3EH
  18. DISK    EQU    13H
  19. MS_DOS    EQU    21H
  20. VID_ROM    EQU    10H
  21. PAR_TAB_LEN    EQU    64
  22. PAR_TBL_INT    EQU    41H
  23. CTL_BRK_INT    EQU    1BH
  24. CTL_C_INT    EQU    23H
  25. ;
  26. PARAMS    STRUC
  27. NUMBER_OF_TRACKS    DW    ?
  28. NUMBER_OF_HEADS        DB    ?
  29. START_REDUCE_WRITE    DW    ?
  30. START_WRITE_PRECOMP    DW    ?
  31. MAX_BITS_TO_CORRECT    DB    ?
  32. CONTROL_OPTIONS        DB    ?
  33. TIME_OUT_READ_WRITE    DB    ?
  34. TIME_OUT_FORMAT        DB    ?
  35. TIME_OUT_DIAG        DB    ?
  36. RESERVED        DB    4 DUP (?)
  37. PARAMS    ENDS
  38. ;
  39. PSEG    SEGMENT    PARA PUBLIC 'CODE'
  40.     ASSUME CS:PSEG, DS:PSEG, ES:PSEG, SS:PSEG
  41.     ORG    100H
  42. MAIN    PROC    NEAR
  43.     JMP    BEGIN
  44.     DB    'Copyright (C) 1987 Richard B. Johnson '
  45. CORUP    DB    CR,LF,'This program file is corrupt!$'
  46. BEGIN:    CALL    CHECK
  47.     MOV    DI,OFFSET SECBUF        ;SECTOR BUFFER
  48.     MOV    CX,0FFH                ;WORDS TO FILL
  49.     MOV    AX,0E500H            ;FILL BYTE
  50.     REP    STOSW                ;FILL IT UP
  51.     POPF                    ;FROM THE CHECKSUM
  52.     JZ    GOOD                ;UNMODIFIED FILE
  53.     MOV    DX,OFFSET CORUP            ;WAS CORRUPT OTHERWISE
  54.     CALL    PROMPT                ;TELL THEM
  55.     MOV    AX,4C01H            ;EXIT WITH ERROR
  56.     INT    MS_DOS                ;EXIT TO DOS
  57. GOOD:    CALL    INIT
  58.     CALL    CLS
  59. REPAINT:
  60.     MOV    SP,OFFSET STKTOP        ;PUT STACK IN A SAFE PLACE
  61.     MOV    WORD PTR [DRIVE],80H        ;NORMALIZE DRIVE NAME
  62.     CALL    SCREEN
  63.     CALL    BUFINP
  64.     CALL    COMMAND
  65.     JMP    SHORT REPAINT
  66. EXIT:    JMP    SHORT FINIS
  67. MAIN    ENDP
  68. ;
  69. SCREEN    PROC    NEAR
  70.     CALL    PLOGO
  71.     MOV    DX,OFFSET PRP1
  72.     CALL    PROMPT
  73.     MOV    AL,BYTE PTR [MAX_DRIVES]
  74.     CBW
  75.     CALL    ASCII
  76.     MOV    DX,OFFSET PRP2
  77.     CALL    PROMPT
  78.     MOV    SI,OFFSET DRIVE_ZERO        ;PARAMETER TABLE
  79.     CALL    SHOW
  80.     CALL    PRESENT
  81.     MOV    DX,OFFSET CRLF
  82.     CALL    PROMPT
  83.     MOV    DX,OFFSET ASK
  84.     CALL    PROMPT
  85.     RET
  86. SCREEN    ENDP
  87. ;
  88. FINIS    PROC    NEAR
  89.     CALL    FORM1
  90.     MOV    DX,OFFSET BYEBYE
  91.     CALL    PROMPT
  92.     MOV    DX,OFFSET CRLF
  93.     CALL    PROMPT
  94.     MOV    AX,4C00H
  95.     INT    MS_DOS
  96. FINIS    ENDP
  97. ;
  98. BUFINP    PROC    NEAR
  99.     MOV    BX,OFFSET CONBUF
  100.     MOV    BYTE PTR [BX],10
  101.     MOV    DX,BX
  102.     MOV    AH,10
  103.     INT    MS_DOS
  104.     RET
  105. BUFINP    ENDP
  106. ;
  107. PROMPT    PROC    NEAR
  108.     MOV    AH,9
  109.     INT    MS_DOS
  110.     RET
  111. PROMPT    ENDP
  112. ;
  113. ASCII    PROC    NEAR
  114.     PUSH    CX
  115.     PUSH    BX
  116.     XOR    CL,CL
  117.     MOV    BX,10000
  118.     CALL    SUBTR
  119.     MOV    BX,1000
  120.     CALL    SUBTR
  121.     MOV    BX,100
  122.     CALL    SUBTR
  123.     MOV    BX,10
  124.     CALL    SUBTR
  125.     ADD    AL,'0'                ;ASCII BIAS
  126.     MOV    DL,AL
  127.     CALL    CONOUT
  128.     POP    BX
  129.     POP    CX
  130.     RET
  131. ;
  132. SUBTR    PROC    NEAR
  133.     MOV    DL,'0'-1            ;ONE LESS THAN ASCII BIAS
  134. SUBTR0:    INC    DL                ;BYTE COUNTER
  135.     SUB    AX,BX
  136.     JNC    SUBTR0                ;CONTINUE
  137.     ADD    AX,BX                ;ONE TOO MANY, ADD BACK
  138.     CMP    DL,'0'                ;SEE IF A ZERO
  139.     JNZ    CONOUT                ;NO, PRINT THE NUMBER
  140.     TEST    CL,CL                ;SEE IF A LEADING ZERO
  141.     JNZ    CONOUT                ;NO LEADING ZERO
  142.     MOV    DL,' '                ;FILL WITH A SPACE
  143.     JMP    SHORT SPACE
  144. CONOUT    PROC    NEAR
  145.     MOV    CL,-1                ;LEADING ZERO FLAG
  146. SPACE    PROC    NEAR
  147.     PUSH    AX
  148.     MOV    AH,2                ;CONSOLE OUTPUT
  149.     INT    MS_DOS                ;CHARACTER IS IN DL
  150.     POP    AX
  151.     RET
  152. SPACE    ENDP
  153. CONOUT    ENDP
  154. SUBTR    ENDP
  155. ASCII    ENDP
  156. ;
  157. INIT    PROC    NEAR
  158.     MOV    WORD PTR [DRIVE],80H        ;FIX UP DRIVE NUMBER
  159.     CALL    GET_PAR                ;GET DRIVE PARAMSTERS
  160.     INT    DISK                ;GET DRIVE PARAMETERS
  161.     TEST    DL,DL                ;SEE IS ANY DRIVES
  162.     JNZ    SOME                ;YES
  163.     RET                    ;NO DRIVES
  164. SOME:    MOV    BYTE PTR [MAX_DRIVES],DL    ;NUMBER OF DRIVES
  165.     MOV    CX,4                ;TABLE ENTRIES
  166.     PUSH    DS                ;SAVE DATA SEGMENT
  167.     XOR    AX,AX                ;GET A ZERO
  168.     MOV    DS,AX                ;INTO DATA SEGMENT
  169.     MOV    SI,PAR_TBL_INT * 4        ;PARAMETER TABLE
  170.     LODSW                    ;GET OFFSET
  171.     MOV    DS,WORD PTR [SI]        ;GET SEGMENT
  172.     MOV    SI,AX
  173.     MOV    WORD PTR ES:[SAV_OFF],AX    ;SAVE LOCATIONS IN LOCAL CODE
  174.     MOV    WORD PTR ES:[SAV_SEG],DS
  175.     MOV    DI,OFFSET DRIVE_ZERO        ;FIRST DRIVE TABLE
  176. MOVDAT:    PUSH    CX                ;SAVE DRIVE COUNT
  177.     MOV    CX,PAR_LEN            ;LENGTH OF PARAMETER TABLE
  178.     REP    MOVSB                ;PUT IN OUR SEGMENT
  179.     POP    CX                ;RESTORE DRIVE COUNT
  180.     LOOP    MOVDAT
  181.     MOV    AL,BYTE PTR DS:[2]        ;SIZE OF PROM/MOD 255
  182.     POP    DS                ;RESTORE DATA
  183.     XOR    AH,AH                ;DUMP HIGH BYTE
  184.     XOR    DX,DX                ;READY FOR MULTIPLY
  185.     MOV    CX,512                ;MOD 512
  186.     MUL    CX
  187.     MOV    WORD PTR [PROM_LEN],AX        ;SAVE PROM LENGTH
  188.     RET
  189. INIT    ENDP
  190. ;
  191. SHOW    PROC    NEAR
  192.     MOV    DX,OFFSET PRP3            ;NUMBER OF TRACKS
  193.     CALL    PROMPT
  194.     MOV    CX,4                ;FOUR DRIVE TYPES
  195.     XOR    BX,BX                ;OFFSET ZERO
  196. N_TRK:    MOV    AX,WORD PTR [BX+SI.NUMBER_OF_TRACKS]
  197.     ADD    BX,16
  198.     PUSH    AX
  199.     CALL    ASCII
  200.     POP    AX
  201.     CALL    HEXW
  202.     LOOP    N_TRK
  203. ;
  204.     MOV    DX,OFFSET PRP4            ;NUMBER OF HEADS
  205.     CALL    PROMPT
  206.     MOV    CX,4                ;FOUR DRIVE TYPES
  207.     XOR    BX,BX                ;OFFSET ZERO
  208. N_HDS:    MOV    AL,BYTE PTR [BX+SI.NUMBER_OF_HEADS]
  209.     ADD    BX,16
  210.     CBW
  211.     PUSH    AX
  212.     CALL    ASCII
  213.     POP    AX
  214.     CALL    HEXW
  215.     LOOP    N_HDS
  216. ;
  217.     MOV    DX,OFFSET PRP5            ;START REDUCE WRITE
  218.     CALL    PROMPT
  219.     MOV    CX,4                ;FOUR DRIVE TYPES
  220.     XOR    BX,BX                ;OFFSET ZERO
  221. N_RWT:    MOV    AX,WORD PTR [BX+SI.START_REDUCE_WRITE]
  222.     ADD    BX,16
  223.     PUSH    AX
  224.     CALL    ASCII
  225.     POP    AX
  226.     CALL    HEXW
  227.     LOOP    N_RWT
  228. ;
  229.     MOV    DX,OFFSET PRP6            ;START PRECOMPENSATION
  230.     CALL    PROMPT
  231.     MOV    CX,4                ;FOUR DRIVE TYPES
  232.     XOR    BX,BX                ;OFFSET ZERO
  233. N_WPC:    MOV    AX,WORD PTR [BX+SI.START_WRITE_PRECOMP]
  234.     ADD    BX,16
  235.     PUSH    AX
  236.     CALL    ASCII
  237.     POP    AX
  238.     CALL    HEXW
  239.     LOOP    N_WPC
  240. ;
  241.     MOV    DX,OFFSET PRP7            ;ERROR CORRECTION
  242.     CALL    PROMPT
  243.     MOV    CX,4                ;FOUR DRIVE TYPES
  244.     XOR    BX,BX                ;OFFSET ZERO
  245. N_BTC:    MOV    AL,BYTE PTR [BX+SI.MAX_BITS_TO_CORRECT]
  246.     ADD    BX,16
  247.     CBW
  248.     PUSH    AX
  249.     CALL    ASCII
  250.     POP    AX
  251.     CALL    HEXW
  252.     LOOP    N_BTC
  253. ;
  254.     MOV    DX,OFFSET PRP8            ;OPTIONS BYTE
  255.     CALL    PROMPT
  256.     MOV    CX,4                ;FOUR DRIVE TYPES
  257.     XOR    BX,BX                ;OFFSET ZERO
  258. N_OPT:    MOV    AL,BYTE PTR [BX+SI.CONTROL_OPTIONS]
  259.     ADD    BX,16
  260.     XOR    AH,AH
  261.     PUSH    AX
  262.     CALL    ASCII
  263.     POP    AX
  264.     CALL    HEXW
  265.     LOOP    N_OPT
  266. ;
  267.     MOV    DX,OFFSET PRP9            ;TIMEOUT
  268.     CALL    PROMPT
  269.     MOV    CX,4                ;FOUR DRIVE TYPES
  270.     XOR    BX,BX                ;OFFSET ZERO
  271. N_TIMR:    MOV    AL,BYTE PTR [BX+SI.TIME_OUT_READ_WRITE]
  272.     ADD    BX,16
  273.     XOR    AH,AH
  274.     PUSH    AX
  275.     CALL    ASCII
  276.     POP    AX
  277.     CALL    HEXW
  278.     LOOP    N_TIMR
  279. ;
  280.     MOV    DX,OFFSET PRP10            ;TIMEOUT
  281.     CALL    PROMPT
  282.     MOV    CX,4                ;FOUR DRIVE TYPES
  283.     XOR    BX,BX                ;OFFSET ZERO
  284. N_TIMF:    MOV    AL,BYTE PTR [BX+SI.TIME_OUT_FORMAT]
  285.     ADD    BX,16
  286.     XOR    AH,AH
  287.     PUSH    AX
  288.     CALL    ASCII
  289.     POP    AX
  290.     CALL    HEXW
  291.     LOOP    N_TIMF
  292. ;
  293.     MOV    DX,OFFSET PRP11            ;TIMEOUT
  294.     CALL    PROMPT
  295.     MOV    CX,4                ;FOUR DRIVE TYPES
  296.     XOR    BX,BX                ;OFFSET ZERO
  297. N_TIMD:    MOV    AL,BYTE PTR [BX+SI.TIME_OUT_DIAG]
  298.     ADD    BX,16
  299.     XOR    AH,AH
  300.     PUSH    AX
  301.     CALL    ASCII
  302.     POP    AX
  303.     CALL    HEXW
  304.     LOOP    N_TIMD
  305.     RET
  306. SHOW    ENDP
  307. ;
  308. HEXW    PROC    NEAR
  309.     PUSH    AX            ;SAVE BYTE
  310.     MOV    DX,OFFSET SPACES
  311.     CALL    PROMPT
  312.     POP    AX
  313.     PUSH    AX
  314.     XCHG    AH,AL
  315.     CALL    HEXB
  316.     POP    AX
  317.     CALL    HEXB
  318.     MOV    DX,OFFSET ENDHEX
  319.     CALL    PROMPT
  320.     RET
  321. HEXW    ENDP
  322. ;
  323. ; Convert byte in AL to    ASCII hex. AX, DX is destroyed.
  324. ;
  325. HEXB    PROC    NEAR
  326.     MOV    AH,AL            ;SAVE BYTE
  327.     SAR    AL,1
  328.     SAR    AL,1
  329.     SAR    AL,1
  330.     SAR    AL,1
  331.     CALL    HEX1
  332.     MOV    AL,AH            ;GET STARTING BYTE
  333. HEX1:    AND    AL,0FH            ;SAVE ONLY LOW FOUR BITS
  334.     ADD    AL,90H            ;ADD BIAS
  335.     DAA                ;OLD INTEL TRICK
  336.     ADC    AL,40H
  337.     DAA
  338.     PUSH    AX
  339.     MOV    DL,AL
  340.     MOV    AH,2                ;CONSOLE OUTPUT
  341.     INT    MS_DOS                ;CHARACTER IS IN DL
  342.     POP    AX
  343.     RET
  344. HEXB    ENDP
  345. ;
  346. PRESENT    PROC    NEAR
  347.     MOV    DX,OFFSET CUR
  348.     CALL    PROMPT
  349.     MOV    WORD PTR [DRIVE],80H    ;FIRST DRIVE
  350.     CALL    GET_PAR            ;GET DRIVE PARAMETERS
  351.     MOV    CL,DL
  352.     XOR    CH,CH
  353. MANY:    PUSH    CX
  354.     CALL    GET_TYPE
  355.     MOV    DX,OFFSET PRP12        ;POINT TO 'DRIVE
  356.     CALL    PROMPT            ;PRINT TO SCREEN
  357.     MOV    AX,WORD PTR [DRIVE]    ;GET DRIVE COUNTER
  358.     SUB    AX,80H
  359.     CALL    ASCII
  360.     MOV    DX,OFFSET PRP13        ;POINT TO 'HEADS
  361.     CALL    PROMPT            ;PRINT TO SCREEN
  362.     CALL    GET_PAR
  363.     MOV    AL,DH            ;GET HEADS
  364.     INC    AL            ;HEADS START TO ZERO
  365.     CBW
  366.     CALL    ASCII            ;PRINT TO SCREEN
  367.     MOV    DX,OFFSET PRP14        ;POINT TO CYLINDERS
  368.     CALL    PROMPT
  369.     PUSH    CX            ;SAVE SECTORS/CYLINDERS
  370.     XCHG    CH,CL            ;PUT MAX CYL IN LOW BYTE
  371.     ROL    CH,1            ;WRAP AROUND TO LOW BITS
  372.     ROL    CH,1
  373.     AND    CH,00000011B        ;MASK HIGH BITS
  374.     MOV    AX,CX            ;TO PRINT
  375.     INC    AX            ;CYLINDERS START AT ZERO
  376.     INC    AX            ;USED TO BE USE FOR BAD SECTOR MAP
  377.     CALL    ASCII
  378.     MOV    DX,OFFSET PRP15        ;POINT TO SECTORS
  379.     CALL    PROMPT
  380.     POP    CX            ;RESTORE SECTORS/CYLINDERS
  381.     AND    CL,00111111B        ;MASK CYLINDER BITS
  382.     MOV    AL,CL            ;COPY TO AX
  383.     XOR    AH,AH
  384.     CALL    ASCII            ;PRINT IT
  385.     MOV    DX,OFFSET TYP
  386.     CALL    PROMPT
  387.     MOV    BX,WORD PTR [DRIVE]    ;GET CURRENT DRIVE
  388.     SUB    BX,80H            ;OFFSET OF DRIVE ZERO
  389.     ADD    BX,OFFSET TYPE0        ;POINT TO DISCRIPTOR
  390.     MOV    AL,BYTE PTR [BX]    ;GET DRIVE TYPE
  391.     INC    AL            ;TYPES START AT ONE
  392.     CBW
  393.     CALL    ASCII            ;PRINT TO SCREEN
  394.     INC    WORD PTR [DRIVE]        ;READY NEXT DRIVE
  395.     POP    CX
  396.     LOOP    MANY
  397.     RET
  398. PRESENT    ENDP
  399. ;
  400. GET_TYPE    PROC    NEAR
  401.     CALL    SET_INT            ;CHANGE PARAMETER TABLE
  402.     CALL    GET_PAR            ;GET DRIVE PARAMETERS
  403.     DEC    DH            ;KNOCK HEADS DOWN
  404.     PUSH    DX            ;SAVE FOR NOW
  405.     DEC    BYTE PTR [DRIVE_ZERO.NUMBER_OF_HEADS]
  406.     CALL    GET_PAR            ;GET DRIVE PARAMETERS
  407.     INC    BYTE PTR [DRIVE_ZERO.NUMBER_OF_HEADS]    ;RESTORE CORRECT
  408.     POP    AX            ;IT WAS DX WHEN PUSHED
  409.     CMP    AX,DX            ;SEE IF PARAMS CHANGED
  410.     MOV    AL,0            ;ASSUME DRIVE ZERO
  411.     JZ    TYPEOK            ;WAS THE CORRECT DRIVE TYPE
  412. ;
  413.     CALL    GET_PAR            ;GET DRIVE PARAMETERS
  414.     DEC    DH            ;KNOCK HEADS DOWN
  415.     PUSH    DX            ;SAVE FOR NOW
  416.     DEC    BYTE PTR [DRIVE_ONE.NUMBER_OF_HEADS]
  417.     CALL    GET_PAR            ;GET DRIVE PARAMETERS
  418.     INC    BYTE PTR [DRIVE_ONE.NUMBER_OF_HEADS]    ;RESTORE CORRECT
  419.     POP    AX            ;IT WAS DX WHEN PUSHED
  420.     CMP    AX,DX            ;SEE IF PARAMS CHANGED
  421.     MOV    AL,1            ;ASSUME DRIVE ONE
  422.     JZ    TYPEOK            ;WAS THE CORRECT DRIVE TYPE
  423. ;
  424.     DEC    DH            ;KNOCK HEADS DOWN
  425.     PUSH    DX            ;SAVE FOR NOW
  426.     DEC    BYTE PTR [DRIVE_TWO.NUMBER_OF_HEADS]
  427.     CALL    GET_PAR            ;GET DRIVE PARAMETERS
  428.     INC    BYTE PTR [DRIVE_TWO.NUMBER_OF_HEADS]    ;RESTORE CORRECT
  429.     POP    AX            ;IT WAS DX WHEN PUSHED
  430.     CMP    AX,DX            ;SEE IF PARAMS CHANGED
  431.     MOV    AL,2            ;ASSUME DRIVE TWO
  432.     JZ    TYPEOK            ;WAS THE CORRECT DRIVE TYPE
  433. ;
  434.     CALL    GET_PAR            ;GET DRIVE PARAMETERS
  435.     DEC    DH            ;KNOCK HEADS DOWN
  436.     PUSH    DX            ;SAVE FOR NOW
  437.     DEC    BYTE PTR [DRIVE_THREE.NUMBER_OF_HEADS]
  438.     CALL    GET_PAR            ;GET DRIVE PARAMETERS
  439.     INC    BYTE PTR [DRIVE_THREE.NUMBER_OF_HEADS]    ;RESTORE CORRECT
  440.     POP    AX            ;IT WAS DX WHEN PUSSED
  441.     CMP    AX,DX            ;SEE IF PARAMS CHANGED
  442.     MOV    AL,3            ;ASSUME DRIVE THREE
  443.     JZ    TYPEOK            ;WAS THE CORRECT DRIVE TYPE
  444.     MOV    AL,-1            ;NONE OF ABOVE
  445. TYPEOK:
  446.     MOV    BX,WORD PTR [DRIVE]    ;GET DRIVE
  447.     SUB    BX,80H            ;NORMALIZE
  448.     ADD    BX,OFFSET TYPE0        ;WHERE TO PUT THE DRIVE TYPE
  449.     MOV    BYTE PTR [BX],AL
  450.     CALL    RES_INT            ;RESTORE INTERRUPTS
  451.     RET
  452. GET_TYPE    ENDP
  453. ;
  454. GET_PAR    PROC    NEAR
  455.     CALL    INI_DRV            ;INITIALIZE TABLE
  456.     MOV    DX,WORD PTR [DRIVE]    ;GET DRIVE PARAMSTERS
  457.     MOV    AX,0800H
  458.     INT    DISK
  459.     RET
  460. GET_PAR    ENDP
  461. ;
  462. FORMAT    PROC    NEAR
  463.     MOV    DX,OFFSET CRLF
  464.     CALL    PROMPT
  465.     JMP    SHORT FORM2
  466. FORM1    PROC    NEAR
  467.     MOV    DL,CR
  468.     CALL    SPACE
  469.     MOV    CX,64
  470. FORM2:    MOV    DL,' '
  471.     CALL    SPACE
  472.     LOOP    FORM2
  473.     RET
  474. FORM1    ENDP
  475. FORMAT    ENDP
  476. ;
  477. PLOGO    PROC    NEAR
  478.     CALL    TOPLINE
  479.     MOV    CX,SPACES1
  480.     CALL    FORMAT
  481.     MOV    DX,OFFSET LOGO1
  482.     CALL    PROMPT
  483.     MOV    CX,SPACES2
  484.     CALL    FORMAT
  485.     MOV    DX,OFFSET LOGO2
  486.     CALL    PROMPT
  487.     RET
  488. PLOGO    ENDP
  489. ;
  490. ; Clear screen and put cursor at home position.
  491. ;
  492. CLS    PROC    NEAR
  493.     MOV    AX,0600H
  494.     MOV    BH,7                ;NORMAL ATTRIBUTE
  495.     XOR    CX,CX                ;UPPER LEFT HAND CORNER
  496.     MOV    DX,1850H            ;LOWER RIGHT
  497.     INT    VID_ROM
  498.     RET
  499. CLS    ENDP
  500. ;
  501. TOPLINE    PROC    NEAR
  502.     MOV    DX,0000H            ;FIRST ROW FIRST COLUMN
  503.     MOV    AH,2                ;SET CURSOR POSITION
  504.     XOR    BH,BH                ;PAGE ZERO
  505.     INT    VID_ROM
  506.     RET
  507. TOPLINE    ENDP
  508. ;
  509. COMMAND    PROC    NEAR
  510.     MOV    SI,OFFSET CONBUF + 1        ;POINT TO COMMAND LINE
  511.     LODSB                    ;GET BYTES TYPED
  512.     TEST    AL,AL
  513.     JZ    CMDEX                ;NOTHING TYPED
  514.     CBW
  515.     MOV    CX,AX
  516.     CALL    UPPER                ;FORCE TO UPPER CASE
  517.     MOV    SI,OFFSET TABLE
  518.     MOV    CX,TAB_LEN            ;BYTES IN THE TABLE
  519. COMP:    PUSH    CX
  520.     MOV    CX,3                ;BYTES IN THE STRING
  521.     MOV    DI,OFFSET CONBUF + 2
  522.     REPZ    CMPSB
  523.     POP    CX                ;RESTORE WORDS IN TABLE
  524.     JNZ    AGAIN
  525.     CALL    WORD PTR [SI]            ;GO THERE
  526.     JMP    SHORT CMDEX            ;GO HOME
  527. AGAIN:    LOOP    COMP
  528. CMDEX:    CALL    FORM1
  529.     RET
  530. COMMAND    ENDP
  531. ;
  532. UPPER    PROC    NEAR
  533.     MOV    DI,SI
  534. FORCE:    LODSB
  535.     CMP    AL,'a'                ;CHECK RANGE
  536.     JC    NOLOW                ;NOT A LOWER CASE LETTER
  537.     CMP    AL,'z'+1            ;LARGER THAN A 'z'?
  538.     JNC    NOLOW                ;NOT LOWER CASE
  539.     AND    AL,95                ;MASK LOWER CASE BITS
  540. NOLOW:    STOSB
  541.     LOOP    FORCE
  542. UPEXIT:    RET
  543. UPPER    ENDP
  544. ;
  545. TABLE    DB    'CHA'
  546.     DW    CHANGE
  547.     DB    'WRI'
  548.     DW    WRITE
  549.     DB    'TRY'
  550.     DW    TRY
  551.     DB    'TES'
  552.     DW    HDTEST
  553.     DB    'NEW'
  554.     DW    REDO
  555.     DB    'CHE'
  556.     DW    CHKSUM
  557.     DB    'EXI'
  558.     DW    FINIS
  559.     DB    'EXP'
  560.     DW    EXPAND
  561.     DB    'SHI'
  562.     DW    SHIP
  563.     DB    'SPE'
  564.     DW    SPEED
  565.     DB    'FOR'
  566.     DW    NFORMAT
  567. TAB_LEN    EQU    $ - TABLE
  568. ;
  569. REDO    PROC    NEAR
  570.     MOV    DX,OFFSET NEW
  571.     CALL    PROMPT
  572.     CALL    INIT
  573.     RET
  574. REDO    ENDP
  575. ;
  576. CHANGE    PROC    NEAR
  577.     CALL    FORM1
  578.     MOV    DX,OFFSET CHANG
  579.     CALL    PROMPT
  580.     MOV    DX,OFFSET DTYPE
  581.     CALL    PROMPT
  582.     CALL    BUFINP
  583.     CALL    EXTRACT
  584.     TEST    AX,AX                ;ANYTHING TYPED?
  585.     JZ    HOME                ;NO
  586.     CMP    AL,5                ;FOUR OR LESS?
  587.     JC    CHGOK                ;YES
  588. HOME:    RET
  589. CHGOK:    MOV    SI,OFFSET DRIVE_ZERO
  590.     DEC    AL                ;CORRECT FOR OFFSET ZERO
  591.     CBW
  592.     MOV    CL,4                ;TIMES SIXTEEN
  593.     SHL    AX,CL
  594.     ADD    SI,AX                ;NEW OFFSET
  595. ;
  596.     CALL    CLS
  597.     CALL    TOPLINE
  598.     MOV    DX,OFFSET PRP3
  599.     CALL    PROMPT
  600.     MOV    AX,WORD PTR [SI.NUMBER_OF_TRACKS]
  601.     CALL    ASCII
  602.     MOV    DX,OFFSET SPACER
  603.     CALL    PROMPT
  604.     CALL    BUFINP
  605.     CALL    EXTRACT
  606.     JCXZ    NEXT1
  607.     MOV    WORD PTR [SI.NUMBER_OF_TRACKS],AX
  608. ;
  609. NEXT1:    MOV    DX,OFFSET PRP4
  610.     CALL    PROMPT
  611.     MOV    AL,BYTE PTR [SI.NUMBER_OF_HEADS]
  612.     CBW
  613.     CALL    ASCII
  614.     MOV    DX,OFFSET SPACER
  615.     CALL    PROMPT
  616.     CALL    BUFINP
  617.     CALL    EXTRACT
  618.     JCXZ    NEXT2
  619.     MOV    BYTE PTR [SI.NUMBER_OF_HEADS],AL
  620. ;
  621. NEXT2:    MOV    DX,OFFSET PRP5
  622.     CALL    PROMPT
  623.     MOV    AX,WORD PTR [SI.START_REDUCE_WRITE]
  624.     CALL    ASCII
  625.     MOV    DX,OFFSET SPACER
  626.     CALL    PROMPT
  627.     CALL    BUFINP
  628.     CALL    EXTRACT
  629.     JCXZ    NEXT3
  630.     MOV    WORD PTR [SI.START_REDUCE_WRITE],AX
  631. ;
  632. NEXT3:    MOV    DX,OFFSET PRP6
  633.     CALL    PROMPT
  634.     MOV    AX,WORD PTR [SI.START_WRITE_PRECOMP]
  635.     CALL    ASCII
  636.     MOV    DX,OFFSET SPACER
  637.     CALL    PROMPT
  638.     CALL    BUFINP
  639.     CALL    EXTRACT
  640.     JCXZ    NEXT4
  641.     MOV    WORD PTR [SI.START_WRITE_PRECOMP],AX
  642. ;
  643. NEXT4:    MOV    DX,OFFSET PRP7
  644.     CALL    PROMPT
  645.     MOV    AL,BYTE PTR [SI.MAX_BITS_TO_CORRECT]
  646.     CBW
  647.     CALL    ASCII
  648.     MOV    DX,OFFSET SPACER
  649.     CALL    PROMPT
  650.     CALL    BUFINP
  651.     CALL    EXTRACT
  652.     JCXZ    NEXT5
  653.     MOV    BYTE PTR [SI.MAX_BITS_TO_CORRECT],AL
  654. ;
  655. NEXT5:    MOV    DX,OFFSET PRP8
  656.     CALL    PROMPT
  657.     MOV    AL,BYTE PTR [SI.CONTROL_OPTIONS]
  658.     XOR    AH,AH
  659.     CALL    ASCII
  660.     MOV    DX,OFFSET SPACER
  661.     CALL    PROMPT
  662.     CALL    BUFINP
  663.     CALL    EXTRACT
  664.     JCXZ    NEXT6
  665.     MOV    BYTE PTR [SI.CONTROL_OPTIONS],AL
  666. ;
  667. NEXT6:    MOV    DX,OFFSET PRP9
  668.     CALL    PROMPT
  669.     MOV    AL,BYTE PTR [SI.TIME_OUT_READ_WRITE]
  670.     XOR    AH,AH
  671.     CALL    ASCII
  672.     MOV    DX,OFFSET SPACER
  673.     CALL    PROMPT
  674.     CALL    BUFINP
  675.     CALL    EXTRACT
  676.     JCXZ    NEXT7
  677.     MOV    BYTE PTR [SI.TIME_OUT_READ_WRITE],AL
  678. ;
  679. NEXT7:    MOV    DX,OFFSET PRP10
  680.     CALL    PROMPT
  681.     MOV    AL,BYTE PTR [SI.TIME_OUT_FORMAT]
  682.     XOR    AH,AH
  683.     CALL    ASCII
  684.     MOV    DX,OFFSET SPACER
  685.     CALL    PROMPT
  686.     CALL    BUFINP
  687.     CALL    EXTRACT
  688.     JCXZ    NEXT8
  689.     MOV    BYTE PTR [SI.TIME_OUT_FORMAT],AL
  690. ;
  691. NEXT8:    MOV    DX,OFFSET PRP11
  692.     CALL    PROMPT
  693.     MOV    AL,BYTE PTR [SI.TIME_OUT_DIAG]
  694.     XOR    AH,AH
  695.     CALL    ASCII
  696.     MOV    DX,OFFSET SPACER
  697.     CALL    PROMPT
  698.     CALL    BUFINP
  699.     CALL    EXTRACT
  700.     JCXZ    NEXT9
  701.     MOV    BYTE PTR [SI.TIME_OUT_DIAG],AL
  702. ;
  703. NEXT9:    CALL    CLS
  704.     RET
  705. CHANGE    ENDP
  706. ;
  707. EXTRACT    PROC    NEAR
  708.     PUSH    SI                ;SAVE INDEX
  709.     MOV    SI,OFFSET CONBUF + 1        ;POINT TO BUFFER
  710.     LODSB                    ;GET CHARACTERS TYPED
  711.     CBW
  712.     MOV    CX,AX                ;USE AS A COUNT
  713.     JCXZ    ENDIT
  714.     XOR    BX,BX                ;USE FOR ACCUMULATOR
  715. SUMEM:    LODSB                    ;GET BYTE
  716.     SUB    AL,'0'                ;REMOVE ASCII BIAS
  717.     JC    ENDIT                ;END OF STRING
  718.     CMP    AL,10
  719.     JNC    ENDIT                ;CHECK RANGE
  720.     CBW
  721.     PUSH    AX                ;SAVE FOR NOW
  722.     MOV    AX,BX                ;GET ACCUMULATED RESULT
  723.     XOR    DX,DX                ;READY FOR MULTIPLY
  724.     MUL    WORD PTR [TEN]            ;MULTIPLY RUNNING COUNT
  725.     MOV    BX,AX                ;GET NEW COUNT
  726.     POP    AX                ;RESTORE CONVERTED BYTE
  727.     ADD    BX,AX                ;ACCUMULATE
  728.     LOOP    SUMEM                ;CONTINUE TO END
  729.     INC    CX                ;USE AS A FLAG
  730. ENDIT:    MOV    AX,BX                ;GET ACCUMUMATOR
  731.     POP    SI                ;RESTORE INDEX
  732.     RET
  733. TEN    DW    10
  734. EXTRACT    ENDP
  735. ;
  736. WRITE    PROC    NEAR
  737.     ASSUME DS:PSEG
  738.     CALL    FORM1
  739.     MOV    DX,OFFSET WRITIN
  740.     CALL    PROMPT
  741.     MOV    DX,OFFSET FNAME            ;POINT TO FILENAME
  742.     XOR    CX,CX                ;NORMAL FILE
  743.     MOV    AH,CREATE            ;CREATE A FILE
  744.     INT    MS_DOS                ;DO IT
  745.     JNC    NOERR1
  746.     MOV    DX,OFFSET MAKERR        ;CAN'T DO IT
  747.     CALL    PROMPT
  748.     CALL    BUFINP
  749.     JMP    WREND
  750. ;
  751. NOERR1:    MOV    WORD PTR [HANDLE],AX        ;SAVE HANDLE
  752.     MOV    BX,AX                ;COPY
  753.     XOR    DX,DX                ;OFFSET ZERO
  754.     MOV    CX,WORD PTR [SAV_OFF]        ;GET BYTES TO WRITE
  755.     PUSH    DS                ;SAVE SEGMENT
  756.     MOV    DS,WORD PTR [SAV_SEG]        ;HD BIOS SEGMENT
  757.     MOV    AH,WRITEF            ;WRITE FIRST PORTION
  758.     INT    MS_DOS
  759.     POP    DS                ;RESTORE SEGMENT
  760.     JNC    NOERR2
  761.     MOV    DX,OFFSET WRERR
  762.     CALL    PROMPT
  763.     CALL    BUFINP
  764.     JMP    SHORT WREND
  765. ;
  766. NOERR2:    MOV    DX,OFFSET DRIVE_ZERO        ;NEW PARAMETERS
  767.     MOV    CX,PAR_TAB_LEN            ;BYTES TO WRITE
  768.     MOV    AH,WRITEF
  769.     MOV    BX,WORD PTR [HANDLE]        ;OPEN FILE
  770.     INT    MS_DOS                ;WRITE SECOND SECTION
  771.     JNC    NOERR3
  772.     MOV    DX,OFFSET WRERR
  773.     CALL    PROMPT
  774.     CALL    BUFINP
  775.     JMP    SHORT WREND
  776. ;
  777. NOERR3:    MOV    DX,WORD PTR [SAV_OFF]        ;GET OFFSET AGAIN
  778.     ADD    DX,PAR_TAB_LEN            ;BYPASS ROM TABLE
  779.     MOV    CX,WORD PTR [PROM_LEN]        ;GET SIZE OF THE PROM
  780.     SUB    CX,PAR_TAB_LEN            ;SUBTRACT PARAMETER TABLE LEN
  781.     SUB    CX,WORD PTR [SAV_OFF]
  782.     MOV    BX,WORD PTR [HANDLE]        ;OPEN FILE
  783.     PUSH    DS                ;SAVE AGAIN
  784.     MOV    DS,WORD PTR [SAV_SEG]        ;GET ADDRESS AGAIN
  785.     MOV    AH,WRITEF
  786.     INT    MS_DOS
  787.     POP    DS                ;RESTORE SEGMENT
  788.     JNC    NOERR4
  789.     MOV    DX,OFFSET WRERR
  790.     CALL    PROMPT
  791.     CALL    BUFINP
  792.     JMP    SHORT WREND
  793. ;
  794. NOERR4:    CMP    WORD PTR [SAV_SEG],0C800H
  795.     JZ    NOERR5
  796.     MOV    DX,OFFSET BADSEG
  797.     CALL    PROMPT
  798.     CALL    BUFINP
  799. NOERR5:    MOV    BX,WORD PTR [HANDLE]        ;OPEN FILE
  800.     MOV    AH,CLOSEF
  801.     INT    MS_DOS
  802. WREND:    RET
  803. WRITE    ENDP
  804. ;
  805. TRY    PROC    NEAR
  806.     MOV    DX,OFFSET OUTSIDE
  807.     CALL    PROMPT
  808.     CALL    SET_INT                ;SET UP NEW TABLES
  809. ;
  810. ; Free some memory
  811. ;
  812.     MOV    BX,OFFSET TOP            ;GET TOP OF PROGRAM
  813.     MOV    CL,4                ;CONVERT TO PARAGRAPHS
  814.     SHR    BX,CL                ;DIV BY SIXTEEN
  815.     INC    BX                ;ROUND UP
  816.     MOV    AH,4AH                ;FUNCTION
  817.     INT    MS_DOS                ;DO IT
  818. ;
  819. ; Load execute COMMAND.COM
  820. ;
  821.     MOV    AX,CS
  822.     MOV    WORD PTR [SEG_1],AX        ;PARAMETER BLOCK FIXUPS
  823.     MOV    WORD PTR [SEG_2],AX
  824.     MOV    WORD PTR [SEG_3],AX
  825.     MOV    BYTE PTR DS:[80H],0        ;SHOW NOTHING TYPED
  826.     MOV    WORD PTR [SP_SAV],SP        ;SAVE STACK POINTER
  827.     MOV    DX,OFFSET COMND            ;POINT TO FILENAME
  828.     MOV    BX,OFFSET BLOCK            ;POINT TO PARAMETER BLOCK
  829.     MOV    AX,4B00H            ;LOAD/EXECUTE
  830.     INT    MS_DOS
  831. ;
  832. ; Recreate environment upon return.
  833. ;
  834.     MOV    AX,CS                ;GET CODE SEGMENT
  835.     MOV    DS,AX
  836.     MOV    ES,AX
  837.     CLI
  838.     MOV    SS,AX
  839.     MOV    SP,WORD PTR [SP_SAV]
  840.     STI
  841.     JNC    FOUND1
  842.     MOV    DX,OFFSET UNABLE1        ;CAN'T FIND THE FILE
  843.     CALL    PROMPT                ;SHOW WE CAN'T FIND FILE
  844.     MOV    DX,OFFSET RETURN
  845.     CALL    PROMPT
  846.     CALL    BUFINP
  847. FOUND1:    CALL    RES_INT                ;RESTORE PARAM TABLE
  848.     CALL    CLS                ;CLEAR THE SCREEN
  849.     RET
  850. TRY    ENDP
  851. ;
  852. CHKSUM    PROC    NEAR
  853.     CALL    FORM1
  854.     MOV    DX,OFFSET SUMIT
  855.     CALL    PROMPT
  856.     MOV    BX,OFFSET TOP            ;GET TOP OF PROGRAM
  857.     MOV    CL,4                ;CONVERT TO PARAGRAPHS
  858.     SHR    BX,CL                ;DIV BY SIXTEEN
  859.     INC    BX                ;ROUND UP
  860.     MOV    AH,4AH                ;FUNCTION
  861.     INT    MS_DOS                ;DO IT
  862. ;
  863. ; Move command line string
  864. ;
  865.     MOV    SI,OFFSET KNOW            ;POINT TO COMMAND LINE STRING
  866.     MOV    DI,80H                ;MOVE TO 80H
  867.     MOV    CL,CMD_LEN            ;LENGTH TO MOVE
  868.     XOR    CH,CH                ;DUMP
  869.     REP    MOVSB
  870.  
  871. ;
  872. ; Load execute CHECKSUM.COM
  873. ;
  874.     MOV    AX,CS
  875.     MOV    WORD PTR [SEG_1],AX        ;PARAMETER BLOCK FIXUPS
  876.     MOV    WORD PTR [SEG_2],AX
  877.     MOV    WORD PTR [SEG_3],AX
  878.     MOV    WORD PTR [SP_SAV],SP        ;SAVE STACK POINTER
  879.     MOV    DX,OFFSET CHKSMF        ;POINT TO FILENAME
  880.     MOV    BX,OFFSET BLOCK            ;POINT TO PARAMETER BLOCK
  881.     MOV    AX,4B00H            ;LOAD/EXECUTE
  882.     INT    MS_DOS
  883. ;
  884. ; Recreate environment upon return.
  885. ;
  886.     MOV    AX,CS                ;GET CODE SEGMENT
  887.     MOV    DS,AX
  888.     MOV    ES,AX
  889.     CLI
  890.     MOV    SS,AX
  891.     MOV    SP,WORD PTR [SP_SAV]
  892.     STI
  893.     JNC    FOUND2
  894.     MOV    DX,OFFSET UNABLE2        ;NO FILE
  895.     CALL    PROMPT                ;SHOW WE CAN'T FIND FILE
  896.     MOV    DX,OFFSET RETURN
  897.     CALL    PROMPT
  898.     CALL    BUFINP
  899. FOUND2:    CALL    CLS                ;CLEAR THE SCREEN
  900.     RET
  901. CHKSUM    ENDP
  902. ;
  903. HDTEST    PROC    NEAR
  904.     CALL    FORM1
  905.     MOV    DX,OFFSET HDTS
  906.     CALL    PROMPT
  907.     CALL    SET_INT
  908.     MOV    BX,OFFSET TOP            ;GET TOP OF PROGRAM
  909.     MOV    CL,4                ;CONVERT TO PARAGRAPHS
  910.     SHR    BX,CL                ;DIV BY SIXTEEN
  911.     INC    BX                ;ROUND UP
  912.     MOV    AH,4AH                ;FUNCTION
  913.     INT    MS_DOS                ;DO IT
  914. ;
  915. ; Load execute HDTEST.COM
  916. ;
  917.     MOV    AX,CS
  918.     MOV    WORD PTR [SEG_1],AX        ;PARAMETER BLOCK FIXUPS
  919.     MOV    WORD PTR [SEG_2],AX
  920.     MOV    WORD PTR [SEG_3],AX
  921.     MOV    BYTE PTR DS:[80H],0        ;SHOW NO COMMAND LINE
  922.     MOV    WORD PTR [SP_SAV],SP        ;SAVE STACK POINTER
  923.     MOV    DX,OFFSET DTESTF        ;POINT TO FILENAME
  924.     MOV    BX,OFFSET BLOCK            ;POINT TO PARAMETER BLOCK
  925.     MOV    AX,4B00H            ;LOAD/EXECUTE
  926.     INT    MS_DOS
  927. ;
  928. ; Recreate environment upon return.
  929. ;
  930.     MOV    AX,CS                ;GET CODE SEGMENT
  931.     MOV    DS,AX
  932.     MOV    ES,AX
  933.     CLI
  934.     MOV    SS,AX
  935.     MOV    SP,WORD PTR [SP_SAV]
  936.     STI
  937.     JNC    FOUND3
  938.     MOV    DX,OFFSET UNABLE3        ;NO FILE
  939.     CALL    PROMPT                ;SHOW WE CAN'T FIND FILE
  940. FOUND3:    MOV    DX,OFFSET RETURN
  941.     CALL    PROMPT
  942.     CALL    RES_INT                ;RESTORE INTERRUPTS
  943.     CALL    BUFINP
  944.     CALL    CLS                ;CLEAR THE SCREEN
  945.     RET
  946. HDTEST    ENDP
  947. ;
  948. ;
  949. SPEED    PROC    NEAR
  950.     CALL    FORM1
  951.     MOV    DX,OFFSET SPED
  952.     CALL    PROMPT
  953.     CALL    SET_INT
  954.     MOV    BX,OFFSET TOP            ;GET TOP OF PROGRAM
  955.     MOV    CL,4                ;CONVERT TO PARAGRAPHS
  956.     SHR    BX,CL                ;DIV BY SIXTEEN
  957.     INC    BX                ;ROUND UP
  958.     MOV    AH,4AH                ;FUNCTION
  959.     INT    MS_DOS                ;DO IT
  960. ;
  961. ; Load execute HDSPEED.COM
  962. ;
  963.     MOV    AX,CS
  964.     MOV    WORD PTR [SEG_1],AX        ;PARAMETER BLOCK FIXUPS
  965.     MOV    WORD PTR [SEG_2],AX
  966.     MOV    WORD PTR [SEG_3],AX
  967.     MOV    BYTE PTR DS:[80H],0        ;SHOW NO COMMAND LINE
  968.     MOV    WORD PTR [SP_SAV],SP        ;SAVE STACK POINTER
  969.     MOV    DX,OFFSET SPEEDF        ;POINT TO FILENAME
  970.     MOV    BX,OFFSET BLOCK            ;POINT TO PARAMETER BLOCK
  971.     MOV    AX,4B00H            ;LOAD/EXECUTE
  972.     INT    MS_DOS
  973. ;
  974. ; Recreate environment upon return.
  975. ;
  976.     MOV    AX,CS                ;GET CODE SEGMENT
  977.     MOV    DS,AX
  978.     MOV    ES,AX
  979.     CLI
  980.     MOV    SS,AX
  981.     MOV    SP,WORD PTR [SP_SAV]
  982.     STI
  983.     JNC    FOUND4
  984.     MOV    DX,OFFSET UNABLE4        ;CAN'T FIND FILE
  985.     CALL    PROMPT                ;SHOW WE CAN'T FIND FILE
  986. FOUND4:    MOV    DX,OFFSET RETURN
  987.     CALL    PROMPT
  988.     CALL    RES_INT                ;RESTORE INTERRUPTS
  989.     CALL    BUFINP
  990.     CALL    CLS                ;CLEAR THE SCREEN
  991.     RET
  992. SPEED    ENDP
  993. ;
  994. ;
  995. SHIP    PROC    NEAR
  996.     CALL    FORM1
  997.     MOV    DX,OFFSET SHIPP
  998.     CALL    PROMPT
  999.     CALL    SET_INT
  1000.     MOV    BX,OFFSET TOP            ;GET TOP OF PROGRAM
  1001.     MOV    CL,4                ;CONVERT TO PARAGRAPHS
  1002.     SHR    BX,CL                ;DIV BY SIXTEEN
  1003.     INC    BX                ;ROUND UP
  1004.     MOV    AH,4AH                ;FUNCTION
  1005.     INT    MS_DOS                ;DO IT
  1006. ;
  1007. ; Load execute SHIP.COM
  1008. ;
  1009.     MOV    AX,CS
  1010.     MOV    WORD PTR [SEG_1],AX        ;PARAMETER BLOCK FIXUPS
  1011.     MOV    WORD PTR [SEG_2],AX
  1012.     MOV    WORD PTR [SEG_3],AX
  1013.     MOV    BYTE PTR DS:[80H],0        ;SHOW NO COMMAND LINE
  1014.     MOV    WORD PTR [SP_SAV],SP        ;SAVE STACK POINTER
  1015.     MOV    DX,OFFSET SHIPF            ;POINT TO FILENAME
  1016.     MOV    BX,OFFSET BLOCK            ;POINT TO PARAMETER BLOCK
  1017.     MOV    AX,4B00H            ;LOAD/EXECUTE
  1018.     INT    MS_DOS
  1019. ;
  1020. ; Recreate environment upon return.
  1021. ;
  1022.     MOV    AX,CS                ;GET CODE SEGMENT
  1023.     MOV    DS,AX
  1024.     MOV    ES,AX
  1025.     CLI
  1026.     MOV    SS,AX
  1027.     MOV    SP,WORD PTR [SP_SAV]
  1028.     STI
  1029.     JNC    FOUND5
  1030.     MOV    DX,OFFSET UNABLE5        ;CAN'T FIND FILE
  1031.     CALL    PROMPT                ;SHOW WE CAN'T FIND FILE
  1032. FOUND5:    MOV    DX,OFFSET RETURN
  1033.     CALL    PROMPT
  1034.     CALL    RES_INT                ;RESTORE INTERRUPTS
  1035.     CALL    BUFINP
  1036.     CALL    CLS                ;CLEAR THE SCREEN
  1037.     RET
  1038. SHIP    ENDP
  1039. ;
  1040. SET_INT    PROC    NEAR
  1041.     PUSH    ES                ;SAVE SEGMENT
  1042.     MOV    AH,35H                ;GET INT VECTOR
  1043.     MOV    AL,PAR_TBL_INT            ;DISK PARAMETER TABLE
  1044.     INT    MS_DOS                ;RETURNS IN ES:BX
  1045.     MOV    WORD PTR [PAR_OFF],BX        ;SAVE IN CODE SEGMENT
  1046.     MOV    WORD PTR [PAR_SEG],ES
  1047.     POP    ES                ;RESTORE SEGMENT
  1048. ;
  1049.     MOV    DX,OFFSET DRIVE_ZERO        ;NEW PARAMETER TABLE
  1050.     MOV    AH,25H                ;PATCH INT VECTOR
  1051.     MOV    AL,PAR_TBL_INT            ;INTERRUPT TO PATCH
  1052.     INT    MS_DOS                ;PATCH VECTOR
  1053. ;
  1054. INI_DRV    PROC    NEAR
  1055.     MOV    AH,9                ;INITIALIZE DRIVE PARAMS
  1056.     MOV    DX,80H
  1057.     INT    DISK                ;DO IT
  1058.     RET
  1059. INI_DRV    ENDP
  1060. SET_INT    ENDP
  1061. ;
  1062. ; Restore moved vectors
  1063. ;
  1064. RES_INT    PROC    NEAR
  1065.     MOV    DX,WORD PTR [PAR_OFF]        ;GET SAVED OFFSET
  1066.     PUSH    DS                ;SAVE SEGMENT
  1067.     MOV    DS,WORD PTR [PAR_SEG]        ;GET SAVED VECTOR SEGMENT
  1068.     MOV    AH,25H                ;PATCH INT VECTOR
  1069.     MOV    AL,PAR_TBL_INT            ;INTERRUPT TO PATCH
  1070.     INT    MS_DOS                ;RESTORE VECTOR
  1071.     POP    DS                ;RESTORE SEGMENT
  1072. ;
  1073.     MOV    AH,9                ;INITIALIZE DRIVE PARAMS
  1074.     MOV    DX,80H
  1075.     INT    DISK                ;DO IT
  1076.     RET
  1077. RES_INT    ENDP
  1078. ;
  1079. EXPAND    PROC    NEAR
  1080.     CALL    FORM1                ;FILL UP SPACES
  1081.     MOV    DX,OFFSET EXP            ;WANNA DO THIS?
  1082.     CALL    PROMPT                ;ASK
  1083.     CALL    BUFINP                ;GET RESPONSE
  1084.     CMP    BYTE PTR [CONBUF+1],0
  1085.     JZ    EXPXT
  1086.     AND    BYTE PTR [CONBUF+2],95        ;MAP TO UPPER CASE
  1087.     CMP    BYTE PTR [CONBUF+2],'Y'
  1088.     JZ    DOIT
  1089. EXPXT:    RET
  1090. DOIT:    CALL    FORM1
  1091.     MOV    DX,OFFSET PRP16            ;POINT TO WHICH DRIVE?
  1092.     CALL    PROMPT                ;ASK
  1093.     CALL    BUFINP                ;GET RESPONSE
  1094.     CALL    EXTRACT                ;GET BINARY
  1095.     JCXZ    EXPXT                ;NOTHING TYPED
  1096.     CMP    AX,2                ;CHECK LIMITS
  1097.     JNC    EXPXT                ;NO SUCH DRIVE
  1098.     ADD    AX,80H                ;ADD IN BIAS
  1099.     MOV    WORD PTR [DRIVE],AX
  1100. ;
  1101.     CALL    SET_INT                ;SET UP INTERRUPT
  1102.     MOV    DX,WORD PTR [DRIVE]        ;GET DRIVE NAME
  1103.     MOV    BX,OFFSET SECBUF        ;SECTOR BUFFER
  1104.     MOV    AX,0F00H            ;WRITE TO SECTOR BUFFER
  1105.     INT    DISK                ;WRITE TO SECTOR BUFFER
  1106. ;
  1107.     MOV    DX,WORD PTR [DRIVE]        ;GET DRIVE
  1108.     CALL    GET_PAR                ;GET DRIVE PARAMETERS
  1109.     XCHG    CH,CL                ;WHOLE TRACK INTO CL
  1110.     AND    CH,11000000B            ;MASK SECTORS
  1111.     ROL    CH,1
  1112.     ROL    CH,1                ;INTO LOW POSITION
  1113.     MOV    WORD PTR [MAX_TRK],CX        ;SAVE FOR NOW
  1114. DEXP:    INC    WORD PTR [MAX_TRK]        ;TRY TO ADD ANOTHER TRACK
  1115.     MOV    DX,OFFSET ATTEMPT        ;POINT TO PROMPT
  1116.     CALL    PROMPT
  1117.     MOV    AX,WORD PTR [MAX_TRK]
  1118.     INC    AX
  1119.     PUSH    AX
  1120.     CALL    ASCII                ;PRINT NEW MAX TRACK
  1121.     POP    AX
  1122.     MOV    BX,WORD PTR [DRIVE]        ;GET DRIVE IN USE
  1123.     SUB    BX,80H                ;REMOVE BIAS
  1124.     ADD    BX,OFFSET TYPE0            ;WHERE THE 'TYPE' IS
  1125.     MOV    BL,BYTE PTR [BX]        ;GET DRIVE TYPE
  1126.     XOR    BH,BH                ;RESET HIGH BYTE
  1127.     MOV    CL,4                ;LENGTH OF THE TABLE
  1128.     ROL    BX,CL                ;TIMES SIXTEEN
  1129.     ADD    BX,OFFSET DRIVE_ZERO        ;PARAMETER TABLE
  1130.     MOV    WORD PTR [BX],AX        ;PUT IN NEW MAX CYLINDER
  1131.     CALL    INI_DRV                ;INITIALIZE
  1132. ;
  1133.     MOV    BX,WORD PTR [MAX_TRK]        ;GET MAX TRACK AGAIN
  1134.     XCHG    BH,BL                ;SWAP HIGH/LOW
  1135.     MOV    CL,6                ;BITS TO MOVE
  1136.     SHL    BL,CL                ;MOVE EM OVER
  1137.     MOV    CX,BX                ;COPY NEW CYLINDER
  1138.     OR    CL,1                ;SECTOR ONE
  1139. ;
  1140. ; Format the drive starting at CX cylinder.
  1141. ;
  1142.     PUSH    CX                ;SAVE CYLINDER
  1143.     MOV    DX,WORD PTR [DRIVE]        ;GET DRIVE
  1144.     MOV    AX,0705H            ;FORMAT STARTING AT TRK CX
  1145.     INT    DISK                ;WITH INTERLEAVE OF 5
  1146.     POP    CX                ;RESTORE CYLINDER
  1147.     JC    DDONE
  1148. ;
  1149. ; No reported errors so attempt to read the new track 10 times
  1150. ;
  1151.     MOV    BYTE PTR [RCOUNT],10        ;TIMES TO READ
  1152. ROVER:    PUSH    CX                ;SAVE CYLINDER
  1153.     MOV    AX,0411H            ;VERIFY 17 SECTORS
  1154.     MOV    DX,WORD PTR [DRIVE]        ;GET DRIVE
  1155.     INT    DISK
  1156.     POP    CX                ;RESTORE CYLINDER
  1157.     JC    DDONE
  1158.     DEC    BYTE PTR [RCOUNT]        ;READ COUNTER
  1159.     JNZ    ROVER
  1160. ;
  1161. ; No reported errors so back up one track to see if we just overwrote
  1162. ; previous track.
  1163. ;
  1164.     PUSH    CX                ;SAVE CYLINDER
  1165.     MOV    BX,WORD PTR [MAX_TRK]        ;GET MAX TRACK AGAIN
  1166.     DEC    BX                ;BUMP TRACK DOWN
  1167.     XCHG    BH,BL                ;SWAP HIGH/LOW
  1168.     MOV    CL,6                ;BITS TO MOVE
  1169.     SHL    BL,CL                ;MOVE EM OVER
  1170.     MOV    CX,BX                ;COPY NEW CYLINDER
  1171.     OR    CL,1                ;SECTOR ONE
  1172.     MOV    AX,0411H            ;VERIFY 17 SECTORS
  1173.     MOV    DX,WORD PTR [DRIVE]        ;GET DRIVE
  1174.     INT    DISK
  1175.     POP    CX                ;RESTORE CYLINDER
  1176.     JC    DDONE                ;CAN'T DO IT, DRIVE IS OFF
  1177.     PUSH    CX                ;SAVE CYLINDER
  1178.     MOV    CX,1                ;SECTOR 1 CYL 0
  1179.     MOV    AX,0411H            ;VERIFY 17 SECTORS
  1180.     MOV    DX,WORD PTR [DRIVE]        ;GET DRIVE
  1181.     INT    DISK
  1182.     POP    CX                ;RESTORE CYLINDERS
  1183.     JC    DDONE
  1184.     MOV    DX,OFFSET VERIFY
  1185.     CALL    PROMPT
  1186.     JMP    DEXP                ;CONTINUE
  1187. ;
  1188. DDONE:    CALL    RES_INT                ;RESTORE INTERRUPTS
  1189.     MOV    BX,WORD PTR [DRIVE]        ;GET DRIVE IN USE
  1190.     SUB    BX,80H                ;REMOVE BIAS
  1191.     ADD    BX,OFFSET TYPE0            ;WHERE THE 'TYPE' IS
  1192.     MOV    BL,BYTE PTR [BX]        ;GET DRIVE TYPE
  1193.     XOR    BH,BH                ;RESET HIGH BYTE
  1194.     MOV    CL,4                ;LENGTH OF THE TABLE
  1195.     ROL    BX,CL                ;TIMES SIXTEEN
  1196.     ADD    BX,OFFSET DRIVE_ZERO        ;PARAMETER TABLE
  1197.     DEC    WORD PTR [BX]            ;RESTORE NEW MAX CYLINDER
  1198.     MOV    DX,OFFSET PRP18            ;ASK 'WANNA FORMAT MORE?
  1199.     CALL    PROMPT
  1200.     CALL    BUFINP                ;GET RESPONSE
  1201.     CMP    BYTE PTR [CONBUF+1],0
  1202.     JZ    EXEXT
  1203.     AND    BYTE PTR [CONBUF+2],95        ;MAP TO UPPER CASE
  1204.     CMP    BYTE PTR [CONBUF+2],'Y'
  1205.     JNZ    EXEXT
  1206.     CALL    RFORMAT                ;REFORMAT THE DRIVE
  1207. EXEXT:    RET
  1208. EXPAND    ENDP
  1209. ;
  1210. NFORMAT    PROC    NEAR
  1211.     CALL    FORM1                ;FILL UP SPACES
  1212.     MOV    DX,OFFSET PRP21            ;ASK 'WANNA FORMAT ?
  1213.     CALL    PROMPT
  1214.     CALL    BUFINP                ;GET RESPONSE
  1215.     CMP    BYTE PTR [CONBUF+1],0
  1216.     JZ    NOWAY                ;DIDN'T THINK SO
  1217.     AND    BYTE PTR [CONBUF+2],95        ;MAP TO UPPER CASE
  1218.     CMP    BYTE PTR [CONBUF+2],'Y'
  1219.     JNZ    NOWAY
  1220.     CALL    FORM1
  1221.     MOV    DX,OFFSET PRP16            ;POINT TO WHICH DRIVE?
  1222.     CALL    PROMPT                ;ASK
  1223.     CALL    BUFINP                ;GET RESPONSE
  1224.     CALL    EXTRACT                ;GET BINARY
  1225.     JCXZ    NOWAY                ;NOTHING TYPED
  1226.     CMP    AX,2                ;CHECK LIMITS
  1227.     JNC    NOWAY                ;NO SUCH DRIVE
  1228.     ADD    AX,80H                ;ADD IN BIAS
  1229.     MOV    WORD PTR [DRIVE],AX
  1230.     JMP    SHORT RFORMAT
  1231. NOWAY:    RET
  1232. RFORMAT    PROC    NEAR
  1233.     CALL    FORM1                ;FILL UP SPACES
  1234.     MOV    DX,OFFSET PRP20            ;INTERLEAVE FACTOR?
  1235.     CALL    PROMPT                ;ASK
  1236.     CALL    BUFINP                ;GET RESPONSE
  1237.     CALL    EXTRACT                ;CONVERT TO BINARY
  1238.     JCXZ    NOFMT
  1239.     PUSH    AX                ;SAVE
  1240.     CALL    FORM1
  1241.     MOV    DX,OFFSET PRP19            ;POINT TO 'FORMATTING
  1242.     CALL    PROMPT
  1243.     MOV    AX,WORD PTR [DRIVE]
  1244.     XOR    AH,AH
  1245.     SUB    AL,80H
  1246.     CALL    ASCII
  1247.     MOV    DX,WORD PTR [DRIVE]        ;GET DRIVE NAME
  1248.     MOV    BX,OFFSET SECBUF        ;SECTOR BUFFER
  1249.     MOV    AX,0F00H            ;WRITE TO SECTOR BUFFER
  1250.     INT    DISK                ;WRITE TO SECTOR BUFFER
  1251.     CALL    SET_INT                ;SET UP INTERRUPT
  1252.     CALL    INI_DRV                ;INITIALIZE
  1253.     MOV    DX,WORD PTR [DRIVE]        ;THE DRIVE
  1254.     MOV    CX,1                ;TRACK ZERO SECTOR ONE
  1255.     POP    AX
  1256.     MOV    AH,07                ;FORMAT STARTING AT TRK CX
  1257.     INT    DISK                ;WITH INTERLEAVE OF 5
  1258.     CALL    RES_INT                ;RESTORE INTERRUPTS
  1259. NOFMT:    RET
  1260. RFORMAT    ENDP
  1261. NFORMAT    ENDP
  1262. ;
  1263. DRIVE_ZERO    PARAMS <,,,,,,,,,>
  1264. PAR_LEN        EQU    $ - DRIVE_ZERO
  1265. DRIVE_ONE    PARAMS <,,,,,,,,,>
  1266. DRIVE_TWO    PARAMS <,,,,,,,,,>
  1267. DRIVE_THREE    PARAMS <,,,,,,,,,>
  1268. MAX_DRIVES        DB    ?
  1269. ;
  1270. LOGO1    DB    'Hard Disk Adjustment Tool  Version 3.0$'
  1271. SPACES1    EQU    (COLUMNS - ($ - LOGO1))/2
  1272. LOGO2    DB    'Copyright (C) 1987 Richard B. Johnson$'
  1273. SPACES2    EQU    (COLUMNS - ($ - LOGO2))/2
  1274. LOGOLEN2    EQU    $ - LOGO2
  1275. ATTEMPT    DB    CR,'                                                '
  1276.     DB    CR,'EXPAND> Attempting to write cyl. $'
  1277. VERIFY    DB    ' Verify OK $'
  1278. PRP1    DB    CR,LF,LF,'Number of drives present.$'
  1279. PRP2    DB    CR,LF,'Hard disk drive type.....'
  1280.     DB    '    1'
  1281.     DB    '       '
  1282.     DB    '     2'
  1283.     DB    '       '
  1284.     DB    '     3'
  1285.     DB    '       '
  1286.     DB    '     4'
  1287.     DB    '      $'
  1288. PRP3    DB    CR,LF,'1: Number of tracks......$'
  1289. PRP4    DB    CR,LF,'2: Number of heads.......$'
  1290. PRP5    DB    CR,LF,'3: Cyl. reduced current..$'
  1291. PRP6    DB    CR,LF,'4: Cyl. write precomp....$'
  1292. PRP7    DB    CR,LF,'5: Bits to error correct.$'
  1293. PRP8    DB    CR,LF,'6: Control option byte...$'
  1294. PRP9    DB    CR,LF,'7: Time-out for R/W......$'
  1295. PRP10    DB    CR,LF,'8: Time-out for format...$'
  1296. PRP11    DB    CR,LF,'9: Time-out for diag.....$'
  1297. PRP12    DB    CR,LF,'Drive$'
  1298. PRP13    DB    '      Heads =$'
  1299. PRP14    DB    '   Cylinders =$'
  1300. PRP15    DB    '   Sectors =$'
  1301. PRP16    DB    CR,'FORMAT> Which drive? 0 - 1 $'
  1302. PRP18    DB    CR,'FORMAT> Want to reformat the entire drive? Y/N $'
  1303. PRP19    DB    CR,'FORMAT> Formatting drive$'
  1304. PRP20    DB    CR,'FORMAT> Interleave factor? 1 - 15 $'
  1305. PRP21    DB    CR,'FORMAT> Do you really want to do this? Y/N $'
  1306. TYP    DB    '   Type =$'
  1307. CUR    DB    CR,LF,'                          -'
  1308.     DB    ' Current drive parameters '
  1309.     DB    '-$'
  1310. ASK    DB    CR,LF,' Change, Checksum, Exit, Expand, Format, New,'
  1311.     DB    ' Ship, Speed, Test, Try, Write'
  1312.     DB    CR,LF,'ADJUST> $'
  1313. WRITIN    DB    CR,'WRITING> HDISK.ROM$'
  1314. BYEBYE    DB    CR,'EXITING> $'
  1315. CHANG    DB    CR,'CHANGE> $'
  1316. OUTSIDE    DB    CR,'TRY> (Type EXIT to return) $'
  1317. HDTS    DB    CR,'TEST> $'
  1318. SPED    DB    CR,'SPEED> $'
  1319. SHIPP    DB    CR,'SHIP> $'
  1320. NEW    DB    CR,'NEW> $'
  1321. SUMIT    DB    CR,'CHECKSUM> HDISK.ROM$'
  1322. EXP    DB    CR,'EXPAND> Do you really want to do this? Y/N $'
  1323. RETURN    DB    '  [Return] $'
  1324. DTYPE    DB    'Drive type? (1 - 4) $'
  1325. CRLF    DB    CR,LF,'$'
  1326. SPACES    DB    '  [$'
  1327. ENDHEX    DB    ']$'
  1328. SPACER    DB    ':  $'
  1329. FNAME    DB    'HDISK.ROM',0
  1330. COMND    DB    '\COMMAND.COM',0
  1331. CHKSMF    DB    'CHECKSUM.COM',0
  1332. DTESTF    DB    'HDTEST.COM',0
  1333. SPEEDF    DB    'HDSPEED.COM',0
  1334. SHIPF    DB    'SHIP.COM',0
  1335. UNABLE1    DB    ' Unable to execute \COMMAND.COM'
  1336.     DB    CR,LF,'(Must exist in the TOP directory) $'
  1337. UNABLE2    DB    ' Unable to execute CHECKSUM.COM'
  1338.     DB    CR,LF,'(Must exist in the default directory) $'
  1339. UNABLE3    DB    ' Unable to execute HDTEST.COM'
  1340.     DB    CR,LF,'(Must exist in the default directory) $'
  1341. UNABLE4    DB    ' Unable to execute HDSPEED.COM'
  1342.     DB    CR,LF,'(Must exist in the default directory) $'
  1343. UNABLE5    DB    ' Unable to execute SHIP.COM'
  1344.     DB    CR,LF,'(Must exist in the default directory) $'
  1345. MAKERR    DB    ' Unable to CREATE directory entry [Return] $'
  1346. WRERR    DB    ' Unable to WRITE to the disk [Return] $'
  1347. BADSEG    DB    ' BIOS ROM pointer wrong. '
  1348.     DB       'Reboot with NO device drivers! [Return] $'
  1349. KNOW    DB    CMD_LEN - 2
  1350.     DB    ' HDISK.ROM',CR
  1351. CMD_LEN    EQU    ($ - KNOW)
  1352. HANDLE    DW    ?
  1353. DRIVE    DW    80H
  1354. SAV_OFF    DW    ?            ;OFFSET OF HARD DISK TABLES
  1355. SAV_SEG    DW    ?            ;SEGMENT OF HARD DISK BIOS
  1356. PAR_OFF    DW    ?            ;HDISK PARAMETER TABLE OFFSET
  1357. PAR_SEG    DW    ?            ;HDISK PARAMETER TABLE SEGMENT
  1358. SP_SAV    DW    ?            ;SAVE STACK FOR OVERLAY
  1359. PROM_LEN    DW    ?        ;SIZE OF THE HD BIOS PROM
  1360. MAX_TRK    DW    ?
  1361. TYPE0    DB    -1
  1362. TYPE1    DB    -1
  1363. RCOUNT    DB    ?
  1364. BLOCK    DW    0            ;SEGMENT ADDRESS OF ENVIRONMENT
  1365.     DW    80H
  1366. SEG_1    DW    ?
  1367.     DW    5CH
  1368. SEG_2    DW    ?
  1369.     DW    6CH
  1370. SEG_3    DW    ?
  1371. ;
  1372. CONBUF    LABEL    WORD
  1373.     DB    16 DUP(?)
  1374. ;
  1375.     DB    30 DUP('STACK  ')
  1376. STKTOP    LABEL    WORD
  1377. EVEN
  1378. SECBUF    LABEL    BYTE
  1379. CHECK    PROC    NEAR
  1380.     XOR    AH,0            ;START WITH ZERO
  1381.     MOV    SI,100H            ;WHERE THE DATA STARTS
  1382.     MOV    CX,(OFFSET TOP - OFFSET MAIN)    ;BYTES TO CHECK
  1383. CHKEM:    LODSB                ;GET BYTE
  1384.     ADD    AH,AL
  1385.     LOOP    CHKEM
  1386.     POP    AX            ;GET RETURN ADDRESS
  1387.     PUSHF                ;SAVE FLAGS ON STACK
  1388.     PUSH    AX            ;SAVE RETURN ADDRESS
  1389.     RET                ;GO HOME
  1390. CHECK    ENDP
  1391.     ORG    SECBUF + 512
  1392. TOP    EQU    $
  1393. PSEG    ENDS
  1394.     END    MAIN
  1395.