home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol172 / du-v75a.a86 < prev    next >
Encoding:
Text File  |  1984-05-30  |  49.4 KB  |  3,147 lines

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