home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol247 / du-75e.aq6 / DU-75E.A86
Text File  |  1986-02-27  |  55KB  |  3,130 lines

  1. ;    29-Jul-85 fixed code at CLCSUB to prevent int 0, same ver 7.5-E
  2. ;    21-Jul-85 revised for 32 bit mult/div in GTLSEC and CLCSUB routines
  3. ;        changed to rev 7.5-E. WHAT A MESS....
  4. ;    29-Mar-85 relaxed for CCP/M ver 4.1 and up changed to -D ver
  5. ;    8-11-84 revsed for PC_MODE support renamed DU-V75C.A86
  6. ;    04/15/84 revised to correct minor bugs - renamed DU-V75B.A86
  7. ;
  8. ;      DU.ASM  V7.5    Revised 1/23/81 ( CP/M-80 version )
  9. ;    DISK UTILITY - By Ward Christensen
  10. ;
  11. ;    DU-75A.A86 is a CP/M-86 translation of the CP/M-80 version.
  12. ;    
  13. ;    The original translation came from the SLICER USER GROUP
  14. ;    disk #2, via Micro Cornucopia, PO Box 223, Bend, OR
  15. ;    It did not indicate the name of the translator who should
  16. ;    be thanked for his work.  That version appeared as DU-75.A86
  17. ;
  18. ;    See DU77.DOC for description and detailed instructions.
  19. ;    See original issue ver 7.5 for history of changes and authors
  20. ;    NOTE: see below for change in multiple cmd symbol.
  21. ;
  22. ;     03/05/84 by H.M. Van Tassell, (201)-755-5372
  23. ;         120 Hill Hollow  Road, Watchung, NJ 07060 
  24. ;
  25. ;    Added direct BIOS disk routines for CP/M-86 Plus ver 3.1
  26. ;    and CCP/M-86 ver 3.1, with minimum changes to get it to work.
  27. ;    There is now a check for version number with exit if unknown.
  28. ;
  29. ;    Fixed a bug with Map when using directory initialized for time
  30. ;    stamping, added user&drive to prompt, and changed the multiple
  31. ;    command symbol from ';' to '!'. *** THIS IS CP/M CONVENTION ***
  32. ;
  33. ;    Changed LISTOUT to use BDOS rather than BIOS call since under
  34. ;    CCP/M-86, a BIOS call to LIST must have it's device number in
  35. ;    register DL. The BDOS call uses the default list device and DU
  36. ;    will "own" the printer once it is called using L_WRITE.
  37. ;
  38. ;    to generate: ASM86 DU ! GENCMD DU 8080 CODE[MF00]
  39. ;                            
  40. ;        ----------------
  41. ;
  42.  
  43. L_WRITE        equ    5    ;write to default list device
  44. S_BIOS        equ    50    ;direct bios call
  45. DRV_DPB        equ    31    ;get drive DPB, returns SYSDAT in ES
  46.  
  47.  
  48. ; bios disk call data structure
  49. ;
  50. SELECT_DISK    equ  word ptr 0[bx]
  51. SET_TRACK    equ  word ptr 2[bx]
  52. SET_DMASEG    equ  word ptr 4[bx]
  53. SET_DMAOFF    equ  word ptr 6[bx]
  54. SET_SECTOR    equ  word ptr 8[bx]
  55. READ_SECTOR    equ  word ptr 10[bx]
  56. WRITE_SECTOR    equ  word ptr 12[bx]
  57. SECTOR_XLAT    equ  word ptr 14[bx]
  58. HOME_DISK    equ  word ptr 16[bx]
  59.  
  60.  
  61. BIO_SELDSK     equ    9        ;BIOS function number
  62. BIO_READ      equ    10        ;BIOS function number
  63. BIO_WRITE      equ    11        ;BIOS function number
  64.  
  65. ; partial data structure of Disk Parameter Header (DPH)
  66. ;
  67. DPH_XLATE    equ    word ptr 0    ;offset to xlate table
  68. LOG_SEQN    equ    byte ptr 6    ;to force reset of permanent media
  69. DPB_PTR31    equ    word ptr 8    ;offset of DPB pointer in DPH (v3.1)
  70. DPB_PTR11    equ    word ptr 10    ;offset in version 1.1
  71. DPB_SIZE    equ    17        ;size of Disk Parameter Block
  72.  
  73.  
  74. ;------- for CP/M ver 3.1 & CCP/M ver 3.1 ----
  75. BIOS_ENTRY      equ    dword ptr .28h    ;loc of BIOS entry in SYStem DATa
  76.  
  77. ;------------ for CP/M ver 3.1 --------------
  78. UDA_SEG          equ    word ptr .4eh    ;loc of UDA seg in SYStem DATa area
  79.  
  80. ;------------- for CCP/M ver 3.1 -------------
  81. S_SYSDAT    equ    154        ;get SYStem DATa area addr
  82. P_PDADR        equ    156        ;get PDA address
  83.  
  84. CCPM_31        equ    1431h        ;CCP/M-86 version number
  85.  
  86. P_UDA        equ    word ptr 10h    ;loc of UDA seg in User Data Area
  87. ;-------------------------------------------------------------------------
  88. ;
  89. ;System equates
  90. ;
  91. BASE    EQU    0
  92. ;
  93.     ORG BASE +5CH
  94. FCB    DB 0
  95. ;
  96. PRINT    EQU    9
  97. RESETDK    EQU    13
  98. SELDK    EQU    14
  99. SRCHF    EQU    17    ;SEARCH FIRST
  100. SUSER    EQU    32
  101. GETDSK    EQU    25
  102. GETDPB    EQU    31
  103. ;
  104. ;    BIOS
  105. ;
  106. CONSTF    EQU    2
  107. CONINF    EQU    3
  108. CONOUTF    EQU    4
  109. LISTF    EQU    5
  110. ;
  111. S2OFF    EQU    14    ;OFFSET INTO FCB FOR S2 BYTE
  112. S2MASK    EQU    0FH    ;MASK FOR EXTENDED RC BITS OF S2
  113. DPBLEN    EQU    15    ;SIZE OF CP/M 2.x DISK PARM BLOCK
  114. ;
  115. ;
  116. ;Define ASCII characters
  117. ;
  118. CR    EQU    0DH    ;CARRIAGE RETURN
  119. LF    EQU    0AH    ;LINE FEED
  120. TAB    EQU    09H    ;TAB
  121. BS    EQU    08H    ;BACKSPACE
  122. ;
  123.     CSEG
  124.     ORG 100H
  125. ;
  126.     JMP PASTCK    ;JUMP OVER CLOCK BYTE AND I.D.
  127. ;
  128. BCONST:
  129.     MOV AL,CONSTF
  130.     JMP BIOS
  131. ;
  132. BCONIN:
  133.     MOV AL,CONINF
  134.     JMP BIOS
  135. ;
  136. BCONOUT:
  137.     MOV AL,CONOUTF
  138.     JMP BIOS
  139. ;
  140. BLIST:
  141.     MOV AL,LISTF
  142.     JMP BIOS
  143. ;------------------------------------------------------------------------
  144. BHOME:
  145.     mov bx,bios_call_tbl
  146.     jmp home_disk
  147. ;
  148. SEL:
  149.     mov bx,bios_call_tbl
  150.     jmp select_disk
  151. ;
  152. TRK:
  153.     mov bx,bios_call_tbl
  154.     jmp set_track
  155. ;
  156. SEC:
  157.     mov bx,bios_call_tbl
  158.     jmp set_sector
  159. ;
  160. DMA:
  161.     mov bx,bios_call_tbl
  162.     jmp set_dmaoff
  163. ;
  164. DSKREAD:
  165.     mov bx,bios_call_tbl
  166.     jmp read_sector
  167. ;
  168. DSKWRITE:
  169.     mov bx,bios_call_tbl
  170.     jmp write_sector
  171. ;
  172. BSECTTRAN:
  173.     mov bx,bios_call_tbl
  174.     jmp sector_xlat
  175. ;
  176. SETDMAB:
  177.     mov bx,bios_call_tbl
  178.     jmp set_dmaseg
  179. ;
  180.  
  181.  
  182. ; checks cpm version and initializes things
  183. cpmchk:
  184.     mov    cl,12            ;get version number
  185.     int    224
  186.     mov    cpm_version,ax        ;and save it
  187.     test    ah,01h            ;is it mp/m ?
  188.     jnz     is_mpm
  189.     cmp    al,22h            ;is it version 11?
  190.     je    ver_11
  191.     cmp    al,31h            ;is it version 31?
  192.     jae    ver_31
  193.                     ;else it is unknown version
  194. unk_ver:                ;say unknown and exit
  195.     mov    dx,offset wvmsg
  196.     mov    cl,9
  197.     int    224
  198.     jmp    exit
  199. is_mpm:                    ;MP/M is not supported
  200.     mov    dx,offset mpmsg        ;say it and exit
  201.     mov    cl,9
  202.     int    224
  203.     jmp    exit
  204.  
  205. ver_11:
  206.     mov    bios_call_tbl,offset table11
  207.     jmps    ver_ok
  208. ver_31:
  209.     mov    bios_call_tbl,offset table31
  210. ver_ok:
  211.     mov ax,ds            ;setup our dseg for
  212.     mov idmaseg,ax            ;sector buffer read/write
  213.     mov dmaseg,ax            
  214.     mov dmaoff,80h            ;and default buffer
  215.     ret
  216.  
  217.  
  218. ; direct bios call for cp/m-86 version 1.1
  219. ;
  220. select_disk11:
  221.     mov    al,9            ;bios fucn 9
  222.     jmps    bios            ;returns dph addr in es:bx
  223. set_track11:
  224.     mov    al,10
  225.     jmps    bios
  226. set_dmaseg11:
  227.     mov    al,17
  228.     jmps    bios
  229. set_dmaoff11:
  230.     mov    al,12
  231.     jmps    bios
  232. set_sector11:
  233.     mov    al,11
  234.     jmps    bios
  235. read_sector11:
  236.     mov    al,13
  237.     jmps    bios
  238. write_sector11:
  239.     mov    al,14
  240.     jmps    bios
  241. sector_xlat11:
  242.     mov    al,16
  243.     jmps    bios
  244. home_disk11:
  245.     mov    al,8 
  246.     jmps    bios
  247.  
  248. ;
  249. bios:
  250.     mov bpb_func,al        ;bios function number
  251.     mov bpb_cx,cx
  252.     mov bpb_dx,dx
  253.     mov dx,offset bpb
  254.     mov cl,S_BIOS        ;direct bios function call = 50
  255.     
  256. bdos:    int 224            ;fall thru
  257.     ret
  258.  
  259. ;
  260. ; direct bios disk calls for CP/M-86 version 3.1
  261. ;
  262. set_sector31:
  263.     call logi_2_phy        ;convert logical record number to
  264.     mov isector,cx        ;physical sector number
  265.     ret
  266.  
  267. set_track31:
  268.     mov itrack,cx
  269.     ret
  270.  
  271. sector_xlat31:
  272.     call pseudo_xlat    ;translate logical records
  273.     ret            ;BX = pseudo xlate record number
  274.  
  275. set_dmaseg31:            
  276.     mov dmaseg,cx        ;user dma segment
  277.     ret
  278.  
  279. set_dmaoff31:
  280.     mov dmaoff,cx        ;user dma offset
  281.     ret
  282.  
  283. home_disk31:            ;do nothing, there aint no home
  284.     xor ax,ax        ;but make sure al=0
  285.     ret
  286.  
  287. pseudo_xlat:
  288. ;---------
  289. ;    ENTRY:    CX = logical record number (relative 1)
  290. ;    EXIT:    BX = pseudo logical sector number
  291. ;             (gives same result as if disk had same number of
  292. ;              physical sectors as there are 128 byte records)
  293.  
  294.     mov bx,cx        ;just in case there is no xlate
  295.     cmp sec_xlat_tbl,0 ! jz no_xlat ;is there an xlate table?
  296.     inc cx            ;do this only for DU-V75
  297.     call logi_2_phy        ;returns AX = physical sector
  298.     mov bx,sec_xlat_tbl    ;point to disk xlate table
  299.     push ds ! mov ds,sysaddr ;in the SYStem DATa area
  300.     xlat sec_xlat_tbl    ;AL = translated phy sector number
  301.     pop ds
  302.     mov cl,PHYSHF        ;get physical shift factor
  303.     shl ax,cl            
  304.     add ax,rec_offset    ;add in the record offset into sector
  305.     inc ax            ;make it relative to 1
  306.     mov bx,ax        ;move to BX
  307. no_xlat:
  308.     ret
  309.  
  310. logi_2_phy:
  311. ;----------
  312. ;    ENTRY:    CX = logical record number (relative to 1)
  313. ;    EXIT:    CX=AX = physical sector number (relative to 0)
  314. ;        rec_offset contains record offset into phy sector
  315. ;
  316.     dec cx            ;now relative to zero
  317.     mov ax,cx         ;move logical record number
  318.     xor bh,bh        ;clear high byte 
  319.     mov bl,PHYMSK        ;get physical mask
  320.     and cx,bx        ;CX = logical record offset into
  321.     mov rec_offset,cx    ;...physical sector
  322.     mov cl,PHYSHF        ;get physical shift factor
  323.     shr ax,cl        
  324.     mov cx,ax        ;CX=AX = physical sector number
  325.     ret
  326.  
  327.  
  328. ;++++++++++++++++++++++++++++++++++++++
  329. select_disk31:        ;selects a drive
  330. ;-------------
  331. ; resets login sequence number of drive to 0, to force
  332. ; permanent media to be logged in again on disk reset
  333. ;    Entry:    CL = drive to select
  334. ;        DL = 0 if initial select, else 1
  335.  
  336.     mov trk_sect,0ffffh        ;indicate not in memory
  337.     mov idrive,cl            ;put drive in table
  338.     push es ! push ds        ;save context
  339.     push cx                ;save drive
  340.     call getsu            ;set up DS and ES
  341.     pop cx                ;restore drive
  342.     mov ax,BIO_SELDSK        ;do the BIOS SELDSK call
  343.     callf BIOS_ENTRY        ;call the BIOS thru entry point
  344.     cmp bx,0 ! jz sel_error         ;bx = 0 is an illegal drive
  345.  
  346.     mov LOG_SEQN[bx],0        ;to force a disk reset set the
  347.                     ;...login sequence no. to zero
  348.     mov cx,DPH_XLATE[bx]        ;get xlate table offset in SYSDAT
  349.                     ;copy DPB to local storage
  350.     pop es ! push es        ;get our dseg into ES
  351.     mov es:sec_xlat_tbl,cx        ;save xlate table address
  352.     mov di,offset dpb        ;setup dest of dpb
  353.     mov si,DPB_PTR31[bx]        ;get the info from DPH (ver 31)
  354.  
  355.     cmp Word Ptr[si],0FFFFh        ; is this a PC_MODE dpb?
  356.     jne not_pc_dpb
  357.       add si,12            ;yes, correct for difference
  358. not_pc_dpb:
  359.  
  360.     mov cx,DPB_SIZE
  361.     rep movsb            ;copy DPB into local storage
  362. sel_error:
  363.     pop ds ! pop es            ;restore context
  364.     mov cl,PHYSHF            ; This is a dirty trick
  365.     shl SPT,cl            ; to get a SPT for DU
  366.     
  367.     cmp PHYSHF,4              ;make sure sector_buf is OK
  368.     jbe buf_ok            ; >>> PHYSHF TABLE <<<
  369.       mov dx,offset toobig        ; 128 = 0    1024 = 3
  370.       mov cl,9            ; 256 = 1    2048 = 4
  371.       int 224            ; 512 = 2    4096 = 5
  372.       jmp exit
  373. buf_ok:
  374.     ret
  375.  
  376. sect_to_mem: 
  377. ;------------
  378. ;    ENTRY:     itrack & isector specified
  379. ;    EXIT:     sector is in memory, does read if required
  380. ;        AX BX = 0 if no error
  381. ;
  382.     mov ax,itrack            ;get track
  383.     cmp ax,0 ! jnz not_zero
  384.       cmp ax,1 ! jmps no_match
  385. not_zero:
  386.     mov bx,isector            ;and sector numbers
  387.     cmp ax,trk_sect    ! jne no_match    ;if same as last time
  388.     cmp bx,trk_sect+2        ;then sector is in memory
  389. no_match:
  390.     mov trk_sect,ax            ;save for next time
  391.     mov trk_sect+2,bx
  392.     mov ax,0 ! mov bx,ax        ;clear AX BX registers
  393.     je got_sect            ;if not in memory, then
  394.     mov bx,BIO_READ            ;signal a read
  395.     call biosiopb            ;read a physical sector
  396. got_sect:
  397.     ret
  398.  
  399. read_sector31:    ;reads a logical record from disk to buffer
  400. ;-------------
  401. ;
  402.     call sect_to_mem        ;get sector
  403.     push si ! push di ! push es
  404.     cld ! mov es,dmaseg        ;setup user dma segment
  405.     mov di,dmaoff            ;where to copy 128 byte record
  406.     mov si,rec_offset        ;record offset into sector buffer
  407.     mov cl,7 ! shl si,cl        ;times 128
  408.     add si,offset sector_buf    ;points to start of record
  409.     mov cx,128/2            ;move 128 bytes
  410.     rep movsw            ;so do the move
  411.     pop es ! pop di ! pop si
  412.     ret
  413.     
  414.  
  415. write_sector31:    ;writes a physical sector
  416. ;--------------
  417. ;
  418.     call sect_to_mem
  419.     push si ! push di ! push es ! push ds
  420.     mov ds,dmaseg            ;source of user data to copy
  421.     mov si,dmaoff            ;into sector buffer
  422.     cld ! mov es,idmaseg        ;setup for sector buffer dma segment
  423.     mov di,rec_offset        ;record offset into sector buffer
  424.     mov cl,7 ! shl di,cl        ;times 128
  425.     add di,offset sector_buf    ;points to start of record
  426.     mov cx,128/2            ;move 128 bytes
  427.     rep movsw            ;so do the move
  428.     pop ds ! pop es ! pop di ! pop si
  429.     mov bx,BIO_WRITE        ;signal a write
  430.                     ;fall thru to write sector to disk
  431. biosiopb:    ;put the IOPB on the stack, call BIOS
  432.     push ds                ;ds will contain SYSDAT seg
  433.     push es                ;es will contain UDA seg
  434.                     ;push iopb onto stack
  435.     mov ah,imcnt
  436.     mov al,idrive
  437.     push ax                ;drive and multi-sector count
  438.     push itrack            ;track #
  439.     push isector            ;sector # = 0
  440.     push idmaseg            ;sector buffer DMA segment
  441.     push idmaoff            ;sector buffer DMA offset
  442.  
  443.     call getsu            ;set up DS-SYSDAT and ES-UDA
  444.     mov ax,bx            ;set I/O function into AX
  445.     callf BIOS_ENTRY        ;call indirect the BIOS
  446.                     ;AL,BL = return status
  447.     add sp,10            ;restore stack
  448.     pop es                ;restore original ES
  449.     pop ds                ;ditto for DS
  450.     ret
  451.  
  452. ;======
  453. getsu:    
  454. ;======
  455. ;    entry:    DS = local data seg
  456. ;    exit:    DS = SYSDAT seg, ES=UDA seg (for call to XIOS)
  457.  
  458.     mov ax,udaaddr            ;get the saved value
  459.     or ax,ax            ;set flags
  460.     jz get_ds_es            ;uninitialized, go get DS and ES
  461.       mov es,ax            ;we've been here before, so load regs
  462.       mov ds,sysaddr
  463.       ret
  464.  
  465. get_ds_es:                ;this is the initial call
  466. ;---------
  467.  
  468.     cmp     cpm_version,CCPM_31    ;is it CCP/M-86 version 1431+?
  469.     jb    get_ds_es10        ;or version 1031
  470.  
  471. get_ds_es14:    ;use this for CCP/M-86 version 1431
  472. ;----------
  473.     mov cl,P_PDADR            ;will return Process Desc Addr in BX
  474.     int 224                ;...and SYStem DATa seg in ES
  475.     mov ax,es:P_UDA[bx]        ;grab UDA_seg
  476.     jmps com_su            ;jmp to common
  477.     
  478. get_ds_es10:    ;use this with CP/M-86 version 1031
  479. ;----------
  480.     mov cl,DRV_DPB            ;will return SYStem DATa seg in ES
  481.     int 224
  482.     mov ax,es:UDA_seg        ;grab UDA_seg
  483.                     ;fall thru to common 
  484. com_su:        ;this is common to both versions
  485.  
  486.     mov sysaddr,es            ;save system data segment (SYSDAT)
  487.     push es
  488.     mov udaaddr,ax            ;save for UDS_seg for future calls
  489.     mov es,ax            ;get UDA_seg into ES
  490.     pop ds                ;get SYSDAT into DS
  491.     ret
  492.  
  493. ;-----------------------------------------------------------------------
  494. ;
  495. CLOCK    DB    1    ;<---PUT NON-ZERO HERE FOR 4 MHZ CLOCK
  496. ;
  497. PASTCK:
  498.     MOV AX,CS
  499.     MOV DS,AX
  500.     MOV SS,AX
  501.     MOV ES,AX
  502.     MOV SP,OFFSET STACK
  503.     
  504.     call cpmchk        ;make sure right version, do setup
  505. ;
  506. HELLO:    CALL ILPRT
  507.     DB    CR,LF,'DISK UTILITY ver 7.5-E',CR,LF
  508.     DB    'For CP/M-86 & CCP/M-86 ver 3.1-4.1',CR,LF
  509.     DB    CR,LF
  510.     DB    'Type ? for help, X or ESC Quits'
  511.     DB    CR,LF,0
  512.  
  513.     CALL GETSTP    ;SET UP PARAMETERS
  514.     MOV BX,OFFSET BASE +80H    ;TO INPUT BUFF
  515.     MOV AL,BYTE PTR [BX]
  516.     OR AL,AL
  517.     JZ PRMPTR    ;NO COMMAND
  518. ;
  519. ;Got initial command, set it up
  520.     MOV CH,AL    ;SAVE LENGTH
  521.     DEC CH
  522.     JZ PRMPTR
  523.     MOV DX,OFFSET INBUF
  524.     INC BX    ;SKIP LEN
  525.     INC BX    ;SKIP ' '
  526.     CALL MOVE
  527.     MOV AL,CR
  528.     XCHG BX,DX
  529.     MOV [BX],AL
  530.     XCHG BX,DX
  531.     MOV BX,OFFSET INBUF
  532.     JMP PRMPTI
  533. ;
  534. PRMPTR:    XOR AL,AL
  535.     MOV  QFLAG,AL
  536.     CALL RDBUF
  537. ;
  538. PRMPTI:    MOV AL,255
  539.     MOV  BYTE PTR TOGO,AL    ;LOOP COUNT FOR "/"
  540.     MOV  BYTE PTR TOGO+1,AL
  541. ;
  542. PROMPT    EQU    $
  543. SETSTK:
  544.     MOV SP, OFFSET STACK
  545.     XOR AL,AL    ;ZERO 2-UP PRINT
  546.     MOV  TWOUP,AL    ;..SWITCH
  547.     MOV AL,1
  548.     MOV  FTSW,AL    ;TELL SEARCH NOT TO INCR
  549.     PUSH BX
  550.     MOV BX,OFFSET BASE +100H
  551.     MOV BUFAD,BX    ;FOR RDBYTE
  552.     POP BX
  553.     CALL CTLCS    ;ABORT?
  554.     JZ PRMPTR    ;..YES, READ BUFFER
  555. ;
  556. ;Do we have to position in directory after find?
  557.     MOV AL,FINDFL
  558.     OR AL,AL
  559.     JZ L@00005
  560.     JMP POSDIR    ;POSITION IN DIRECTORY
  561. L@00005:
  562.     MOV AL,BYTE PTR [BX]
  563.     CMP AL,CR
  564.     JZ PRMPTR
  565.     CMP AL,'!'    ;LOGICAL CR?
  566.     PUSHF
  567.     INC BX
  568.     POPF
  569.     JZ PROMPT
  570.     CALL UPCASE
  571.     MOV  DUMTYP,AL    ;TYPE OF DUMP (A,D,H)
  572. ;
  573. ;Command dispatcher
  574. ;
  575.     CMP AL,'+'
  576.     JNZ L@00008
  577.     JMP PLUS
  578. L@00008:
  579. ;
  580.     CMP AL,'-'
  581.     JNZ L@00009
  582.     JMP MINUS
  583. L@00009:
  584. ;
  585.     CMP AL,'='
  586.     JNZ L@00010
  587.     JMP SEARCH
  588. L@00010:
  589. ;
  590.     CMP AL,'<'
  591.     JNZ L@00011
  592.     JMP SAVE
  593. L@00011:
  594. ;
  595.     CMP AL,'>'
  596.     JNZ L@00012
  597.     JMP RESTOR
  598. L@00012:
  599. ;
  600.     CMP AL,'#'
  601.     JNZ L@00013
  602.     JMP STATS
  603. L@00013:
  604. ;
  605.     CMP AL,'?'
  606.     JNZ L@00014
  607.     JMP HELP
  608. L@00014:
  609. ;
  610.     CMP AL,'A'
  611.     JNZ L@00015
  612.     JMP DUMP
  613. L@00015:
  614. ;
  615.     CMP AL,'C'
  616.     JNZ L@00016
  617.     JMP CHG
  618. L@00016:
  619. ;
  620.     CMP AL,'D'
  621.     JNZ L@00017
  622.     JMP DUMP
  623. L@00017:
  624. ;
  625.     CMP AL,'F'
  626.     JNZ L@00018
  627.     JMP POSFIL
  628. L@00018:
  629. ;
  630.     CMP AL,'G'
  631.     JNZ L@00019
  632.     JMP POS
  633. L@00019:
  634. ;
  635.     CMP AL,'H'
  636.     JNZ L@00020
  637.     JMP DUMP
  638. L@00020:
  639. ;
  640.     CMP AL,'L'
  641.     JNZ L@00021
  642.     JMP LOGIN
  643. L@00021:
  644. ;
  645.     CMP AL,'M'
  646.     JNZ L@00022
  647.     JMP MAP
  648. L@00022:
  649. ;
  650.     CMP AL,'N'
  651.     JNZ L@00023
  652.     JMP NEWDSK
  653. L@00023:
  654. ;
  655.     CMP AL,'P'
  656.     JNZ L@00024
  657.     JMP PRNTFF
  658. L@00024:
  659. ;
  660.     CMP AL,'Q'
  661.     JNZ L@00025
  662.     JMP QUIET
  663. L@00025:
  664. ;
  665.     CMP AL,'R'
  666.     JNZ L@00026
  667.     JMP DOREAD
  668. L@00026:
  669. ;
  670.     CMP AL,'S'
  671.     JNZ L@00027
  672.     JMP POS
  673. L@00027:
  674. ;
  675.     CMP AL,'T'
  676.     JNZ L@00028
  677.     JMP POS
  678. L@00028:
  679. ;
  680.     CMP AL,'U'    ;******CP/M 2.x ONLY******
  681.     JNZ L@00029
  682.     JMP USER
  683. L@00029:
  684. ;
  685.     CMP AL,'V'
  686.     JNZ L@00030
  687.     JMP VIEW
  688. L@00030:
  689. ;
  690.     CMP AL,'W'
  691.     JNZ L@00031
  692.     JMP DORITE
  693. L@00031:
  694. ;
  695.     CMP AL,'X'
  696.     JNZ L@00032
  697. QUIT:
  698.     CALL ILPRT 
  699.     DB    'Confirm Quiting (Y/N)? ',0
  700.     CALL CONIN
  701.     CALL UPCASE
  702.     CMP AL,'Y'
  703.     JE EXIT
  704.       CALL CRLF
  705.       JMP PRMPTR
  706. ;
  707. EXIT:
  708.     MOV CL,0
  709.     MOV DL,0
  710.     JMP BDOS    ;RETURN TO CP/M 86
  711.         
  712. L@00032:
  713. ;
  714.     CMP AL,'Z'
  715.     JNZ L@00033
  716.     JMP SLEEP
  717. L@00033:
  718. ;
  719.     CMP AL,'/'
  720.     JNZ L@00034
  721.     JMP REPEAT
  722. L@00034:
  723. ;
  724. WHAT:    XOR AL,AL
  725.     MOV  QFLAG,AL
  726.     CALL ILPRT
  727.     DB    '?',0
  728.     JMP PRMPTR
  729. ;
  730. ;Memory full error
  731. ;
  732. MEMFUL:    XOR AL,AL
  733.     MOV  QFLAG,AL
  734.     CALL ILPRT
  735.     DB    '+++ Out of memory +++'
  736.     DB    CR,LF,0
  737.     JMP PRMPTR
  738. ;
  739. ;Print disk statistics
  740. ;
  741. STATS:    PUSH BX
  742.     CALL ILPRT
  743.     DB    'Disk Information:',CR,LF
  744.     DB    'Tracks:',9,9,0
  745.     MOV BX,MAXTRK
  746.     INC BX
  747.     CALL DEC
  748.     CALL ILPRT
  749.     DB    CR,LF,'Sec/trk:',9,0
  750.     MOV BX,SPT
  751.     CALL DEC
  752.     CALL ILPRT
  753.     DB    CR,LF,'Grpsize:',9,0
  754.     MOV AL,BLM
  755.     INC AL
  756.     MOV BL,AL
  757.     MOV BH,0
  758.     CALL DEC
  759.     CALL ILPRT
  760.     DB    ' (sectors per group)',CR,LF
  761.     DB    'Tot grps:',9,0
  762.     MOV BX,DSM
  763.     CALL DEC
  764.     CALL ILPRT
  765.     DB    CR,LF,'Dir entries:',9,0
  766.     MOV BX,DRM
  767.     INC BX
  768.     CALL DEC
  769.     CALL ILPRT
  770.     DB    CR,LF,'Sys tracks:',9,0
  771.     MOV BX,SYSTRK
  772.     CALL DEC
  773.     CALL CRLF
  774.     POP BX
  775.     JMP PROMPT
  776. ;
  777. ;The following command resets the disk
  778. ;system thru CP/M, and may be usable for
  779. ;changing the disk density or format.
  780. ;This can only be done if your BIOS resets
  781. ;the auto-density select parameters at
  782. ;every track-zero access.
  783. ;
  784. NEWDSK:    PUSH BX
  785.     MOV CL,RESETDK
  786.     CALL BDOS
  787.     MOV AL,DRIVE
  788.     MOV CL,AL
  789.     POP BX
  790.     CALL SELECT
  791.     JMP PROMPT
  792. ;
  793. ;Quite mode
  794. ;
  795. QUIET:    MOV  QFLAG,AL    ;NOW QUIET
  796.     JMP PROMPT
  797. ;
  798. ;Repeat buffer contents
  799. ;
  800. REPEAT:    CALL DECIN    ;NN SPECIFIED?
  801.     MOV AL,DH
  802.     OR AL,DL
  803.     JZ NNN        ;NO.
  804.     MOV BX,TOGO
  805.     INC BX    ;TEST FOR FIRST TIME
  806.     MOV AL,BH
  807.     OR AL,BL    ;WAS IT 0FFFFH?
  808.     JNZ NNN        ;NO: COUNTING
  809.     XCHG BX,DX    ;GET COUNT
  810.     MOV TOGO,BX    ;SET COUNT
  811. ;
  812. NNN:    MOV BX,TOGO
  813.     XCHG BX,DX
  814.     MOV BX,OFFSET INBUF    ;READY TO REPEAT
  815.     INC DX    ;TEST FOR 0FFFFH
  816.     MOV AL,DH
  817.     OR AL,DL
  818.     JNZ L@00037
  819.     JMP PROMPT    ;CONTINOUS
  820. L@00037:
  821.     DEC DX    ;COUNT DOWN
  822.     DEC DX    ;MAKE UP FOR PREV INX D
  823.     XCHG BX,DX
  824.     MOV TOGO,BX
  825.     MOV AL,BH    ;ALL DONE?
  826.     OR AL,BL
  827.     XCHG BX,DX    ;GET BACK INBUF PTR
  828.     JZ L@00038
  829.     JMP PROMPT    ;NO, KEEP GOING
  830. L@00038:
  831.     JMP PRMPTR    ;ALL DONE
  832. ;
  833. ;Set CP/M 2.x user number
  834. ;
  835. USER:
  836.     CALL DECIN    ;GET REQUESTED USER NO.
  837.     MOV AL,DL
  838.     CMP AL,32    ;VALID?
  839.     JNAE L@00040
  840.     JMP WHAT
  841. L@00040:
  842.     MOV AL,DH
  843.     OR AL,AL
  844.     JZ L@00041
  845.     JMP WHAT
  846. L@00041:
  847.     MOV UNUM,DL    ;SAVE IT
  848.     MOV CL,SUSER
  849.     PUSH BX    ;SAVE CHAR POINTER
  850.     CALL BDOS    ;SET USER NO.
  851.     POP BX
  852.     JMP PROMPT
  853. ;
  854. ;Toggle print flag
  855. ;
  856. PRNTFF:    MOV AL,PFLAG
  857.     XOR AL,1
  858.     MOV  PFLAG,AL
  859.     JMP PROMPT
  860. ;
  861. ;Sleep routine, in tenths of a sec
  862. ;
  863. SLEEP:    CALL HEXIN    ;GET COUNT IF ANY
  864.     MOV AL,DL    ;ANY?
  865.     OR AL,AL
  866.     JNZ SLEPLP
  867.     MOV DL,10
  868. ;
  869. SLEPLP:    MOV CX,OFFSET 10000    
  870.     MOV AL,CLOCK
  871.     OR AL,AL
  872.     JZ SLEEP2
  873.     MOV CX,OFFSET 32000
  874. ;
  875. SLEEP2:
  876.     DEC CX
  877.     MOV AL,CH
  878.     OR AL,CL
  879.     JNZ SLEEP2
  880.     PUSH DX
  881.     CALL CTLCS
  882.     POP DX
  883.     JNZ L@00045
  884.     JMP PRMPTR
  885. L@00045:
  886.     DEC DL
  887.     JNZ SLEPLP
  888.     JMP PROMPT
  889. ;
  890. ;Check for control-C or S
  891. ;
  892. CTLCS:    CALL CONST
  893.     OR AL,AL
  894.     JNZ GETC
  895.     OR AL,1    ;NO CHAR, RETN NZ
  896.     RET
  897. ;
  898. GETC:    CALL CONIN
  899.     and al,5fh
  900.     cmp al,'Q'    ;a Q will quit
  901.     jz quit_ret
  902.     AND AL,1FH    ;ALLOW ASCII
  903.     CMP AL,'S'-40H
  904.     JNZ L@00048
  905.     CALL CONIN
  906. L@00048:
  907.     CMP AL,'['-40H  ;AN ESCAPE WILL QUIT
  908.     JZ QUIT_RET
  909.     CMP AL,'C'-40H  ;AND SO WILL ^C
  910.  
  911. QUIT_RET:
  912.     RET    ;0 SET IF CTL-C,esc
  913. ;
  914. ;Find our way at initialization
  915. ;
  916. GETSTP:
  917.     MOV    CL,SUSER    ;GET USER NUMBER
  918.     MOV    DL,0FFH        ;GET USER
  919.     CALL    BDOS
  920.     MOV    UNUM,AL        ;SET USER NUMBER
  921.  
  922.     MOV CL,GETDSK
  923.     CALL BDOS    ;GET CURNT DSK
  924.     MOV CL,AL    ;  WE HAVE TO SELECT
  925.     JMP SELECT    ;  TO GET THE DPH
  926. ;
  927. LOGIN:    CALL DOLOG
  928.     JMP PROMPT
  929. ;
  930. DOLOG:    MOV AL,BYTE PTR [BX]    ;DISK REQ?
  931.     MOV DX,OFFSET 0
  932.     CMP AL,CR
  933.     JNZ L@00049
  934.     JMP LGNODK
  935. L@00049:
  936.     CMP AL,'!'
  937.     JNZ L@00050
  938.     JMP LGNODK
  939. L@00050:
  940.     CALL UPCASE
  941.     INC BX
  942.     SUB AL,'A'
  943.     MOV CL,AL
  944. ;
  945. SELECT:    PUSH BX
  946.     MOV AL,CL    ;put drive in AL
  947.     push cx        ;save drive
  948.     mov dl,0    ;indicate first select    
  949.     CALL SEL    ;SELECT DISK THRU BIOS
  950.     MOV AL,BH
  951.     OR AL,BL
  952.     pop cx
  953.     JNZ L@00052
  954.     JMP WHAT    ;SELECT ERROR
  955. L@00052:
  956.     MOV  DRIVE,CL    ;REMEMBER LATER WHERE WE ARE
  957. ;
  958.     MOV AX,ES:[BX]    ;GET THE SECTOR TABLE PTR
  959.     MOV SECTBL,AX
  960.     MOV AX,8        ;IN VER 31 OFFSET IS 8
  961.     CMP BYTE PTR CPM_VERSION,31H
  962.     JAE AX8
  963.     MOV AX,10        ;BUT IN VER 11 IT IS 10 BYTES
  964. AX8:    ADD BX,AX
  965.     MOV BX,ES:[BX]    ;GET DPB PTR
  966. ;
  967. SELSKP:    CALL LOGIT
  968.     MOV BX,SYSTRK    ;RESET TRACK AND SECTOR
  969.     XCHG BX,DX    ;  TO DIRECTORY
  970.     CALL SETTRK    ;  ON EVERY
  971.     MOV DX,OFFSET 1    ;  LOGIN
  972.     CALL SETSEC    ;  CHANGE
  973.     MOV BX,PHYSEC    ;THIS LOGIC WILL TELL
  974.     MOV AL,BH    ;  IF FIRST SEC
  975.     OR AL,BL    ;  IS PHYSICAL 0
  976.     MOV  FIRST0,AL
  977.     cmp byte ptr cpm_version,31h ;if ver 31 then
  978.     jb no_set_0             ;use first sector=1
  979.     mov first0,1
  980. no_set_0:
  981.     CALL CLCSUB
  982.     POP BX
  983. ;
  984. LGNODK:    CALL NORITE
  985.     RET
  986. ;
  987. ;Read in the disk directory
  988. ;
  989. REDDIR:    PUSH BX
  990.     CALL NORITE    ;POSITIONING LOST
  991.     MOV BX,SYSTRK
  992.     MOV CURTRK,BX
  993.     MOV BX,OFFSET 1
  994.     MOV CURSEC,BX
  995.     MOV BX,DRM    ;GET DIR SIZE FROM DPB
  996.     INC BX    ; MAKE 1-RELATIVE
  997.     CALL ROTRHL
  998.     CALL ROTRHL    ;DIVIDE BY 4 (4 NAMES/SECTOR)
  999.     MOV CX,BX
  1000.     MOV DX,OFFSET DIRECT    ;DMA ADDR
  1001. ;
  1002. RDIRLP:    PUSH CX
  1003.     PUSH DX
  1004.     MOV CX,DX
  1005.     MOV AL,0F0H    ;FORCE MEMORY
  1006.     CMP AL,DH
  1007.     JAE L@00053
  1008.     JMP MEMFUL
  1009. L@00053:
  1010.     CALL SETDMA
  1011.     MOV BX,CURTRK
  1012.     XCHG BX,DX
  1013.     CALL SETTRK
  1014.     MOV BX,CURSEC
  1015.     XCHG BX,DX
  1016.     CALL SETSEC
  1017.     CALL READ
  1018.     CALL NXTSEC
  1019.     POP DX
  1020.     POP CX
  1021.     MOV BX,OFFSET 80H
  1022.     ADD BX,DX
  1023.     XCHG BX,DX
  1024.     DEC CX
  1025.     MOV AL,CH
  1026.     OR AL,CL
  1027.     JNZ RDIRLP
  1028.     MOV CX,OFFSET BASE +80H
  1029.     CALL SETDMA
  1030.     POP BX
  1031.     RET
  1032. ;
  1033. ;Map the directory
  1034. ;
  1035. MAP:    CALL REDDIR    ;READ IN DIRECTORY
  1036.     MOV CL,0    ;INIT START GRP #
  1037.     MOV AL,AL0    ;READ DIR GRP BITS
  1038.     CALL COLECT    ;COLLECT COUNT OF DIR GRPS..
  1039.     MOV AL,AL1    ;..IN REGISTER C
  1040.     CALL COLECT
  1041.     MOV CH,0    ;BC NOW HAS A DEFAULT START GRP #
  1042.     CALL HEXIN
  1043.     PUSH BX    ;SAVE INBUF PTR
  1044.     MOV AL,DL    ;GET START
  1045.     OR AL,DH    ;NOTHING?
  1046.     JZ MAPDF    ;..YES, DFLT
  1047.     MOV CX,DX
  1048. ;
  1049. MAPDF:    CALL HEXB
  1050.     MOV AL,'-'
  1051.     CALL TYPEOUT
  1052.     CALL GETGRP    ;GET GRP(C) TO HL
  1053. ;
  1054. MAPCNT:
  1055.     INC CX    ;NEXT GRP #
  1056.     PUSH BX
  1057.     MOV BX,DSM    ;GET HIGHEST GRP #
  1058.     INC BX    ;PLUS 1 FOR COMPARISON
  1059.     MOV AL,BL    ;WHEN BC REACHES DSM+1..
  1060.     CMP AL,CL    ;..THEN WE HAVE EXCEEDED..
  1061.     JNZ MAPC1    ;.. THE DISK CAPACITY..
  1062.     MOV AL,BH
  1063.     CMP AL,CH
  1064. ;
  1065. MAPC1:    POP BX
  1066.     JZ MAPEND    ;.. AND WE ARE DONE
  1067.     PUSH BX
  1068.     CALL GETGRP    ;GET ANOTHER
  1069.     POP DX    ;SEE IF SAME
  1070.     CALL CTLCS
  1071.     JZ MAPND2
  1072.     MOV AL,DH
  1073.     CMP AL,BH
  1074.     JNZ MAPDIF
  1075.     MOV AL,DL
  1076.     CMP AL,BL
  1077.     JZ MAPCNT    ;SAME, CONTINUE
  1078. ;
  1079. ;Different file encountered
  1080. MAPDIF:
  1081.     DEC CX
  1082.     CALL HEXB
  1083.     INC CX
  1084.     XCHG BX,DX
  1085.     CALL MAPNAM
  1086.     JMP MAPDF
  1087. ;
  1088. ;End of map
  1089. ;
  1090. MAPEND:
  1091.     DEC CX    ;GET LAST
  1092.     CALL HEXB
  1093.     CALL MAPNAM
  1094.     POP BX
  1095.     CALL CRLF
  1096. ;
  1097. ;End of map - reposition to previous group
  1098. ;
  1099. MAPND2:    PUSH BX
  1100.     MOV BX,GROUP
  1101.     XCHG BX,DX
  1102.     JMP POSGP2
  1103. ;
  1104. ;Print file name pointed to by HL
  1105. ;
  1106. MAPNAM:    CALL SPACE
  1107.     MOV AL,BH
  1108.     OR AL,BL    ;NONE?
  1109.     JZ NONAME
  1110.     MOV AL,BYTE PTR [BX]    ;SEE IF ALLOC
  1111. ;    cmp al,20h ! je noname
  1112. ;    cmp al,21h ! je noname
  1113.     CMP AL,0E5H    ;FREE?
  1114.     MOV AL,' '
  1115.     JNZ MPNSP1
  1116.     MOV AL,'['
  1117. ;
  1118. MPNSP1:    CALL TYPEOUT
  1119.     PUSH BX    ;SAVE POINTER
  1120.     MOV AL,BYTE PTR [BX]
  1121.     CALL HEX    ;SHOW USER NUMBER
  1122.     CALL SPACE
  1123.     INC BX    ;SKIP USER BYTE
  1124.     PUSH CX
  1125.     MOV CH,8
  1126.     CALL MAPN2
  1127.     MOV AL,'.'
  1128.     CALL TYPEOUT
  1129.     MOV CH,3
  1130.     CALL MAPN2
  1131.     POP CX
  1132.     CALL SPACE
  1133.     MOV AL,BYTE PTR [BX]    ;GET EXT
  1134.     CALL HEX
  1135.     POP BX
  1136.     MOV AL,BYTE PTR [BX]
  1137.     CMP AL,0E5H
  1138.     MOV AL,' '
  1139.     JNZ MPNSP2
  1140.     MOV AL,']'
  1141. ;
  1142. MPNSP2:    CALL TYPEOUT    ;")" IF ERASED FILE
  1143.     JMP FLIP
  1144. ;
  1145. NONAME:    CALL ILPRT
  1146.     DB    '    ++FREE++        ',0
  1147. ;
  1148. FLIP:    MOV AL,TWOUP
  1149.     XOR AL,1
  1150.     MOV  TWOUP,AL
  1151.     JNZ L@00064
  1152.     JMP CRLF
  1153. L@00064:
  1154. ;
  1155. DELIM:    MOV AL,':'
  1156.     CALL TYPEOUT
  1157.     JMP SPACE
  1158. ;
  1159. ;Print name, length in B
  1160. ;
  1161. MAPN2:    MOV AL,BYTE PTR [BX]
  1162.     AND AL,7FH    ;STRIP POSSIBLE 2.x ATTRIBUTE BIT
  1163.     INC BX
  1164.     CMP AL,' '    ;PRINTABLE?
  1165.     JNAE MAPN2H    ;..NO, IN HEX
  1166.     CMP AL,7EH    ;7E IS LEADIN ON SOME CRTS
  1167.     JNAE MAPN2A
  1168. ;
  1169. MAPN2H:    CALL BHEX
  1170.     JMP MAPN2Z
  1171. ;
  1172. MAPN2A:    CALL TYPEOUT
  1173. ;
  1174. MAPN2Z:    DEC CH
  1175.     JNZ MAPN2
  1176.     RET
  1177. ;
  1178. ;Find which file group (BC) belongs to
  1179. ;
  1180. GETGRP:    MOV BX,DRM    ;MAX DIR ENTRY #
  1181.     INC BX    ;MAKE 1-RELATIVE
  1182.     MOV FILECT,BX
  1183.     MOV BX,OFFSET DIRECT
  1184. ;
  1185. GETGLP:    PUSH BX    ;SAVE POINTER TO NAME
  1186.     MOV AL,BYTE PTR [BX]    ;PICK UP user number
  1187.     cmp al,20h ! je getgnf    ;user must be <20h
  1188.     cmp al,21h ! je getgnf  ;
  1189.     MOV DX,OFFSET 14    ;NOW GET RECORD COUNT
  1190.     ADD BX,DX    ; S2 PORTION ..
  1191.     MOV AL,BYTE PTR [BX]    ;  IS 0 IN CP/M 1.4
  1192.     CMP AL,0E5H
  1193.     JZ GETGNF
  1194.     AND AL,0FH
  1195.     MOV DL,AL
  1196.     INC BX
  1197.     MOV AL,BYTE PTR [BX]
  1198.     OR AL,DL
  1199.     JZ GETGNF
  1200.     MOV DL,16    ;FIRST SET FOR 8-BIT GRPS
  1201.     MOV AL,BYTE PTR DSM+1
  1202.     OR AL,AL
  1203.     JZ SMALGP
  1204.     MOV DL,8    ;NOPE, BIG GROUPS
  1205. ;
  1206. SMALGP:    MOV DH,AL    ;SAVE GRP SIZE INDICATOR
  1207. ;
  1208. GETGL2:
  1209.     INC BX    ;POINTING INTO DM FIELD
  1210.     CALL GRPCMP    ;COMPARE BC GP # AGAINST 1 DM FLD
  1211.     JZ GETGOT    ;JUMP IF FOUND ONE
  1212.     DEC DL    ;ELSE COUNT DOWN
  1213.     JNZ GETGL2    ;GO TEST SOME MORE
  1214. ;
  1215. GETGNF:    POP BX    ;NOT THIS ONE
  1216.     
  1217.     MOV DX,OFFSET 32    ;SO GO TO NEXT
  1218.     ADD BX,DX
  1219.     XCHG BX,DX
  1220.     MOV BX,FILECT    ;THERE IS LIMIT TO EVERYTHING
  1221.     DEC BX
  1222.     MOV FILECT,BX
  1223.     MOV AL,BH
  1224.     OR AL,BL
  1225.     XCHG BX,DX    ;RE-ALIGN
  1226.     JNZ GETGLP
  1227. ;
  1228. ;Group is not allocated to any file
  1229.     MOV BX,OFFSET 0    ;SAY SO
  1230.     RET
  1231. ;
  1232. ;Found the file
  1233. ;
  1234. GETGOT:    POP BX
  1235.     RET
  1236. ;
  1237. ;Save the current sector
  1238. ;
  1239. SAVE:    MOV AL,WRFLG
  1240.     OR AL,AL
  1241.     JNZ L@00074
  1242.     JMP BADW    ;NONE TO SAVE
  1243. L@00074:
  1244.     PUSH BX
  1245.     MOV BX,OFFSET BASE +80H
  1246.     MOV DX,OFFSET SAVBUF
  1247.     MOV CH,128
  1248.     CALL MOVE
  1249.     MOV AL,1    ;..SHOW
  1250.     MOV  SAVEFL,AL    ;..SAVED EXISTS
  1251.     POP BX
  1252.     JMP PROMPT
  1253. ;
  1254. ;Restore the current sector
  1255. ;
  1256. RESTOR:    MOV AL,SAVEFL
  1257.     OR AL,AL
  1258.     JZ NOSAVE    ;NONE TO SAVE
  1259.     PUSH BX
  1260.     MOV BX,OFFSET SAVBUF
  1261.     MOV DX,OFFSET BASE +80H
  1262.     MOV CH,128
  1263.     CALL MOVE
  1264.     POP BX
  1265.     JMP PROMPT
  1266. ;
  1267. NOSAVE:    XOR AL,AL
  1268.     MOV  QFLAG,AL
  1269.     CALL ILPRT
  1270.     DB    '++NO "<" SAVE COMMAND ISSUED'
  1271.     DB    CR,LF,0
  1272.     JMP PRMPTR
  1273. ;
  1274. ;Move (HL) to (DE) length in B
  1275. ;
  1276. MOVE:    MOV AL,BYTE PTR [BX]
  1277.     XCHG BX,DX
  1278.     MOV [BX],AL
  1279.     XCHG BX,DX
  1280.     INC BX
  1281.     INC DX
  1282.     DEC CH
  1283.     JNZ MOVE
  1284.     RET
  1285. ;
  1286. MOVEFROMBIOS:
  1287.     MOV AL,ES:BYTE PTR [BX]
  1288.     XCHG BX,DX
  1289.     MOV [BX],AL
  1290.     XCHG BX,DX
  1291.     INC BX
  1292.     INC DX
  1293.     DEC CH
  1294.     JNZ MOVEFROMBIOS
  1295.     RET
  1296. ;
  1297. NORITE:    XOR AL,AL    ;GET 0
  1298.     MOV  WRFLG,AL    ;CAN'T WRITE NOW
  1299.     RET
  1300. ;
  1301. ;No match in search, try next char
  1302. ;
  1303. SRNOMT:    POP BX
  1304.     CALL CTLCS    ;ABORT?
  1305.     JNZ SEARCH    ;...YES
  1306.     MOV BX,OFFSET INBUF
  1307.     MOV BYTE PTR [BX],CR
  1308.     JMP CLCGRP    ;SHOW WHERE STOPPED
  1309. ;
  1310. ;Search for character string
  1311. ;
  1312. SEARCH:    PUSH BX    ;SAVE STRING POINTER
  1313. ;
  1314. SRCHL:    CALL RDBYTE    ;GET A BYTE
  1315.     MOV CH,AL    ;SAVE IT
  1316.     MOV AL,BYTE PTR [BX]    ;CHECK NEXT MATCH CHAR.
  1317.     CMP AL,'<'    ;WILL IT BE HEX?
  1318.     MOV AL,CH    ;RESTORE DISK CHAR
  1319.     JZ SRCHL1
  1320.     AND AL,7FH    ;NEXT CHAR IS ASCII...STRIP BIT 7
  1321. ;
  1322. SRCHL1:    LAHF
  1323.     XCHG AL,AH
  1324.     PUSH AX
  1325.     XCHG AL,AH
  1326.     CALL GETVAL    ;GET SEARCH VALUE
  1327.     MOV CH,AL
  1328.     POP AX
  1329.     XCHG AL,AH
  1330.     SAHF
  1331.     CMP AL,CH    ;MATCH?
  1332.     JNZ SRNOMT    ;NO MATCH
  1333.     INC BX
  1334.     MOV AL,BYTE PTR [BX]    ;DONE?
  1335.     CMP AL,CR
  1336.     JZ SREQU
  1337.     CMP AL,'!'
  1338.     JNZ SRCHL
  1339. ;
  1340. ;Got match
  1341. SREQU:    XOR AL,AL
  1342.     MOV  QFLAG,AL
  1343.     CALL ILPRT
  1344.     DB    '= AT ',0
  1345.     MOV AL,BYTE PTR BUFAD
  1346.     AND AL,7FH
  1347.     CALL HEX
  1348.     CALL CRLF
  1349.     JMP CLCGRP
  1350. ;
  1351. ;Get value from input buffer
  1352. ;
  1353. GETVAL:    MOV AL,BYTE PTR [BX]
  1354.     CMP AL,'<'    ;HEX ESCAPE?
  1355.     JZ L@00082
  1356.     RET    ;NO, RETURN
  1357. L@00082:
  1358. ;"<<" means one "<"
  1359.     INC BX
  1360.     MOV AL,BYTE PTR [BX]
  1361.     CMP AL,'<'
  1362.     JNZ L@00083
  1363.     RET
  1364. L@00083:
  1365. ;Got hex
  1366.     PUSH DX
  1367.     CALL HEXIN    ;GET VALUE
  1368.     CMP AL,'>'    ;PROPER DELIM?
  1369.     MOV AL,DL    ;GET VALUE
  1370.     POP DX
  1371.     JZ L@00084
  1372.     JMP WHAT    ;ERROR
  1373. L@00084:
  1374.     RET
  1375. ;
  1376. ;Read a byte at a time
  1377. ;
  1378. RDBYTE:    PUSH BX
  1379.     MOV AL,FTSW    ;FIRST READ?
  1380.     OR AL,AL
  1381.     JNZ READ1
  1382.     MOV BX,BUFAD
  1383.     MOV AL,BL
  1384.     OR AL,AL    ;IN BUFFER?
  1385.     JS NORD        ;YES, SKIP READ
  1386. ;
  1387. ;Have to read
  1388.     CALL NXTSEC
  1389. ;
  1390. READ1:    XOR AL,AL
  1391.     MOV  FTSW,AL    ;NOT FIRST READ
  1392.     MOV BX,CURSEC
  1393.     XCHG BX,DX
  1394.     CALL SETSEC
  1395.     MOV BX,CURTRK
  1396.     XCHG BX,DX
  1397.     CALL SETTRK
  1398.     CALL READ
  1399.     CALL CLCSUB
  1400.     MOV BX,OFFSET BASE +80H
  1401. ;
  1402. NORD:    MOV AL,BYTE PTR [BX]
  1403.     INC BX
  1404.     MOV BUFAD,BX
  1405.     POP BX
  1406.     RET
  1407. ;
  1408. ;View the file in ASCII starting at
  1409. ;current sector, stepping thru the disk
  1410. ;
  1411. VIEW:    MOV AL,WRFLG
  1412.     OR AL,AL
  1413.     JNZ L@00087
  1414.     JMP BADDMP
  1415. L@00087:
  1416.     CALL HEXIN    ;GET DISPL IF ANY
  1417.     PUSH BX
  1418.     MOV AL,DL
  1419.     OR AL,AL
  1420.     JNZ VIEWLP
  1421.     INC DL    ;DFLT=1
  1422. ;
  1423. VIEWLP:    MOV BX,OFFSET BASE +80H    ;TO DATA
  1424. ;
  1425. VEWCHR:    CALL CTLCS
  1426.     JZ VEWEND
  1427.     MOV AL,BYTE PTR [BX]
  1428.     CMP AL,1AH
  1429.     JZ VEWEOF
  1430.     AND AL,7FH
  1431.     CMP AL,7EH
  1432.     JAE VIEWHX    ;SHOW RUBOUT AND TILDE AS HEX
  1433.     CMP AL,' '
  1434.     JAE VIEWPR
  1435.     CMP AL,CR
  1436.     JZ VIEWPR
  1437.     CMP AL,LF
  1438.     JZ VIEWPR
  1439.     CMP AL,TAB
  1440.     JZ VIEWPR
  1441. ;
  1442. VIEWHX:    MOV AL,BYTE PTR [BX]    ;NOT ASCII...PRINT AS <NN>
  1443.     CALL BHEX
  1444.     JMP VIEWNP
  1445. ;
  1446. VIEWPR:    CALL TYPEOUT
  1447. ;
  1448. VIEWNP:    INC BL
  1449.     JNZ VEWCHR
  1450.     DEC DL
  1451.     JZ VEWEND
  1452.     PUSH DX    ;SAVE COUNT
  1453.     CALL NXTSEC
  1454.     MOV BX,CURSEC
  1455.     XCHG BX,DX
  1456.     CALL SETSEC
  1457.     MOV BX,CURTRK
  1458.     XCHG BX,DX
  1459.     CALL SETTRK
  1460.     CALL READ
  1461.     POP DX    ;RESTORE COUNT
  1462.     JMP VIEWLP
  1463. ;
  1464. VEWEOF:    CALL ILPRT
  1465.     DB    CR,LF,TAB,'++EOF++',CR,LF,0
  1466. ;
  1467. VEWEND:    POP BX
  1468.     CALL CRLF
  1469.     JMP CLCGRP
  1470. ;
  1471. ;Dump in hex or ASCII
  1472. ;
  1473. DUMP:    MOV AL,WRFLG
  1474.     OR AL,AL
  1475.     JNZ DUMPOK
  1476. ;
  1477. BADDMP:    XOR AL,AL
  1478.     MOV  QFLAG,AL
  1479.     CALL ILPRT
  1480.     DB    '++Can''t dump, no sector read.',CR,LF,0
  1481. ;
  1482. EXPL:    XOR AL,AL
  1483.     MOV  QFLAG,AL
  1484.     CALL ILPRT
  1485.     DB    'Use G command following F,',CR,LF
  1486.     DB    'or R or S following T',CR,LF,0
  1487.     JMP PRMPTR
  1488. ;
  1489. DUMPOK:    MOV AL,BYTE PTR [BX]
  1490.     CMP AL,'!'
  1491.     JZ DUMPDF    ;DFLT
  1492.     CMP AL,CR
  1493.     JNZ DMPNDF
  1494. ;
  1495. ;Use default
  1496. DUMPDF:    MOV CX,OFFSET BASE +80H
  1497.     MOV DX,OFFSET 0FFH
  1498.     JMP DUMP1
  1499. ;
  1500. DMPNDF:    CALL DISP
  1501.     MOV CX,DX
  1502.     CMP AL,CR
  1503.     JZ DUMP1
  1504.     CMP AL,'!'
  1505.     JZ DUMP1
  1506.     INC BX    ;SKIP ','
  1507.     CALL DISP
  1508. ;
  1509. ;BC = start, DE = end
  1510. ;
  1511. DUMP1:    PUSH BX    ;SAVE COMMAND POINTER
  1512.     MOV BX,CX
  1513. ;
  1514. DUMPLP:    MOV AL,BL
  1515.     AND AL,7FH
  1516.     CALL HEX
  1517.     CALL SPACE
  1518.     CALL SPACE
  1519.     MOV AL,DUMTYP
  1520.     CMP AL,'A'
  1521.     JZ DUMPAS
  1522.     PUSH BX    ;SAVE START
  1523. ;
  1524. DHEX:    MOV AL,BYTE PTR [BX]
  1525.     CALL HEX
  1526.     MOV AL,BL
  1527.     AND AL,3
  1528.     CMP AL,3
  1529.     JNZ L@00104
  1530.     CALL SPACE
  1531. L@00104:
  1532.     MOV AL,BL
  1533.     AND AL,7
  1534.     CMP AL,7
  1535.     JNZ L@00105
  1536.     CALL SPACE
  1537. L@00105:
  1538.     MOV AL,DL
  1539.     CMP AL,BL
  1540.     JZ DPOP
  1541.     INC BX
  1542.     MOV AL,BL
  1543.     AND AL,0FH
  1544.     JNZ DHEX
  1545. ;
  1546. DPOP:    CALL CTLCS
  1547.     JNZ L@00108
  1548.     JMP PRMPTR
  1549. L@00108:
  1550.     MOV AL,DUMTYP
  1551.     CMP AL,'H'
  1552.     JZ DNOAS    ;HEX ONLY
  1553.     POP BX    ;GET START ADDR
  1554. ;
  1555. DUMPAS:    CALL ASTER
  1556. ;
  1557. DCHR:    MOV AL,BYTE PTR [BX]
  1558.     AND AL,7FH
  1559.     CMP AL,' '
  1560.     JNAE DPER
  1561.     CMP AL,7EH
  1562.     JNAE DOK
  1563. ;
  1564. DPER:    MOV AL,'.'
  1565. ;
  1566. DOK:    CALL TYPEOUT
  1567.     MOV AL,DL
  1568.     CMP AL,BL
  1569.     JZ DEND
  1570.     INC BX
  1571.     MOV AL,BL
  1572.     AND AL,0FH
  1573.     JNZ DCHR
  1574. ;
  1575. DEND:    CALL ASTER
  1576.     CALL CRLF
  1577.     PUSH DX
  1578.     CALL CTLCS
  1579.     POP DX
  1580.     JNZ L@00114
  1581.     JMP PRMPTR
  1582. L@00114:
  1583.     MOV AL,DL
  1584.     CMP AL,BL
  1585.     JZ L@00115
  1586.     JMP DUMPLP
  1587. L@00115:
  1588.     POP BX
  1589.     JMP PROMPT
  1590. ;
  1591. DNOAS:    POP CX
  1592.     CALL CRLF
  1593.     MOV AL,DL
  1594.     CMP AL,BL
  1595.     JZ L@00116
  1596.     JMP DUMPLP
  1597. L@00116:
  1598.     POP BX
  1599.     JMP PROMPT
  1600. ;
  1601. ;Position
  1602. ;
  1603. POS:    LAHF
  1604.     XCHG AL,AH
  1605.     PUSH AX
  1606.     XCHG AL,AH
  1607.     MOV AL,BYTE PTR [BX]
  1608.     CMP AL,'!'
  1609.     JZ POSINQ
  1610.     CMP AL,CR
  1611.     JNZ POSOK
  1612. ;
  1613. POSINQ:    POP AX
  1614.     XCHG AL,AH
  1615.     SAHF
  1616.     JMP INQ
  1617. ;
  1618. POSOK:    POP AX
  1619.     XCHG AL,AH
  1620.     SAHF
  1621.     CMP AL,'T'
  1622.     JZ POSTKD
  1623.     CMP AL,'S'
  1624.     JZ POSSCD
  1625.     CMP AL,'G'
  1626.     JNZ L@00121
  1627.     JMP POSGPH
  1628. L@00121:
  1629.     JMP WHAT
  1630. ;
  1631. POSTKD:    CALL DECIN
  1632. ;
  1633. POSTRK:    PUSH BX
  1634.     MOV BX,MAXTRK
  1635.     CALL SUBDE
  1636.     POP BX
  1637.     JAE L@00122
  1638.     JMP OUTLIM
  1639. L@00122:
  1640.     CALL SETTRK
  1641.     CALL NORITE    ;TRACK DOESN'T READ
  1642.     MOV AL,1
  1643.     MOV  NOTPOS,AL    ;SHOW NOT POSITIONED
  1644.     JMP CLCGRP
  1645. ;
  1646. POSSCD:    CALL DECIN
  1647.     MOV AL,DH
  1648.     OR AL,DL
  1649.     JNZ L@00123
  1650.     JMP WHAT    ;DON'T ALLOW SECTOR 0
  1651. L@00123:
  1652. ;
  1653. POSSEC:    PUSH BX
  1654.     MOV BX,SPT
  1655.     CALL SUBDE
  1656.     POP BX
  1657.     JAE L@00124
  1658.     JMP WHAT
  1659. L@00124:
  1660.     CALL SETSEC
  1661.     CALL READ
  1662.     XOR AL,AL
  1663.     MOV  NOTPOS,AL    ;POSITIONED OK
  1664. ;
  1665. CLCGRP:    CALL CLCSUB
  1666.     JMP INQ
  1667. ;
  1668. ;Calculate group from track and sector
  1669. ;
  1670. CLCSUB: push bx
  1671.     mov ax,CURTRK
  1672.     mov bx,SYSTRK
  1673.     cmp bx,ax ! ja a_systrack
  1674.     sub ax,SYSTRK
  1675. a_systrack:
  1676.     xor dx,dx
  1677.     mul SPT        ;TRK*SPT=hi bits in DX lo bits in AX
  1678.     mov bx,CURSEC
  1679.     dec bx
  1680.     add ax,bx    ;add in cursec - 1
  1681.     adc dx,0
  1682. divide1:
  1683.     mov bx,1
  1684.     mov cl,BSH
  1685.     shl bx,cl    ;BX = 2^BSH
  1686.     div bx        ;DX:AX=((CURTRK-SYSTRK)*SPT+CURSEC-1)/(2^BSH)
  1687.  
  1688.     mov group,ax    ;AX=quotent, DX=remainder
  1689.     mov GRPDIS,dl
  1690.     pop bx
  1691.     ret
  1692. ;
  1693. ;Position in the dorectory after a find
  1694. ;(Does not work in CP/M-2.x)
  1695. ;
  1696. POSDIR:    PUSH BX    ;SAVE INBUF
  1697.     MOV BX,WORD PTR BSH
  1698.     XOR AL,AL
  1699.     MOV  FINDFL,AL    ;CANCEL POS REQ
  1700.     MOV AL,DIRPOS    ;GET POSITION
  1701.     RCR AL,1
  1702.     RCR AL,1
  1703.     LAHF
  1704.     XCHG AL,AH
  1705.     PUSH AX
  1706.     XCHG AL,AH
  1707.     AND AL,BH
  1708.     MOV  GRPDIS,AL
  1709.     POP AX
  1710.     XCHG AL,AH
  1711.     SAHF
  1712. ;
  1713. POSDLP:    RCR AL,1
  1714.     DEC BL
  1715.     JNZ POSDLP
  1716.     AND AL,1    ;GET GROUP
  1717.     MOV BL,AL    ;SETUP FOR POSGP2
  1718.     MOV BH,0
  1719.     MOV GROUP,BX
  1720.     XCHG BX,DX
  1721.     JMP POSGP2    ;POSITION TO IT
  1722. ;
  1723. POSGPH:    CALL HEXIN
  1724. ;
  1725. POSGRP:    PUSH BX
  1726.     MOV BX,DSM
  1727.     CALL SUBDE
  1728.     POP BX
  1729.     JAE L@00127
  1730.     JMP OUTLIM
  1731. L@00127:
  1732.     XCHG BX,DX
  1733.     MOV GROUP,BX
  1734.     XCHG BX,DX
  1735.     XOR AL,AL
  1736.     MOV  GRPDIS,AL
  1737.     PUSH BX
  1738. ;
  1739. POSGP2:    CALL GTKSEC
  1740.     CALL SETTRK
  1741.     XCHG BX,DX
  1742.     inc  dx
  1743.     CALL SETSEC
  1744.     CALL READ
  1745.     XOR AL,AL
  1746.     MOV  NOTPOS,AL    ;NOW POSITIONED
  1747.     POP BX
  1748.     JMP INQ
  1749. ;
  1750. GTKSEC:
  1751.     MOV BX,DX    ;BX = number of blocks
  1752.     mov cl,BSH
  1753.     
  1754.     mov ax,1
  1755.     shl ax,cl    ;AX=2^BSH
  1756.     xor dx,dx    ;clear DX register
  1757.     mul bx        ;AX*BX=hi 16 bits in DX, lo in AX
  1758.     xor bx,bx
  1759.     mov bl,GRPDIS
  1760.     add ax,bx    ;add in GRPDIS
  1761.     adc dx,0    ;with carry into DX
  1762. ;
  1763. ;Divide by nbr of sectors, quotient=track, remainder=sector
  1764. ;NOTE for O/S = ver 3.1+, SPT is in 128 byte units, not phy sectors
  1765. ;
  1766. divide2:
  1767.     div Word Ptr SPT ;DX:AX/SPT=AX(quotent)=track, DX(remainder)=sector
  1768.     add ax,SYSTRK    ;add in track offset
  1769.     mov bx,dx    ;and get stuff into proper registers
  1770.     mov dx,ax    ;for the return
  1771.     or bx,bx    ;don't allow a zero sector number
  1772.     ret
  1773. ;
  1774. POSFIL:    CALL NORITE
  1775.     MOV AL,1
  1776.     MOV  FINDFL,AL    ;SO WE POSITION LATER
  1777.     MOV DX,OFFSET FCB
  1778.     XOR AL,AL    ;LOGGED IN DISK
  1779.     XCHG BX,DX
  1780.     MOV [BX],AL
  1781.     XCHG BX,DX
  1782.     INC DX
  1783.     MOV CH,8
  1784.     CALL MVNAME
  1785.     MOV CH,3
  1786.     CALL MVNAME
  1787.     MOV DX,OFFSET FCB
  1788.     MOV CL,SRCHF
  1789.     PUSH BX
  1790.     CALL BDOS
  1791.     INC AL
  1792.     JNZ FLOK
  1793.     MOV  DIRPOS,AL    ;GRP 0 IF NOT FOUND
  1794.     CALL ILPRT
  1795.     DB    '++FILE NOT FOUND',CR,LF,0
  1796.     POP BX
  1797.     JMP PROMPT
  1798. ;
  1799. FLOK:    DEC AL
  1800.     MOV  DIRPOS,AL    ;SAVE POS. IN DIR
  1801.     AND AL,3
  1802.     MOV BL,AL
  1803.     MOV BH,0
  1804.     ADD BX,BX
  1805.     ADD BX,BX
  1806.     ADD BX,BX
  1807.     ADD BX,BX
  1808.     ADD BX,BX
  1809.     MOV DX,OFFSET BASE +80H
  1810.     ADD BX,DX
  1811.     MOV DX,OFFSET 32
  1812.     XCHG BX,DX
  1813.     ADD BX,DX
  1814.     XCHG BX,DX
  1815.     MOV AL,'D'
  1816.     MOV  DUMTYP,AL
  1817.     JMP DUMPLP    ;WHICH POPS H
  1818. ;
  1819. MVNAME:    MOV AL,BYTE PTR [BX]
  1820.     CMP AL,'.'
  1821.     JZ MVIPAD
  1822.     CMP AL,CR
  1823.     JZ PAD
  1824.     CMP AL,'!'
  1825.     JZ PAD
  1826.     CALL UPCASE
  1827.     XCHG BX,DX
  1828.     MOV [BX],AL
  1829.     XCHG BX,DX
  1830.     INC BX
  1831.     INC DX
  1832.     DEC CH
  1833.     JNZ MVNAME
  1834.     MOV AL,BYTE PTR [BX]
  1835.     CMP AL,CR
  1836.     JNZ L@00135
  1837.     RET
  1838. L@00135:
  1839.     CMP AL,'!'
  1840.     JNZ L@00136
  1841.     RET
  1842. L@00136:
  1843.     INC BX
  1844.     CMP AL,'.'
  1845.     JNZ L@00137
  1846.     RET
  1847. L@00137:
  1848.     JMP WHAT
  1849. ;
  1850. MVIPAD:
  1851.     INC BX
  1852. ;
  1853. PAD:    MOV AL,' '
  1854.     XCHG BX,DX
  1855.     MOV [BX],AL
  1856.     XCHG BX,DX
  1857.     INC DX
  1858.     DEC CH
  1859.     JNZ PAD
  1860.     RET
  1861. ;
  1862. PLUS:    MOV DX,OFFSET 1    ;DFLT TO 1 SECT
  1863.     MOV AL,BYTE PTR [BX]    ;GET NEXT CHAR
  1864.     CMP AL,CR    ;CR?
  1865.     JZ PLUSGO    ;.. YES, DFLT TO 1
  1866.     CMP AL,'!'
  1867.     JZ PLUSGO
  1868.     CALL HEXIN    ;GET #
  1869.     MOV AL,DH
  1870.     OR AL,DL
  1871.     JNZ L@00141
  1872.     JMP WHAT
  1873. L@00141:
  1874. ;
  1875. PLUSGO:    CALL NXTSEC
  1876.     DEC DX    ;MORE TO GO?
  1877.     MOV AL,DH
  1878.     OR AL,DL
  1879.     JNZ PLUSGO    ;..YES
  1880. ;
  1881. ;Ok, incremented to sector.  Setup and read
  1882. ;
  1883. PLUSMI:    PUSH BX
  1884.     MOV BX,CURSEC
  1885.     XCHG BX,DX
  1886.     CALL SETSEC
  1887.     MOV BX,CURTRK
  1888.     XCHG BX,DX
  1889.     CALL SETTRK
  1890.     POP BX
  1891.     CALL READ
  1892.     JMP CLCGRP
  1893. ;
  1894. MINUS:    MOV DX,OFFSET 1    ;SET DFLT
  1895.     MOV AL,BYTE PTR [BX]    ;GET CHAR
  1896.     CMP AL,CR    ;CR?
  1897.     JZ MINGO    ;.. YES, DFLT=1
  1898.     CMP AL,'!'
  1899.     JZ MINGO
  1900.     CALL HEXIN    ;..NO, GET ##
  1901.     MOV AL,DH
  1902.     OR AL,DL
  1903.     JNZ L@00145
  1904.     JMP WHAT
  1905. L@00145:
  1906. ;
  1907. MINGO:    PUSH BX
  1908.     MOV BX,CURSEC
  1909.     DEC BX
  1910.     MOV AL,BH
  1911.     OR AL,BL
  1912.     JNZ MINOK
  1913.     MOV BX,CURTRK
  1914.     MOV AL,BH
  1915.     OR AL,BL
  1916.     JNZ SEASH
  1917.     MOV BX,MAXTRK    ;WRAP TO END OF DISK
  1918.     MOV CURTRK,BX
  1919.     MOV BX,MAXSEC
  1920.     JMP MINOK
  1921. ;
  1922. SEASH:
  1923.     DEC BX
  1924.     MOV CURTRK,BX
  1925.     MOV BX,SPT
  1926. ;
  1927. MINOK:    MOV CURSEC,BX
  1928.     POP BX
  1929.     DEC DX
  1930.     MOV AL,DH
  1931.     OR AL,DL
  1932.     JNZ MINGO
  1933.     JMP PLUSMI
  1934. ;
  1935. ;Go to next sector
  1936. ;
  1937. NXTSEC:    PUSH BX
  1938.     PUSH DX
  1939.     MOV BX,CURSEC
  1940.     INC BX
  1941.     XCHG BX,DX
  1942.     MOV BX,SPT
  1943.     CALL SUBDE
  1944.     XCHG BX,DX
  1945.     JAE NEXTOK
  1946.     MOV BX,CURTRK
  1947.     INC BX
  1948.     XCHG BX,DX
  1949.     MOV BX,MAXTRK
  1950.     CALL SUBDE
  1951.     JAE TRASK
  1952.     MOV DX,OFFSET 0    ;WRAP TO START OF DISK
  1953. ;
  1954. TRASK:    XCHG BX,DX
  1955.     MOV CURTRK,BX
  1956.     MOV BX,OFFSET 1
  1957. ;
  1958. NEXTOK:    MOV CURSEC,BX
  1959.     POP DX
  1960.     POP BX
  1961.     RET
  1962. ;
  1963. ;Tell what group, displacement, track, sector, physical sector
  1964. ;
  1965. INQ:    CALL INQSUB
  1966.     JMP PROMPT
  1967. ;
  1968. ;Position inquiry subroutine
  1969. ;Executed via: G S or T (with no operands)
  1970. ;
  1971. INQSUB:    PUSH BX
  1972.     MOV BX,SYSTRK
  1973.     XCHG BX,DX
  1974.     MOV BX,CURTRK
  1975.     CALL SUBDE
  1976.     JNAE NOGRP
  1977.     CALL ILPRT
  1978.     DB    'G=',0
  1979.     MOV BX,GROUP
  1980.     MOV CH,BH
  1981.     MOV CL,BL
  1982.     CALL HEXB
  1983.     MOV AL,':'
  1984.     CALL TYPEOUT
  1985.     MOV AL,GRPDIS
  1986.     CALL HEX
  1987.     MOV AL,','
  1988.     CALL TYPEOUT
  1989. ;
  1990. NOGRP:    CALL ILPRT
  1991.     DB    ' T=',0
  1992.     MOV BX,CURTRK
  1993.     CALL DEC
  1994.     CALL ILPRT
  1995.     DB    ', S=',0
  1996.     MOV BX,CURSEC
  1997.     CALL DEC
  1998.     CALL ILPRT
  1999.     DB    ', PS=',0
  2000.     MOV BX,PHYSEC
  2001.     CALL DEC
  2002.     CALL CRLF
  2003.     POP BX
  2004.     RET
  2005. ;
  2006. CHG:    MOV AL,BYTE PTR [BX]    ;GET TYPE (HEX, ASCII)
  2007.     CALL UPCASE
  2008.     LAHF
  2009.     XCHG AL,AH
  2010.     PUSH AX
  2011.     XCHG AL,AH    ;SAVE "H" OR "A"
  2012.     INC BX
  2013.     CALL DISP    ;GET, VALIDATE DISP TO DE
  2014.     INC BX
  2015.     MOV CX,OFFSET 0    ;SHOW NO 'THRU' ADDR
  2016.     CMP AL,'-'    ;TEST DELIM FR. DISP
  2017.     JNZ CHGNTH    ;NO THRU
  2018.     PUSH DX    ;SAVE FROM
  2019.     CALL DISP    ;GET THRU
  2020.     INC BX    ;SKIP END DELIM
  2021.     MOV CX,DX    ;BC = THRU
  2022.     POP DX    ;GET FROM
  2023.     JMP CHGAH
  2024. ;
  2025. CHGNTH:    CMP AL,','
  2026.     JZ L@00153
  2027.     JMP WHAT
  2028. L@00153:
  2029. ;
  2030. CHGAH:    POP AX
  2031.     XCHG AL,AH
  2032.     SAHF
  2033.     CMP AL,'H'
  2034.     JNZ L@00154
  2035.     JMP CHGHEX
  2036. L@00154:
  2037.     CMP AL,'A'
  2038.     JZ L@00155
  2039.     JMP WHAT
  2040. L@00155:
  2041. ;
  2042. ;Change ASCII
  2043. CHGALP:    MOV AL,BYTE PTR [BX]
  2044.     CMP AL,CR
  2045.     JNZ L@00156
  2046.     JMP PROMPT
  2047. L@00156:
  2048.     CMP AL,'!'
  2049.     JNZ L@00157
  2050.     JMP PROMPT
  2051. L@00157:
  2052.     XCHG BX,DX
  2053.     MOV AL,[BX]
  2054.     XCHG BX,DX
  2055.     CMP AL,' '
  2056.     JNAE CHGAHX
  2057.     CMP AL,7EH
  2058.     JAE CHGAHX
  2059.     JMP CHGA2
  2060. ;
  2061. CHGAHX:    CALL BHEX
  2062.     JMP CHGA3
  2063. ;
  2064. CHGA2:    CALL TYPEOUT
  2065. ;
  2066. CHGA3:    MOV BACK,BX    ;IN CASE "THRU"
  2067.     CALL GETVAL    ;ASCII OR <HEX>
  2068.     XCHG BX,DX
  2069.     MOV [BX],AL
  2070.     XCHG BX,DX    ;UPDATE CHAR
  2071.     INC BX    ;TO NEXT INPUT CHAR
  2072. ;See if 'THRU' requested
  2073.     MOV AL,CL
  2074.     OR AL,AL
  2075.     JZ CHANTH
  2076.     CMP AL,DL    ;DONE?..
  2077.     JNZ L@00161
  2078.     JMP PROMPT    ;..YES
  2079. L@00161:
  2080.     MOV BX,BACK
  2081. ;
  2082. CHANTH:    INC DL
  2083.     JZ L@00162
  2084.     JMP CHGALP
  2085. L@00162:
  2086.     MOV AL,BYTE PTR [BX]
  2087.     CMP AL,CR
  2088.     JNZ L@00163
  2089.     JMP PROMPT
  2090. L@00163:
  2091.     CMP AL,'!'
  2092.     JNZ L@00164
  2093.     JMP PROMPT
  2094. L@00164:
  2095.     JMP WHAT
  2096. ;
  2097. ;Change hex
  2098. ;
  2099. CHGHCM:
  2100.     INC BX
  2101. ;
  2102. CHGHEX:    MOV AL,BYTE PTR [BX]
  2103.     CMP AL,CR
  2104.     JNZ L@00165
  2105.     JMP PROMPT
  2106. L@00165:
  2107.     CMP AL,'!'
  2108.     JNZ L@00166
  2109.     JMP PROMPT
  2110. L@00166:
  2111.     CMP AL,','    ;DELIM?
  2112.     JZ CHGHCM
  2113.     PUSH DX
  2114.     MOV HEXAD,BX    ;IN CASE 'THRU'
  2115.     CALL HEXIN    ;POSITIONS TO DELIM
  2116.     MOV AL,DL    ;GET VALUE
  2117.     POP DX    ;..ADDR
  2118.     LAHF
  2119.     XCHG AL,AH
  2120.     PUSH AX
  2121.     XCHG AL,AH    ;SAVE VALUE
  2122.     XCHG BX,DX
  2123.     MOV AL,[BX]
  2124.     XCHG BX,DX    ;GET OLD
  2125.     CALL HEX    ;ECHO IN HEX
  2126.     POP AX
  2127.     XCHG AL,AH
  2128.     SAHF    ;GET NEW
  2129.     XCHG BX,DX
  2130.     MOV [BX],AL
  2131.     XCHG BX,DX    ;SAVE NEW
  2132.     MOV AL,CL    ;SEE IF 'THRU'
  2133.     OR AL,AL
  2134.     JZ CHHNTH    ;..NO.
  2135.     CMP AL,DL    ;..YES, DONE?
  2136.     JNZ L@00169
  2137.     JMP PROMPT
  2138. L@00169:
  2139.     MOV BX,HEXAD    ;..NO: MORE
  2140. ;
  2141. CHHNTH:    INC DL
  2142.     JNZ CHGHEX
  2143.     MOV AL,BYTE PTR [BX]
  2144.     CMP AL,CR
  2145.     JNZ L@00171
  2146.     JMP PROMPT
  2147. L@00171:
  2148.     CMP AL,'!'
  2149.     JNZ L@00172
  2150.     JMP PROMPT
  2151. L@00172:
  2152.     JMP WHAT
  2153. ;
  2154. DOREAD:    MOV AL,NOTPOS
  2155.     OR AL,AL
  2156.     JNZ CANTRD
  2157.     CALL READ
  2158.     JMP PROMPT
  2159. ;
  2160. CANTRD:    XOR AL,AL
  2161.     MOV  QFLAG,AL    ;NOT QUIET
  2162.     CALL ILPRT
  2163.     DB    '++Can''t read - not positioned',CR,LF
  2164.     DB    'Position by:',CR,LF
  2165.     DB    9,'Track then Sector, or',CR,LF
  2166.     DB    9,'Group',CR,LF,0
  2167.     JMP PROMPT
  2168. ;
  2169. DORITE:    CALL WRITE
  2170.     JMP PROMPT
  2171. ;
  2172. BHEX:    LAHF
  2173.     XCHG AL,AH
  2174.     PUSH AX
  2175.     XCHG AL,AH
  2176.     MOV AL,'<'
  2177.     CALL TYPEOUT
  2178.     POP AX
  2179.     XCHG AL,AH
  2180.     SAHF
  2181.     CALL HEX
  2182.     MOV AL,'>'
  2183.     CALL TYPEOUT
  2184.     RET
  2185. ;
  2186. HEXB:    MOV AL,BYTE PTR DSM+1
  2187.     OR AL,AL
  2188.     JZ HEXX
  2189.     MOV AL,CH
  2190.     CALL HEX
  2191. ;
  2192. HEXX:    MOV AL,CL
  2193. ;
  2194. HEX:    LAHF
  2195.     XCHG AL,AH
  2196.     PUSH AX
  2197.     XCHG AL,AH
  2198.     RCR AL,1
  2199.     RCR AL,1
  2200.     RCR AL,1
  2201.     RCR AL,1
  2202.     CALL NIBBL
  2203.     POP AX
  2204.     XCHG AL,AH
  2205.     SAHF
  2206. ;
  2207. NIBBL:    AND AL,0FH
  2208.     CMP AL,10
  2209.     JNAE HEXNU
  2210.     ADD AL,7
  2211. ;
  2212. HEXNU:    ADD AL,'0'
  2213.     JMP TYPEOUT
  2214. ;
  2215. ;Decimal output routine
  2216. ;
  2217. DEC:    PUSH CX
  2218.     PUSH DX
  2219.     PUSH BX
  2220.     MOV CX,-OFFSET 10
  2221.     MOV DX,-OFFSET 1
  2222. ;
  2223. DECOU2:    PUSHF
  2224.     ADD BX,CX
  2225.     RCR SI,1
  2226.     POPF
  2227.     RCL SI,1
  2228.     PUSHF
  2229.     INC DX
  2230.     POPF
  2231.     JNAE DECOU2
  2232.     MOV CX,OFFSET 10
  2233.     ADD BX,CX
  2234.     XCHG BX,DX
  2235.     MOV AL,BH
  2236.     OR AL,BL
  2237.     JZ L@00177
  2238.     CALL DEC
  2239. L@00177:
  2240.     MOV AL,DL
  2241.     ADD AL,'0'
  2242.     CALL TYPEOUT
  2243.     POP BX
  2244.     POP DX
  2245.     POP CX
  2246.     RET
  2247. ;
  2248. SPACE:    MOV AL,' '
  2249.     JMP TYPEOUT
  2250. ;
  2251. ASTER:    MOV AL,'*'
  2252.     JMP TYPEOUT
  2253. ;
  2254. ;Inline print routine
  2255. ;
  2256. ILPRT:    POP SI
  2257.     XCHG BX,SI
  2258.     PUSH SI
  2259. ;
  2260. ILPLP:    CALL CTLCS    ;ABORT?
  2261.     JNZ L@00178
  2262.     JMP PRMPTR
  2263. L@00178:
  2264.     MOV AL,BYTE PTR [BX]
  2265.     CMP AL,1    ;PAUSE?
  2266.     JNZ ILPOK
  2267.     CALL CONIN
  2268.     CMP AL,1bh ! je il_abort    ;escape
  2269.     CMP AL,'Q'-40h ! je il_abort    ;^Q
  2270.     CMP AL,'C'-40h ! je il_abort    ;^C=ABORT?
  2271.      JMPS L@00180
  2272. IL_ABORT:
  2273.     JMP PRMPTR
  2274. L@00180:
  2275.     JMP ILPNX
  2276. ;
  2277. ILPOK:    CALL TYPEOUT
  2278. ;
  2279. ILPNX:
  2280.     INC BX
  2281.     MOV AL,BYTE PTR [BX]
  2282.     OR AL,AL
  2283.     JNZ ILPLP
  2284.     INC BX
  2285.     POP SI
  2286.     XCHG BX,SI
  2287.     PUSH SI
  2288.     RET
  2289. ;
  2290. ;DISP calls HEXIN, and validates a sector
  2291. ;displacement, then converts it to an address
  2292. ;
  2293. DISP:    CALL HEXIN
  2294.     LAHF
  2295.     XCHG AL,AH
  2296.     PUSH AX
  2297.     XCHG AL,AH    ;SAVE DELIMITER
  2298.     MOV AL,DH
  2299.     OR AL,AL
  2300.     JNZ BADISP
  2301.     MOV AL,DL
  2302.     OR AL,AL
  2303.     JS BADISP
  2304.     ADD AL,80H    ;TO POINT TO BUFFER AT BASE+80H
  2305.     MOV DL,AL
  2306.     MOV DH,BASE/256
  2307.     POP AX
  2308.     XCHG AL,AH
  2309.     SAHF    ;GET DELIM
  2310.     RET
  2311. ;
  2312. BADISP:    XOR AL,AL
  2313.     MOV  QFLAG,AL
  2314.     CALL ILPRT
  2315.     DB    '++BAD DISPLACEMENT (NOT 0-7F)'
  2316.     DB    CR,LF,0
  2317.     JMP PRMPTR
  2318. ;
  2319. HEXIN:    MOV DX,OFFSET 0
  2320.     MOV AL,BYTE PTR [BX]
  2321.     CMP AL,'#'    ;DECIMAL?
  2322.     JZ HDIN        ;MAKE DECIMAL
  2323. ;
  2324. HINLP:    MOV AL,BYTE PTR [BX]
  2325.     CALL UPCASE
  2326.     CMP AL,CR
  2327.     JNZ L@00185
  2328.     RET
  2329. L@00185:
  2330.     CMP AL,'!'
  2331.     JNZ L@00186
  2332.     RET
  2333. L@00186:
  2334.     CMP AL,','
  2335.     JNZ L@00187
  2336.     RET
  2337. L@00187:
  2338.     CMP AL,'-'    ;'THRU'?
  2339.     JNZ L@00188
  2340.     RET
  2341. L@00188:
  2342.     CMP AL,'>'
  2343.     JNZ L@00189
  2344.     RET
  2345. L@00189:
  2346.     INC BX
  2347.     CMP AL,'0'
  2348.     JAE L@00190
  2349.     JMP WHAT
  2350. L@00190:
  2351.     CMP AL,'9'+1
  2352.     JNAE HINNUM
  2353.     CMP AL,'A'
  2354.     JAE L@00192
  2355.     JMP WHAT
  2356. L@00192:
  2357.     CMP AL,'F'+1
  2358.     JNAE L@00193
  2359.     JMP WHAT
  2360. L@00193:
  2361.     SUB AL,7
  2362. ;
  2363. HINNUM:    SUB AL,'0'
  2364.     XCHG BX,DX
  2365.     ADD BX,BX
  2366.     ADD BX,BX
  2367.     ADD BX,BX
  2368.     ADD BX,BX
  2369.     ADD AL,BL
  2370.     MOV BL,AL
  2371.     XCHG BX,DX
  2372.     JMP HINLP
  2373. ;
  2374. HDIN:
  2375.     INC BX    ;SKIP '.'
  2376. ;
  2377. DECIN:    MOV DX,OFFSET 0
  2378. ;
  2379. DINLP:    MOV AL,BYTE PTR [BX]
  2380.     CALL UPCASE
  2381.     CMP AL,CR
  2382.     JNZ L@00194
  2383.     RET
  2384. L@00194:
  2385.     CMP AL,'!'
  2386.     JNZ L@00195
  2387.     RET
  2388. L@00195:
  2389.     CMP AL,','
  2390.     JNZ L@00196
  2391.     RET
  2392. L@00196:
  2393.     CMP AL,'-'    ;'THRU'?
  2394.     JNZ L@00197
  2395.     RET
  2396. L@00197:
  2397.     INC BX
  2398.     CMP AL,'0'
  2399.     JAE L@00198
  2400.     JMP WHAT
  2401. L@00198:
  2402.     CMP AL,'9'+1
  2403.     JNAE L@00199
  2404.     JMP WHAT
  2405. L@00199:
  2406.     SUB AL,'0'
  2407.     PUSH BX
  2408.     MOV BH,DH
  2409.     MOV BL,DL
  2410.     ADD BX,BX
  2411.     ADD BX,BX
  2412.     ADD BX,DX
  2413.     ADD BX,BX
  2414.     ADD AL,BL
  2415.     MOV BL,AL
  2416.     MOV AL,BH
  2417.     ADC AL,0
  2418.     MOV BH,AL
  2419.     XCHG BX,DX
  2420.     POP BX
  2421.     JMP DINLP
  2422. ;
  2423. ;Read in a console buffer full
  2424. ;
  2425. RDBUF:    ;PRINT PROMPT AS DU nnA:
  2426.     CALL    ILPRT
  2427.     DB    CR,LF,'DU ',0     ;SAY WHO WE ARE
  2428.     MOV     AL,UNUM
  2429.     CMP     AL,0 ! JZ DONT_0
  2430.     MOV    BL,AL       ;DISPLAY USER NUMBER
  2431.     MOV    BH,0
  2432.     CALL    DEC        ;PRINT IN DECIMAL
  2433. DONT_0:
  2434.     MOV    AL,DRIVE    ;GET DRIVE NUMBER
  2435.     ADD    AL,'A'        ;CONVERT TO ASCII
  2436.     CALL    TYPEOUT
  2437.     CALL    ILPRT        ;PRINT THE PROMPT
  2438.     DB    ': ',0    
  2439. ;
  2440. RDBF1:    MOV BX,OFFSET INBUF
  2441.     MOV CH,0
  2442. ;
  2443. RDBLP:    CALL CONIN
  2444.     MOV CL,AL    ;SAVE FOR BS TEST
  2445. ;
  2446. ;Evaluate control characters
  2447. ;
  2448.     CMP AL,'U'-40H
  2449.     JNZ L@00200
  2450.     JMP RDCTLU
  2451. L@00200:
  2452. ;
  2453.     CMP AL,CR
  2454.     JZ RDCR
  2455. ;
  2456.     CMP AL,'H'-40H
  2457.     JZ RDBS
  2458. ;
  2459.     CMP AL,7FH
  2460.     JZ RDBS
  2461. ;
  2462.     CMP AL,'R'-40H
  2463.     JZ RDCTLR
  2464. ;
  2465.     CMP AL,'X'-40H
  2466.     JZ RDCTLX
  2467.  
  2468.     CMP AL,'['-40H
  2469.     JNE NO_QUIT
  2470.       JMP QUIT
  2471. NO_QUIT:
  2472. ;
  2473.     CMP AL,' '
  2474.     JNAE RDBLP
  2475. ;
  2476.     MOV BYTE PTR [BX],AL
  2477.     INC BX
  2478.     INC CH
  2479.     JS FULL
  2480.     CALL TYPEOUT
  2481.     JMP RDBLP
  2482. ;
  2483. FULL:    DEC CH
  2484.     PUSHF
  2485.     DEC BX
  2486.     POPF
  2487.     MOV AL,'*'    ;SIGNAL WE'RE FULL
  2488.     CALL TYPEOUT
  2489.     JMP RDBLP
  2490. ;
  2491. ;Got CR
  2492. ;
  2493. RDCR:    MOV BYTE PTR [BX],AL    ;SAVE IT
  2494.     CALL TYPEOUT    ;ECHO IT
  2495.     MOV AL,LF    ;ECHO..
  2496.     CALL TYPEOUT    ;..LF
  2497.     MOV BX,OFFSET INBUF
  2498.     RET
  2499. ;
  2500. ;Got DELETE or BS, echo if BS
  2501. ;
  2502. RDBS:    XOR AL,AL    ;AT FRONT..
  2503.     OR AL,CH    ;..OF LINE?
  2504.     JZ RDCTLU    ;.. YES, ECHO ^U
  2505.     DEC BX
  2506.     DEC CH
  2507.     MOV AL,CL
  2508.     CMP AL,'H'-40H    ;BS?
  2509.     JZ BACKUP    ;ECHO THE BS
  2510.     MOV AL,BYTE PTR [BX]    ;ECHO..
  2511.     CALL TYPEOUT    ;..DELETED CHAR
  2512.     JMP RDBLP
  2513. ;
  2514. BACKUP:    CALL WIPER
  2515.     JMP RDBLP
  2516. ;
  2517. RDCTLX:    INC CH
  2518. ;
  2519. RDCX1:    DEC CH
  2520.     JZ RDBF1
  2521.     CALL WIPER
  2522.     JMP RDCX1
  2523. ;
  2524. WIPER:    PUSH CX
  2525.     PUSH DX
  2526.     PUSH BX
  2527.     MOV DX,OFFSET BSMSG    ;BACKSPACE, SPACE, BACKSPACE
  2528.     MOV CL,PRINT
  2529.     CALL BDOS
  2530.     POP BX
  2531.     POP DX
  2532.     POP CX
  2533.     RET
  2534. ;
  2535. BSMSG    DB    BS,' ',BS,'$'
  2536. ;
  2537. ;Got CTL-R, retype
  2538. ;
  2539. RDCTLR:    MOV BYTE PTR [BX],CR
  2540.     CALL CRLF
  2541.     MOV BX,OFFSET INBUF
  2542.     MOV CH,0
  2543. ;
  2544. RDCRL:    MOV AL,BYTE PTR [BX]
  2545.     CMP AL,CR
  2546.     JNZ L@00211
  2547.     JMP RDBLP
  2548. L@00211:
  2549.     CALL TYPEOUT
  2550.     INC CH
  2551.     INC BX
  2552.     JMP RDCRL
  2553. ;
  2554. ;Got CTL-U or backup to beginning of line.
  2555. ;
  2556. RDCTLU:    MOV AL,'^'
  2557.     CALL TYPEOUT
  2558.     MOV AL,'U'
  2559.     CALL TYPEOUT
  2560.     JMP RDBUF
  2561. ;
  2562. CRLF:    MOV AL,CR
  2563.     CALL TYPEOUT
  2564.     MOV AL,LF
  2565.     JMP TYPEOUT
  2566. ;
  2567. UPCASE:    CMP AL,60H
  2568.     JNB L@00212
  2569.     RET
  2570. L@00212:
  2571.     AND AL,5FH    ;MAKE UPPER CASE
  2572.     RET
  2573. ;
  2574. CONST:    PUSH CX
  2575.     PUSH DX
  2576.     PUSH BX
  2577.     CALL BCONST    ;GET CONSOLE STATUS USING BIOS CALL
  2578.     POP BX
  2579.     POP DX
  2580.     POP CX
  2581.     RET
  2582. ;
  2583. CONIN:    PUSH CX
  2584.     PUSH DX
  2585.     PUSH BX
  2586.     CALL BCONIN    ;GET CONSOLE CHAR FROM BIOS
  2587.     POP BX
  2588.     POP DX
  2589.     POP CX
  2590.     RET
  2591. ;
  2592. ;Console out with TAB expansion
  2593. ;    Enter: char in AL
  2594. ;
  2595. TYPEOUT:
  2596.     PUSH CX
  2597.     PUSH DX
  2598.     PUSH BX
  2599.     MOV CL,AL    ;FOR OUTPUT ROUTINE
  2600.     CMP AL,TAB
  2601.     JNZ TYPE2
  2602. ;
  2603. TYPTAB:    MOV AL,' '
  2604.     CALL TYPEOUT
  2605.     MOV AL,TABCOL
  2606.     AND AL,7
  2607.     JNZ TYPTAB
  2608.     JMP TYPRET
  2609. ;
  2610. ;Filter out control characters to
  2611. ;prevent garbage during view of file
  2612. ;
  2613. TYPE2:    CMP AL,' '
  2614.     JAE TYPEQ
  2615.     CMP AL,CR
  2616.     JZ TYPEQ
  2617.     CMP AL,LF
  2618.     JNZ TYPNCR
  2619. ;
  2620. TYPEQ:    MOV AL,QFLAG
  2621.     OR AL,AL
  2622.  
  2623. VCONOT:    JNZ L@00218
  2624.     PUSH CX
  2625.     CALL BCONOUT    ;CONSOLE OUT THRU BIOS
  2626.     POP CX
  2627. L@00218:
  2628. ;
  2629. ;Update column used in tab expansion
  2630.     MOV AL,CL    ;GET CHAR
  2631.     CMP AL,CR
  2632.     JNZ TYPNCR
  2633.     MOV AL,0
  2634.     MOV  TABCOL,AL
  2635.     JMP TYPLST
  2636. ;
  2637. TYPNCR:    CMP AL,' '    ;CTL CHAR?
  2638.     JNAE TYPLST    ;..NO CGANGE IN COL
  2639.     MOV AL,TABCOL
  2640.     INC AL
  2641.     MOV  TABCOL,AL
  2642. ;
  2643. TYPLST:    MOV AL,PFLAG
  2644.     AND AL,1
  2645.     JZ L@00221
  2646.     CALL LISTOUT    ;FROM C REG.
  2647. L@00221:
  2648. ;
  2649. TYPRET:    POP BX
  2650.     POP DX
  2651.     POP CX
  2652.     RET
  2653. ;
  2654. LISTOUT: ;enter char in CL        
  2655.     mov dl,cl    ;put char in DL
  2656.     mov cl,L_WRITE    ;write to default list device
  2657.     CALL BDOS    ;LIST TO PRINTER THRU BDOS
  2658.     RET
  2659. ;
  2660. HOME:    PUSH BX
  2661.     CALL BHOME    ;HOME DRIVE THRU BIOS
  2662.     POP BX
  2663.     RET
  2664. ;
  2665. ;Set track # in DE
  2666. ;
  2667. SETTRK:    PUSH BX
  2668.     MOV BX,MAXTRK
  2669.     CALL SUBDE
  2670.     POP BX
  2671.     JNAE OUTLIM
  2672.     XCHG BX,DX
  2673.     MOV CURTRK,BX
  2674.     XCHG BX,DX
  2675.     MOV CX,DX
  2676.     PUSH BX
  2677.     CALL TRK    ;SET TRACK THRU BIOS
  2678.     POP BX
  2679.     RET
  2680. ;
  2681. SETSEC:    PUSH BX
  2682.     PUSH DX
  2683.     MOV BX,SYSTRK
  2684.     XCHG BX,DX
  2685.     MOV CURSEC,BX
  2686.     MOV BX,CURTRK
  2687.     CALL SUBDE
  2688.     POP CX
  2689.     MOV BX,CX
  2690.     JAE NOTSYS
  2691.     MOV AL,FIRST0    ;SEE IF FIRST SEC 0
  2692.     OR AL,AL
  2693.     JNZ GSTSEC    ;NO, JUMP AWAY
  2694.     DEC BX    ;YES, SO DECREMENT
  2695.     JMP GSTSEC    ;  REQUESTED, THEN GO
  2696. ;
  2697. NOTSYS:    MOV BX,SECTBL
  2698.     XCHG BX,DX
  2699.     DEC CX
  2700.     CALL BSECTTRAN
  2701.     MOV AL,BYTE PTR SPT+1    ;IF SPT<256 (HI-ORD = 0)
  2702.     OR AL,AL    ; THEN FORCE 8-BIT TRANSLATION
  2703.     JNZ VSCTR1    ; ELSE KEEP ALL 16 BITS
  2704.     MOV BH,AL
  2705. VSCTR1:
  2706. GSTSEC:
  2707.     MOV PHYSEC,BX
  2708.     cmp byte ptr cpm_version,31h
  2709.     jb aint31
  2710.       mov bx,cursec    ;version 31 does it's own xlate, use cursec
  2711. aint31:
  2712.     MOV CX,BX
  2713.     CALL SEC    ;SET SECTOR THRU BIOS
  2714.     POP BX
  2715.     RET
  2716. ;
  2717. OUTLIM:    XOR AL,AL
  2718.     MOV  QFLAG,AL
  2719.     CALL ILPRT
  2720.     DB    '++not within tracks 0-',0
  2721.     PUSH BX
  2722.     MOV BX,MAXTRK
  2723.     CALL DEC
  2724.     POP BX
  2725.     CALL ILPRT
  2726.     DB    '++'
  2727.     DB    CR,LF,0
  2728.     CALL NORITE
  2729.     JMP PRMPTR
  2730. ;
  2731. SETDMA:
  2732.     CALL DMA    ;SET UP DMA FOR BIOS
  2733.     MOV CX,CS    ;SET DMA SEGMENT FOR BIOS
  2734.     JMP SETDMAB
  2735. ;
  2736. ;
  2737. READ:    MOV AL,1
  2738.     MOV  WRFLG,AL
  2739.     PUSH BX
  2740.     CALL DSKREAD    ;READ DISK THRU BIOS
  2741.     OR AL,AL
  2742.     JZ READOK
  2743.     XOR AL,AL
  2744.     MOV  QFLAG,AL
  2745.     CALL ILPRT
  2746.     DB    '++READ failed, sector may be invalid++'
  2747.     DB    CR,LF,0
  2748. ;
  2749. READOK:    POP BX
  2750.     RET
  2751. ;
  2752. WRITE:    MOV AL,WRFLG
  2753.     OR AL,AL
  2754.     JNZ PWRITE
  2755. ;
  2756. BADW:    XOR AL,AL
  2757.     MOV  QFLAG,AL
  2758.     CALL ILPRT
  2759.     DB    '++CANNOT WRITE UNLESS READ ISSUED'
  2760.     DB    CR,LF,0
  2761.     JMP EXPL
  2762. ;
  2763. PWRITE:    PUSH BX
  2764.     MOV CL,1    ;FORCE WRITE TYPE 1 IN CASE 2.x DEBLOCK USED
  2765.     CALL DSKWRITE    ;WRITE DISK
  2766.     OR AL,AL
  2767.     JZ WRITOK
  2768.     XOR AL,AL
  2769.     MOV  QFLAG,AL
  2770.     CALL ILPRT
  2771.     DB    '++WRITE failed++',CR,LF,0
  2772. ;
  2773. WRITOK:    POP BX
  2774.     RET
  2775. ;
  2776. ;Help
  2777. ;
  2778. HELP:    CALL ILPRT
  2779.     DB    'Operands in brackets [...] are optional'
  2780.     DB    CR,LF
  2781.     DB    'Numeric values: ''n'' are decimal, ''x'' hex'
  2782.     DB    CR,LF,CR,LF
  2783.     DB    '+[n]   step in [n] sectors;'
  2784.     DB    CR,LF
  2785.     DB    '-[n]   step out [n] sectors'
  2786.     DB    CR,LF
  2787.     DB    '#      print disk parameters for curr drive.'
  2788.     DB    CR,LF
  2789.     DB    '=xxx   search for ASCII xxx from curr sector.'
  2790.     DB    CR,LF
  2791.     DB    '       Caution: upper/lower case matters.'
  2792.     DB    CR,LF
  2793.     DB    '       Use <xx> for hex:'
  2794.     DB    CR,LF
  2795.     DB    '       To find "IN AL,0C0h" use: =<E4><C0>     or'
  2796.     DB    CR,LF
  2797.     DB    '       "(tab)H,0(CR)(LF)" use: =<9>H,0<D><A>'
  2798.     DB    CR,LF
  2799.     DB    '<      save current sector into mem. buff.'
  2800.     DB    CR,LF
  2801.     DB    '>      restore saved sector'
  2802.     DB    CR,LF
  2803.     DB    '?      give help'
  2804.     DB    CR,LF
  2805.     DB    'A[ff,tt] ASCII dump'
  2806.     DB    CR,LF,CR,LF
  2807.     DB    '(Type SP bar to continue)'
  2808.     DB    1,CR,LF,CR,LF
  2809.     DB    'C      Change:'
  2810.     DB    CR,LF
  2811.     DB    '       CHaddr,byte,byte... (hex)'
  2812.     DB    CR,LF
  2813.     DB    '  or   CAaddr,data...  (Ascii)'
  2814.     DB    CR,LF
  2815.     DB    '       <xx> Allowed for imbedded hex.'
  2816.     DB    CR,LF
  2817.     DB    '  or   CHfrom-thru,byte  e.g. ch0-7f,e5'
  2818.     DB    CR,LF
  2819.     DB    '  or   CAfrom-thru,byte'
  2820.     DB    CR,LF
  2821.     DB    'D[ff,tt] Dump (hex+ASCII)'
  2822.     DB    CR,LF
  2823.     DB    'Fn.t   Find file'
  2824.     DB    CR,LF
  2825.     DB    'Gnn    CP/M Allocation Group nn'
  2826.     DB    CR,LF
  2827.     DB    'H[ff,tt]       hex dump'
  2828.     DB    CR,LF
  2829.     DB    'L      Log in drive'
  2830.     DB    CR,LF
  2831.     DB    'Lx     Log in drive x'
  2832.     DB    CR,LF
  2833.     DB    'M[nn]  Map [from group nn]'
  2834.     DB    CR,LF,CR,LF
  2835.     DB    '(Type SP bar to continue)'
  2836.     DB    1,CR,LF,CR,LF
  2837.     DB    'N      New disk'
  2838.     DB    CR,LF
  2839.     DB    'P      Toggle printer switch'
  2840.     DB    CR,LF
  2841.     DB    'Q      Quiet mode (no msgs)'
  2842.     DB    CR,LF
  2843.     DB    'R      Read current sector'
  2844.     DB    CR,LF
  2845.     DB    'Snn    Sector nn'
  2846.     DB    CR,LF
  2847.     DB    'Tnn    Track nn'
  2848.     DB    CR,LF
  2849.     DB    'Unn    Set User nn for Find command'
  2850.     DB    CR,LF
  2851.     DB    'V[nn]  View [nn] ASCII sectors'
  2852.     DB    CR,LF
  2853.     DB    'W      Write current sector'
  2854.     DB    CR,LF
  2855.     DB    'X      Exit program'
  2856.     DB    CR,LF
  2857.     DB    'Z[nn]  Sleep [nn tenths]'
  2858.     DB    CR,LF
  2859.     DB    '/[nn]  Repeat [nn (decimal) times]'
  2860.     DB    CR,LF,CR,LF
  2861.     DB    '(Type SP bar to continue)'
  2862.     DB    1,CR,LF,CR,LF
  2863.     DB    'Cancel a function with ESC or Ctl-C.'
  2864.     DB    CR,LF
  2865.     DB    'Suspend output with S or Ctl-S.'
  2866.     DB    CR,LF
  2867.     DB    'Separate commands with "!".'
  2868.     DB    CR,LF
  2869.     DB    '       Example: g0'
  2870.     DB    CR,LF
  2871.     DB    '       +!d!z#20!/'
  2872.     DB    CR,LF
  2873.     DB    '       would step in, dump, sleep 2 sec, '
  2874.     DB    CR,LF
  2875.     DB    '       and repeat until control-c typed.'
  2876.     DB    CR,LF
  2877.     DB    'All "nn" usage except "/", "T", and "S" are'
  2878.     DB    CR,LF
  2879.     DB    '        HEX.  Use #nn for decimal.'
  2880.     DB    CR,LF,CR,LF
  2881.     DB    'See DU.DOC for complete examples.'
  2882.     DB    CR,LF,CR,LF,0
  2883.     JMP PROMPT
  2884. ;
  2885. ;********************************
  2886. ;*                *
  2887. ;*    Utility Subroutines    *
  2888. ;*                *
  2889. ;********************************
  2890. ;
  2891. GRPCMP:    MOV AL,CL
  2892.     INC DH
  2893.     DEC DH
  2894.     JZ CMP8
  2895.     CMP AL,BYTE PTR [BX]
  2896.     PUSHF
  2897.     INC BX
  2898.     POPF
  2899.     JZ L@00231
  2900.     RET
  2901. L@00231:
  2902.     MOV AL,CH
  2903. ;
  2904. CMP8:    CMP AL,BYTE PTR [BX]
  2905.     RET
  2906. ;
  2907. ;2's complement HL ==> HL
  2908. ;
  2909. NEG:
  2910.     NOT BX
  2911.     PUSHF
  2912.     INC BX
  2913.     POPF
  2914.     RET
  2915. ;
  2916. ;HL/2 ==> HL
  2917. ;
  2918. ROTRHL:    OR AL,AL
  2919.     MOV AL,BH
  2920.     RCR AL,1
  2921.     MOV BH,AL
  2922.     MOV AL,BL
  2923.     RCR AL,1
  2924.     MOV BL,AL
  2925.     RET
  2926. ;
  2927. ;Collect the number of '1' bits
  2928. ;in A as a count in C
  2929. ;
  2930. COLECT:    MOV CH,8
  2931. ;
  2932. COLOP:    RCL AL,1
  2933.     JAE COSKIP
  2934.     INC CL
  2935. ;
  2936. COSKIP:    DEC CH
  2937.     JNZ COLOP
  2938.     RET
  2939. ;
  2940. ;HL-DE ==> HL
  2941. ;
  2942. SUBDE:
  2943.     SUB BX,DX
  2944.     RET
  2945. ;
  2946. ;Quick Kludge multiply
  2947. ;HL=DE ==> HL
  2948. ;
  2949. MULT:    PUSH CX
  2950.     PUSH DX
  2951.     XCHG BX,DX
  2952.     MOV CX,DX
  2953.     MOV AL,CH
  2954.     OR AL,CL
  2955.     JNZ MULCON
  2956.     MOV BX,OFFSET 0    ;FILTER SPECIAL CASE
  2957.     JMP MLDONE    ;  OF MULTIPLY BY 0
  2958. ;
  2959. MULCON:
  2960.     DEC CX
  2961.     MOV DX,BX
  2962. ;
  2963. MULTLP:    MOV AL,CH
  2964.     OR AL,CL
  2965.     JZ MLDONE
  2966.     ADD BX,DX
  2967.     DEC CX
  2968.     JMP MULTLP
  2969. ;
  2970. MLDONE:    POP DX
  2971.     POP CX
  2972.     RET
  2973. ;
  2974. ;Routine to fill in disk params
  2975. ;with every drive change
  2976. ;
  2977. LOGIT:
  2978.     cmp byte ptr cpm_version,31h     ;if it's ver 31 the select
  2979.     jae logcal            ;routine done moved DPB
  2980.       MOV DX,OFFSET DPB    ;   THEN MOVE TO LOCAL
  2981.       MOV CH,DPBLEN    ;  WORKSPACE
  2982.       CALL MOVEFROMBIOS
  2983. ;
  2984. LOGCAL:    MOV BX,OFFSET GRPDIS
  2985.     MOV AL,BYTE PTR [BX]
  2986.     PUSH AX
  2987.     MOV AL,BLM
  2988.     MOV BYTE PTR [BX],AL
  2989.     PUSH BX
  2990.     MOV BX,DSM
  2991.     XCHG BX,DX
  2992.     CALL GTKSEC
  2993.     MOV MAXSEC,BX
  2994.     XCHG BX,DX
  2995.     MOV MAXTRK,BX
  2996.     POP BX
  2997.     POP AX
  2998.     MOV BYTE PTR [BX],AL
  2999.     RET
  3000. ;
  3001. ;
  3002. DATAOFFSET EQU OFFSET$
  3003.     DSEG
  3004.     ORG DATAOFFSET
  3005. ;
  3006. ;
  3007. ;
  3008.     RW 200
  3009. STACK    RW 1    ;LOCAL STACK
  3010. ;
  3011. ;Temporary storage area
  3012. ;
  3013. BUFAD    DW    BASE +100H ;FORCES INITIAL READ
  3014. HEXAD    DW    0    ;TO RE-FETCH A VALUE
  3015. TOGO    DW    0FFFFH    ;REPEAT COUNT (FFFF=CONT)
  3016. TWOUP    DB    0
  3017. PFLAG    DB    0    ;1=PRINT
  3018. GROUP    DW    0
  3019. GRPDIS    DB    0
  3020. SAVEFL    DB    0
  3021. CURTRK    DW    0
  3022. CURSEC    DW    1
  3023. PHYSEC    DW    1
  3024. TABCOL    DB    0
  3025. FILECT    DW    0
  3026. DIRPOS    DB    0
  3027. FINDFL    DB    0    ;1=MUST POSITION AFTER FIND
  3028. FTSW    DB    1    ;SEARCH W/O INCREMENT
  3029. NOTPOS    DB    1    ;INITIALLY NOT POSITIONED
  3030. WRFLG    DB    0    ;MAY NOT WRITE UNTIL '+', '-',
  3031. ;             OR 'G' COMMAND
  3032. QFLAG    DB    0    ;QUIET? (0=NO)
  3033. FIRST0    DB    0    ;SETS TO 0 IF FIRST SEC # IS 0
  3034. UNUM    DB    0    ;USER NUMBER
  3035. DRIVE    DB    0
  3036. MAXTRK    DW    0
  3037. MAXSEC    DW    0
  3038. SECTBL    DW    0    ;POINTER TO SECTOR SKEW TABLE
  3039. ;
  3040. BACK    RW 1    ;TO BACK UP IN "CA0-7F,X"
  3041. DUMTYP    RS 1
  3042. ;
  3043. ;--------------------------------------------------
  3044.  
  3045. bios_call_tbl     rw    1        ;address of bios call table goes here
  3046.  
  3047. table11    dw    offset select_disk11    ;direct bios calls for cp/m-11
  3048.     dw    offset set_track11
  3049.     dw    offset set_dmaseg11
  3050.     dw    offset set_dmaoff11    
  3051.     dw    offset set_sector11
  3052.     dw    offset read_sector11    
  3053.     dw    offset write_sector11      
  3054.     dw    offset sector_xlat11    
  3055.     dw    offset home_disk11
  3056.  
  3057. table31    dw    offset select_disk31    ;direct bios calls for cp/m-31
  3058.     dw    offset set_track31
  3059.     dw    offset set_dmaseg31
  3060.     dw    offset set_dmaoff31    
  3061.     dw    offset set_sector31
  3062.     dw    offset read_sector31    
  3063.     dw    offset write_sector31      
  3064.     dw    offset sector_xlat31    
  3065.     dw    offset home_disk31
  3066.  
  3067. bpb        rs    0        ;bios parameter block
  3068. bpb_func    rb    1        ;for direct bios call 50
  3069. bpb_cx        rw    1
  3070. bpb_dx        rw    1
  3071.  
  3072. cpm_version    dw    0        ;cpm version
  3073.  
  3074. sysaddr        dw    0        ;SYSDAT addr
  3075. udaaddr        dw    0        ;process UDA addr
  3076.  
  3077. imcnt        db    1        ;multi-sector count (preset to 1)
  3078. idrive        rb    1        ;drive number (a:=0)
  3079. itrack        rw    1        ;track number (first track=0)
  3080. isector        rw    1        ;sector number (first sector=0)
  3081. idmaseg        rw    1        ;dma segment for sector buffer
  3082. idmaoff        dw    offset sector_buf ;dma offset for sector buffer
  3083.  
  3084. dmaseg        rw    1        ;dma segment for data
  3085. dmaoff        rw    1        ;dma offset for data
  3086.  
  3087. trk_sect    dw    0ffffh,0    ;number of track/sector in memory
  3088.  
  3089. sec_xlat_tbl    dw    0        ;address of BIOS xlat table
  3090.  
  3091. rec_offset    dw    0        ;logical record offset into phy sec
  3092.  
  3093. ;  data storage for Disk Parameter Block (DPB)
  3094. ;
  3095. dpb        rs    0        ;17 bytes of storage
  3096. ;
  3097. SPT        rw    1
  3098. BSH        rb    1
  3099. BLM        rb    1
  3100. EXM        rb    1
  3101. DSM        rw    1
  3102. DRM        rw    1
  3103. AL0        rb    1
  3104. AL1        rb    1
  3105. CKS        rw    1
  3106. SYSTRK        rw    1
  3107. PHYSHF        rb    1        ;not in CP/M-86 ver 1.1
  3108. PHYMSK        rb    1        ; "   "   "      "   "
  3109. ;
  3110. ;End of disk parameter block
  3111.  
  3112. wvmsg        db    13,10,'Only CP/M-86 ver 1.1 & 3.1 Plus '
  3113.         db    'and CCP/M ver 3.1-4.1 are Supported$'
  3114. mpmsg        db    13,10,'THE MP/M OPERATING SYSTEM IS NOT SUPPORTED$'
  3115.  
  3116. toobig        db    13,10,'SECTOR SIZE TOO BIG - ABORTING$'
  3117.  
  3118. sector_buf    rs    2048
  3119.  
  3120. ;--------------------------------------------------
  3121. ;
  3122. SAVBUF    RS 128
  3123. INBUF    RS 128
  3124. ;
  3125. ;Directory read in here; also search work area
  3126. ;
  3127. WORK    EQU    $
  3128. DIRECT    EQU    $
  3129.     END
  3130.