home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / debug / wadesrc.lbr / MONCPM.AZM / MONCPM.ASM
Assembly Source File  |  1988-06-19  |  27KB  |  1,780 lines

  1.     title    'System dependent routines for monitor'
  2. ;
  3. ;    Last Edited    85-04-27    Wagner
  4. ;
  5. ;    Copyright (c) 1984, 1985 by
  6. ;
  7. ;        Thomas Wagner
  8. ;        Patschkauer Weg 31
  9. ;        1000 Berlin 33
  10. ;        West Germany
  11. ;
  12. ;       Released to the public domain 1987
  13. ;
  14. ;
  15. ;    System dependent routines are collected in this module.
  16. ;
  17. ;    INITSYSTEM    is called upon initial entry into the monitor.
  18. ;            any hardware initialisation necessary only once
  19. ;            should be inserted here.
  20. ;            Also, this routine may initialise the default list,
  21. ;            dump, and assemble address (normally 0), and the
  22. ;            protection expression.
  23. ;
  24. ;    INITCIO        is called upon each re-entry into the monitor, i.e.
  25. ;            after a break.
  26. ;            it may be used to disable interrupts for the console
  27. ;            or to re-init console i/o.
  28. ;
  29. ;    WRCHAR        should write the character unedited to the console.
  30. ;    RDCHAR        should read a character from the console.
  31. ;    POLLCH        must return true if a character is available.
  32. ;            the character itself is not read by this routine.
  33. ;
  34. ;    JMACRO        may switch console input to a file.
  35. ;    KILLMAC        must revert input to the console.
  36. ;
  37. ;
  38. ;    READ        can read a file from the disk or via a communication
  39. ;            line. an offset or load address is passed.
  40. ;
  41. ;    WRITE        can write a file to the disk or via a communication 
  42. ;            line. a start and end address is passed.
  43. ;
  44. ;    FILE        may use the information in "string" to generate
  45. ;            a filename for read/write, or for any other purpose.
  46. ;
  47. ;    USERDEF        user defined command. jump to CMDERR if you do not
  48. ;            supply a debugger command here.
  49. ;
  50. ;
  51.     cseg
  52. ;
  53.     maclib    z80
  54.     maclib    monopt
  55. ;
  56. ;
  57.     public    next,biosloc
  58. ;
  59.     public    initsystem,initcio
  60. ;
  61.     public    rdchar,pollch
  62.     public    wrchar
  63. ;
  64.     public    jmacro,killmac
  65.     public    userdef
  66. ;
  67.     public    start,read,write,file
  68.     IF    symbolic
  69.     public    sfile
  70.     public    readsymbol,symwrite,puthexbyte,putfilch
  71.     ENDIF
  72. ;
  73. ;
  74.     IF    symbolic
  75.     extrn    syminit,rdsymname,defsymbol,wsymbols
  76.     ENDIF
  77.     extrn    regpc,string,regiff,regsp
  78.     extrn    break
  79.     extrn    listaddr,dumpaddr,asmaddr
  80.     IF    hilo
  81.     extrn    highval,lowval,maxval,topval
  82.     ENDIF
  83.     extrn    protexpbuf
  84.     extrn    string,getch,testch,skipsep,skipsp,isdigit,iscontrol
  85.     extrn    expression
  86.     extrn    sgetch,stestch
  87.     extrn    monent,cmderr,eocmd
  88.     extrn    wrstr,crlf
  89.     extrn    dishighlow
  90.     extrn    inipeek
  91. ;
  92.     IF    extended
  93.     extrn    cbank,listbnk,dumpbnk,asmbnk
  94. ;
  95. dfltbnk    equ    1        ; default bank on program start
  96. ;
  97.     ENDIF
  98. ;
  99. ;------------------------------------------------------------------------------
  100. ;------------------------------------------------------------------------------
  101. ;
  102. fcb    equ    05ch
  103. fcb2    equ    06ch
  104. ;
  105. ;
  106. ;    RSX-Header
  107. ;
  108. serial:
  109.     db    0,0,0,0,0,0
  110. start:
  111.     jmp    cpmmon
  112. next:
  113.     jmp    0
  114. ;
  115. prev:
  116.     dw    0
  117. remove:
  118.     db    0ffh        ; remove after execution
  119. nonbank:
  120.     db    0
  121.     db    'MONIT   '
  122. loader:
  123.     db    0
  124.     db    0,0
  125. ;
  126. ;
  127.     jmp    warmboot    ; boot-jump
  128. biostab:
  129.     jmp    warmboot    ; exit through cleanup routine for warm boot
  130. bioconst:
  131.     ds    3
  132. bioconin:
  133.     ds    3
  134. bioconout:
  135.     ds    29*3        ; remaining functions are not trapped
  136. ;
  137. ;
  138. biosloc    ds    2        ; real BIOS entry saved here
  139. ;
  140. ;
  141. warmboot:
  142.     lxi    h,0
  143.     push    h        ; simulate break at 0
  144.     jmp    break
  145. ;
  146. ;
  147. ;
  148. cpmmon:
  149.     mov    a,c
  150.     ora    a
  151.     jrz    warmboot    ; 0 is warm boot
  152. ;
  153.     cpi    26        ; set DMA ?
  154.     jrnz    cpmmon10
  155.     sded    dmaaddr        ; save DMA address
  156.     jmp    next
  157. ;
  158. cpmmon10:
  159.     cpi    45        ; set error mode ?
  160.     jrnz    cpmmon20
  161.     mov    a,e
  162.     sta    errmode
  163.     jmp    next
  164. ;
  165. cpmmon20:
  166.     cpi    1        ; console input ?
  167.     jrnz    cpmmon30
  168.     lda    trapinput
  169.     ora    a
  170.     jz    next        ; pass on if no trap
  171.     call    next
  172.     lxi    h,trapchar
  173.     cmp    m
  174.     rnz            ; return char if <> trap character
  175.     mvi    c,1
  176.     lxi    h,next
  177.     push    h        ; set retaddr to "next", so next time
  178.     jmp    break        ; program will get the character
  179. ;
  180. cpmmon30:
  181.     cpi    6
  182.     jrnz    cpmmon40
  183.     mov    a,e
  184.     inr    a
  185.     jrz    cpmconin
  186.     inr    a
  187.     jz    next
  188.     inr    a
  189.     jnz    next
  190. cpmconin:
  191.     lda    trapinput
  192.     ora    a
  193.     jz    next        ; pass on if no trap
  194.     call    next
  195.     lxi    h,trapchar
  196.     cmp    m
  197.     rnz            ; return char if <> trap character
  198.     lxi    h,cpmconi1
  199.     push    h        ; set retaddr to "cpmconi1", so next time
  200.     jmp    break        ; program will get the character
  201. ;
  202. cpmconi1:
  203.     mvi    c,6
  204.     IF    cpm3
  205.     mvi    e,0fdh
  206.     jmp    next
  207.     ELSE
  208.     mvi    e,0ffh
  209.     call    next
  210.     ora    a
  211.     jrz    cpmconi1
  212.     ret
  213.     ENDIF
  214. ;
  215. ;
  216. cpmmon40:
  217.     cpi    60        ; RSX call ?
  218.     jnz    next        ; pass on if not RSX
  219. ;
  220.     lda    initcpm
  221.     ora    a
  222.     jnz    next        ; pass on if initialised
  223.     dcr    a
  224.     sta    initcpm        ; mark initialised
  225. ;
  226. ;    parameter block for initialisation:
  227. ;
  228. ;    db    0,0        ; reserved
  229. ;    dw    protstr        ; address of protection expression string
  230. ;
  231.     xchg
  232.     inx    h
  233.     inx    h
  234.     mov    e,m
  235.     inx    h
  236.     mov    d,m
  237.     sded    pesave
  238. ;
  239.     lxi    h,80h
  240.     shld    dmaaddr
  241.     xra    a
  242.     sta    errmode
  243. ;
  244.     lhld    1        ; get BIOS entry
  245.     shld    biosloc
  246.     inx    h
  247.     inx    h        ; skip WBOOT
  248.     inx    h
  249.     shld    goconst+1    ; save bios table entry for const
  250.     lxi    d,bioconst
  251.     lxi    b,3
  252.     ldir
  253.     shld    goconin+1    ; save entry for conin
  254.     lxi    b,3
  255.     ldir
  256.     shld    goconout+1    ; save entry for conout
  257.     lxi    b,29*3
  258.     ldir
  259.     lxi    h,biostab
  260.     shld    1        ; replace BIOS entry point
  261.     lxi    h,conin
  262.     shld    bioconin+1    ; replace CONIN-entry in our BIOS trap table
  263.     xra    a
  264.     sta    trapinput    ; mark no input trapping
  265.     jmp    monent        ; monitor main entry
  266. ;
  267. ;
  268. ;    replacement for BIOS-conin for user trap
  269. ;
  270. conin:
  271.     lda    trapinput
  272.     ora    a
  273.     jrnz    conin10
  274. goconin:
  275.     jmp    0
  276. ;
  277. conin10:
  278.     call    goconin
  279.     push    h
  280.     lxi    h,trapchar
  281.     cmp    m
  282.     pop    h
  283.     rnz
  284.     push    h
  285.     lxi    h,goconin
  286.     xthl                ; put "goconin" as retaddr on stack
  287.     jmp    break            ; so on return prog will get char
  288. ;
  289. ;
  290. ;
  291. ;    initsystem:    initialise
  292. ;
  293. ;        entry:    -
  294. ;
  295. ;        exit:    -
  296. ;
  297. ;        uses:    may use all registers
  298. ;
  299. initsystem:
  300.     lxi    h,100h
  301.     shld    listaddr
  302.     shld    dumpaddr
  303.     shld    asmaddr
  304.     IF    extended
  305.     mvi    a,dfltbnk
  306.     sta    cbank
  307.     sta    listbnk
  308.     sta    dumpbnk
  309.     sta    asmbnk
  310.     ENDIF
  311.     IF    hilo
  312.     shld    lowval
  313.     shld    highval
  314.     shld    maxval
  315.     ENDIF
  316.     shld    regpc
  317.     lxi    h,serial-1
  318.     shld    topval
  319.     lxi    d,warmboot
  320.     mov    m,d
  321.     dcx    h
  322.     mov    m,e
  323.     shld    regsp        ; set sp to bottom, with retaddr = debexit
  324. ;
  325.     lhld    pesave
  326.     lxi    d,protexpbuf
  327. init10:
  328.     mov    a,m
  329.     stax    d
  330.     inx    h
  331.     inx    d
  332.     ora    a
  333.     jrnz    init10
  334. ;
  335.     lxi    h,100h
  336.     lxi    d,101h
  337.     lxi    b,serial-104h
  338.     mov    m,a
  339.     ldir            ; clear memory
  340. ;
  341.     call    inipeek
  342. ;
  343.     IF    symbolic
  344.     lxi    h,serial
  345.     call    syminit
  346.     lxi    h,fcb2
  347.     lxi    d,symfcb
  348.     lxi    b,32
  349.     ldir
  350.     ENDIF
  351. ;
  352.     lda    fcb+1
  353.     cpi    ' '
  354.     stc
  355.     cnz    read
  356.     IF    symbolic
  357.     lda    symfcb+1
  358.     cpi    ' '
  359.     rz
  360.     lxi    h,symstr
  361.     call    wrstr
  362.     jmp    readsymdefault
  363. ;
  364. symstr    db    'SYMBOLS',0dh,0ah,0
  365. ;
  366.     ELSE
  367.     ret
  368.     ENDIF
  369. ;
  370. ;
  371. ;    initcio:    initialise console I/O
  372. ;
  373. ;        entry:    -
  374. ;
  375. ;        exit:    -
  376. ;
  377. ;        uses:    may use all registers
  378. ;
  379. initcio:
  380.     ret
  381. ;
  382. ;
  383. ;------------------------------------------------------------------------------
  384. ;
  385. ;
  386. ;    rdchar:        read char from console
  387. ;
  388. ;        entry:    -
  389. ;
  390. ;        exit:    A = character
  391. ;
  392. ;        uses:    -
  393. ;
  394. rdchar:
  395.     push    b
  396.     push    d
  397.     push    h
  398.     lda    macactive
  399.     ora    a
  400.     jrz    rdchar1
  401.     call    getmacch
  402.     jrnc    rdcharex
  403.     call    killmac
  404. rdchar1:
  405.     call    goconin
  406. rdcharex:
  407.     pop    h
  408.     pop    d
  409.     pop    b
  410.     ret
  411. ;
  412. ;
  413. ;    pollch:        test if console input available
  414. ;            (should abort macro if active and char available)
  415. ;
  416. ;        entry:    -
  417. ;
  418. ;        exit:    A <> 0 if input available, flags set
  419. ;
  420. ;        uses:    -
  421. ;
  422. pollch:
  423.     push    b
  424.     push    d
  425.     push    h
  426. goconst:
  427.     call    0
  428. ;
  429.     ora    a
  430.     push    psw
  431.     cnz    killmac
  432.     pop    psw
  433.     pop    h
  434.     pop    d
  435.     pop    b
  436.     rz
  437.     ori    0ffh
  438.     ret
  439. ;
  440. ;
  441. ;    wrchar:        write char to console
  442. ;
  443. ;        entry:    A = character
  444. ;
  445. ;        exit:    -
  446. ;
  447. ;        uses:    -
  448. ;
  449. wrchar:
  450.     push    b
  451.     push    d
  452.     push    h
  453.     push    psw
  454.     mov    c,a
  455. goconout:
  456.     call    0
  457.     pop    psw
  458.     pop    h
  459.     pop    d
  460.     pop    b
  461.     ret
  462. ;
  463. ;------------------------------------------------------------------------------
  464. ;
  465. ;    killmac:    revert input to console
  466. ;
  467. ;        entry:    IX points to input line
  468. ;
  469. ;        exit:    -
  470. ;
  471. ;        uses:    may use all registers
  472. ;
  473. ;
  474. killmac:
  475.     lxi    h,macactive
  476.     mov    a,m
  477.     ora    a
  478.     rz
  479.     mvi    m,0        ; mark no longer active
  480.     jmp    closerd        ; close the file
  481. ;
  482. ;
  483. ;    jmacro:        activate macro-file
  484. ;
  485. ;        entry:    IX points to input line
  486. ;
  487. ;        exit:    -
  488. ;
  489. ;        uses:    may use all registers
  490. ;
  491. jmacro:
  492.     lxi    h,macpars
  493.     lxi    d,macpars+1
  494.     lxi    b,19
  495.     mvi    m,0
  496.     ldir            ; clear parameter pointers
  497.     call    killmac
  498.     call    testch        ; any character ?
  499.     jz    cmderr        ; error if not
  500.     lxi    h,myfcb
  501.     call    parsefn        ; parse filename
  502.     jc    cmderr        ; error if parse filename found an error
  503.     jrz    jmac50        ; ok if no more parameters
  504. ;
  505.     lxi    d,macparbuf
  506.     lxi    b,80
  507.     ldir            ; copy buffer from position after filename
  508.     lxi    h,macpars
  509.     lxix    macparbuf
  510.     call    skipsp        ; skip spaces
  511.     pushix
  512.     pop    d        ; pointer into DE
  513.     mvi    b,10        ; max params
  514.     ldax    d
  515.     cpi    ','
  516.     jrnz    jmac10
  517.     inx    d        ; skip first comma
  518. ;
  519. jmac10:
  520.     ldax    d
  521.     inx    d
  522.     ora    a
  523.     jrz    jmac50
  524.     cpi    ' '
  525.     jrz    jmac10        ; skip spaces
  526.     cpi    ','
  527.     jrnz    jmac20
  528.     inx    h
  529.     inx    h
  530.     djnz    jmac10        ; empty parameter
  531.     jmp    cmderr
  532. ;
  533. jmac20:
  534.     dcx    d
  535.     mov    m,e        ; save start position
  536.     inx    h
  537.     mov    m,d
  538.     inx    h
  539. jmac30:
  540.     ldax    d
  541.     inx    d
  542.     ora    a
  543.     jrz    jmac50        ; ready if end of string
  544.     cpi    ','
  545.     jrnz    jmac30        ; skip chars to next comma
  546.     jr    jmac10
  547. ;
  548. jmac50:
  549.     call    openrd
  550.     mvi    a,0ffh
  551.     sta    macactive    ; mark macro active
  552.     lxi    h,0
  553.     shld    parmp        ; mark no parameter active
  554.     ret            ; ready
  555. ;
  556. ;
  557. ;    getmacch:    get one char from macro
  558. ;
  559. getmacch:
  560.     lhld    parmp        ; parameter expansion pointer
  561.     mov    a,h
  562.     ora    l
  563.     jrnz    getmacpar    ; branch if inside parameter expansion
  564.     call    getfilch
  565.     rc            ; ret with carry if EOF
  566. ;
  567. getmacc1:
  568.     cpi    '@'        ; parameter ?
  569.     jrz    getmacc2
  570.     ora    a        ; ret with char if not
  571.     ret
  572. ;
  573. getmacc2:
  574.     call    getfilch    ; get next char
  575.     jc    cmderr        ; error if single @
  576.     cpi    '@'
  577.     rz            ; @@ becomes one @
  578.     call    isdigit
  579.     jc    cmderr        ; error if not @n
  580.     sui    '0'
  581.     add    a        ; * 2
  582.     mov    e,a
  583.     mvi    d,0
  584.     lxi    h,macpars
  585.     dad    d        ; point to parameter pointer
  586.     mov    e,m
  587.     inx    h
  588.     mov    d,m        ; get parameter pointer
  589.     xchg
  590.     shld    parmp        ; set parameter expansion pointer
  591.     jr    getmacch    ; go try again
  592. ;
  593. getmacpar:
  594.     mov    a,m
  595.     ora    a
  596.     jrz    getmacparend    ; ready if end of string
  597.     cpi    ','
  598.     jrz    getmacparend    ; ready if comma
  599.     inx    h
  600.     shld    parmp
  601.     ora    a        ; else ret with char
  602.     ret
  603. ;
  604. ;
  605. getmacparend:
  606.     lxi    h,0
  607.     shld    parmp        ; clear parameter pointer
  608.     jr    getmacch    ; and try again
  609. ;
  610. ;
  611. ;------------------------------------------------------------------------------
  612. ;
  613. ;    U:    User interrupt character
  614. ;
  615. userdef:
  616.     call    eocmd
  617.     lxi    h,uintstr
  618.     call    wrstr            ; prompt
  619.     call    rdchar            ; get unedited character from console
  620.     cpi    0dh
  621.     jrz    userintdel        ; CR means delete char
  622.     sta    trapchar        ; store char
  623.     call    iscontrol
  624.     jrc    userint1        ; ok if not control
  625.     push    psw
  626.     mvi    a,'^'            ; else display as ^c
  627.     call    wrchar
  628.     pop    psw
  629.     adi    40h            ; make it displayable
  630. userint1:
  631.     call    wrchar
  632.     sta    trapinput        ; mark char exists
  633.     jmp    crlf
  634. ;
  635. userintdel:
  636.     xra    a
  637.     sta    trapinput        ; mark no trap
  638.     jmp    crlf
  639. ;
  640. ;
  641. uintstr    db    'Ch: ',0
  642. ;
  643. ;------------------------------------------------------------------------------
  644. ;
  645. ;    file:        set filename for read/write
  646. ;
  647. ;        entry:    "string" contains parameter text
  648. ;            (first char is 'F'-command)
  649. ;
  650. ;        exit:    -
  651. ;
  652. ;        uses:    may use all registers
  653. ;
  654. file:
  655.     lxix    string        ; to start of string
  656.     call    skipsep
  657.     call    getch        ; skip 'F'
  658.     call    stestch
  659.     cpi    ' '
  660.     jrz    file5        ; ok if first char is ' '
  661.     dcxix
  662.     mvix    ' ',0        ; set first char to space
  663. ;
  664. file5:
  665.     lxi    h,51h
  666.     lxi    d,52h
  667.     lxi    b,5
  668.     mvi    m,0
  669.     ldir            ; clear password pointers
  670. ;
  671.     pushix            ; save start position
  672.     pushix            ; again
  673.     lxi    h,fcb
  674.     call    parsefn
  675.     popix            ; string position
  676. ;    
  677.     lxi    d,80h
  678.     jrc    file10        ; ready if error
  679.     jrz    file10        ; ready if EOS
  680. ;
  681.     inx    h        ; skip separator
  682.     xchg            ; into DE
  683. ;
  684. file10:
  685.     push    d
  686.     lxi    h,fcb+16    ; password ?
  687.     mov    a,m
  688.     cpi    ' '
  689.     jrz    file20
  690. ;
  691.     call    pwcount        ; get password pointer/count field
  692. ;
  693.     mov    a,b
  694.     sta    52h
  695.     adi    81h
  696.     sta    51h        ; set addr
  697.     mov    a,c
  698.     sta    53h        ; set length
  699. ;
  700. file20:
  701.     popix            ; string start into IX
  702.     pushix            ; save
  703.     lxi    h,0
  704.     shld    80h
  705.     lxi    h,fcb2
  706.     call    parsefn
  707.     popix
  708.     lxi    h,fcb2+16    ; password ?
  709.     mov    a,m
  710.     cpi    ' '
  711.     jrz    file30
  712. ;
  713.     call    pwcount        ; get password pointer/count field
  714. ;
  715.     lda    52h
  716.     add    b
  717.     adi    81h
  718.     sta    54h        ; set addr
  719.     mov    a,c
  720.     sta    56h        ; set length
  721. ;
  722. file30:
  723.     xra    a
  724.     sta    52h
  725.     lxi    h,0
  726.     shld    7ch
  727.     shld    7eh
  728.     popix            ; string start
  729.     lxi    h,81h
  730.     mvi    b,0
  731. file31:
  732.     call    sgetch
  733.     mov    m,a
  734.     jrz    file40
  735.     inx    h
  736.     inr    b
  737.     jr    file31
  738. ;
  739. file40:
  740.     mov    a,b
  741.     sta    80h        ; set command line length
  742. ;
  743.     ret
  744. ;
  745. ;
  746.     IF    symbolic
  747. ;
  748. ;    sfile:        set filename for symbol read/write
  749. ;
  750. ;        entry:    "string" contains parameter text
  751. ;
  752. ;        exit:    -
  753. ;
  754. ;        uses:    may use all registers
  755. ;
  756. sfile:
  757.     lxi    h,symfcb
  758.     call    parsefn
  759.     jc    cmderr
  760.     ret
  761. ;
  762.     ENDIF
  763. ;
  764. ;
  765. pwcount:
  766.     lxi    b,0
  767. pwcount5:
  768.     call    sgetch
  769.     jrz    pwcount10
  770.     cpi    ';'
  771.     jrz    pwcount10
  772.     inr    b
  773.     jr    pwcount5
  774. ;
  775. pwcount10:
  776.     mov    a,m
  777.     ora    a
  778.     rz
  779.     cpi    ' '
  780.     rz
  781.     inx    h
  782.     inr    c
  783.     jr    pwcount10
  784. ;
  785. ;
  786. ;    parsefn:    scan input line for filename
  787. ;
  788. ;        entry:    IX = input line pointer
  789. ;            HL = fcb address
  790. ;
  791. ;        exit:    HL = pointer to next char if not error or eol
  792. ;            carry set if error
  793. ;            zero set if end of line
  794. ;
  795. ;        uses:    all regs
  796. ;
  797. ;
  798. parsefn:
  799.     IF    cpm3
  800.     sixd    pfcbin
  801.     shld    pfcbout
  802.     mvi    c,152
  803.     lxi    d,pfcbin
  804.     call    next
  805.     ELSE
  806.     call    scanfn
  807.     ENDIF
  808.     mov    a,l
  809.     ora    h
  810.     rz
  811.     inx    h
  812.     mov    a,h
  813.     ora    l
  814.     stc
  815.     rz
  816.     dcx    h
  817.     ora    a
  818.     ret
  819. ;
  820. ;
  821.     IF    NOT cpm3
  822. ;
  823. ;    scanfn:        scan input line for filename
  824. ;
  825. ;        entry:    IX = input line pointer
  826. ;            HL = fcb address
  827. ;
  828. ;        exit:    HL = next input line address if more follows
  829. ;            HL = 0 if end of input line reached
  830. ;            HL = 0ffffh if error occurred
  831. ;
  832. ;        uses:    all regs
  833. ;
  834. scanfn:
  835.     push    h
  836.     mvi    m,0        ; init drive to 0
  837.     inx    h
  838.     mov    d,h
  839.     mov    e,l
  840.     inx    d
  841.     mvi    m,' '
  842.     lxi    b,11
  843.     ldir            ; init fn/ft to spaces
  844.     mvi    m,0
  845.     lxi    b,4
  846.     ldir            ; init ex/s1/s2/rc to 0
  847.     mvi    m,' '
  848.     lxi    b,8
  849.     ldir            ; init password field to spaces
  850.     mvi    m,0
  851.     lxi    b,11
  852.     ldir            ; init remainder of fcb to 0
  853.     pop    h
  854.     push    h
  855.     call    scanskip
  856.     call    isdelim
  857.     jrnc    scanfnret    ; ret with next char if delimiter
  858.     call    sgetch        ; get the char
  859.     push    psw
  860.     call    stestch        ; check next char
  861.     cpi    ':'
  862.     jrnz    scanfn10    ; branch if not a drive specification
  863.     pop    psw
  864.     cpi    'A'
  865.     jrc    scanfnreterr    ; ret error if not A..P
  866.     cpi    'P'+1
  867.     jrnc    scanfnreterr
  868.     sui    'A'-1
  869.     mov    m,a        ; set drive spec
  870.     call    sgetch        ; skip ':'
  871.     call    stestch        ; get next char
  872.     call    isdelim
  873.     jrnc    scanfnret    ; ret if drive spec only
  874.     call    sgetch        ; get the char
  875.     push    psw
  876. ;
  877. scanfn10:
  878.     pop    psw
  879.     inx    h
  880.     mov    m,a
  881.     inx    h
  882.     mvi    b,8        ; max length + 1
  883. scanfn20:
  884.     call    stestch
  885.     cpi    '.'
  886.     jrz    scanfn40    ; branch if extent
  887.     call    isdelim
  888.     jrnc    scanfnret    ; ready if delimiter
  889.     dcr    b
  890.     jrz    scanfnreterr    ; error if fn too long
  891.     call    sgetch
  892.     cpi    '*'
  893.     jrz    scanfn30    ; '*' is translated to ???...
  894.     mov    m,a
  895.     inx    h
  896.     jr    scanfn20
  897. ;
  898. scanfn30:
  899.     mvi    m,'?'
  900.     inx    h
  901.     djnz    scanfn30
  902.     mvi    b,1
  903.     jr    scanfn20
  904. ;
  905. ;
  906. scanfn40:
  907.     pop    h
  908.     push    h
  909.     lxi    b,9
  910.     dad    b        ; point to extent
  911.     mvi    b,4        ; max length + 1
  912.     call    sgetch        ; skip '.'
  913. ;
  914. scanfn50:
  915.     call    stestch
  916.     call    isdelim
  917.     jrnc    scanfnret    ; ready if delimiter
  918.     dcr    b
  919.     jrz    scanfnreterr    ; error if extent too long
  920.     call    sgetch
  921.     cpi    '*'
  922.     jrz    scanfn60
  923.     mov    m,a
  924.     inx    h
  925.     jr    scanfn50
  926. ;
  927. scanfn60:
  928.     mvi    m,'?'
  929.     inx    h
  930.     djnz    scanfn60
  931.     mvi    b,1
  932.     jr    scanfn50
  933. ;
  934. ;
  935. scanfnret:
  936.     pop    h
  937.     call    scanskip
  938.     jrz    scanfnret0    ; return 0 if end of line
  939.     pushix
  940.     pop    h
  941.     ret
  942. ;
  943. scanfnreterr:
  944.     pop    h
  945.     lxi    h,0ffffh
  946.     ret
  947. ;
  948. scanfnret0:
  949.     lxi    h,0
  950.     ret
  951. ;
  952. ;
  953. scanskip:
  954.     ldx    a,0
  955.     ora    a
  956.     rz
  957.     cpi    ' '
  958.     jnz    stestch
  959.     inxix
  960.     jr    scanskip
  961. ;
  962. isdelim:
  963.     ora    a
  964.     rz
  965.     push    h
  966.     push    b
  967.     lxi    h,delimtab
  968.     lxi    b,delimlen
  969.     ccir
  970.     pop    b
  971.     pop    h
  972.     rz            ; ret zero if delimiter
  973.     stc
  974.     ret            ; else ret with carry set
  975. ;
  976. delimtab:
  977.     db    ' ;=<>.:,|[]'
  978. ;
  979. delimlen    equ    $-delimtab
  980. ;
  981.     ENDIF
  982. ;
  983. ;
  984. ;------------------------------------------------------------------------------
  985. ;
  986.     IF    fileops
  987. ;
  988. ;
  989. ;    read:        read a file
  990. ;
  991. ;        entry:    A/HL = offset (or load address)
  992. ;            Carry set if no offset given
  993. ;
  994. read:
  995.     jrnc    read1
  996.     lxi    h,0
  997. read1:
  998.     shld    rwoffset    ; save offset
  999.     lxi    h,fcb
  1000.     call    rwinit
  1001.     call    openrd
  1002.     IF    cpm3
  1003.     lda    myfcb        ; drive id
  1004.     sta    50h        ; set as program load drive
  1005.     ENDIF
  1006.     call    ishexfile
  1007.     jz    rdhexfile
  1008. ;
  1009.     xra    a
  1010.     sta    myfcb+32    ; clear cr to read first record again
  1011.     call    erroff
  1012. ;
  1013.     IF    cpm3
  1014.     lda    rwbuf        ; get first byte of file
  1015.     cpi    0c9h        ; RET instruction ?
  1016.     jrnz    rdcomfile    ; normal COM-file if not
  1017.     call    iscomfile    ; .COM-Extension ?
  1018.     jrnz    rdcomfile    ; don't process RSX if not
  1019. ;
  1020.     lxi    h,rsxstr
  1021.     call    wrstr
  1022.     lhld    rwoffset
  1023.     lxi    d,100h
  1024.     dad    d
  1025.     shld    myfcb+33    ; set load address
  1026.     lxi    d,myfcb
  1027.     mvi    c,59        ; load overlay function
  1028.     call    next        ; load program & attached RSX
  1029.     ora    a
  1030.     jnz    rwerror
  1031.     IF    hilo
  1032.     lhld    topval
  1033.     shld    maxval
  1034.     lhld    6
  1035.     shld    highval
  1036.     lded    regsp
  1037.     dsbc    d        ; RSX-entry-address - current SP
  1038.     jrnc    rsxldok        ; ok if SP below RSX
  1039.     lhld    6
  1040.     mov    a,l
  1041.     ani    0f0h
  1042.     mov    l,a
  1043.     xra    a
  1044.     dcx    h
  1045.     mov    m,a        ; set stack to 0
  1046.     dcx    h
  1047.     mov    m,a
  1048.     shld    regsp        ; else set SP at RSX entry
  1049.     ENDIF
  1050. rsxldok:
  1051.     call    closerd
  1052.     IF    hilo
  1053.     jmp    dishighlow
  1054.     ELSE
  1055.     ret
  1056.     ENDIF
  1057. ;
  1058. rsxstr    db    'Attached RSX',0dh,0ah,0
  1059. ;
  1060.     ENDIF
  1061. ;
  1062. rdcomfile:
  1063.     lhld    rwoffset
  1064.     lxi    d,100h
  1065.     dad    d
  1066.     push    h
  1067.     lxi    d,80h
  1068.     ora    a
  1069.     dsbc    d
  1070.     jc    rwerror        ; cant read below 80h
  1071.     pop    h
  1072. ;
  1073. rdcomloop:
  1074.     push    d        ; save 80h
  1075.     push    h        ; save current DMA
  1076.     xchg            ; DMA into HL
  1077.     dad    d        ; add 80 again for last read addr
  1078.     IF    hilo
  1079.     lbcd    topval        ; max read addr
  1080.     ELSE
  1081.     lxi    b,serial-1    ; maximum read addr
  1082.     ENDIF
  1083.     inx    b        ; plus one to get carry
  1084.     ora    a
  1085.     dsbc    b
  1086.     jnc    rwerror        ; error if read would overwrite us
  1087.     mvi    c,26
  1088.     call    next        ; set dma
  1089.     lxi    d,myfcb
  1090.     mvi    c,20
  1091.     call    next        ; read file
  1092.     pop    h
  1093.     pop    d
  1094.     ora    a
  1095.     jrnz    rdready
  1096.     dad    d        ; increase dma addr
  1097.     jr    rdcomloop    ; continue if no error
  1098. ;
  1099. rdready:
  1100.     IF    hilo
  1101.     dcx    h
  1102.     shld    highval
  1103.     xchg
  1104.     lhld    maxval
  1105.     ora    a
  1106.     dsbc    d
  1107.     jrnc    rdready1
  1108.     sded    maxval
  1109.     ENDIF
  1110. rdready1:
  1111.     push    psw
  1112.     call    closerd
  1113.     IF    hilo
  1114.     call    dishighlow
  1115.     ENDIF
  1116.     pop    psw
  1117.     cpi    1
  1118.     jnz    cmderr        ; error if not eof
  1119.     ret
  1120. ;
  1121. ;
  1122. ;    read intel hex format
  1123. ;
  1124. rdhexfile:
  1125.     lxi    h,0
  1126.     shld    tmphigh
  1127. ;
  1128. rdhexloop:
  1129.     call    getfilch
  1130.     jrc    rdhexready
  1131.     cpi    ':'
  1132.     jrnz    rdhexloop
  1133. ;
  1134.     call    gethexbyte
  1135.     mov    b,a        ; length
  1136.     mov    c,a        ; init checksum
  1137. ;
  1138.     call    gethexbyte
  1139.     mov    d,a
  1140.     call    gethexbyte
  1141.     mov    e,a        ; address
  1142.     call    gethexbyte    ; type
  1143.     ora    a
  1144.     jrz    rdhexdata
  1145.     dcr    a
  1146.     jrz    rdhexready1    ; ready on end of file marker
  1147.     cpi    2        ; 03 = start addr
  1148.     jnz    cmderr
  1149.     xchg
  1150.     shld    regpc
  1151.     shld    listaddr
  1152.     call    rdchecksum
  1153.     jmp    rdhexloop
  1154. ;
  1155. rdhexready1:
  1156.     call    rdchecksum
  1157. ;
  1158. rdhexready:
  1159.     IF    hilo
  1160.     lhld    tmphigh
  1161.     dcx    h
  1162.     shld    highval
  1163.     xchg
  1164.     lhld    maxval
  1165.     ora    a
  1166.     dsbc    d
  1167.     jrnc    rdhexready2
  1168.     sded    maxval
  1169.     ENDIF
  1170. rdhexready2:
  1171.     call    closerd
  1172.     IF    hilo
  1173.     jmp    dishighlow
  1174.     ELSE
  1175.     ret
  1176.     ENDIF
  1177. ;
  1178. ;
  1179. rdhexdata:
  1180.     mov    a,b
  1181.     ora    a
  1182.     jrz    rdhexloop
  1183.     lhld    rwoffset
  1184.     dad    d
  1185.     push    h
  1186.     ora    a
  1187.     lxi    d,80h
  1188.     dsbc    d
  1189.     jc    cmderr
  1190.     pop    h
  1191.     push    h        ; current address
  1192.     mov    e,b        ; DE = length (D is still = 0)
  1193.     dad    d        ; top addr for this record
  1194.     IF    hilo
  1195.     lded    topval        ; max allowed addr
  1196.     ELSE
  1197.     lxi    d,serial-1
  1198.     ENDIF
  1199.     inx    d        ; plus one for carry
  1200.     ora    a
  1201.     dsbc    d
  1202.     jnc    cmderr        ; error if read above top
  1203.     pop    h
  1204. ;
  1205. rdhexdatloop:
  1206.     call    gethexbyte
  1207.     mov    m,a
  1208.     inx    h
  1209.     djnz    rdhexdatloop
  1210. rdhexdend:
  1211.     call    rdchecksum
  1212.     xchg
  1213.     lhld    tmphigh
  1214.     ora    a
  1215.     dsbc    d
  1216.     jnc    rdhexloop
  1217.     sded    tmphigh
  1218.     jmp    rdhexloop
  1219. ;
  1220. ;
  1221. gethexbyte:
  1222.     push    b
  1223.     push    d
  1224.     push    h
  1225.     call    getfilch
  1226.     jc    cmderr
  1227.     call    aschex
  1228.     rlc
  1229.     rlc
  1230.     rlc
  1231.     rlc
  1232.     push    psw
  1233.     call    getfilch
  1234.     jc    cmderr
  1235.     call    aschex
  1236.     mov    c,a
  1237.     pop    psw
  1238.     ora    c
  1239.     pop    h
  1240.     pop    d
  1241.     pop    b
  1242.     push    psw
  1243.     add    c
  1244.     mov    c,a
  1245.     pop    psw
  1246.     ret
  1247. ;
  1248. ;
  1249. rdchecksum:
  1250.     mov    b,c
  1251.     call    gethexbyte
  1252.     neg
  1253.     cmp    b
  1254.     jnz    cmderr
  1255.     ret
  1256. ;
  1257. ;
  1258. aschex:
  1259.     sui    '0'
  1260.     jc    cmderr
  1261.     cpi    10
  1262.     rc
  1263.     sui    'A'-'0'
  1264.     jc    cmderr
  1265.     adi    10
  1266.     cpi    10h
  1267.     rc
  1268.     jmp    cmderr
  1269. ;
  1270. ;------------------------------------------------------------------------------
  1271. ;
  1272. rwrestore:
  1273.     lded    dmaaddr
  1274.     mvi    c,26
  1275.     call    next        ; restore user DMA
  1276.     IF    cpm3
  1277.     lda    errmode
  1278.     mvi    c,45
  1279.     call    next        ; restore error mode
  1280.     ENDIF
  1281.     ret            ; ready
  1282. ;
  1283. rwerror:
  1284.     call    rwrestore
  1285.     jmp    cmderr
  1286. ;
  1287. erroff:
  1288.     IF    cpm3
  1289.     mvi    e,0feh
  1290.     mvi    c,45
  1291.     jmp    next        ; set error mode
  1292.     ELSE
  1293.     ret
  1294.     ENDIF
  1295. ;
  1296. ;
  1297. rwinit:
  1298.     lxi    d,myfcb
  1299.     lxi    b,14
  1300.     ldir            ; copy fcb
  1301.     mov    h,d
  1302.     mov    l,e
  1303.     inx    d
  1304.     mvi    m,0
  1305.     lxi    b,21
  1306.     ldir            ; fill fcb with 0
  1307.     ret
  1308. ;
  1309. iscomfile:
  1310.     lxi    h,comstr
  1311.     jr    ishexcom
  1312. ;
  1313. ishexfile:
  1314.     lxi    h,hexstr
  1315. ishexcom:
  1316.     lxi    d,myfcb+9    ; extension
  1317.     mvi    b,3
  1318. ishexlp:
  1319.     ldax    d
  1320.     ani    7fh
  1321.     cmp    m
  1322.     rnz
  1323.     inx    d
  1324.     inx    h
  1325.     djnz    ishexlp
  1326.     xra    a
  1327.     ret
  1328. ;
  1329. hexstr    db    'HEX'
  1330. comstr    db    'COM'
  1331. ;
  1332. ;------------------------------------------------------------------------------
  1333. ;
  1334. ;    write:        write file
  1335. ;
  1336. ;        entry:    A/HL = first address
  1337. ;            DE = last address
  1338. ;
  1339. write:
  1340.     lda    fcb+1
  1341.     cpi    ' '
  1342.     jz    cmderr
  1343.     push    d        ; save end
  1344.     push    h        ; save start
  1345.     ora    a
  1346.     dsbc    d
  1347.     jnc    cmderr        ; error    if end <= start
  1348.     lxi    h,fcb
  1349.     call    rwinit
  1350.     call    openwr
  1351.     call    ishexfile
  1352.     jz    wrhexfile
  1353. ;
  1354. wrcomfile:
  1355.     call    eocmd
  1356.     call    erroff
  1357.     pop    d        ; start
  1358. ;
  1359. wrcomloop:
  1360.     push    d
  1361.     mvi    c,26
  1362.     call    next        ; set dma
  1363.     lxi    d,myfcb
  1364.     mvi    c,21
  1365.     call    next        ; write file
  1366.     pop    h
  1367.     ora    a
  1368.     jnz    rwerror
  1369.     lxi    d,80h
  1370.     dad    d        ; increase dma addr
  1371.     pop    d        ; get end
  1372.     push    d
  1373.     xchg
  1374.     ora    a
  1375.     dsbc    d        ; end - current
  1376.     jrnc    wrcomloop    ; continue if current < end
  1377.     pop    d        ; discard end
  1378. ;
  1379.     lxi    d,myfcb
  1380.     mvi    c,16
  1381.     call    next        ; close
  1382.     inr    a
  1383.     jz    rwerror
  1384.     jmp    rwrestore
  1385. ;
  1386. ;
  1387. wrhexfile:
  1388.     call    expression
  1389.     jrnc    wrhexfil10
  1390.     lxi    h,0
  1391. wrhexfil10:
  1392.     shld    rwoffset
  1393.     call    eocmd
  1394.     pop    h        ; start
  1395. wrhexloop:
  1396.     mvi    b,16
  1397.     xchg
  1398.     lhld    rwoffset
  1399.     dad    d
  1400.     push    d
  1401.     call    starthexrec
  1402.     pop    h
  1403. wrhexl1:
  1404.     mov    a,m
  1405.     call    puthexbyte
  1406.     inx    h
  1407.     djnz    wrhexl1
  1408.     push    h
  1409.     call    endhexrec
  1410.     pop    d        ; curr
  1411.     pop    h        ; end
  1412.     push    h
  1413.     ora    a
  1414.     dsbc    d        ; end - curr
  1415.     xchg
  1416.     jrnc    wrhexloop
  1417. ;
  1418.     pop    d
  1419.     mvi    b,0
  1420.     lxi    h,0
  1421.     call    starthexrec
  1422.     call    endhexrec
  1423.     jmp    closewr
  1424. ;
  1425. ;
  1426. puthexbyte:
  1427.     push    psw
  1428.     add    c
  1429.     mov    c,a
  1430.     pop    psw
  1431.     push    b
  1432.     push    d
  1433.     push    h
  1434.     push    psw
  1435.     rrc
  1436.     rrc
  1437.     rrc
  1438.     rrc
  1439.     call    puthexdig
  1440.     pop    psw
  1441.     call    puthexdig
  1442.     pop    h
  1443.     pop    d
  1444.     pop    b
  1445.     ret
  1446. ;
  1447. puthexdig:
  1448.     ani    0fh
  1449.     adi    '0'
  1450.     cpi    '9'+1
  1451.     jc    putfilch
  1452.     adi    'A'-'0'-10
  1453.     jmp    putfilch
  1454. ;
  1455. ;
  1456. starthexrec:
  1457.     push    h
  1458.     mvi    a,':'
  1459.     push    b
  1460.     call    putfilch
  1461.     pop    b
  1462.     mvi    c,0
  1463.     mov    a,b
  1464.     call    puthexbyte
  1465.     pop    h
  1466.     mov    a,h
  1467.     call    puthexbyte
  1468.     mov    a,l
  1469.     call    puthexbyte
  1470.     mov    a,b
  1471.     ora    a
  1472.     mvi    a,0
  1473.     jnz    puthexbyte
  1474.     inr    a
  1475.     jmp    puthexbyte
  1476. ;
  1477. ;
  1478. endhexrec:
  1479.     push    h
  1480.     mov    a,c
  1481.     neg
  1482.     call    puthexbyte
  1483.     mvi    a,0dh
  1484.     call    putfilch
  1485.     mvi    a,0ah
  1486.     call    putfilch
  1487.     pop    h
  1488.     ret
  1489. ;
  1490. ;
  1491. ;------------------------------------------------------------------------------
  1492. ;
  1493. ;    openrd:        open file (fcb = myfcb) for reading
  1494. ;
  1495. openrd:
  1496.     call    killmac
  1497.     call    erroff        ; set error mode
  1498.     lxi    d,myfcb
  1499.     mvi    c,15
  1500.     call    next        ; open the file
  1501.     inr    a
  1502.     jz    rwerror        ; error if not opened
  1503.     xra    a
  1504.     sta    myfcb+32    ; clear cr-field
  1505.     call    getfilrec    ; read
  1506.     jnz    cmderr        ; read already did the rwrestore
  1507.     ret
  1508. ;
  1509. ;
  1510. ;    getfilrec:    read one record from the file
  1511. ;
  1512. ;        exit:    A = read error code (<> 0 if error)
  1513. ;
  1514. getfilrec:
  1515.     xra    a
  1516.     sta    rwptr
  1517.     call    erroff        ; set error mode
  1518.     lxi    d,rwbuf
  1519.     mvi    c,26
  1520.     call    next        ; set dma
  1521.     lxi    d,myfcb
  1522.     mvi    c,20
  1523.     call    next        ; read
  1524.     push    psw
  1525.     call    rwrestore
  1526.     pop    psw
  1527.     ora    a
  1528.     ret            ; ret with error code from read
  1529. ;
  1530. ;
  1531. ;    getfilch:    get one byte from the file
  1532. ;
  1533. ;        exit:    A = char
  1534. ;            Carry set if EOF
  1535. ;
  1536. getfilch:
  1537.     lda    rwptr
  1538.     cpi    128
  1539.     jrnz    getfilch1
  1540.     call    getfilrec
  1541.     stc
  1542.     rnz
  1543. getfilch1:
  1544.     lxi    h,rwptr
  1545.     mov    e,m
  1546.     inr    m
  1547.     mvi    d,0
  1548.     lxi    h,rwbuf
  1549.     dad    d
  1550.     mov    a,m
  1551.     cpi    1ah
  1552.     stc
  1553.     rz
  1554.     ora    a
  1555.     ret
  1556. ;
  1557. ;
  1558. ;    closerd:    close read file
  1559. ;
  1560. closerd:
  1561.     call    erroff
  1562.     lxi    d,myfcb
  1563.     mvi    c,16
  1564.     call    next
  1565.     jmp    rwrestore
  1566. ;
  1567. ;
  1568. ;    openwr:        open file (fcb = myfcb) for writing
  1569. ;
  1570. openwr:
  1571.     call    killmac
  1572.     call    erroff        ; set error mode
  1573.     lxi    d,myfcb
  1574.     mvi    c,19
  1575.     call    next        ; delete file
  1576.     mov    a,h
  1577.     ora    a
  1578.     jnz    rwerror        ; abort if physical error
  1579.     lxi    d,myfcb
  1580.     mvi    c,22        ; make file
  1581.     call    next
  1582.     inr    a
  1583.     jz    rwerror        ; error if not made
  1584.     xra    a
  1585.     sta    myfcb+32    ; clear CR-field
  1586.     sta    rwptr
  1587.     call    rwrestore
  1588.     ret
  1589. ;
  1590. ;
  1591. ;    putfilrec:    write one record to the file
  1592. ;
  1593. putfilrec:
  1594.     xra    a
  1595.     sta    rwptr
  1596.     call    erroff        ; set error mode
  1597.     lxi    d,rwbuf
  1598.     mvi    c,26
  1599.     call    next        ; set dma
  1600.     lxi    d,myfcb
  1601.     mvi    c,21
  1602.     call    next        ; write
  1603.     push    psw
  1604.     call    rwrestore
  1605.     pop    psw
  1606.     ora    a
  1607.     jnz    cmderr        ; abort on error
  1608.     ret
  1609. ;
  1610. ;
  1611. ;    putfilch:    put one byte to the file
  1612. ;
  1613. ;        entry:    A = char
  1614. ;
  1615. putfilch:
  1616.     push    psw
  1617.     lda    rwptr
  1618.     cpi    128
  1619.     jrnz    putfilch1
  1620.     call    putfilrec
  1621. putfilch1:
  1622.     pop    psw
  1623.     lxi    h,rwptr
  1624.     mov    e,m
  1625.     inr    m
  1626.     mvi    d,0
  1627.     lxi    h,rwbuf
  1628.     dad    d
  1629.     mov    m,a
  1630.     ret
  1631. ;
  1632. ;
  1633. ;    closewr:    close the file
  1634. ;
  1635. closewr:
  1636.     lda    rwptr
  1637.     cpi    128
  1638.     jrz    closewr1
  1639.     mvi    a,01ah
  1640.     call    putfilch        ; fill  record with 1a
  1641.     jr    closewr
  1642. ;
  1643. closewr1:
  1644.     call    putfilrec        ; write last record
  1645.     call    erroff
  1646.     lxi    d,myfcb
  1647.     mvi    c,16            ; close
  1648.     call    next
  1649.     inr    a
  1650.     jz    rwerror
  1651.     jmp    rwrestore
  1652. ;
  1653. ;
  1654.     IF    symbolic
  1655. ;
  1656. ;    readsymbol:    read symbols from file
  1657. ;
  1658. readsymdefault:
  1659.     lxi    h,0
  1660.     shld    rwoffset
  1661.     jr    readsym10
  1662. ;
  1663. readsymbol:
  1664.     jrnc    readsym01
  1665.     lxi    h,0
  1666. readsym01:
  1667.     shld    rwoffset
  1668.     call    eocmd
  1669.     lda    symfcb+1
  1670.     cpi    ' '
  1671.     jz    cmderr
  1672. readsym10:
  1673.     lxi    h,symfcb
  1674.     call    rwinit
  1675.     call    openrd
  1676. readsymline:
  1677.     lxix    string
  1678.     mvi    b,80        ; max input line length
  1679. readsymlin10:
  1680.     push    b
  1681.     call    getfilch
  1682.     pop    b
  1683.     jrc    readsymlin80
  1684.     cpi    0dh
  1685.     jrz    readsymlin70
  1686.     cpi    0ah
  1687.     jrz    readsymlin10
  1688.     cpi    09h
  1689.     jrnz    readsymlin20
  1690.     mvi    a,' '
  1691. readsymlin20:
  1692.     cpi    20h
  1693.     jc    rwerror
  1694.     stx    a,0
  1695.     inxix
  1696.     djnz    readsymlin10
  1697.     jmp    rwerror
  1698. ;
  1699. readsymlin70:
  1700.     mov    a,b
  1701.     cpi    80
  1702.     jrz    readsymline
  1703.     call    evalsym
  1704.     jr    readsymline
  1705. ;
  1706. readsymlin80:
  1707.     mov    a,b
  1708.     cpi    80
  1709.     cnz    evalsym
  1710.     call    closerd
  1711.     jmp    dishighlow
  1712. ;
  1713. ;
  1714. evalsym:
  1715.     mvix    0,0
  1716.     lxix    string
  1717. evalsym10:
  1718.     call    skipsp
  1719.     rz
  1720.     call    expression
  1721.     jc    cmderr
  1722.     lded    rwoffset
  1723.     dad    d
  1724.     push    h
  1725.     call    rdsymname
  1726.     jc    cmderr
  1727.     pop    d
  1728.     call    defsymbol
  1729.     jr    evalsym10
  1730. ;
  1731. ;
  1732. ;    symwrite:    write symbols to file
  1733. ;
  1734. symwrite:
  1735.     lda    symfcb+1
  1736.     cpi    ' '
  1737.     jz    cmderr
  1738.     call    eocmd
  1739.     lxi    h,symfcb
  1740.     call    rwinit
  1741.     call    openwr
  1742.     call    wsymbols
  1743.     jmp    closewr
  1744. ;
  1745. ;
  1746.     ENDIF    ; symbolic
  1747. ;
  1748.     ENDIF    ; fileops
  1749. ;
  1750. ;------------------------------------------------------------------------------
  1751. ;
  1752.     dseg
  1753. ;
  1754. initcpm        db    0
  1755. dmaaddr        ds    2
  1756. errmode        ds    1
  1757. ;
  1758. ;
  1759. trapinput    ds    1
  1760. trapchar    ds    1
  1761. macactive    ds    1
  1762. parmp        ds    2
  1763. macparbuf    ds    80
  1764. macpars        ds    20
  1765. ;
  1766. myfcb        ds    36
  1767. rwbuf        ds    128
  1768. rwptr        ds    1
  1769. ;
  1770. symfcb        ds    36
  1771. ;
  1772. pfcbin        ds    2
  1773. pfcbout        ds    2
  1774. ;
  1775. rwoffset    equ    pfcbin
  1776. pesave        equ    pfcbout
  1777. tmphigh        equ    pfcbout
  1778. ;
  1779.     end
  1780.