home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / BDOS / DOSPLSOR.ARK / CCPLUS.MAC < prev    next >
Text File  |  1986-10-27  |  32KB  |  1,370 lines

  1. title    CCP+ v2.2 (c) by C.B Falconer (1986 Oct. 27)
  2. ;
  3. ; Z80 cpu required.  Use CCPLUS 1.7 for 8080/8085
  4. ;
  5. ; SEE CCP+.DOC for features, etc. Assembles as is with M80 or SLRMAC.
  6. ; For M80 Z80.LIB must be available and must rename source 'CCPLUS'.
  7. ;
  8. ; 2.2    86/10/27. Search suppression for DOS+ use.  Added KILL command
  9. ;    to abort submit/job operations.  CCP+ knows how executed. cbf
  10. ; 2.1    86/10/11 Fixed so "-b:xyz name" executes name in b:xyz.lbr
  11. ;    (with CCPXTEND mounted).  Was aborting. Added non-wheel drive
  12. ;    access checks.  Commands suppressed under wheel now search for
  13. ;    transients, and transient execution is non-suppressable. Now a
  14. ;    du consisting of ":" alone specifies default. Fixed REN. cbf
  15. ; 2.0    86/10/2 Preliminary beta test release. Complete rewrite of 1.7
  16. ;
  17. ccpver    equ    22;        UPDATE with each revision
  18. true    equ    -1
  19. false    equ    not true
  20. debug    equ    false;        true allows linking to existing code
  21. cr    equ    0dh
  22. lf    equ    0ah
  23. tab    equ    09h
  24. eof    equ    01ah
  25. ;
  26. ; User configurable values.  See patch area at end.
  27. doupsft    equ    true;        FALSE for NO command line upshift
  28. ;                at initialization.
  29. subuser    equ    0;        User # for $$$.sub files
  30. maxuser    equ    31;        Max user when wheel set
  31. whluser    equ    13;        Max user when wheel not set
  32. dcols    equ    5;        columns for directory display
  33. ; END user options
  34. ;
  35. ; For M80 the following must be upper case.
  36. INCLUDE    Z80.LIB
  37. ;
  38. ; CPM/DOS+ syscall values
  39. @cin    equ    1
  40. @cout    equ    2
  41. @instg    equ    10
  42. @csta    equ    11
  43. @rsdsk    equ    13
  44. @seldk    equ    14
  45. @fopen    equ    15
  46. @fclose    equ    16
  47. @srch1    equ    17
  48. @srchn    equ    18
  49. @fpurg    equ    19
  50. @rdseq    equ    20
  51. @wtseq    equ    21
  52. @fnew    equ    22
  53. @frenm    equ    23
  54. @curdk    equ    25
  55. @stdma    equ    26
  56. @usrcd    equ    32
  57. ;
  58. ; CPM/DOS+ definitions
  59. reboot    equ    0
  60. iobyte    equ    reboot+3
  61. defdu    equ    reboot+4;    user/drive fields
  62.     if    debug;        link separately
  63. extrn     sysfnc
  64.     else
  65. sysfnc     equ    reboot+5;    connector to BDOS system
  66.     endif
  67. defcbk    equ    reboot+05ch
  68. defdma    equ    reboot+080h
  69. tpa    equ    reboot+100h
  70. ;
  71. ; Macros
  72. tdig    macro
  73.     rlc
  74.     rlc
  75.     rlc
  76.     rlc
  77.     endm
  78. ;
  79. ;    --------- Start    ----------
  80. ;
  81. ; Standard entry points.  The "cold" entry is auto-patched to "both"
  82. ; at initial execution, for single sign-on and to cater to peculiar
  83. ; Osborne 1 peculiar cold boot mechanism.
  84. begin:    jmp    cold;        execute command
  85.     jmp    warm;        clear command line
  86. ;
  87. ; This MUST start at begin+6 for compatability.
  88. ibfsiz:    db    126;    size of input buffer. space for eol mark.
  89. ;            127 can cause obscure problems.
  90. ; set the following byte 0 for no cold start default command
  91. ibflen:    db    0;    patch command length for cold execution
  92. ;            and install command below, 0 terminator
  93. ;
  94. ; For Osborne 1, do not modify. Result won't boot
  95. iobuff:    dw    0,0,0,0,0,0,0;    needed for OS1 autoboot. Why?
  96.     db    '  CCP+ v', ccpver/10 + '0', '.', ccpver MOD 10 + '0'
  97.     db    ' (C) 1986, C.B. Falconer,'
  98.     db    ' Tel. (203) 281-1438,'
  99.     db    ' 680 Hartford Tpk., Hamden, CT., USA'
  100.     ds    136-($-begin),0;    must have 2 spare bytes here.
  101. ;
  102. nofmsg:    db    'No File',0
  103. fulmsg:    db    'No room',0
  104. allmsg:    db    'All (y/N)?',0
  105. foldms:    db    'File exists',0
  106. dnmsg:    db    'No '
  107. upmsg:    db    'UPSHIFT',0
  108. ;
  109. ; Check for valid drive access.  Carry if drive (a) invalid.
  110. ; entry (a) = 0 is default, always valid, 1, 2.. for A, B..
  111. ; a,f,h,l
  112. drvchk:    lhld    whlmsk
  113. ;    "    "
  114. ; Entry here can check against mask hl (usually drvmsk)
  115. ; a,f,h,l
  116. drvckw:    ora    a
  117.     rz
  118.     dcr    a
  119. ;    "    "
  120. ; move bit (a) of hl to carry. 0 is lsb, 15 is msb
  121. ; a,f,h,l
  122. bitmsk:    sui    16
  123. bitm1:    dad    h;        left shift 16-n times
  124.     inr    a
  125.     jrnz    bitm1
  126.     ret
  127. ;
  128. ; Upshift (a) if lower case alpha.
  129. ; a,f
  130. upshft:    cpi    'a'
  131.     rc
  132.     cpi    'z'+1
  133.     rnc
  134.     ani    05fh
  135.     ret
  136. ;
  137. ; Check (a) valid digit, carry if not
  138. ; f
  139. qnum:    cpi    '0'
  140.     rc
  141.     cpi    '9'+1
  142.     cmc
  143.     ret
  144. ;
  145. ; crlf to console
  146. ; a,f
  147. crlf:    mvi    a,cr
  148.     call    couta
  149.     mvi    a,lf
  150. ;    "    "
  151. ; console output from (a)
  152. ; a,f
  153. couta:    push    d
  154.     mov    e,a
  155.     mvi    a,@cout
  156.     call    bdos
  157.     pop    d
  158.     ret
  159. ;
  160. ; Numeric 1..99 to console.  Convert to Ascii, zero suppress
  161. ; a,f
  162. putnum:    cpi    10
  163.     jrc    pn2;        1 digit only
  164.     push    b
  165.     mvi    c,'0'-1
  166. pn1:    inr    c
  167.     adi    -10
  168.     jrc    pn1
  169.     adi    10
  170.     push    psw
  171.     mov    a,c
  172.     call    couta
  173.     pop    psw
  174.     pop    b
  175. pn2:    adi    '0'
  176.     jr    couta
  177. ;
  178. ; Test for any console character ready. If so purge it and
  179. ; return nz flag.  Else return z flag.  Nulls absorbed
  180. ; a,f
  181. qbreak:    mvi    a,@csta
  182.     call    bdos
  183.     rz
  184.     mvi    a,@cin
  185.     jr    bdos
  186. ;
  187. ; called from xcom and xtyp.  If disk is default then search system
  188. ; disk on failure. z flag indicates failure
  189. ; a,f,d,e
  190. fopenf:    xra    a
  191.     sta    frecd
  192.     lxi    d,fcbdrv
  193.     lda    cmdmsk+1;    (get high byte)
  194.     ral
  195.     jrc    fopen;        search disabled
  196.     ldax    d
  197.     ora    a
  198.     jrnz    fopen;        not default, restrict search
  199.     call    fopen
  200.     rnz;            success on default drive
  201.     inr    a;        i.e. disk a
  202.     stax    d;        now try the system drive
  203.     call    fopen
  204.     rnz;            success
  205.     stax    d;        restore default drive id for ccpxtd
  206.     ret
  207. ;
  208. ; open file (de)^. z flag for failure
  209. ; a,f
  210. fopen:    mvi    a,@fopen
  211. ;    "    "
  212. ; execute functions, Z flag for 0ffh, increment return value
  213. ; a,f
  214. sfncr:    call    bdos
  215.     inr    a
  216.     ret
  217. ;
  218. ; close file (de)^. Z flag for failure
  219. ; a,f
  220. fclose:    mvi    a,@fclose
  221.     jr    sfncr
  222. ;
  223. ; search next on (de)^. Z flag for failure, exit (a) incremented
  224. ; a,f
  225. srchn:    mvi    a,@srchn
  226.     jr    sfncr
  227. ;
  228. ; search for file fcbdrv. Z flag for failure, exit (a) incremented.
  229. ; a,f,d,e
  230. ffind:    lxi    d,fcbdrv
  231.     mvi    a,@srch1
  232.     jr    sfncr
  233. ;
  234. ; purge file (de)^, z flag for failure
  235. ; a,f
  236. fpurge:    mvi    a,@fpurg
  237.     jr    sfncr
  238. ;
  239. ; read from file fcbdrv. z flag for success
  240. ; a,f,d,e
  241. freadf:    lxi    d,fcbdrv
  242. ;    "    "
  243. ; read from file (de)^. z flag for success
  244. ; a,f,d,e
  245. rdseq:    mvi    a,@rdseq
  246.     jr    bdos
  247. ;
  248. ; write to file (de)^. z flag for success
  249. ; a,f
  250. fwrite:    mvi    a,@wtseq
  251.     jr    bdos
  252. ;
  253. ; create file (de)^; z flag for success
  254. ; a,f
  255. create:    mvi    a,@fnew
  256.     jr    sfncr
  257. ;
  258. ; set dma access to defdma area
  259. ; a,f,d,e
  260. sdma80:    lxi    d,defdma
  261. ;    "    "
  262. ; set dma access to (de)^
  263. ; a,f
  264. setdma:    mvi    a,@stdma
  265.     jr    bdos
  266. ;
  267. ; Find current logged disk
  268. qdisk:    mvi    a,@curdk
  269.     jr    bdos
  270. ;
  271. ; Set user to absolute value in fcbusr and select on BDOS.
  272. ; Do not modify or select drive. Leave drv/usr in bc
  273. ; Update fcbusr to absolute value
  274. ; a,f,b,c,e
  275. setusr:    lbcd    fcbusr;        c := user, b := drive
  276.     mov    a,c
  277.     ora    a
  278.     cm    quser;        default, get current user
  279.     mov    c,a;        now an absolute value
  280.     sbcd    fcbusr
  281. ;    "    "
  282. ; set user to a
  283. ; a,f,e
  284. susera:    mov    e,a
  285.     jr    suser
  286. ;
  287. ; find current user code
  288. ; a,f,e
  289. quser:    mvi    e,0ffh
  290. ;    "    "
  291. ; set user (e)
  292. ; a,f
  293. suser:    mvi    a,@usrcd
  294.     jr    bdos
  295. ;
  296. ; reset disk system
  297. ; a,f
  298. rsdisk:    mvi    a,@rsdsk
  299. ;    "    "
  300. ; execute bdos call, return (a), set flags. Preserve other registers
  301. ; This is the sole connection to the outside world.
  302. ; a,f
  303. bdos:    push    h
  304.     push    d
  305.     push    b
  306.     pushix
  307.     mov    c,a
  308.     call    sysfnc
  309.     ora    a;        set flags on return value
  310.     popix
  311.     pop    b
  312.     pop    d
  313.     pop    h
  314.     ret
  315. ;
  316. ; Get a line from $$$.SUB file, and reduce the file size.
  317. ; If anything fails, purge $$$.SUB and reset subflg
  318. ; Line is placed in <ibflen,iobuff). 1st byte is length
  319. ; a,f,d,e,h,l
  320. getsub:    lda    subusr
  321.     call    susera
  322.     lxi    d,subfcb;    Jam the user
  323.     call    fopen
  324.     jrz    killsub;    not found
  325.     push    d
  326.     lda    subrc
  327.     dcr    a
  328.     sta    subrcd
  329.     lxi    d,ibflen
  330.     call    setdma
  331.     pop    d
  332.     call    rdseq;        load the record
  333.     jrnz    killsub;    read failed
  334.     sta    ibflen+127;    ensure eol marked
  335.     lxi    h,subs2
  336.     mov    m,a;        zero, mark modified for close
  337.     inx    h
  338.     dcr    m;        reduce file size (ok, read worked)
  339.     call    fclose
  340.     jrz    killsub;    failure
  341.     call    qbreak
  342.     jrz    preset;        no break (else kill the submit job)
  343. ;    "    "
  344. ; kill any existing $$$.sub file,
  345. ; reset subflg, and default drv/usr/dma
  346. ; a,f,d,e
  347. killsub:
  348.     lda    subusr
  349.     call    susera
  350.     lxi    d,subfcb
  351.     call    fpurge
  352.     xra    a
  353.     sta    subflg
  354. ;    "    "
  355. ; Set default DMA/drive/user (in defdu)
  356. preset:    call    sdma80;        restore default dma setting
  357. ;    "    "
  358. ; select the default drive/user (in defdu)
  359. ; a,f,e
  360. setdud:    lda    defdu
  361.     push    psw
  362.     tdig
  363.     ani    0fh
  364.     call    susera
  365.     pop    psw
  366. ;    "    "
  367. ; select drive (a). DOS handles redundancies.
  368. ; a,f,e
  369. seldka:    ani    0fh
  370.     mov    e,a
  371.     push    h
  372.     lhld    drvmsk
  373.     call    bitmsk;        validate selection, 0..15 here
  374.     pop    h
  375.     jc    badcmd;        invalid on this system
  376.     mvi    a,@seldk
  377.     jr    bdos
  378. ;
  379. ; Get command, either from subfile (preferred) or console.
  380. ; This line is NOT upshifted.
  381. ; a,f,d,e,h,l
  382. getcmd:    lda    subflg
  383.     ora    a
  384.     cnz    getsub;        Get from sub file if possible
  385.     lda    defdu
  386.     push    psw
  387.     ani    0fh
  388.     adi    'A'
  389.     call    couta
  390.     pop    psw
  391.     tdig
  392.     ani    0fh
  393.     cnz    putnum
  394.     mvi    a,'>'
  395.     call    couta;        finish the prompt
  396.     lda    subflg
  397.     ora    a
  398.     lxi    h,iobuff
  399.     jnz    tstr;        a subfile line loaded, echo & exit
  400. ;    "    "
  401. ; Input line from console. Add line end mark. Return de^ to ibflen 
  402. ; a,f,d,e,h,l
  403. getln:    lxi    d,ibfsiz
  404.     mvi    a,@instg
  405.     call    bdos;        else read from console & exit
  406.     inx    d;        to ibflen
  407.     ldax    d
  408.     mov    l,a
  409.     xra    a
  410.     mov    h,a
  411.     dad    d;        point to line end
  412.     inx    h
  413.     mov    m,a;        and mark it
  414.     ret
  415. ;
  416. ; Parse the next field from the command line (IX^) into fcbdrv. Any
  417. ; drive/user specifications are recorded in fcbdrv and fcbusr
  418. ; (which default to 0 and -1 respectively).  name and type are parsed
  419. ; into fname and ftype, blank padded, with any '*'s expanded into
  420. ; '?'s, and the fields are blank padded.  At exit IX points to the
  421. ; field terminating delimiter char and lastwd points to the 1st char.
  422. ; a contains a count of '?' characters in fname & ftype fields, with
  423. ; flags set on it.  Illegal chars. cause abort.
  424. ; a,f,b,c,d,e,h,l,ix
  425. parse:    xra    a
  426. ;    "    "
  427. ; Entry to parse 2nd drive spec. for xcom, when a = 010h
  428. parsef:    lxi    h,fcbusr
  429.     call    index;        select fcb or alternate fcb
  430.     call    skipbk;        skip any leading blanks
  431.     sixd    lastwd;        save marker for errors
  432.     call    getdu;        c := user, b := drv
  433.     mov    m,c;        set fcbusr
  434.     inx    h
  435.     mov    m,b;        set fcbdrv, set up for ldfld
  436.     call    lastch
  437.     cpi    ':'
  438.     cz    nextch;        Absorb any du terminating ':'
  439.     mvi    b,8
  440.     push    h
  441.     call    ldfld;        fill the name field
  442.     call    lastch
  443.     cpi    '.'
  444.     cz    nextch;        Absorb any name terminating '.'
  445.     mvi    b,3;         (else terminator blank fills)
  446.     call    ldfld;        fill the type field
  447.     mvi    b,3
  448. parse1:    inx    h
  449.     mvi    m,0
  450.     djnz    parse1;        zero ex, s2, s1 fields
  451.     lxi    b,11 shl 8;    b := 11, c := 0
  452.     pop    h
  453.     mvi    a,'?'
  454. parse2:    inx    h
  455.     cmp    m
  456.     jrnz    parse3
  457.     inr    c
  458. parse3:    djnz    parse2;        count the '?'s in fname/ftype
  459.     mov    a,c
  460.     ora    a;        z flag for no wild cards
  461.     ret
  462. ;
  463. ; load up to (b) chars from (ix)^ up to (hl)^ up.
  464. ; skip to delimiter.  Implement any wild cards on "*"
  465. ; blank fill if less than (b) chars available.
  466. ; Upshift any lower case characters.
  467. ; a,f,b,h,l,ix
  468. ldfld:    call    lastch;        on (ix)^ and load it
  469.     jrz    ldfld4;        delimiter
  470.     inx    h
  471.     cpi    '*'
  472.     jrnz    ldfld1
  473.     mvi    m,'?';        expand '*'
  474.     jr    ldfld2;        dont skip past it
  475. ldfld1:    call    upshft;        upshift any lower case
  476.     mov    m,a
  477.     call    nextch
  478. ldfld2:    djnz    ldfld
  479.     call    lastch;        on (de)^ and load it
  480.     rz;            a delimiter
  481. ldfld3:    call    nextch;        else skip to a delimiter
  482.     rz
  483.     jr    ldfld3
  484. ldfld4:    inx    h
  485.     mvi    m,' ';        blank fill
  486.     djnz    ldfld4
  487.     ret
  488. ;
  489. ; getdu returns any "du" spec. in b and c, with c = user, b = drv
  490. ; The default user is signified by a -1 value, default drive by 0
  491. ; At entry, IX points to the start of the field to be parsed. At
  492. ; exit, either IX is unchanged (no du found), or points to ':'
  493. ; a,f,b,c,d,e,ix
  494. getdu:    lxi    b,0ffh;        set defaults
  495.     pushix
  496.     pop    d;        pre-scan for valid du field
  497.     ldax    d
  498.     call    upshft;        2.1 - No ':' abort here
  499.     call    qnum
  500.     jrnc    getdu1;        1st char digit, no d
  501.     cpi    '@'
  502.     rc;            < '@', no du spec
  503.     cpi    'P'+1
  504.     rnc;            > P, no du spec
  505.     inx    d
  506.     ldax    d
  507.     cpi    ':'
  508.     jrz    getdu2;        d spec only
  509.     call    qnum
  510.     rc;            no 'du' spec
  511. getdu1:    inx    d
  512.     ldax    d
  513.     cpi    ':'
  514.     jrz    getdu2;        du spec found
  515.     call    qnum
  516.     rc;            no du spec
  517.     inx    d
  518.     ldax    d
  519.     cpi    ':'
  520.     rnz;            not terminal ':', no du spec
  521. ;    "    "
  522. ; prescan found a valid du format, now load it
  523. getdu2:    call    lastch
  524.     call    qnum
  525.     jrnc    getdu3;        digit, no d portion
  526.     call    upshft
  527.     sui    '@'
  528.     mov    b,a;        save d portion
  529.     call    nextch
  530. getdu3:    cpi    ':'
  531.     rz;            no 'u' portion
  532.     ani    0fh
  533.     mov    c,a
  534.     call    nextch
  535.     rz;            ':', 1 digit only
  536.     call    dstep;        incorporate
  537.     call    nextch;        and advance to the (known) ':'
  538.     lda    maxusr
  539.     cmp    c
  540.     jrc    badcmd;        User # too large
  541.     ret
  542. ;
  543. ; Decimal input step. Carry for overflow. c is accumulator, a digit
  544. ; a,f,c,d
  545. dstep:    ani    0fh
  546.     mov    d,a
  547.     mov    a,c
  548.     cpi    26
  549.     cmc
  550.     rc;            overflow
  551.     add    a
  552.     add    a
  553.     add    c;        5*
  554.     add    a;        10*
  555.     add    d
  556.     mov    c,a;        result
  557.     ret;            cy for overflow
  558. ;
  559. ; Get next character from line.  Z flag for a delimiter,
  560. ; and abort if the character is illegal. Do not advance past eoln.
  561. ; Return char in a and leave IX pointing to it. cy for eoln
  562. ; a,f,ix
  563. nextch:    ldx    a,+0
  564.     ora    a
  565.     jrz    lastch;        don't advance past eol
  566.     inxix
  567. ;    "    "
  568. ; Return last character, as above.  Abort if invalid, cy for eoln
  569. ; a,f
  570. lastch:    ldx    a,+0
  571.     ora    a
  572.     stc
  573.     rz;            null is a delimiter
  574.     cpi    '=';        and all these
  575.     rz
  576.     cpi    '_'
  577.     rz
  578.     cpi    '.'
  579.     rz
  580.     cpi    ':'
  581.     rz
  582.     cpi    ';'
  583.     rz
  584.     cpi    '<'
  585.     rz
  586.     cpi    '>';        Redirection chars
  587.     rz
  588.     cpi    ',';        Operand separator
  589.     rz
  590.     cpi    '|';        Piping  separator
  591.     rz;
  592. ;    "    "
  593. ; Check white space, abort on illegal chars. z flag for white
  594. qwhite:    cpi    tab
  595.     rz;            white space is a delimiter
  596.     cpi    ' '
  597.     jrc    badcmd;        abort on illegals
  598.     ret
  599. ;
  600. ; skip blanks and tabs in input line.  Abort on illegal chars.
  601. ; return the 1st non-blank char. found.
  602. ; a,f,ix
  603. skipbk:    call    lastch
  604.     rc;            eoln
  605. skip1:    call    qwhite
  606.     rnz;            not white space
  607. ;    "    "
  608. ; Effectively "call nextch ! call skipbk"
  609. next:    call    nextch
  610.     jrnc    skip1
  611.     ret;            eoln
  612. ;
  613. ; Parse a filename, abort if wild cards specified
  614. pfwild:    call    parse
  615.     rz
  616. ;    "    "
  617. ; Badcmd is a command aborter.  It shows the portion of the
  618. ; current line from lastwd^ thru ix, with a '?', kills any
  619. ; submit job in progress, and returns to the command loop.
  620. badcmd:    call    crlf
  621.     lhld    lastwd
  622.     pushix
  623.     pop    d
  624.     inx    d
  625.     mov    a,e
  626.     sub    l
  627.     mov    b,a;        char count for the field
  628. badcd1:    mov    a,m
  629.     call    couta
  630.     inx    h
  631.     djnz    badcd1;        display the field
  632.     mvi    a,'?'
  633.     call    couta
  634.     call    killsub
  635.     jr    cmdone;        go mark line empty
  636. ;
  637. ;    ****************************
  638. ; The 'cold' entry should be at the magic 035Ch from begin
  639. ; to function with the peculiar Osborne 1 bootstrap loader.
  640. spare    equ    035ch - ($-begin);    available for patching
  641.     if    spare AND 08000h;    i.e. negative
  642.    +++     Code entry point wrong for Osborne 1    +++
  643.     else
  644.      if    spare NE 0
  645.       ds    spare,0;    null fill it
  646.      endif
  647.     endif
  648. ;
  649. ;    ------- Outer Block --------
  650. ;
  651. ; cold entry and sign-on. This is only used on initial entry, and is
  652. ; automatically patched out.  If "cold" and "both" are not on the
  653. ; same page the relocation mechanism in RELOCCP will have problems.
  654. cold:    jmp    signon
  655. ;
  656. ; at entry (c) specifies default user/drive
  657. warm:    xra    a
  658.     sta    ibflen;        kill prestored command
  659. ;    "    "
  660. ; Initialization. Entry here executes pre-stored command. c = usr/drv
  661. both:    lxi    sp,stktop
  662.     lxi    h,both;        Automatic no sign-on patch.
  663.     shld    begin+1;    also allows for Osborne 1 peculiarity
  664.     xra    a
  665.     sta    defdu;        Until input (c) found valid
  666.     call    rsdisk;        true if any '$*.*' file exists
  667.     sta    subflg
  668.     mov    a,c
  669.     call    dvalid;        So defdu is A0: if invalid
  670. ;    "    "
  671. ; Main loop of the command processor.
  672. cmdlp:    lxi    sp,stktop;    in case aborted
  673.     call    preset;        Set default drv/user/dma
  674.     call    crlf
  675.     lda    ibflen
  676.     ora    a
  677.     cz    getcmd;        No prestored, get new
  678.     lda    subflg;        (sub breaks checked before and
  679.     ora    a;         after echo, to ease operation)
  680.     cnz    qbreak;        If console break on sub job
  681.     jrz    cmdlp1
  682.     call    killsub;    then abort sub in progress
  683.     jr    cmdone
  684. cmdlp1:    lxi    h,iobuff;    init cursor to buffer start
  685.     shld    lastwd
  686.     push    h
  687.     popix
  688.     mov    a,m
  689.     cpi    '*'
  690.     jrz    cmdone;        initial '*' is also a comment for now
  691.     sui    ';'
  692.     jrz    cmdone;        an initial ';' marks a comment line
  693.     inr    a;        i.e. cpi ':'
  694.     jrz    cmdone;        and ':' is a label for submit, ignore
  695.     lda    ibflen
  696.     ora    a
  697.     cnz    parse;        next item into fcbdrv
  698.     lda    ibflen
  699.     ora    a
  700.     cnz    exec;        execute the non-null command
  701. ;    "    "
  702. ; Exit point from commands
  703. cmdone:    xra    a;        badcmd re-enters here
  704.     sta    ibflen
  705.     jr    cmdlp;        Until a .COM file reboots
  706. ;
  707. ; hl := hl + a
  708. ; a,f,h,l
  709. index:    add    l
  710.     mov    l,a
  711.     rnc
  712.     inr    h
  713.     ret
  714. ;
  715. ;    ------- The rest is execution features -------
  716. ;
  717. ; The abilities of CCP+ can be modified fairly freely in the following
  718. ; code, without affecting the main parsing and submit execution.
  719. ;
  720. ;    -----------------------------------------------
  721. ;
  722. ; Check wheel permission for command # (a). At entry,
  723. ; a =   0     1   2     3     4     5    6     7   8    9 (= maxcmd+1)
  724. ; for login, dir, era, type, save, ren, caps, go, kill, xcom 
  725. ; Values 10, 11, 12 for du check on login, dir, xcom respectively
  726. ; Returns carry for controlled command
  727. ; a,f,h,l
  728. whlchk:    lhld    @wheel
  729.     mov    a,m
  730.     ora    a
  731.     rnz;            wheel set
  732.     lhld    cmdmsk
  733.     jmp    bitmsk;        put controlling bit in carry
  734. ;
  735. ; Login to drive/user specified by fcbusr, fcbdrv.
  736. ; a,f,b,c,e
  737. login:    call    skipbk
  738.     jrnc    cmdbad;        more in line
  739.     mvi    a,maxcmd+2;    for logins
  740.     call    chkdu;        check validity while defaults marked
  741.     mov    a,c;        chkdu set c := user, b := drv
  742.     inr    a
  743.     ora    b
  744.     rz;            drv/user default, null command
  745.     call    setusr;        update to abs usr, call bdos
  746.     mov    a,c
  747.     tdig
  748.     ani    0f0h
  749.     mov    c,a
  750.     mov    a,b
  751.     dcr    a
  752.     jp    login1;        not default drive
  753.     lda    defdu
  754. login1:    ani    0fh
  755.     ora    c
  756.     mov    c,a;        new defdu value, if valid
  757. ;    "    "
  758. ; validate drive selection before defdu update
  759. ; a,f,e
  760. dvalid:    call    seldka;        so BDOS aborts if invalid
  761.     mov    a,c
  762.     sta    defdu;        outer block does actual selection
  763.     ret
  764. ;
  765. ; Exec receives the initial command line field parsed into fcbdrv,
  766. ; and is responsible for whatever is done with it.  IX has been advanced
  767. ; to the delimiter past this first field.
  768. exec:    lda    ftype
  769.     sui    ' '
  770.     sta    flag;        if good, a default 0
  771.     jrnz    cmdbad;        No type allowed on initial field
  772.     lda    fname
  773.     sui    ' '
  774.     jrz    login;        A login command only
  775.     lbcd    fcbusr;        Something other than a login command
  776.     inr    c
  777.     mov    a,c
  778.     ora    b
  779.     mvi    a,maxcmd
  780.     cz    lookup;        No drv nor user spec, check built-ins
  781.     lxi    h,xfrtbl;      (otherwise a file is specified)
  782.     add    a
  783.     call    index
  784.     mov    a,m
  785.     inx    h
  786.     mov    h,m
  787.     mov    l,a
  788.     pchl;            transfer via hl, returns to main
  789. ;
  790. ; Check validity of du under wheel reset conditions
  791. ; Abort to badcmd if illegal du.  Returns b := drv, c := user
  792. ; Used for login, dir, and execution of transient commands,
  793. ; for which a = 10, 11 or 12 on entry respectively.
  794. ; a,f,b,c,h,l
  795. chkdu:    lbcd    fcbusr
  796.     call    whlchk;        Wheel for command access?
  797.     rnc;            not controlled
  798. ;    "    "
  799. ; Validate against system values, abort if illegal
  800.     inr    c;        so default is 0
  801.     lda    whlusr;        max ALLOWED
  802.     inr    a
  803.     cmp    c
  804.     dcr    c;        restore c
  805.     mov    a,b
  806.     cnc    drvchk;        if u ok check drive
  807.     rnc;            drive ok
  808. ;    "    "
  809. ; linkage to badcmd
  810. cmdbad:    jmp    badcmd
  811. ;
  812. ; search for valid command. Checks (fname) against internal list
  813. ; Returns a := index of command, maxcmd if not found (i.e. xcom)
  814. ; A suppressed command (via wheel/cmdmsk) returns maxcmd
  815. ; a,f,b,c,d,e,h,l
  816. lookup:    lxi    h,cmdtbl
  817.     mvi    c,0
  818.     jr    look4;        to loop entry
  819. look1:    inx    h
  820.     djnz    look1;        skip over command table to next
  821. look2:    inr    c;        advance index, test next entry
  822.     mov    a,c
  823.     cpi    maxcmd
  824.     rnc;            not in command table - exit
  825. look4:    lxi    d,fname
  826.     mvi    b,4;        length of command strings
  827. look5:    ldax    d
  828.     cmp    m
  829.     jrnz    look1;        not this one
  830.     inx    d
  831.     inx    h
  832.     djnz    look5;        more chars to check
  833.     ldax    d
  834.     cpi    ' '
  835.     jrnz    look2;        Not terminated, not command
  836.     mov    a,c;        found
  837.     inr    a;        because 0 describes login
  838.     call    whlchk;        is command suppressed?
  839.     mov    a,c
  840.     rnc
  841.     mvi    a,maxcmd;    yes, look for transient
  842.     ret;            found
  843. ;
  844. ; Set drv/user from fcbusr/fcbdrv.  Expected to be restored.
  845. ; This is used only by the built-in and transient commands.
  846. ; Revise fcbusr/drv to specify absolute values.
  847. ; a,f,b,c,e
  848. setdu:    call    setusr;        b := drv; c := usr
  849.     mov    a,b
  850.     dcr    a;        put in range 0..15
  851.     jp    setdu1;        not default
  852.     lda    defdu;        else get default setting
  853. setdu1:    ani    0fh
  854.     mov    b,a;        now drv/user are absolute values
  855.     call    seldka;        aborts on invalid
  856.     inr    b;        non-default, defeat any paths
  857.     sbcd    fcbusr;        update fcb
  858.     ret
  859. ;
  860. ; DIR command
  861. ; a,f,b,c,d,e,h,l,ix
  862. xdir:    call    skipbk
  863.     xra    a
  864.     sta    flag
  865.     call    parse
  866.     call    skipbk;        so ix^ is at any options (O, S)
  867.     jrc    xdir3;        end of line, no options
  868.     call    upshft
  869.     cpi    'S';        system also
  870.     jrz    xdir1
  871.     cpi    'O';        only system
  872.     jrnz    xdir2;        go check separator
  873. xdir1:    sta    flag
  874.     cz    nextch;        position past any flag found
  875.     call    skipbk
  876.     jrc    xdir3;        eol, no more
  877. xdir2:    cpi    ';'
  878.     jrnz    cmdbad;        should have line end now
  879. xdir3:    call    nextch;        absorb separator
  880.     mvi    a,maxcmd+3
  881.     call    chkdu
  882.     call    setdu;        now bc is abs drv/usr
  883.     lxi    h,fname
  884.     mov    a,m
  885.     cpi    ' '
  886.     jrnz    dir;        something specified
  887.     mvi    b,11;        set *.* default
  888. xdir4:    mvi    m,'?';        with 11 "?"s
  889.     inx    h
  890.     djnz    xdir4
  891. ;    "    "
  892. ; Parameters set up.  List all matching entries
  893. dir:    call    ffind;        return (a) := dir ptr + 1
  894.     jrz    dirx
  895.     mvi    e,1;        so first item causes new line
  896. dir1:    dcr    a;        regain dir block pointer
  897.     rrc
  898.     rrc
  899.     rrc
  900.     ani    060h;
  901.     mov    c,a;        form dir entry pointer
  902.     call    qlist
  903.     jrc    dir9;        suppress this entry
  904.     dcr    e
  905.     jrnz    dir2;        not new line needed
  906.     lda    cols
  907.     mov    e,a
  908.     call    crlf
  909.     call    qdisk
  910.     adi    'A'
  911.     call    couta
  912.     lda    fcbusr
  913.     ora    a
  914.     cnz    putnum;        show user if non-zero
  915.     jr    dir3
  916. dir2:    mvi    a,' '
  917.     call    couta
  918. dir3:    mvi    a,':'
  919.     call    couta
  920.     mvi    b,1;        point to 1st char. in fname
  921. dir4:    mvi    a,' '
  922.     call    couta
  923. dir5:    mov    a,b
  924.     call    idxac
  925.     ani    07fh;        remove any attribute bit
  926.     call    couta
  927.     inr    b;        count position in name
  928.     mov    a,b
  929.     cpi    9
  930.     jrz    dir4;        after fn, insert blank
  931.     cpi    12
  932.     jrc    dir5;        not done, continue
  933. dir9:    call    qbreak;        check for interruption
  934.     rnz;            user break
  935.     call    srchn
  936.     jrnz    dir1;        with (a) := dir entry id
  937. dirx:    call    skipbk
  938.     rc;            end of command line, EXIT
  939.     call    crlf
  940.     call    setdud;        restore defaults and
  941.     jmp    xdir;        repeat for next field
  942. ;
  943. ; Check whether entry should be listed.  defdma holds the
  944. ; directory field, c holds the field index, and flags any
  945. ; command input flag (0 if none, <O)nly system, <S>ystem
  946. ; Set carry if listing to be suppressed
  947. ; a,f,b,h,l
  948. qlist:    mvi    a,10
  949.     call    idxac
  950.     mov    b,a;        get system bit
  951.     lda    flag
  952.     ora    a
  953.     jrnz    qlist1;        a flag
  954.     mov    a,b
  955.     ral
  956.     ret;            with carry for system file
  957. qlist1:    cpi    'S'
  958.     rz;            (S)ystem also, list this one
  959.     mov    a,b;        must be (O)nly system
  960.     cma
  961.     ral
  962.     ret;            carry for non-system
  963. ;
  964. ; load (a+c)th char from defdma array
  965. ; a,f,h,l
  966. idxac:    lxi    h,defdma
  967.     add    c
  968.     call    index
  969.     mov    a,m
  970.     ret
  971. ;
  972. ; TYPE command execution
  973. xtype:    call    pfwild;        aborts if wild cards
  974.     call    setusr;        but not drive, allow paths
  975.     call    fopenf
  976.     jrz    getn6;    badcmd
  977.     call    crlf
  978.     mvi    b,128
  979. xtype1:    mov    a,b
  980.     cpi    128
  981.     jrc    xtype2;        disk read not needed
  982.     call    freadf
  983.     rnz;            eof
  984.     mov    b,a;        a zero
  985. xtype2:    inr    b
  986.     lxi    h,defdma
  987.     call    index
  988.     mov    a,m
  989.     cpi    eof
  990.     rz
  991.     call    couta
  992.     call    qbreak
  993.     jrz    xtype1;        no interruption
  994.     ret
  995. ;
  996. ; Get number from command line.
  997. ; Optional final "+" which sets 'flag'
  998. getnum:    call    pfwild;        forbids wild cards
  999.     lda    fcbdrv
  1000.     ora    a
  1001.     jrnz    getn6;    badcmd;    starts with "d:"
  1002.     lxi    h,fname
  1003.     lxi    b,11 shl 8;    c := 0, b := 11
  1004. getn1:    mov    a,m
  1005.     cpi    ' '
  1006.     jrz    getn5;        done
  1007.     cpi    '+'
  1008.     jrz    getn4;        done, with + flag
  1009.     inx    h
  1010.     call    qnum
  1011.     cnc    dstep;        incorporate
  1012.     jrc    getn6;    badcmd    overflow
  1013.     djnz    getn1
  1014. getn3:    mov    a,c
  1015.     ret
  1016. getn4:    sta    flag;        i.e. "+" terminator
  1017. getn5:    inx    h
  1018.     dcr    b
  1019.     jrz    getn3
  1020.     mov    a,m;        test for excess garbage
  1021.     cpi    ' '
  1022.     jrz    getn5
  1023. getn6:    jmp    badcmd
  1024. ;
  1025. ; SAVE command execution
  1026. xsave:    call    getnum
  1027.     push    psw
  1028.     call    pfwild;        aborts if wildcards
  1029.     call    setdu;        no paths, absolute drive
  1030.     lxi    d,fname
  1031.     ldax    d
  1032.     dcx    d;        to fcbdrv
  1033.     cpi    ' '
  1034.     jrz    getn6;    badcmd;    no name specified
  1035.     call    fpurge
  1036.     call    create
  1037.     jrz    xsave3;        fullup
  1038.     xra    a
  1039.     sta    frecd
  1040.     pop    psw
  1041.     mov    l,a
  1042.     mvi    h,0
  1043.     dad    h;        convert pages to records
  1044.     lxi    d,tpa
  1045.     lda    flag
  1046.     ora    a
  1047.     jrz    xsave1
  1048.     inx    h;        extra record to save
  1049. xsave1:    mov    a,h
  1050.     ora    l
  1051.     jrz    xsave2
  1052.     dcx    h
  1053.     push    h
  1054.     lxi    h,128;        advance to next record
  1055.     dad    d
  1056.     push    h;        save next, d is present
  1057.     call    setdma
  1058.     lxi    d,fcbdrv
  1059.     call    fwrite
  1060.     pop    d;        get back next pointer
  1061.     pop    h;        and record counter
  1062.     jrz    xsave1;        write succeeded
  1063.     jr    fullup;        write failure
  1064. xsave2:    lxi    d,fcbdrv;    done
  1065.     call    fclose
  1066.     rnz;            close succeeded
  1067.     push    h;        so we can arrive with
  1068. xsave3:    pop    h;         junk on the stack
  1069. ;    "    "
  1070. ; NO ROOM message and return
  1071. fullup:    lxi    h,fulmsg
  1072.     jr    xcaps1;    tstrc
  1073. ;
  1074. ; CAPS command execution
  1075. xcaps:    lxi    h,lcuc
  1076.     mov    a,m
  1077.     cma
  1078.     mov    m,a
  1079.     ora    a
  1080.     lxi    h,dnmsg
  1081.     jrz    xcaps1
  1082.     lxi    h,upmsg
  1083. xcaps1:    jr    tstrc;        exit with message
  1084. ;
  1085. ; ERA command execution
  1086. xera:    call    parse
  1087.     cpi    11
  1088.     jrnz    xera1;        not *.* specification
  1089.     lxi    h,allmsg
  1090.     call    tstrc
  1091.     call    getln
  1092.     xchg;            hl points to ibflen
  1093.     dcr    m
  1094.     rnz;            not 1 char reply.  jr byte saver
  1095.     inx    h
  1096.     mov    a,m
  1097.     ani    05fh;        upshift, only interested in 'Y'
  1098.     cpi    'Y'
  1099.     rnz;            not confirmed
  1100. xera1:    call    setdu
  1101.     lxi    d,fcbdrv
  1102.     call    fpurge
  1103.     rnz;            ok
  1104. ;    "    "
  1105. ; crlf,"NO FILE" message
  1106. ; a,f,h,l
  1107. nofile:    lxi    h,nofmsg
  1108. ;    "    "
  1109. ; crlf, then tstr
  1110. ; a,f,h,l
  1111. tstrc:    call    crlf
  1112. ;    "    "
  1113. ; string (hl) to console until 0 byte
  1114. ; a,f,h,l
  1115. tstr:    mov    a,m
  1116.     ora    a
  1117.     rz
  1118.     inx    h
  1119.     call    couta
  1120.     jr    tstr
  1121. ;
  1122. ; REN command execution
  1123. xren:    call    pfwild;        aborts if wild cards
  1124.     call    setdu
  1125.     push    b
  1126.     call    ffind
  1127.     jrnz    xren2;        new name pre-exists
  1128.     lxi    h,fcbdrv
  1129.     lxi    d,filedn
  1130.     lxi    b,16
  1131.     ldir
  1132.     call    skipbk
  1133.     cpi    '='
  1134.     jrz    xren1
  1135.     cpi    '_'
  1136.     jrnz    xren3;    badcmd;    invalid assignment operator.
  1137. xren1:    call    nextch
  1138.     call    pfwild;        aborts on wild card
  1139.     call    skipbk
  1140.     jrnc    xren3;    badcmd;    extra garbage on line
  1141.     lhld    fcbusr
  1142.     mov    a,l
  1143.     inr    a
  1144.     ora    h
  1145.     jrnz    xren3;    badcmd;    2nd spec has a d/u
  1146.     pop    h;        du from 1st spec, absolute
  1147.     shld    fcbusr;        make them match
  1148.     call    setdu
  1149.     call    ffind;        (sets de := fcbdrv)
  1150.     jrz    nofile;        cant find file to rename
  1151.     mvi    a,@frenm
  1152.     jmp    bdos;        rename and EXIT
  1153. xren2:    pop    psw
  1154.     lxi    h,foldms
  1155.     jr    tstrc;        and EXIT with message
  1156. xren3:    jmp    badcmd;        LINKAGE
  1157. ;
  1158. ; COM/CCPXTEND.SYS file not found.  (flag specifies which).
  1159. ; Recycle the loader to load CCPXTEND or abort.
  1160. ; This transient receives the complete command line, and can control
  1161. ; any access rights, search libraries, execute interpreters, etc.
  1162. ccpxtd:    lda    fcbdrv;        no ccp extension when disk specified
  1163.     lxi    h,flag;        nor if already tried
  1164.     ora    m
  1165.     jrnz    xren3;    badcmd
  1166.     dcr    a
  1167.     mov    m,a;        set flag to prevent re-execution etc.
  1168.     lxi    b,13;        user, drive, name, type
  1169.     lxi    d,fcbusr;    Now try for ccp extension
  1170.     lxi    h,xtndf
  1171.     jr    xcom1;        load extension and execute
  1172. ;
  1173. ; anything other than built-ins.  look for a com file first,
  1174. ; If this fails, pass the complete command line to CCPXTEND.SYS
  1175. xcom:    mvi    a,maxcmd+4;    for execution
  1176.     call    chkdu;        allows access restriction
  1177.     lxi    h,com
  1178.     lxi    d,ftype
  1179.     lxi    b,3
  1180. xcom1:    ldir;            set file type to ".COM"
  1181.     call    setusr;        leave drive default, for paths
  1182.     call    fopenf
  1183.     jrz    ccpxtd;        not found, exit
  1184.     lxi    h,tpa-128
  1185. xcom2:    lxi    d,128;        advance store ptr.
  1186.     dad    d
  1187.     lxi    d,begin
  1188.     mov    a,l
  1189.     sub    e
  1190.     mov    a,h
  1191.     sbb    d
  1192.     jnc    fullup;        prevent overwriting ccp on load
  1193.     xchg
  1194.     call    setdma
  1195.     xchg
  1196.     call    freadf;        load the COM file
  1197.     jrz    xcom2;        not eof yet
  1198. ;    "    "
  1199. ; Execute loaded program after parsing command tail into page 0.
  1200. xgo:    call    parse;        1st passed fcb
  1201.     call    next;        past closing delimiter. nextch/skipbk
  1202.     mvi    a,010h
  1203.     call    parsef;        2nd passed fcb
  1204.     xra    a
  1205.     sta    frecd
  1206.     sta    frecnt
  1207.     lxi    d,defcbk
  1208.     lxi    h,fcbdrv
  1209.     lxi    b,33;        set default fcbs for execution
  1210.     ldir
  1211.     lxi    h,iobuff
  1212.     lda    flag
  1213.     ora    a
  1214.     jrnz    xgo2;        keep everything on CCPXTEND
  1215. xgo1:    mov    a,m
  1216.     ora    a
  1217.     jrz    xgo2
  1218.     cpi    ' '
  1219.     jrz    xgo2;        skip the command name
  1220.     inx    h
  1221.     jr    xgo1
  1222. xgo2:    mvi    b,0
  1223.     lxi    d,defdma+1
  1224. xgo3:    lda    lcuc
  1225.     ora    a
  1226.     mov    a,m;        set the passed command line
  1227.     cnz    upshft;        upshifting in effect
  1228.     stax    d
  1229.     ora    a
  1230.     jrz    xgo4
  1231.     inr    b;        count chars passed
  1232.     inx    h
  1233.     inx    d
  1234.     jr    xgo3
  1235. xgo4:    mov    a,b
  1236.     sta    defdma;        set cmd line lgh for execution
  1237.     call    crlf
  1238.     call    preset;        preset drive/user/dma
  1239.     jmp    tpa;        EXECUTE. Return to cmdlp on TOS
  1240. ;
  1241. xfrtbl:    dw    xdir,    xera
  1242.     dw    xtype,    xsave
  1243.     dw    xren,    xcaps
  1244.     dw    xgo,    killsub
  1245.     dw    xcom;        xcom must be last entry
  1246. maxcmd    equ    ($-xfrtbl)/2-1
  1247. ;
  1248. ; Resident commands
  1249. cmdtbl:    db    'DIR '
  1250.     db    'ERA '
  1251.     db    'TYPE'
  1252.     db    'SAVE'
  1253.     db    'REN '
  1254.     db    'CAPS'
  1255.     db    'GO  '
  1256.     db    'KILL'
  1257. ;
  1258. ; Check overall size
  1259.     if    ($-begin) GT 1896
  1260.      +++ CCP+ too large +++
  1261.     else;    enough room
  1262. ;
  1263. ; This space is re-used as execution time stack space.
  1264. ;
  1265. ; cold entry and sign-on. This is only used on initial entry.
  1266. ; If "cold" and "both" are not on the same page the relocation
  1267. ; mechanism in RELOCCP will have problems.
  1268. signon:     lxi    sp,stktop
  1269.      lxi    h,vermsg
  1270.      call    tstrc
  1271.      jmp    both
  1272. ;
  1273. ; Do not lengthen this message, else signon stack use clobbers it.
  1274. vermsg:     db    'CCP+ Ver. '
  1275.      db    ccpver/10 + '0','.',ccpver MOD 10 + '0'
  1276.      db    0
  1277.      ds    1944-($-begin),0; working stack space available
  1278. stktop:     ds    0
  1279.     endif;    Too large check
  1280. ;
  1281. ; Data area.  Starts at 0798h (from begin)
  1282. ;
  1283. ; SUBMIT control block. (34 bytes)
  1284. subusr:    db    subuser
  1285. subfcb:    db    1,'$$$     SUB';    drv A, user 0
  1286. subex:    db    0
  1287. subs1:    db    0
  1288. subs2:    db    0
  1289. subrc:    ds    1,0
  1290. subdn:    ds    16,0
  1291. subrcd:    ds    1,0
  1292. subflg:    ds    1,0;        zero prevents sub file searches
  1293. ;
  1294. ; NOTE: the ",0" in ds statements ensures the areas are 0 filled
  1295. ;
  1296. ; File control block and receiver of parse fields (34 bytes)
  1297. fcbusr:    ds    1,0
  1298. fcbdrv:    ds    1,0
  1299. fname:    ds    8,0
  1300. ftype:    ds    3,0
  1301.     ds    3,0
  1302. frecnt:    ds    1,0
  1303. filedn:    ds    16,0;        map or altfcb image
  1304. frecd:    ds    1,0
  1305. ;
  1306. ; Parsing (3 bytes)
  1307. lastwd:    ds    2,0;        start of current word in iobuff
  1308. flag:    ds    1,0;        Command options.  Multiple uses
  1309. ;
  1310. ; The rest can be re-configured. Placed at the end so location
  1311. ; will not change with revisions. 16 bytes for this group
  1312. com:    db    'COM';            file type for transients
  1313. ;
  1314. ; The following file is loaded, passed the complete command line as
  1315. ; entered by the user, and executed whenever a transient command is
  1316. ; not found.  Distributed CCPXTEND.SYS checks user 0, then looks in
  1317. ; COMMAND.LBR on default and A drives, current user and user 0, and
  1318. ; if that fails attempts to execute RUNPCD Pascal interpreter.  You
  1319. ; are perfectly free to install whatever CCPXTEND file you prefer.
  1320. ; By installing different ones on various drv/user areas you can
  1321. ; alter the system characteristics dependent on login area.  If you
  1322. ; are using normal CPM2.2 installation of the CPMFIX patch will make
  1323. ; files on user area 0 with the SYSTEM attribute visible everywhere,
  1324. ; and thus a single CCPXTEND.SYS can serve all areas by default.
  1325. ; DOS+ requires no such patch, and implements paths.
  1326. xtndf:    db    0,0,'CCPXTENDSYS';    ccp extension usr/drv/filename
  1327. ;
  1328. ; Configuration constants for customization. Patchable.
  1329. ; These ALWAYS appear in the last 16 bytes of the CCP area.
  1330. cols:    db    dcols;        columns to use for directory
  1331. lcuc:    db    doupsft;    zero to prevent command line upshift
  1332. ;                CAPS command modifies at run time.
  1333. maxusr:    db    maxuser;    Limit for parsing. Login max = 15
  1334. whlusr:    db    whluser;    Highest user allowed when @wheel^ = 0
  1335. @wheel:    dw    reboot + 0;    Location of wheel byte. +0 = none.
  1336. ;                (reboot always holds 0c3h=jmp)
  1337. ;
  1338. ; This mask specifies which commands are wheel controlled.
  1339. ; bit (lsb)   0     1   2     3     4     5    6     7     8    9
  1340. ; for         login, dir, era, type, save, ren, caps, go, kill, trans
  1341. ;   AND
  1342. ; bit        10   11    12    cause du checks (wheel off) on
  1343. ; for          login  dir  transients (i.e. running .COM files)
  1344. ;   AND
  1345. ; bit 15 (msb) disables A: search for transients & type command. This
  1346. ; is normally disabled for DOS+, since DOS+ provides the search.
  1347. ;
  1348. ; (The ordering is dependent on the command table)
  1349. ; running transients cannot be disabled, bit 9 is ignored
  1350. ; Set to enable search for .COM files for CPM use.
  1351. cmdmsk:    dw    0; (use    8000h for DOS+)    Mask for wheel controlled cmds
  1352. ;
  1353. ; These masks specify drives that may NOT be accessed.  The lsb (of
  1354. ; the word, weight 1) specifies  A:, the msb (bit 15, weight 8000h)
  1355. ; specifies P:.  DRVMSK can prevent logins causing BDOS SELECT errors
  1356. ; by specifying all drives not physically present in the system.
  1357. ; WHLMSK is used for security purposes.
  1358. ; CAUTION: do not disable drive A on most systems
  1359. drvmsk:    dw    0;        Mask for invalid drives, wheel set
  1360. whlmsk:    dw    0;        Mask for bad drives when @wheel^ = 0
  1361.     db    0,0,0,0;    Spares for future use
  1362. ;                (last word is available for ccitcrc)
  1363. ;
  1364. ; Check for relocator problem
  1365.     if    ((both-begin) SHR 8) NE ((cold-begin) SHR 8)
  1366.      +++ Relocator problems, cold/warm/both pages +++
  1367.     endif;        relocation problem
  1368. ;
  1369.     end
  1370. äⁿ