?login_element?

Subversion Repositories NedoOS

Rev

Rev 634 | Blame | Compare with Previous | Last modification | View Log | Download

  1. ;
  2. ; clinkb.asm:
  3. ;
  4. ; This routine finds, somehow, the name of the next CRL file to search.
  5. ; It also processes any command line options that weren't taken care
  6. ; of back at the start of the link. This routine has grown into a real
  7. ; bitch of kludginess, and I'm sorry about that...but it's so CUTE in
  8. ; the way it does so damned much "on the fly" zipping down the command
  9. ; line. Anyway, once the command line runs out, deff.crl and deff2.crl
  10. ;       (or deff0.crl, deff1.crl, deff2.crl, etc., under MARC)
  11. ; are spit back, and if those have been scanned already then a list of
  12. ; unresolved function references is printed (because this routine wouldn't
  13. ; be CALLED if all the functions had been resolved...) and the user is
  14. ; prompted for another file name, or a special command like abort (control-Q)
  15. ; or search all deff*.crl files again (a carriage-return.)
  16. ;
  17.  
  18. getfn:  lda mflag       ; has command line been fully processed?
  19.         or a
  20.         jp z,gfnzz2     ;if so, go do something else...
  21.  
  22.         lhld cptr       ;no.
  23. gfn0:   ld a,(hl)
  24.         call twhite     ;skip leading white space at the current position
  25.         jp nz,gfna      ;of scanning
  26.         inc hl
  27.         jp gfn0
  28.  
  29. gfna:   or a            ;have we reached the end of the line (so to speak)?
  30.         jp nz,gfnb
  31. gfnzz:  sta mflag       ;yes. set this flag to tell us so next time
  32.  
  33.         lda donef       ;If link has been completed already, and we were
  34.         or a            ;just scanning for more possible command line options,
  35.         ret nz          ;then return right here.
  36.  
  37. gfnzz2: lda dflag       ;if haven't searched DEFF.CRL yet,
  38.         or a
  39.         jp z,gfldf      ;go do it.
  40.  
  41.         IF CPM
  42.         lda d2flag      ;if haven't searched DEFF2.CRL yet,
  43.         or a
  44.         jp z,gfld2f     ;go do it.
  45.  
  46.         lda d3flag      ;if haven't scanned DEFF3.CRL yet,
  47.         or a
  48.         jp z,gfld3f     ;go do it.
  49.         ENDIF
  50.  
  51.         jp gtfnz        ;else go get file name from user.
  52.  
  53. gfnb:   cp '-'          ;is the next thing an option?
  54.         jp nz,gfnc      ;if not, go get filename
  55. gfnb0:  inc hl          ;yes.
  56. gfnb1:  ld a,(hl)               ;put in A and convert to upper case
  57.         call mapuc
  58.         sta opletr      ;save for possible error reports later
  59.  
  60.         cp 'S'          ;print stats?
  61.         jp z,sets
  62.  
  63.         IF MARC
  64.         cp 'M'          ;do maxmem call in c.ccc?
  65.         jp z,setm
  66.         ENDIF
  67.  
  68.         cp 'T'          ;set top of memory?
  69.         jp z,sett
  70.  
  71.         cp 'O'          ;set output filename?
  72.         jp z,seto
  73.  
  74.         cp 'W'          ;write symbol table?
  75.         jp z,setw
  76.  
  77.         cp 'E'          ;set external data starting addr?
  78.         jp z,setext
  79.  
  80.         IF CPM          ;TEMPorRILY UNIMPLEMENETED UNDER MARC
  81.         cp 'Z'          ;inhibit clearing of external data?
  82.         jp z,setz
  83.  
  84.         cp 'Y'          ;read in symbol table file from disk
  85.         jp z,gsyms
  86.  
  87.         cp 'D'          ;debug mode?
  88.         jp z,setd
  89.  
  90.         cp 'N'
  91.         jp z,setn
  92.         ENDIF
  93.  
  94.         cp 'F'          ;switch to scanning of functions (from loading)?
  95.         jp z,setf
  96.  
  97.         call twhite
  98.         jp z,gfn0
  99.         or a
  100.         jp z,gfn0
  101.  
  102.         push af
  103.         ld de,stgbop    ;bad option
  104.         call pstg
  105.         pop af          ;print the option char used
  106.         call outch
  107.         call crlf
  108.         jp abort
  109.  
  110. sets:   sta statf
  111.         jp gfnb0
  112.  
  113.         IF MARC
  114. setm:   push hl         ;insert a "call marc" instruction at mhackl in c.ccc:
  115.         lhld cda        ;get start of code area
  116.         ld de,mhackl    ;get displacement for mhackl in DE
  117.         add hl,de               ;HL --> where "call marc" will go
  118.         ld (hl),0cdh    ;"call" op
  119.         inc hl
  120.         ld (hl),msys&0ffh
  121.         inc hl
  122.         ld (hl),msys/256
  123.        
  124.         lda taddrf      ;if -t option used, don't change taddr
  125.         or a
  126.         jp nz,setm2
  127.  
  128.         lhld curtop     ;make physical top of memory logical top
  129.         shld taddr      ;at run-time
  130.  
  131. setm2:  pop hl          ;restore text pointer
  132.  
  133.         jp gfnb0
  134.         ENDIF
  135.  
  136.  
  137. setw:   sta wflg        ;write symbols out
  138.         jp gfnb0
  139.  
  140.         IF CPM
  141. setz:   sta zflag       ;inhibit clearing external flag
  142.         jp gfnb0
  143.  
  144. setn:   sta nflag       ;activate NOBOOT option
  145.         jp gfnb0
  146.         ENDIF
  147.  
  148. setf:
  149.         IF FORCE
  150.         xor a
  151.         ENDIF
  152.  
  153.         IF NOT FORCE
  154.         ld a,1
  155.         ENDIF
  156.  
  157.         sta fflag
  158.         inc hl
  159.         jp gfn0
  160.  
  161.         IF CPM          ;temp. unimplemented under MARC
  162. setd:   ld a,1          ;for starters, no text list
  163.         sta debugf      ;causes file to be executed
  164.         inc hl          ;pass over the `D'
  165.         call igsp       ;test for arg list text
  166.         cp '"'
  167.         jp nz,gfna      ;if not, all done
  168.         sta debugf      ;set debugf to > 1 to indicate a text list     
  169.         inc hl
  170.         shld argptr     ;and set a pointer to the arg list
  171. setd1:  ld a,(hl)               ;find the trailing quote
  172.         inc hl
  173.         cp '"'
  174.         jp nz,setd1
  175.         jp gfnb1        ;instead of written to disk
  176.         ENDIF
  177.  
  178. sett:   inc hl
  179.         call gtaddd
  180.         ex de,hl
  181.         shld taddr
  182.         ld a,1
  183.         sta taddrf
  184.         ex de,hl
  185.         jp gfn0
  186.  
  187. ;
  188. ; Scan a hex address at text at HL and return
  189. ; with the value in DE, and HL pointing past the text:
  190. ; Complain and abort if no legal value given.  
  191. ;
  192.  
  193. gtaddd: ld de,0
  194. gtad1:  call igsp
  195.         call tsthd
  196.         jp nc,gtad3
  197.         ld de,stgver
  198. stgab:  call pstg
  199.  
  200.         IF CPM
  201.         call crlf
  202.         ENDIF
  203.  
  204.         jp abort
  205.  
  206. gtad2:  ld a,(hl)
  207.         call tsthd
  208.         ret c
  209. gtad3:  call addda
  210.         inc hl
  211.         jp gtad2
  212.  
  213. addda:  push hl
  214.         ex de,hl
  215.         add hl,hl
  216.         add hl,hl
  217.         add hl,hl
  218.         add hl,hl
  219.         ld e,a
  220.         ld d,0
  221.         add hl,de
  222.         ex de,hl
  223.         pop hl
  224.         ret
  225.  
  226. tsthd:  call mapuc
  227.         sub '0'
  228.         ret c
  229.         cp 10
  230.         ccf
  231.         ret nc
  232.         cp 11h
  233.         ret c
  234.         cp 17h
  235.         ccf
  236.         ret c
  237.         sub 7
  238.         ret
  239.  
  240. seto:
  241.         IF MARC
  242.         ld a,1
  243.         sta oflag
  244.         ENDIF
  245.  
  246.         inc hl          ;point HL to filename
  247.         ld de,fcbs      ;this is where the fcb for it will be set up
  248.  
  249.         IF CPM
  250.         lda decl        ;save default crl disk 'cause we're gonna clobber it
  251.         push af
  252.         lda fcbs        ;get default output disk
  253.         sta decl        ;put it here for gfncp2
  254.         ENDIF
  255.  
  256.         call igsp       ;ignore leading space of filename text
  257.         call gfncp2     ;set up fcb
  258.  
  259.         IF CPM
  260.         pop af
  261.         sta decl        ;restore decl
  262.         ENDIF
  263.  
  264.         jp gfn0
  265.  
  266. setext: inc hl
  267.         call gtaddd
  268.         ex de,hl
  269.         shld eaddr
  270.         ld a,1
  271.         sta eflag
  272.         ex de,hl
  273.         jp gfn0
  274.  
  275.         IF CPM
  276. gsyms:  inc hl          ;read in a symbol table file
  277.         call igsp       ;ignore spaces
  278.         push hl         ;assume "sym" extension by default
  279.         ld hl,fcb+9
  280.         ld (hl),'S'
  281.         inc hl
  282.         ld (hl),'Y'
  283.         inc hl
  284.         ld (hl),'M'
  285.         pop hl
  286.  
  287.         call gfncp      ;set up the default FCB w/file name
  288.         xor a
  289.         call open       ;try to open the symbols file for reading
  290.         jp c,gsym2      ;if can't, don't read in symbols
  291.         ld hl,tbuff
  292.         shld buffp      ;init buffer pointer
  293.  
  294.         lhld cdp
  295.         push hl         ;save code pointer
  296. gsymlp: ld a,1          ;set "reading symbol" flag
  297.         sta rdngsm
  298.         call dosym      ;process a symbol
  299.         jp nc,gsymlp    ;until we run out
  300.         pop hl          ;get back
  301.         shld cdp
  302.         xor a           ;clear "reading symbols" flag
  303.         sta rdngsm
  304.  
  305.         call close      ;close symbol file
  306. gsym2:  lhld cptr       ;get back text pointer
  307.         jp gfn0 ;and go process more commands
  308.  
  309.  
  310.  
  311. dosym:  call igsht      ;ignore garbage
  312.         ret c           ;return if EOF
  313.         call tsthd      ;legal value character?
  314.         jp c,serror
  315.         call getval     ;get value in hex from file
  316.  
  317.         push hl         ;this gets added later,
  318.         call getcdf
  319.         call cmh        ;so subtract it now!   
  320.         ex de,hl
  321.         pop hl
  322.  
  323.         add hl,de               ;subtracting...
  324.         shld cdp        ;set up for call to entt1
  325.         call getname    ;get symbol name at sname buffer
  326.         ld hl,sname     ;get pointer to name
  327.         ld de,stgmn     ;is it the "MAIN" entry?
  328.         call stcmp
  329.         ret z           ;if so, don't yank it!
  330.         ld a,1         
  331.         sta gotf        ;this is so that entt1 defines the symbol here
  332.         call entt1
  333.         xor a           ;no error
  334.         ret             ;and done with the symbol
  335.  
  336. serror: ld de,stgserr   ;"illegal symbol in file"
  337.         jp stgab
  338.  
  339. getname: ld hl,sname
  340.         call igsht
  341.         jp c,serror     ;if no legal 1st char of symbol name, error
  342. getn2:  ld (hl),a
  343.         inc hl
  344.         call getcc      ;get next char
  345.         jp c,getn3      ;if EOF, also end-of-symbol!
  346.         call tstsht     ;is it "whitespace" character?
  347.         jp nz,getn2     ;if not, store and get next char
  348. getn3:  dec hl          ;turn on bit 7 of last char
  349.         ld a,(hl)
  350.         or 80h
  351.         ld (hl),a
  352.         ret
  353.  
  354.  
  355. getval: ld hl,0         ;clear sum
  356. getv2:  add hl,hl               ;shift sum left 4 bits
  357.         add hl,hl
  358.         add hl,hl
  359.         add hl,hl
  360.         ld e,a          ;add new hex digit to sum
  361.         ld d,0
  362.         add hl,de
  363.         call getcc      ;any more chars?
  364.         call tsthd
  365.         jp nc,getv2     ;if so, go do them
  366.         ret             ;else done
  367.  
  368.  
  369. igsht:  call getcc      ;get character from file
  370.         call tstsht     ;if no more, return C set
  371.         ret c
  372.         jp z,igsht      ;and ignore junk
  373.         ret
  374.         ENDIF
  375.  
  376. tstsht: call twhite
  377.         ret z
  378.         cp 0dh          ;cr?
  379.         ret z
  380.         cp 0ah          ;lf?
  381.         ret z
  382.         cp 1ah          ;EOF?
  383.         scf
  384.         ret z           ;if so, set C
  385.         ccf             ;else not EOF
  386.         ret             ;else good character
  387.  
  388.         IF CPM
  389. getcc:  push hl         ;save HL
  390.         lhld buffp      ;get buffer pointer
  391.         ld a,l
  392.         and 7fh         ;start of buffer?
  393.         jp nz,getc2
  394.         call reads      ;yes. read in a sector
  395.         ret c           ;return C if EOF
  396. getc2:  ld a,(hl)               ;get char from buffer
  397.         push af ;save character
  398.         inc hl          ;bump pointer
  399.         ld a,l          ;end of sector?
  400.         and 7fh
  401.         jp nz,getc3
  402.         ld hl,tbuff
  403. getc3:  pop af
  404.         shld buffp      ;and save for next time
  405.         pop hl          ;restore HL
  406.         or a            ;clear Carry
  407.         ret
  408.         ENDIF
  409.  
  410. igsp:   ld a,(hl)               ;ignore spaces at text at HL
  411.         call twhite
  412.         ret nz
  413.         inc hl
  414.         jp igsp
  415.  
  416. ;
  417. ; At this point, we have a filename on the command line. It will
  418. ; be interpreted as the name of a CRL file, and scanned for needed
  419. ; functions:
  420. ;
  421.  
  422. gfnc:   call gfncp      ;collect up the name
  423.         jp afterg
  424.  
  425. ;
  426. ; This routine, given a pointer to the ascii text of a CP/M filename,
  427. ; sets up the default fcb with the given name. The disk to stick in the
  428. ; the disk byte by default is loaded from decl, but that is overridable
  429. ; if an explicit disk designator is given.
  430. ;
  431. ; The filename may also be preceded by a user number code of form "#/",
  432. ; causing a switch to that user area for the duration of the file scan,
  433. ; and then a reversion back to the current user area.
  434. ;
  435.  
  436. gfncp:
  437. ;       IF CPM          ;put a CP/M filename into the default fcb:
  438.         ld de,fcb
  439. gfncp2: push de         ;save pointer to working fcb
  440.         push hl         ;save text pointer
  441.         call gdec       ;user area prefix? If so, starts with number...
  442.         jp c,gfncp4     ;if not, don't assume a user number is there
  443.         ld a,(hl)               ;if we saw a number, check for trailing slash
  444.         cp '/'
  445.         jp nz,gfncp4    ;if no slash, it wasn't a user number
  446.  
  447.         ex (sp),hl              ;pop old text pointer off stack
  448.         pop hl
  449.  
  450.         ;push de                ;save DE
  451.         ;ld e,b         ;set the user number to the given value
  452.         ;ld c,sguser
  453.         ;lda nouser
  454.         ;or a
  455.         ;push hl                ;save pointer to slash in text
  456.         ;IF NOT ALPHA
  457.         ;call z,bdos
  458.         ;ENDIF
  459.         ;pop hl         ;get back text pointer
  460.  
  461.         ;pop de         ;restore DE
  462.         inc hl          ;bump text ptr past the slash
  463.         push hl         ;push back so we can fall through to next section
  464.         xor a           ;disable default disk searching
  465.         sta search
  466.  
  467. gfncp4: pop hl          ;restore text pointer to start of filename
  468. gfncp5: inc hl
  469.         ld a,(hl)               ;is an explicit disk designator given?
  470.         dec hl
  471.         cp ':'
  472.         lda decl
  473.         ld (de),a               ;in case not, set it up with the default disk
  474.         jp nz,gfnc0
  475.         xor a           ;disable default disk searching
  476.         sta search
  477.         ld a,(hl)               ;else get the actual disk letter
  478.         call mapuc      ;in upper case, of course
  479.         sub '@'         ;subtract offset to put into proper range
  480.         inc hl
  481.         inc hl
  482.         ld (de),a               ;save at start of target fcb
  483.         ld a,(hl)               ;space or null follow designator?
  484.         or a
  485.         jp z,gfncp9
  486.         cp ' '
  487.         jp nz,gfnc0     ;if not, go parse filename
  488. gfncp9: pop de          ;else don't, having only modified disk designator.
  489.         ret
  490.        
  491. gfnc0:  inc de
  492. gfnc1:  ld b,8
  493.         call gfnc3      ;load the principle filename
  494.         ld a,(hl)
  495.         or a
  496.         jp z,gfnca      ;end of command line?
  497.         cp ' '          ;if not, was filename terminated by a space?
  498.         jp z,gfnca      ;if so, don't touch the COM extension
  499.         inc hl          ;else either clear the extension (if a lone "." given)
  500.         ld b,3          ;or set up the new exntension.
  501.         call gfnc3
  502. gfnca:  shld cptr       ;save command line pointer
  503.         ex (sp),hl              ;exchage command line pointer with fcb address on stack
  504.         ld de,12        ;clear the extent field of the fcb
  505.         add hl,de
  506.         ld (hl),0
  507.         pop hl          ;get back the command line pointer and return
  508.         ret
  509.  
  510. ;
  511. ; This routine copies up to B ascii letters from text at HL to the fcb
  512. ; filename or extension field at DE, padding with spaces on the right:
  513. ;
  514.  
  515. gfnc3:  ld a,(hl)
  516.         or a
  517.         jp z,padsp
  518.         call twhite
  519.         jp z,padsp
  520.         cp '.'
  521.         jp z,padsp
  522.         call mapuc
  523.         ld (de),a      
  524.         inc de
  525.         inc hl
  526.         dec b
  527.         jp nz,gfnc3
  528. padsp:  ld a,b
  529.         or a
  530.         ret z
  531.         ld a,' '
  532.         ld (de),a
  533.         inc de
  534.         dec b
  535.         jp padsp
  536. ;       ENDIF
  537.  
  538.         IF NOT CPM      ;for MARC, copy the filename to fcbt:
  539.         ld de,fcbt
  540. gfncp2: ld a,(hl)
  541.         or a
  542.         jp z,gfncp3
  543.         call tstsht     ;end of name?
  544.         jp z,gfncp3
  545.         ld (de),a
  546.         inc hl
  547.         inc de
  548.         jp gfncp2      
  549.  
  550. gfncp3: shld cptr
  551.         xor a
  552.         ld (de),a
  553.         ret
  554.         ENDIF
  555.  
  556. afterg: lda donef               ;if all done, we don't need to load the file
  557.         or a
  558.         jp nz,getfn
  559.  
  560.         IF CPM
  561.           call scrl
  562. ;         inc a
  563. ;         sta search            ;search current, then default disk/user area
  564.         ENDIF
  565.  
  566.         IF NOT CPM
  567.           push hl
  568.           ld hl,fcbt
  569.           call scrl
  570.           pop hl
  571.         ENDIF  
  572.  
  573.         ret
  574.  
  575. ;
  576. ; Announce missing functions after all given CRL files have been
  577. ; read in and there are still unresolved function references:
  578. ;
  579.  
  580. gtfnz:  ld de,stgas
  581.         call pstg       ;"missing functions:"
  582.         call list       ;list out function names
  583.  
  584.         IF MARC
  585.         xor a
  586.         sta dlast       ;reset deff?.crl counter whenever going into
  587.         ENDIF           ;interactive mode under MARC
  588.  
  589. getfn2: call crlf
  590.         ld de,stg7      ;ask for input
  591.         call pstg
  592.  
  593. gfl1:   ld hl,tbuff     ;get a line of user input at tbuff
  594.  
  595.         IF CPM          ;under CP/M, use the bdos call to get a line of input
  596.         ld (hl),120
  597.         ex de,hl
  598.         ld c,readbuf
  599.         call bdos       ;get line of input
  600.         call crlf
  601.         ld hl,tbuff+2   ;get length byte
  602.         push hl
  603.         dec hl 
  604.         ld a,(hl)
  605.         inc a
  606.         add l
  607.         ld l,a
  608.         ld (hl),0
  609.         pop de
  610.         ENDIF
  611.  
  612.         IF NOT CPM              ;get a line of input under MARC:
  613.         push hl         ;save pointer to start of text line buffer area
  614. gfl1a:  call inch       ;get a character from console
  615.         ld (hl),a               ;save it
  616.         inc hl          ;bump pointer
  617.         cp newlin       ;newline?
  618.         jp nz,gfl1a
  619.         dec hl
  620.         ld (hl),0               ;if so, change it to a null
  621.         pop de          ;and restore pointer to accumulated line into DE
  622.         ENDIF
  623.  
  624. gfl1b:  ld a,(de)
  625.         inc de
  626.         call twhite
  627.         jp z,gfl1b
  628.  
  629.         IF CPM
  630.         cp 1ah          ;control-Z?
  631.         jp nz,gfl1c     ;if so, abort the linkage
  632.         ENDIF
  633.  
  634.         IF NOT CPM
  635.         jp gfl1c        ;don't bother checking for ^Q under MARC, since
  636.         ENDIF           ;^C's are handled by the OS.
  637.  
  638. abort:
  639.         lhld errbyt
  640.         ld (hl),0ffh
  641.  
  642.         IF NOT ALPHA
  643.         ;ld e,0         ;switch to user 0 to erase submit file under ZSYSTEM
  644.         ;ld c,sguser
  645.         ;lda nouser
  646.         ;or a
  647.         ;jp nz,abort2
  648.  
  649.         ;lda zenvf      ;zsystems?
  650.         ;or a
  651.         ;call nz,bdos   ;if so, change to user 0
  652. abort2:
  653.         ENDIF
  654.  
  655.         ld de,subfile   ;if so, erase submit file on user 0
  656.         ld c,delete
  657.         call bdos
  658.  
  659.         ;lda curusr     ;restore to current user area
  660.         ;ld e,a
  661.         ;ld c,sguser
  662.         ;lda nouser
  663.         ;or a
  664.         ;IF NOT ALPHA
  665.         ;call z,bdos
  666.         ;ENDIF
  667.  
  668.         ld de,stgabt    ;abort message
  669.         call pstg
  670.         jp exit
  671.  
  672.         IF NOT CPM
  673.         lda marcfd      ;any file open?
  674.         or a
  675.         call nz,close   ;if so, close it
  676.         call crlf       ;put out extra CR-LF under MARC
  677.         ld hl,-1
  678.         jp exit
  679.         ENDIF
  680.  
  681. gfl1c:  or a            ;null input line?
  682.         jp nz,gfl2
  683.  
  684.         IF MARC
  685.         xor a           ;if so, cause all deff*.crl files to be searched
  686.         sta dflag       ;under MARC
  687.         ENDIF
  688.  
  689. gfldf:
  690.         IF FORCE
  691.         xor a
  692.         sta fflag       ;turn off forced loading while scanning libraries
  693.         ENDIF
  694.  
  695.         ld hl,deffs     ; search deff.crl (or current deff?.crl under MARC)
  696.  
  697.         IF MARC         ;now--go through all deff?.crl files under MARC
  698.         push hl
  699.         lda dlast       ;has the cycle been started yet?
  700.         or a            ;if so, go on to next iteration
  701.         jp nz,gfldfn
  702.         ld a,'0'        ;else start it up with deff0.crl
  703.         sta dlast
  704.         dec a           ;make it so it gets bumped to '0' and used
  705.  
  706. gfldfn: ld de,10        ;point to variable location
  707.         add hl,de
  708.  
  709.         inc a           ;bump dlast to next value
  710.         cp ':'          ;if up past the digits, turn it into an 'a'
  711.         jp nz,gfldfo
  712.         ld a,'a'
  713.  
  714. gfldfo: sta dlast       ;save for looping
  715.         ld (hl),a               ;and put into filename as next deff?.crl to search
  716.         cp '4'
  717.         jp c,gfldfp
  718.  
  719.         sta quietf      ;be quiet if past deff3.crl
  720.  
  721. gfldfp: pop hl 
  722.  
  723.         ex de,hl
  724.         lhld noffst     ;add either 0 (to search /libC) or 6 (current direct)
  725.         add hl,de
  726.         ENDIF
  727.  
  728.         IF CPM
  729.         ld de,fcb
  730.         ENDIF
  731.  
  732.         IF NOT CPM
  733.         ld de,fcbt
  734.         ENDIF
  735.  
  736.         call ldfn
  737.  
  738.         IF CPM
  739.         call setdu      ;make library user area the current user area
  740.         xor a
  741.         sta d2flag      ;cause deff2.crl and deff3.crl to be re-scanned
  742.         sta d3flag
  743.         sta search      ;don't search anywhere but default
  744.         inc a
  745.         sta dflag       ;and say that deff.crl has now been scanned
  746.         ENDIF
  747.  
  748.         ret
  749.  
  750.  
  751. ;       IF CPM          ;only search DEFF2.CRL and DEFF3.CRL explicitly
  752. gfld2f: ld hl,deff2s    ;under CP/M
  753.         ld de,fcb
  754.         call ldfn
  755.         xor a
  756.         sta search      ;only search default
  757.         inc a
  758.         sta d2flag
  759.         call setdu      ;set library user area to be current
  760.         ret
  761.  
  762. gfld3f: ld hl,deff3s
  763.         ld de,fcb
  764.         call ldfn
  765.         xor a
  766.         sta search      ;only search default
  767.         inc a
  768.         sta quietf      ;don't complain if can't open file
  769.         sta d3flag
  770.         call setdu      ;set library user area to be current
  771.         ret
  772.  
  773. setdu:  ;lda defusr
  774.         ;ld e,a
  775.         ;ld c,sguser
  776.         ;lda nouser
  777.         ;or a
  778.         ;IF NOT ALPHA
  779.         ;call z,bdos
  780.         ;ENDIF
  781.         ret
  782. ;       ENDIF
  783.  
  784. gfl2:   ex de,hl                ;put text address in HL
  785.         dec hl
  786.         call gfncp      ;set up fcb with name of file
  787.  
  788.         IF MARC
  789.         ld hl,fcbt
  790.         ENDIF
  791. ;
  792. ;       IF CPM
  793. ;       ld a,1
  794. ;       sta search      ;search current, then default disk/user area
  795. ;       ENDIF
  796.  
  797.         call scrl
  798.         ret
  799.  
  800. ;
  801. ; List out names of missing functions:
  802. ;
  803.  
  804. list:   ld hl,tab1
  805.         shld fngtt
  806.         ld b,7
  807. lst1:   call fung2
  808.         ret c
  809.  
  810. lst2:   ld a,(hl)
  811.         push af
  812.         and 7fh
  813.  
  814.         IF CPM
  815.         call mapuc
  816.         ENDIF
  817.  
  818.         call outch
  819.         pop af
  820.         or a
  821.         inc hl
  822.         jp p,lst2
  823.         dec b
  824.         jp nz,lst3
  825.         call crlf
  826.         ld b,7
  827. lst3:   ld a,' '
  828.         call outch
  829.         call outch
  830.         jp lst1
  831.  
  832. readc:  lda segf        ;if segment, don't read in C.CCC
  833.         or a
  834.         ret nz
  835.  
  836.         IF CPM
  837.         call savfn      ;else do...if CP/M, save main filename for later use
  838.         ENDIF
  839.  
  840.         ld hl,ccc       ;get name of c.ccc
  841.  
  842.         IF MARC
  843.         ex de,hl
  844.         lhld noffst     ;add either 0 (to search /libC) or 6 (current direct)
  845.         add hl,de
  846.         ENDIF
  847.  
  848.         IF CPM
  849.         ld de,fcb       ;set up fcb under CP/M
  850.         call ldfn
  851.         ENDIF
  852.  
  853.         xor a
  854.         call open       ;open c.ccc for reading
  855.         jp c,abort      ;abort if can't find it
  856.  
  857.         IF CPM          ;read in c.ccc under CP/M
  858.         lhld cda
  859. rdc1:   call reads
  860.         jp c,rdc2
  861.         call cpys
  862.         jp rdc1
  863.         ENDIF
  864.  
  865.         IF NOT CPM
  866.         lda marcfd      ;figure out how big c.ccc really is
  867.         ld c,m$fsize
  868.         call msys
  869.         ex de,hl                ;put length into DE (from HL)
  870.         lhld cda        ;get load address into HL
  871.         call reads      ;under MARC, call read to get entire file in
  872.         ENDIF
  873.  
  874.  
  875.  
  876. rdc2:   lhld cda
  877.         ld a,(hl)               ;test if ZSYSTEMS c.ccc
  878.         cp 0ebh
  879.         jp z,rdc2a
  880.         xor a           ;if not, reset zsysf, else set it
  881. rdc2a:  sta zsysf
  882.  
  883.         ld de,cccsiz
  884.         add hl,de
  885.         ld e,(hl)
  886.         inc hl
  887.         ld d,(hl)      
  888.         lhld cda
  889.         add hl,de
  890.         shld cdp
  891.         call close
  892.        
  893.         IF CPM
  894.         call resfn      ;restore main filename to default fcb under CP/M
  895.         ENDIF
  896.  
  897.         IF TESTING
  898.         call printf
  899.            db 'c.ccc loaded correctly',0
  900.         ENDIF
  901.  
  902.         ret             ;end of readc routine
  903.  
  904.         IF CPM
  905. savfn:  ld hl,fcb
  906.         ld de,fcbt
  907.         jp ldfn
  908.  
  909. resfn:  ld hl,fcbt
  910.         ld de,fcb
  911.         jp ldfn
  912.         ENDIF
  913.  
  914.         IF CPM
  915. ldfn:   ld b,13
  916. ldf1:   ld a,(hl)
  917.         ld (de),a
  918.         inc hl
  919.         inc de
  920.         dec b
  921.         jp nz,ldf1
  922.         ret
  923.         ENDIF
  924.  
  925.         IF NOT CPM
  926. ldfn:   ld a,(hl)
  927.         ld (de),a
  928.         inc hl
  929.         inc de
  930.         or a
  931.         jp nz,ldfn
  932.         ret
  933.         ENDIF
  934.  
  935.  
  936. ;
  937. ; Read a function in to memory from the currently open CRL file:
  938. ;
  939.  
  940. rdfun:  call ckabrt
  941.         lda fcnt        ;bump function count
  942.         inc a
  943.         sta fcnt
  944.         cp 255          ;reached functional limit of clink?
  945.         jp nz,rdf0
  946.         ld de,stgtmf    ;yes. complain and abort.
  947.         jp stgab
  948.                         ;else proceed reading in the function:
  949. rdf0:   lhld enst       ;get starting position of function in the file
  950.         ld b,h
  951.         ld c,l          ;put into BC
  952.         call cmh        ;negate it
  953.         ex de,hl
  954.         lhld enend      ;get ending position (actually start of next one)
  955.         add hl,de               ;subtract starting position to get length
  956.         push hl         ;save length
  957.         ex de,hl                ;put into DE
  958.         lhld cdp        ;and add to current load address
  959.         add hl,de
  960.  
  961. rdf0a:  lda curtop+1    ;to see if it overflows memory
  962.         dec a           ;** possible bug fix ***
  963.         ld l,a
  964.         ld a,h
  965.         cp l
  966.         jp c,rdf1               ;no overflow
  967.                         ;yes.... overflow
  968.  
  969.         IF CPM
  970.         lda ccpok       ;CCP intact?
  971.         or a
  972.         jp nz,rdf00a    ;if so, try making it go away
  973.         ENDIF
  974.  
  975. rdf0b:  ld de,stgom     ;if so, print message and abort
  976.         jp stgab        ;just abort under CP/M
  977.  
  978. rdf00a:
  979.         IF CPM
  980.         push hl         ;save HL
  981.         ld hl,NEDOOSMEMTOP;lhld bdosp   ;get protected memory address
  982.         ld l,0
  983.         shld curtop     ;make it new top of memory
  984.         pop hl          ;restore HL
  985.         xor a
  986.         sta ccpok       ;clear CCP intact flag
  987.         jp rdf0a        ;go try again
  988.         ENDIF
  989.  
  990. rdf1:
  991.         IF CPM
  992.         ld de,fcb       ;OK, function will fit into memory.
  993.         call setdat
  994.         ld a,c
  995.         or 80h
  996.         ld l,a
  997.         ld h,ram/256
  998.         shld tbp
  999.         call reads
  1000.         ENDIF
  1001.  
  1002.         IF NOT CPM
  1003.         lhld enst       ;get starting position of function in CRL file
  1004.         ld b,0          ;absolute seek
  1005.         ld c,m$seek
  1006.         lda marcfd
  1007.         call msys       ;seek to correct position in file
  1008.         jp nz,ferror
  1009.         ENDIF
  1010.  
  1011.         lhld cdp        ;get code pointer
  1012.         ex de,hl                ;put into DE: this is where the data will go
  1013.         pop hl          ;get length of function module
  1014.         push hl
  1015.         add hl,de               ;add to base address
  1016.         shld cdn        ;save this for some other routine to futz with
  1017.  
  1018.         IF CPM
  1019.         pop hl
  1020. rdf2:   call rdbt
  1021.         ld (de),a
  1022.         inc de
  1023.         dec hl
  1024.         ld a,h
  1025.         or l
  1026.         jp nz,rdf2
  1027.         ret
  1028.         ENDIF
  1029.  
  1030.         IF NOT CPM
  1031.         pop de          ;get length of function module
  1032.         lhld cdp        ;get load address for function module
  1033.         call reads      ;read in the module
  1034.         ret
  1035.         ENDIF
  1036.  
  1037.         IF CPM          ;all this kludgery only for CP/M
  1038. rdbt:   push hl
  1039.         lhld tbp
  1040.         ld a,l
  1041.         or a
  1042.         jp z,rdb2
  1043.         ld a,(hl)
  1044.         inc hl
  1045.         shld tbp
  1046.         pop hl
  1047.         ret
  1048.  
  1049. rdb2:   call reads
  1050.         ld hl,tbuff
  1051.         ld a,(hl)
  1052.         inc hl
  1053.         shld tbp
  1054.         pop hl
  1055.         ret
  1056.  
  1057. ;
  1058. ; Routine used under CP/M to set the extent and record fields
  1059. ; of the default fcb to the first sector of the function to be read in:
  1060. ;
  1061. ;bc=
  1062. ;de=fcb
  1063. setdat: ld h,b
  1064.         ld l,c
  1065.         add hl,hl
  1066.         ld a,h
  1067.         and 7fh
  1068.         ld hl,32
  1069.         add hl,de
  1070.         ld (hl),a
  1071.         sta tmpnr
  1072.         ld a,b
  1073.         rlca
  1074.         rlca
  1075.         and 3
  1076.         ;ld hl,12
  1077.         ;add hl,de
  1078.         ;cp (hl)
  1079.         ;ret z
  1080.         ;push af
  1081.         ;push hl
  1082.         ;call close
  1083.         ;pop hl
  1084.         ;pop af
  1085.         ;ld (hl),a
  1086.         ;call open
  1087.         ;jp c,abort
  1088.         lda tmpnr
  1089.         sta fcb+_rrn;32
  1090.         ret
  1091.         ENDIF           ;end of this section of CP/M-only kludgery
  1092.  
  1093. pre:
  1094.         IF TESTING
  1095.         call printf
  1096.           db 'calling rdfun:',0
  1097.         ENDIF
  1098.  
  1099.         call rdfun      ;read in the function
  1100.  
  1101.         IF TESTING
  1102.         call printf
  1103.           db 'returned from rdfun.',0
  1104.         ENDIF
  1105.        
  1106.         lhld cdp
  1107.  
  1108.         push hl         ;find start of code, so on-the-fly
  1109. pre0:   ld a,(hl)               ;reference fixing can be done for
  1110.         inc hl          ;those references to functions
  1111.         or a            ;already processed and in their
  1112.         jp nz,pre0      ;fixed positions.
  1113.         inc hl          ;found end of name list.
  1114.         inc hl          ;now HL -> start of actual func code
  1115.         shld fncodb     ;save function code begin addr
  1116.         pop hl
  1117.        
  1118.         lda fcnt2
  1119.         ld b,a
  1120.         ld c,0
  1121. pre1:   ld a,(hl)
  1122.         or a
  1123.         jp z,pre2
  1124.         push hl
  1125.         inc c
  1126.         ld h,b
  1127.         ld l,c
  1128.         shld refv
  1129.         xor a
  1130.         sta gotf
  1131.         pop hl
  1132.         push hl
  1133.         push bc
  1134.         call entt1
  1135.         pop bc
  1136.         pop hl
  1137.         call pb7hi
  1138.         jp pre1
  1139.  
  1140. pre2:   inc hl
  1141.         ld c,(hl)
  1142.         inc hl
  1143.         ld b,(hl)
  1144.         inc hl
  1145.         ex de,hl
  1146.         lhld cdp
  1147.         push hl
  1148.         push hl
  1149.         call cmh
  1150.         add hl,de
  1151.         ex de,hl
  1152.         pop hl
  1153.         call sqish
  1154.         pop hl
  1155.         add hl,bc
  1156.         push hl
  1157.         ld c,(hl)
  1158.         inc hl
  1159.         ld b,(hl)
  1160.         inc hl
  1161.         push hl
  1162.         call getcdf2
  1163.         shld fadr
  1164.         pop hl
  1165. pre3:   ld a,b
  1166.         or c
  1167.         jp z,pre4
  1168.         ld e,(hl)
  1169.         inc hl
  1170.         ld d,(hl)
  1171.         inc hl
  1172.         push hl
  1173.         lhld cdp
  1174.         add hl,de
  1175.         ld e,(hl)
  1176.         inc hl
  1177.         ld d,(hl)
  1178.         push hl
  1179.         lhld fadr
  1180.         add hl,de
  1181.         ex de,hl
  1182.         pop hl
  1183.         ld (hl),d
  1184.         dec hl
  1185.         ld (hl),e
  1186.         pop hl
  1187.         dec bc
  1188.         jp pre3
  1189.  
  1190. pre4:   pop hl
  1191.         shld cdp
  1192.         ret
  1193.  
  1194. cmh:    push af
  1195.         ld a,h
  1196.         cpl
  1197.         ld h,a
  1198.         ld a,l
  1199.         cpl
  1200.         ld l,a
  1201.         inc hl
  1202.         pop af
  1203.         ret
  1204.  
  1205.  
  1206. sqish:  push bc
  1207.         ld b,h
  1208.         ld c,l
  1209.         add hl,de
  1210.         ex de,hl
  1211.         lhld cdn
  1212. sq2:    ld a,(de)
  1213.         ld (bc),a
  1214.         ld a,d
  1215.         cp h
  1216.         jp nz,sq3
  1217.         ld a,e
  1218.         cp l
  1219.         jp nz,sq3
  1220.         pop bc
  1221.         ret
  1222. sq3:    inc de
  1223.         inc bc
  1224.         jp sq2
  1225.  
  1226.  
  1227. reslv:  ld hl,tab1
  1228.         ld d,0
  1229. rlv2:   ld a,(hl)
  1230.         or a
  1231.         ret z
  1232.         inc hl
  1233.         jp p,rlv2
  1234.         ld a,(hl)
  1235.         and 7fh
  1236.         ld b,a
  1237.         inc hl
  1238.         ld c,(hl)
  1239.         inc hl
  1240.         push hl
  1241.         push de
  1242.         ld l,d
  1243.         ld h,0
  1244.         add hl,hl
  1245.         ld de,tab2
  1246.         add hl,de
  1247.         ld e,(hl)
  1248.         inc hl
  1249.         ld d,(hl)
  1250.         call getcdf
  1251.         add hl,de
  1252.         shld doresv
  1253.         pop de
  1254.         pop hl
  1255.  
  1256. rlv3:   ld a,b
  1257.         or c
  1258.         jp nz,rlv4
  1259.         inc d
  1260.         jp rlv2
  1261.  
  1262. rlv4:   push de
  1263.         push hl
  1264.         inc hl
  1265.         ld l,(hl)
  1266.         ld h,0
  1267.         add hl,hl
  1268.         ld de,tab2
  1269.         add hl,de
  1270.         ld e,(hl)
  1271.         inc hl
  1272.         ld d,(hl)
  1273.         pop hl
  1274.         ld a,(hl)
  1275.         inc hl
  1276.         inc hl
  1277.         call dores
  1278.         pop de
  1279.         dec bc
  1280.         jp rlv3
  1281.  
  1282.  
  1283. dores:  push hl
  1284.         push bc
  1285.         ld c,a
  1286.         ld b,0
  1287.         ld hl,0
  1288.         add hl,bc
  1289.         add hl,bc
  1290.         add hl,bc
  1291.         inc hl
  1292.         add hl,de
  1293.         ex de,hl
  1294.         lhld doresv
  1295.         ex de,hl
  1296.         ld (hl),e
  1297.         inc hl
  1298.         ld (hl),d
  1299.         pop bc
  1300.         pop hl
  1301.         ret
  1302.  
  1303.  
  1304. entt1:  ex de,hl
  1305.         ld hl,tab1
  1306.         ld bc,0
  1307.         xor a
  1308.         sta fcnt2
  1309. et1a:   ld a,(hl)
  1310.         or a
  1311.         jp z,et1c
  1312.         push bc
  1313.         call stcmp
  1314.         pop bc
  1315.         jp z,et1d
  1316.         lda fcnt2
  1317.         inc a
  1318.         sta fcnt2
  1319. et1b:   call past1e
  1320.         inc bc
  1321.         jp et1a
  1322.  
  1323. et1c:   ld a,(de)
  1324.  
  1325.         IF CPM
  1326.         call mapuc2
  1327.         ENDIF
  1328.  
  1329.         ld (hl),a
  1330.         inc de
  1331.         inc hl
  1332.         or a
  1333.         jp p,et1c
  1334.         ld (hl),0
  1335.         inc hl
  1336.         ld (hl),0
  1337.         inc hl
  1338.         ld (hl),0
  1339.         dec hl
  1340.         dec hl
  1341.  
  1342.         xor a           ;allow this symbol entry
  1343.         sta rdngsm
  1344.        
  1345.         push de
  1346.         call ckov2      ;check for table 1 overflow
  1347.         pop de
  1348.  
  1349. et1d:   lda gotf
  1350.         or a
  1351.         ld a,(hl)
  1352.         inc hl          ;has the function just been read in?
  1353.         jp nz,et1e
  1354.         or a            ;no. has it been read in previously?
  1355.         jp p,et1d2
  1356.  
  1357.  
  1358.         lda fcnt2       ;yes. fix reference immediately. first
  1359.         ld l,a          ; compute where referenced function will
  1360.         ld h,0          ; reside at run time...
  1361.         add hl,hl               ;now HL is offset into tab2.
  1362.         ld de,tab2      ;get HL pointing to location of address
  1363.         add hl,de               ; of referenced function.
  1364.         ld a,(hl)               ;and get the address.
  1365.         inc hl
  1366.         ld h,(hl)
  1367.         ld l,a          ;now HL points to the function code in RAM
  1368.         ex de,hl                ;need to add offset to get actual
  1369.         call getcdf     ; load address
  1370.         add hl,de               ;now HL = load address of the referenced func
  1371.         shld doresv     ;save it for use by dores.
  1372.  
  1373.         lhld fncodb     ;now compute location of reference within
  1374.         ex de,hl                ; the new function...DE -> start of code
  1375.         lda refv        ;A tells position # of jump vector
  1376.         jp dores        ;let dores figure out the rest and do
  1377.  
  1378. et1d2:  push de
  1379.         ld e,(hl)
  1380.         dec hl
  1381.         ld d,(hl)
  1382.         inc de
  1383.         ld (hl),d
  1384.         inc hl
  1385.         ld (hl),e
  1386.         pop de
  1387.         inc hl
  1388.         call tb1ex
  1389.  
  1390.         call ckfng
  1391.         ex de,hl
  1392.         lhld refv
  1393.         ex de,hl
  1394.         ld (hl),e
  1395.         inc hl
  1396.         ld (hl),d
  1397.         ret
  1398.  
  1399. et1e:   lda rdngsm      ;has new symbol been previously defined?
  1400.         or a
  1401.         jp z,et1e2
  1402.  
  1403.         dec hl          ;perhaps. test if table entry is defined...
  1404.         ld a,(hl)
  1405.         or a
  1406.         inc hl
  1407.         jp p,et1e2      ;if bit 7 was set on that byte, it was defined...
  1408.                         ; so was it?
  1409.         ld de,stgdps    ;yes...complain
  1410.         ld hl,sname
  1411.         lda fflag       ;forcing all functions from a crl file?
  1412.         or a
  1413.         jp z,et1e0
  1414.  
  1415.         ld a,81h        ;set this so function doesn't get loaded later
  1416.         sta gotf
  1417.         ld de,stgdpf    ;if so, use special message for duplicate entry
  1418.         lhld savnam     ;get pointer to function name
  1419.        
  1420.         IF FORCE
  1421.         push hl
  1422.         ld a,(hl)
  1423.         cp 'M'
  1424.         jp nz,et1e00
  1425.         inc hl
  1426.         ld a,(hl)
  1427.         cp 'A'
  1428.         jp nz,et1e00
  1429.         inc hl
  1430.         ld a,(hl)
  1431.         cp 'I'
  1432.         jp nz,et1e00
  1433.         inc hl
  1434.         ld a,(hl)
  1435.         cp 'N'+80h
  1436.         jp nz,et1e00
  1437.         pop hl
  1438.         ret
  1439.  
  1440. et1e00: pop hl
  1441.         ENDIF
  1442.  
  1443. et1e0:  call pstg
  1444. et1e1:  call pfnm
  1445.         call crlf       ;follow with CR-LF combo
  1446.         ret             ;and ignore the symbol name this time...
  1447.  
  1448.  
  1449. et1e2:  dec hl
  1450.         ld a,(hl)
  1451.         or 80h
  1452.         ld (hl),a
  1453.         ld hl,tab2
  1454.         add hl,bc
  1455.         add hl,bc
  1456.         ex de,hl
  1457.         lhld cdp
  1458.         ex de,hl
  1459.         ld (hl),e
  1460.         inc hl
  1461.         ld (hl),d
  1462.         ret
  1463.  
  1464. ckfng:  push de
  1465.         push hl
  1466.         ex de,hl
  1467.         lhld fngtt
  1468.         ld a,h
  1469.         sub d
  1470.         jp c,ckfd
  1471.         jp nz,ckfng1
  1472.         ld a,l
  1473.         sub e
  1474.         jp c,ckfd
  1475. ckfng1: inc hl
  1476.         inc hl
  1477.         shld fngtt
  1478. ckfd:   pop hl
  1479.         pop de
  1480.         ret
  1481.  
  1482. ;
  1483. ; Expand tab1 from the current position of HL by 2 bytes:
  1484. ;
  1485.  
  1486. tb1ex:  push hl
  1487.         push bc
  1488.  
  1489.         push hl
  1490.         lhld tb1end
  1491.         ld b,h
  1492.         ld c,l
  1493.         dec bc
  1494.         dec bc
  1495.         pop hl
  1496.  
  1497.         call cmh
  1498.         add hl,bc
  1499.         inc hl
  1500.         push bc
  1501.         ld b,h          ;set BC to the count
  1502.         ld c,l
  1503.  
  1504.         lhld tb1end
  1505.         ex de,hl
  1506.         pop hl          ;HL is source addr
  1507.  
  1508.         ld a,2          ;if on 8080, do it the hard way
  1509.         inc a
  1510.         jp po,z80exp
  1511.  
  1512. ex8080: ld a,(hl)
  1513.         ld (de),a
  1514.         dec hl
  1515.         dec de
  1516.         dec bc
  1517.         ld a,b
  1518.         or c
  1519.         jp nz,ex8080
  1520.         jp ckov
  1521.  
  1522. z80exp: db 0edh,0b8h    ;LDDR on Z80.
  1523.  
  1524. ckov:   lhld tb1end     ;check last byte of tab1 (initialized to zero)
  1525.         ld de,-10
  1526.         add hl,de
  1527.         ld a,(hl)
  1528.         or a            ;if still zero, ok
  1529.         jp z,ckovok
  1530.         ld de,stgt1o    ;else overflow
  1531.         jp stgab
  1532.  
  1533. ckov2:  push hl
  1534.         push bc
  1535.         jp ckov
  1536.        
  1537. ckovok: pop bc
  1538.         pop hl
  1539.         ret
  1540.  
  1541. ;
  1542. ; Test the strings at DE (b7 high on last char) and
  1543. ; at HL for equality:
  1544. ;
  1545.  
  1546. stcmp:  push bc
  1547.         push de
  1548.         push hl
  1549. stcm1:  ld a,(hl)
  1550.  
  1551.         IF CPM
  1552.         call mapuc2
  1553.         ENDIF
  1554.  
  1555.         ld b,a
  1556.         ld a,(de)
  1557.  
  1558.         IF CPM
  1559.         call mapuc2
  1560.         ENDIF
  1561.  
  1562.         cp b
  1563.         jp nz,stcm3
  1564.         or a
  1565.         jp m,stcm2
  1566.         inc de
  1567.         inc hl
  1568.         jp stcm1
  1569. stcm2:  pop de
  1570.         pop de
  1571.         pop bc
  1572.         xor a
  1573.         inc hl
  1574.         ret
  1575. stcm3:  pop hl
  1576.         pop de
  1577.         pop bc
  1578.         ret
  1579.  
  1580. ;
  1581. ; Map character in A to upper case, preserving
  1582. ; the parity bit:
  1583. ;
  1584.  
  1585. mapuc2: push bc
  1586.         or a
  1587.         push af
  1588.         and 7fh
  1589.         call mapuc
  1590.         ld b,a
  1591.         pop af
  1592.         ld a,b
  1593.         pop bc
  1594.         ret p
  1595.         or 80h
  1596.         ret
  1597.  
  1598. ;
  1599. ; Test routine for debugging MARC version under CP/M:
  1600. ;
  1601.         IF TESTING2
  1602. test:   ld hl,argvtt    ;test argv
  1603.         push hl
  1604.         ld hl,2         ;test argc
  1605.         push hl
  1606.         ld hl,0         ;dummy return address
  1607.         push hl
  1608.         jp  tpa
  1609.  
  1610. argvtt: dw argv0
  1611.         dw argv1
  1612.         dw argv2
  1613.  
  1614. argv0:  db 'clink',0
  1615. argv1:  db 't',0
  1616. argv2:  db '-s',0
  1617.         ENDIF
  1618.  
  1619.         IF TESTING OR TESTING3
  1620. printf: ex (sp),hl              ;save HL on stack, get string pointer into HL
  1621.         push de         ;save DE
  1622.         ex de,hl                ;put string pointer into DE
  1623.         call pstg       ; print the string
  1624.         ex de,hl                ;put return address from DE into HL
  1625.         push hl
  1626.         call crlf       ; and follow with cr-lf
  1627.         pop hl          ;get back return address
  1628.         pop de          ; restore DE
  1629.         ex (sp),hl              ;put return address back on stack, get back HL 
  1630.         ret            
  1631.         ENDIF           ;end of test sequence
  1632.  
  1633.  
  1634. ;
  1635. ; Return Z true if char is space or tab:
  1636. ;
  1637.  
  1638. twhite: cp ' '
  1639.         ret z
  1640.         cp tab
  1641.         ret
  1642.  
  1643. wsp:    equ getfn
  1644.  
  1645. ascb:   ds 4    ;ascii buffer used for hex-to-decimal conversion
  1646.         db 0
  1647.  
  1648. curtop: ds 2    ;pointer to top of user memory
  1649.  
  1650. zsysf:  ds 2    ;z systems flag
  1651.  
  1652. donef:  ds 1    ;tells if all linked up yet
  1653. decl:   ds 1    ;disk from which to get deff and deff2
  1654. cdp:    ds 2    ;points to next free space in code
  1655. cdn:    ds 2
  1656. enst:   ds 2    ;used to pass disk addr of function to "rdfun"
  1657. enend:  ds 2    ;used to pass last disk addr of function + 1 to "rdfun"
  1658. smsf:   ds 2    ;external data block size
  1659. quietf: ds 1    ;true if we don't want to complain if can't open file
  1660.  
  1661.  
  1662. fcnt:   ds 1    ;function count...holds current function number
  1663. fcnt2:  ds 1
  1664. gotf:   ds 1    ;set true when calling "entt1" w/ just-loaded function
  1665. statf:  ds 1    ;true if -s option given
  1666. wflg:   ds 1    ;true if -w option given
  1667. segf:   ds 1    ;true if segment being linked
  1668. zflag:  ds 1    ;true if -z option given
  1669. tmpnr:  ds 1    ;workspace used by "setdat" routine
  1670. fngtt:  ds 2
  1671. refv:   ds 2
  1672. fadr:   ds 2
  1673. bufp:   ds 2
  1674. buffp:  ds 2    ;used by gsyms routine as buffer pointer
  1675.  
  1676. cline:  ds 140  ;elongated for v1.32
  1677. sname:  ds 15
  1678. cptr:   ds 2
  1679. mflag:  ds 1
  1680. dflag:  ds 1    ;true if we've scanned DEFF.CRL under CP/M, or if we've
  1681.                 ;scanned all deff?.crl files under MARC
  1682.  
  1683. taddr:  ds 2    ;address of top of memory available to running program
  1684. taddrf: ds 1
  1685. eflag:  ds 1    ;if external address supplied
  1686. eaddr:  ds 2    ;if eflag true: extern. addr.
  1687. extadd: ds 2    ; final external address.
  1688. wrsmf:  ds 1    ;true if writing symbols to disk during outch calls
  1689. rdngsm: ds 1    ;true if reading a symbol from a file
  1690. nsmbs:  ds 2
  1691. tbase:  ds 2
  1692. fflag:  ds 1    ;true when loading all functions; else scanning for needed ones
  1693. runsat: ds 2    ;load address
  1694. savcdp: ds 2    ;save cdp here while reading in symbols
  1695. debugf: ds 1    ;true if running file instead of writing to disk
  1696. argptr: ds 2    ;points to arg list text if used with -d option
  1697. fncodb: ds 2    ;used in new mod to do reference fixing on the fly
  1698. doresv: ds 2
  1699. fargb:  ds 2
  1700. savnam: ds 2    ;used to save function name pointers for error printout
  1701. tb1siz: ds 2
  1702. cda:    ds 2
  1703. tb1end: ds 2
  1704. tab2:   ds 512
  1705. direc:  ds 512
  1706.  
  1707.         IF CPM
  1708. d2flag: ds 1    ;true if we've scanned DEFF2.CRL
  1709. d3flag: ds 1    ;true if we've scanned DEFF3.CRL
  1710. hflag:  ds 1    ;true if Leo want's lhld 4206 instead of 0006
  1711. tbp:    ds 2
  1712. ccpok:  ds 1
  1713. spsav:  ds 2
  1714. nflag:  ds 1    ;true if "-n" for noboot given
  1715. curusr: ds 1    ;current user area number
  1716. savdrv: ds 1    ;saved drive number when temporrily gone elsewhere
  1717. search: ds 1    ;true to search current drive/user area for file, then default
  1718.         ENDIF
  1719.  
  1720.         IF MARC
  1721. argc:   ds 1
  1722. argv:   ds 2
  1723. marcfd: ds 1
  1724. maxmd:  ds 1    ;true if maxmem call done yet
  1725. iflag:  ds 1    ;true if image mode output file wanted; else load format file
  1726. btsav:  ds 1    ;scratch used by writld routine
  1727. endtst: ds 1
  1728. datap:  ds 2
  1729. runsav: ds 2
  1730. oflag:  ds 1    ;true if -o given
  1731. noffst: ds 2    ;either 0 or 6, depending on whether -c option used
  1732. fcbs:   ds 40
  1733. fcbt:   ds 40
  1734. consfd: ds 1    ;1 if console output going to stdout, or 2 for stderr
  1735. dlast:  ds 1    ;last deff?.crl file searched ('1', '2', ...), or 0 if none
  1736.         ENDIF
  1737.  
  1738.         ds 75
  1739. stack:  equ $
  1740.  
  1741. tab1:   equ $           ;reference table begins here
  1742.  
  1743.         ;IF LASM
  1744.         ;end
  1745.         ;ENDIF
  1746.