?login_element?

Subversion Repositories NedoOS

Rev

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

  1. ;
  2. ;
  3. ; cc2a.asm
  4. ;
  5. ; 7/18/82: Added Kirkland debugging feature: if kflg (110h) is non-zero,
  6. ;          we assume it is the proper restart value to be inserted
  7. ;          at the start of each expression that is the first on a line,
  8. ;          to be followed by the line number.
  9. ;
  10. ; 12/30/85: Added new "modstk" module numbering/naming mechandsm as
  11. ;       previously implemented in CC.
  12. ;
  13.  
  14.  
  15.  
  16.         jp cc2          ;jump around data passed from call c,during autoload:
  17.  
  18.         IF CPM
  19. chainf: db 0            ;true if cc2 being auto-loaded by cc1 (103h)
  20.         ENDIF
  21.  
  22.         IF NOT CPM
  23. chainf: db 1            ;always being auto-loaded if under MARC
  24.         ENDIF
  25.  
  26. optimf: db 1            ;true if value-fetch hack is OK to perform (104h)
  27. cccadr: dw ram+100h     ;address of base of run-time package    (105h)
  28. exaddr: ds 2            ;explicit external address, (if eflag is true) (107h)
  29. eflag:  db 0            ;default to no explicit external address (109h)
  30.  
  31.         IF MARC
  32. fnam:   ds 2            ;pointer to filename for use in writing out crl file
  33.         ENDIF
  34.  
  35.         IF CPM
  36. ;spsav: ds 2            ;saved CCP stack pointer under CP/M (10Ah)
  37.         ds 2 ;NU (constant addresses!!!)
  38.         ENDIF
  39.  
  40. curtop: ds 2            ;current top of memory (10Ch)
  41.  
  42.         IF MARC
  43. maxmd:  db 0            ;maxmem done flag, under MARC
  44.         ENDIF
  45.  
  46.         IF CPM
  47. ccpok:  db 1            ;CCP still intact flag, under CP/M (10Eh)
  48.         ENDIF
  49.  
  50.         IF CPM
  51. erasub: db 0            ;bit 0: true if erasing submit files on error (10Fh)
  52.                         ;bit 1: "werrs" true if writing RED file
  53.         ENDIF
  54.  
  55.         IF NOT CPM
  56.         ds 1            ;dummy byte under MARC
  57.         ENDIF
  58.  
  59. cdbflg: db 0            ;CDB flag (-k<n> option to CC1) (110h)
  60.  
  61.         IF CPM
  62. defsub: db 0            ;where to find submit files (CP/M only) (111h)
  63. conpol: db 1            ;whether or not to poll console for interrupts (112h)
  64. errbyt: dw errdum       ;ZCPR3 error condition flag address (dummy default)
  65.         ENDIF
  66.  
  67.  
  68.         IF NOT CPM
  69.         ds 4
  70.         ENDIF
  71.  
  72. oktort: db 0            ;extracted from ccpok b1 on startup
  73. wboote: db 1            ;extracted from ccpok b2 on startup
  74. zenvf:  db 0            ;extracted from ccpok b3 on startup
  75.  
  76. errdum: ds 1            ;dummy zcpr3 error flag
  77.  
  78.  
  79. cc2:    ;ld hl,0                ;save current SP in HL
  80.         ;add hl,sp
  81.         ld sp,0;stack   ;set up new stack
  82.         call initstdio
  83.  
  84.         IF CPM
  85.         lda defsub
  86.         inc a
  87.         sta subfile
  88.         ENDIF
  89.  
  90.         lda chainf     
  91.         or a
  92.         jp z,cc2a               ;if not chaining, go initialize stuff
  93.  
  94.                         ; UNPACK ccpok:
  95.  
  96.         lda ccpok       ;extract oktort from ccpok
  97.         ld b,a
  98.         and 1           ;b0
  99.         sta ccpok       ;set ccpok flag
  100.  
  101.         ld a,b
  102.         and 2           ;b1
  103.         rrca
  104.         sta oktort      ;set ok to return to ccp flag
  105.  
  106.         ld a,b
  107.         and 4           ;b2
  108.         rrca
  109.         rrca
  110.         sta wboote      ;set do warm boot on exit flag
  111.  
  112.         ld a,b
  113.         and 8           ;b3
  114.         rrca
  115.         rrca
  116.         rrca
  117.         sta zenvf       ;set ZCPR3 flag
  118.  
  119.         or a            ;Z environment?
  120.         jp nz,cc20a     ;if not, go do greeting
  121.  
  122.         ld hl,errdum    ;else set errbyt address to dummy
  123.         shld errbyt
  124.  
  125. cc20a:  ld de,s00       ;print CR-LF if being chained to from cc1
  126.         call pstgco     ;if chaining, print CR-LF before sign-on message
  127.         jp cc2b
  128.  
  129. cc2a:   ;shld spsav     ;save CCP stack pointer
  130.         ld hl,NEDOOSMEMTOP;lhld ram+6
  131.         shld curtop     ;set up current top of memory below CCP
  132.         ld a,1
  133.         sta ccpok       ;set CCP not bashed flag
  134.        
  135. cc2b:   lhld errbyt
  136.         ld (hl),0               ;no error by default
  137.  
  138.         ld de,s0        ;regular sign-on msg
  139.         call pstgco
  140.  
  141.         call c2init     ;do rest of initialization
  142.  
  143. cc2c:   call dofun      ;process a function
  144.         lhld cdp
  145.         call igshzz     ;lde pointer to next function
  146.         shld cdp        ;and save text pointer
  147.         ld a,(hl)               ;get 1st char of next function
  148.         ld hl,entn      ;bump entry count (function count)
  149.         inc (hl)
  150.         or a
  151.         jp nz,cc2c      ;are we at EOF?
  152.  
  153.         lhld codp       ;yes.
  154.         dec hl
  155.         shld eofad      ;set this for the "writf" routine
  156.  
  157.         call errwrp     ;wrap up error handling, exit if there were errors
  158.  
  159.         ld hl,ascb+4    ;else do write out a CRL file...
  160.         ld (hl),'K'     ;but first give a usage report
  161.  
  162.         IF CPM
  163.         ld hl,NEDOOSMEMTOP;lhld bdosp   ;this is as high as free memory can ever get
  164.         ld l,0
  165.         ENDIF
  166.  
  167.         ex de,hl
  168.         lhld codp       ;and this is as high as we got generating code
  169.         call cmh
  170.         add hl,de
  171.         ld a,h          ;divide difference by 1K
  172.         rra
  173.         rra
  174.         and 3fh
  175.         ld l,a          ;and print out result
  176.         ld h,0
  177.         dec hl
  178.         xor a
  179.         call prhcs      ;print out their difference
  180.         ld de,stgtsp    ;with some text
  181.         call pstg       ;and...
  182.  
  183.         call writf      ;write out the CRL file
  184.  
  185.         IF CPM
  186. exit:   QUIT ;lda wboote        ;do warm boot on exit?
  187.         ;or a
  188.         ;jp nz,ram              ;if so, go boot
  189.  
  190.         ;lda chainf     ;did we chain?
  191.         ;or a
  192.         ;jp z,ram               ;if not, do warm boot in case we're SID-ing
  193.  
  194.         ;lhld spsav     ;get possibly saved CCP SP
  195.         ;ld sp,hl
  196.  
  197.         ;lda ccpok      ;CCP intact?
  198.         ;or a
  199.         ;ret nz         ;return if so
  200.  
  201.         ;lda oktort     ;ok to return DESPITE ccpok's value?
  202.         ;or a
  203.         ;ret nz         ;if so, return
  204.  
  205.         ;jp ram         ;else warm-boot
  206.        
  207.         ENDIF
  208.  
  209.  
  210. ;
  211. ; Some standard routine addresses within C.CCC, all relative
  212. ; to the origin of C.Ccall c,(stored at cccadr at run time)
  213. ; These values will change anytime C.Ccall c,is reconfigured.
  214. ;
  215.  
  216. ldei:   equ 04dh        ;value-fetch routines
  217. sdei:   equ 05ch
  218. lsei:   equ 06bh
  219. ssei:   equ 077h
  220. ldli:   equ 083h
  221. sdli:   equ 090h
  222.  
  223.  
  224. pzinh:  equ 09dh                ;flag conversion routines
  225. pnzinh: equ pzinh+6
  226. pcinh:  equ pzinh+12
  227. pncinh: equ pzinh+18
  228. ppinh:  equ pzinh+24
  229. pminh:  equ pzinh+30
  230. pzind:  equ pzinh+36
  231. pnzind: equ pzinh+42
  232. pcind:  equ pzinh+48
  233. pncind: equ pzinh+54
  234. ppind:  equ pzinh+60
  235. pmind:  equ pzinh+66
  236.  
  237. eqwel:  equ 0e5h        ;relational operator routines
  238.  
  239. blau:   equ 0ebh
  240. albu:   equ blau+1
  241.  
  242. bgau:   equ 0f2h
  243. agbu:   equ bgau+1
  244.  
  245. blas:   equ 0f9h
  246. albs:   equ blas+1
  247.  
  248. bgas:   equ 104h
  249. agbs:   equ bgas+1
  250.  
  251.  
  252. smod:   equ 10fh
  253. usmod:  equ 129h
  254. smul:   equ 13fh        ;multaplicative operator routines
  255. usmul:  equ 16bh
  256. usdiv:  equ 189h
  257. sdiv:   equ 1cbh
  258.  
  259.  
  260. sderbl: equ 1e4h        ;shift operator routines
  261. shlrbe: equ sderbl+1
  262. sdelbl: equ 1f2h
  263. shllbe: equ sdelbl+1
  264.  
  265.  
  266. cmhl:   equ 1fah        ;2's complement routines
  267. cmd:    equ 202h
  268.  
  269.  
  270.  
  271. ;
  272. ; Keyword codes
  273. ;
  274.  
  275. gotcd:  equ 8dh         ;goto
  276. rencd:  equ 8eh         ;return
  277. sizcd:  equ 8fh         ;sizeof
  278. brkcd:  equ 90h         ;break
  279. cntcd:  equ 91h         ;continue
  280. ifcd:   equ 92h         ;if
  281. elscd:  equ 93h         ;else
  282. docd:   equ 95h         ;do
  283. whlcd:  equ 96h         ;while
  284. swtcd:  equ 97h         ;switch
  285. lbrcd:  equ 9bh         ;{
  286. rbrcd:  equ 9ch         ;}
  287. mainc:  equ 9dh         ;main
  288. pplus:  equ 0b2h        ;++
  289. mmin:   equ 0b3h        ;--
  290. arrow:  equ 0b4h        ;->
  291. mincd:  equ 0b5h        ;-
  292. mulcd:  equ 0b6h        ;*
  293. divcd:  equ 0b7h        ;/
  294. ancd:   equ 0bbh        ;&
  295. letcd:  equ 0beh        ;=
  296. notcd:  equ 0bfh        ;!
  297. open:   equ 0c2h        ;(
  298. close:  equ 0c3h        ;)
  299. plus:   equ 0c4h        ;+
  300. period: equ 0c5h        ;.
  301. semi:   equ 0c6h        ;";"
  302. comma:  equ 0c7h        ;,
  303. openb:  equ 0c8h        ;[
  304. closb:  equ 0c9h        ;]
  305. colon:  equ 0cah        ;:
  306. circum: equ 0cbh        ;~
  307. qmark:  equ 0c0h        ;?
  308. slcd:   equ 0b0h        ;<<
  309. srcd:   equ 0b1h        ;>>
  310. lecd:   equ 0aeh        ;<=
  311. gecd:   equ 0afh        ;>=
  312. eqcd:   equ 0aah        ;==
  313. neqcd:  equ 0abh        ; <excl.pt.>=
  314. modcd:  equ 0b8h        ;%
  315. gtcd:   equ 0b9h        ;>
  316. ltcd:   equ 0bah        ;<
  317. xorcd:  equ 0bch        ;^
  318. orcd:   equ 0bdh        ;|
  319. andand: equ 0ach        ;&&
  320. oror:   equ 0adh        ;||
  321.  
  322.  
  323. ;
  324. ; Text strings:
  325. ;
  326.  
  327. s1:     db 'Can''t open file+'
  328. s2:     db cr,lf,'Write error+'
  329. s2a:    db 'CRL Dir overflow: break up source file+'
  330. s3:     db 'Missing label+'
  331. s4:     db 'Missing semicolon+'
  332. s4a:    db 'Extra text after statement, before ";"+'
  333. stgms:  equ s4  ;a more mnemonic name for this error msg
  334. s5:     db 'Illegal statement+'
  335. s6:     db 'Can''t create CRL file+'
  336. stg7:   db 'Bad operator+'
  337. stg8:   db 'Lvalue required+'
  338. stg8a:  db '++ or -- operator needs Lvalue+'
  339. stg8b:  db 'Bad left operand in assignment expr.+'
  340. stg9:   db 'Mismatched parens+'
  341. stg9a:  db 'Mismatched brackets+'
  342. stg10:  db 'Bad expression+'
  343. stg11:  db 'Bad function name+'
  344. stg13:  db 'Bad arg to unary op+'
  345. stg14:  db 'Expecting ":"+'
  346. stg15:  db 'Bad subscript+'
  347. stg16:  db 'Bad array base+'
  348. stg17:  db 'Bad struct or union spec+'
  349. stg17a: db 'Using undefined struct type+'
  350. stg18:  db 'Bad type in binary operation+'
  351. stg19:  db 'Bad struct or union member+'
  352. stg20:  db 'Bad member name+'
  353. stg21:  db 'Illegal indirection+'
  354. stgie:  db 'Internal error: garbage in file or bug in C+'
  355. stgom:  db 'Sorry, out of memory. Break it up!+'
  356. stgeof: db 'Encountered EOF unexpectedly+'
  357. stgbf:  db 'Bad parameter list+'
  358. stgeri: db cr,lf,'RED error output initiated+'
  359.  
  360.         IF CPM
  361. stgabo: db 'Compilation aborted by ^C+'
  362.         ENDIF
  363.  
  364.         IF NOT CPM
  365. stgabo: db 'Compilation aborted+'
  366.         ENDIF
  367.  
  368. stgbbo: db 'Expecting binary op+'
  369. stgeop: db 'Missing "("+'
  370. stgecp: db 'Missing ")"+'
  371.  
  372. stgtsp: db 'to spare',cr,lf;cr
  373.         IF MARC
  374.            db lf
  375.         ENDIF
  376.         db 0
  377.  
  378. stgftb: db 'The function ',0
  379. stgtb2: db ' is too complex; break it into smaller ones+'
  380. stgmlb: db 'Missing "{" in function def''n+'
  381. stgcsn: db 'Control Structure '
  382. stgetc: db 'Nesting too deep+'
  383.  
  384.         IF CPM
  385. subfile: db 1,'$$$     SUB',0,0,0,0
  386.         ENDIF
  387.  
  388. s00:    db cr,lf,0
  389.  
  390. patch:  dw 0,0,0,0,0,0,0,0,0,0ffffh     ;patch space
  391. patch2: dw 0,0,0,0,0,0,0,0ffffh
  392. patch3: dw 0,0,0,0,0,0,0ffffh
  393.  
  394.  
  395. ;
  396. ; Special codes
  397. ;
  398.  
  399. nlcd:   equ 0f7h        ;new-line (linefeed)
  400. concd:  equ 0f8h        ;constant code (followed by 2 byte value)
  401. varcd:  equ 0f9h        ;variable code (foll. by 2 byte disp into s.t.)
  402. lblcd:  equ 0fah        ;label code (foll. by 2-byte label val)
  403. labrc:  equ 0fch        ;label reference (foll. by 2-byte label code value)
  404. strcd:  equ 0fdh        ;string code (foll. by 2-byte sting #)
  405. swtbc:  equ 0feh        ;byte following `switch(expr)', preceding case table
  406.  
  407. litrl:  equ 0f7h
  408. endms:  equ 38h
  409.  
  410. modbeg: equ 0f5h
  411. modend: equ 0f6h
  412.  
  413.  
  414.  
  415. minit:  lda optimf      ;look at rst7 bit of optimization flag
  416.         and 40h
  417.         ret z           ;if not set, don't fudge with macro table
  418.         ld hl,m16bz
  419.         shld mactz
  420.         shld mactz+2
  421.         ld hl,m18z
  422.         shld mactz+4
  423.         shld mactz+6
  424.         ret
  425.  
  426.  
  427. ;
  428. ; Come here on an internal error (if ierror is called instead
  429. ; of jumped to, that makes it easier to find out where the
  430. ; internal error occurred)
  431. ;
  432.  
  433. ierror: ld de,stgie     ;come here when things are REALLY skewered
  434.  
  435. ;
  436. ; Print out error and abort compilation:
  437. ;
  438.  
  439. perrab: call perr
  440.  
  441.  
  442. ;
  443. ; The general abort entry point...abort submit processing
  444. ; and reboot.
  445. ;
  446.  
  447. errab:  push hl
  448.         lhld errbyt
  449.         ld (hl),1               ;set zcpr3 error flag (or dummy under CP/M)
  450.         pop hl
  451.        
  452.         lda werrs
  453.         or a
  454.         call nz,errwr2
  455.  
  456. errab2:
  457.         ld a,7          ;ring a bell for errors having occurred
  458.         call outch
  459.         lda erasub      ;bother to erase submit files?
  460.         or a
  461.         jp z,exit               ;if not, all done
  462.  
  463.         ;ld c,sguser    ;get current user
  464.         ;ld e,0ffh
  465.  
  466.         ;push af        ;save current user
  467.  
  468.         ;ld c,sguser    ;select user 0
  469.         ;ld e,0
  470.         ;lda zenvf      ;but only under ZSYSTMS!
  471.         ;or a
  472.         ;call nz,bdos
  473.  
  474.         ld de,subfile   ;erase pending submit files
  475.         call delf2
  476.  
  477.         ;pop af         ;get original user
  478.         ;ld e,a
  479.         ;ld c,sguser    ;select original user
  480.         ;call bdos
  481.  
  482.         jp exit ;all done
  483.  
  484.  
  485. ;
  486. ; Routine that expects a semicolon to be the next non-space
  487. ; character in the text. If it isn't, spew an error. If it
  488. ; is, pass over it:
  489. ;
  490.  
  491. psemi:  call igsht
  492.         cp semi
  493.         jp nz,psmi2
  494.         inc hl
  495.         ret
  496.  
  497. psmi2:  push hl
  498.         lhld nlcnt      ;get current line number
  499.         ex (sp),hl              ;put in on stack, get text ptr in HL
  500.         call fsemi      ;advance to semicolon
  501.         ex (sp),hl              ;push text ptr onto stack, get old line no. in HL
  502.         ex de,hl                ;put old line no. in DE
  503.         lhld nlcnt      ;get current line no.
  504.         call cmpdh     
  505.         pop hl          ;get back current text ptr
  506.         ld de,s4
  507.         jp nz,psmi3     ;if no semicolon on current line, complain about
  508.                         ; missing semicolon
  509.         ld de,s4a       ;else complain about superfluous characters    
  510. psmi3:  call perr
  511.         inc hl          ;advance text ptr past semicolon
  512.         ret
  513.  
  514.  
  515. ;
  516. ; Routine to skip everything until a semicolon is found (used
  517. ; mainly in error-recovery following the detection of a really
  518. ; screwy, non-cleanly-recoverable error):
  519. ;
  520.  
  521. fsemi:  ld a,(hl)
  522.         or a
  523.         jp z,igshe1     ;if EOF, bad error
  524.         cp semi
  525.         ret z
  526.  
  527.         ld de,s5
  528.         cp lbrcd
  529.         jp z,perrab
  530.         cp rbrcd
  531.         jp z,perrab
  532.  
  533.         cp nlcd
  534.         jp nz,fsemi3
  535.         push hl
  536.         lhld nlcnt
  537.         inc hl
  538.         shld nlcnt
  539.         pop hl
  540. fsemi3: call cdtst
  541.         jp c,fsemi5
  542.         inc hl
  543.         inc hl
  544. fsemi4: inc hl
  545.         jp fsemi
  546.  
  547. fsemi5: cp modbeg
  548.         jp nz,fsemi4
  549.         push de
  550.         ld de,13
  551.         add hl,de
  552.         pop de
  553.         jp fsemi
  554.  
  555.  
  556. ;
  557. ; Given HL->text, pass by any special codes and white space:
  558. ;
  559.  
  560. pascd:  call igsht
  561.         call cdtst
  562.         ret c
  563.         inc hl
  564.         inc hl
  565.         inc hl
  566.         jp pascd
  567.  
  568. igcd:   equ pascd
  569.  
  570. pascd2: call igshzz
  571.         or a
  572.         ret z
  573.         call cdtst
  574.         jp nc,pscd3
  575.         or a
  576.         ret
  577. pscd3:  inc hl
  578.         inc hl
  579.         inc hl
  580.         or a
  581.         jp pascd2
  582.  
  583. cdtst:  cp 0f8h
  584.         ret c
  585.         cp 0feh
  586.         ccf
  587.         ret
  588.  
  589. ;
  590. ; Ignore white space in text (but acknowledge newlines
  591. ;  by bumping line count when they're encountered), and handle
  592. ; modbeg/modend:
  593. ;
  594.  
  595. igsht:  call igshzz
  596.         or a
  597.         ret nz
  598.         lda prnflg      ;file ends inside parens or brackets?
  599.         or a
  600.         jp z,igshe1
  601.  
  602.         ld de,stg9      ;yes...if prnflag is 1, then use parens message
  603.         dec a
  604.         jp z,igsht0    
  605.         ld de,stg9a     ;else use brackets message
  606.  
  607. igsht0: lhld prnsav
  608.         shld nlcnt
  609.         jp perrab
  610.  
  611. igshe1: ld de,stgeof
  612. igshe2: jp perrab
  613.  
  614. igshzz: ld a,(hl)
  615.         or a
  616.         ret z
  617.         cp nlcd
  618.         jp nz,igsh2
  619.         push hl         ;bump newline count
  620.         lhld nlcnt
  621.         inc hl
  622.         shld nlcnt
  623.         pop hl
  624.         inc hl
  625.         jp igshzz
  626.  
  627. igsh2:  cp lblcd
  628.         jp nz,igsh3
  629.         push de
  630.         inc hl
  631.         ld e,(hl)
  632.         inc hl
  633.         ld d,(hl)
  634.         inc hl
  635.         call entl
  636.         pop de
  637.         jp igshzz
  638.  
  639. igsh3:  cp ' '
  640.         jp nz,igsh4
  641. igsh3a: inc hl
  642.         jp igshzz
  643.  
  644. igsh4:  cp modbeg       ;module begin?
  645.         jp nz,igsh5
  646.         inc hl
  647.         call pushmn     ;push module name on module stack
  648.         jp igshzz
  649.  
  650. igsh5:  cp modend       ;module end?
  651.         ret nz
  652.         call popmn      ;pop module name
  653.         jp igsh3a
  654.  
  655. ;
  656. ; Push module name at HL onto modstk, save current line number
  657. ; after it in the module stack, bump modstc, and reset nlcnt:
  658. ;
  659.  
  660. pushmn: ex de,hl        ;put text ptr in DE
  661.         push hl ;save HL
  662.         ld hl,modstc
  663.         inc (hl)
  664.         lhld modstp
  665.         ld b,12
  666.         call ldrc
  667.         push de
  668.         ex de,hl
  669.         lhld nlcnt
  670.         ex de,hl
  671.         ld (hl),e
  672.         inc hl
  673.         ld (hl),d
  674.         inc hl
  675.         shld modstp
  676.         ld hl,0
  677.         shld nlcnt
  678.         pop de
  679.         pop hl
  680.         ex de,hl
  681.         ret
  682.                
  683. ;
  684. ; Pop modstk entry:
  685. ;
  686.  
  687. popmn:  push hl
  688.         push de
  689.         lhld modstp
  690.         dec hl
  691.         ld d,(hl)
  692.         dec hl
  693.         ld e,(hl)
  694.         ex de,hl
  695.         shld nlcnt
  696.         ld hl,-12
  697.         add hl,de
  698.         shld modstp
  699.         ld hl,modstc
  700.         dec (hl)
  701.         pop de
  702.         pop hl
  703.         ret
  704.  
  705. ;
  706. ; lde B bytes from (DE) to (HL):
  707. ;
  708.  
  709. ldrc:   push af
  710. ldrc1:  ld a,(de)
  711.         ld (hl),a
  712.         inc hl
  713.         inc de
  714.         dec b
  715.         jp nz,ldrc1
  716.         pop af
  717.         ret            
  718.  
  719.  
  720. ;
  721. ; Peek forward to next token, without actually processing any
  722. ; codes or changing status of the text pointer from the current value:
  723. ;
  724.  
  725. peeknxt:
  726.         push hl         ;save text pointer
  727.         push de
  728.         dec hl
  729. peekn1: inc hl          ;look at next char
  730. peekn2: ld a,(hl)               ;if null, done
  731.         or a
  732.         jp z,peekn4
  733.         cp nlcd ;ignore all whitespace and codes
  734.         jp z,peekn1
  735.         call cdtst
  736.         jp c,peekn3
  737.         inc hl
  738.         inc hl
  739.         jp peekn1
  740. peekn3: cp ' '
  741.         jp z,peekn1
  742.         cp modend
  743.         jp z,peekn1
  744.         cp modbeg
  745.         jp nz,peekn4
  746.         ld de,13
  747.         add hl,de
  748.         jp peekn2      
  749. peekn4: pop de
  750.         pop hl
  751.         ret
  752.  
  753.  
  754. ;
  755. ; Given that HL->open paren in text, find the matching
  756. ; close paren and pass by it (if no matching paren is ever
  757. ; found, announce an error ocurring on original line where
  758. ; the open paren was found):
  759. ;
  760.  
  761. mtchp:  ld a,1
  762.         sta prnflg
  763.         push hl
  764.         lhld nlcnt
  765.         shld prnsav
  766.         pop hl
  767.         call mtchpz
  768.         push af
  769.         xor a
  770.         sta prnflg
  771.         pop af
  772.         ret
  773.  
  774. mtchpz: inc hl
  775.         call igcd
  776.         cp close
  777.         jp nz,mtcp2
  778.         inc hl
  779.         ret
  780.  
  781. mtcp2:  cp open
  782.         jp nz,mtchpz
  783.         call mtchpz
  784.         dec hl
  785.         jp mtchpz
  786.  
  787. ;
  788. ; Similar to mtchp, except for square brackets instead:
  789. ;
  790.  
  791. mtchb:  ld a,2
  792.         sta prnflg
  793.         push hl
  794.         lhld nlcnt
  795.         shld prnsav
  796.         pop hl
  797.         call mtchbz
  798.         push af
  799.         xor a
  800.         sta prnflg
  801.         pop af
  802.         ret
  803.  
  804.  
  805. mtchbz: inc hl
  806.         call igcd
  807.         cp closb
  808.         jp nz,mtcbz2
  809.         inc hl
  810.         ret
  811.  
  812. mtcbz2: cp openb
  813.         jp nz,mtchbz
  814.         call mtchbz
  815.         dec hl
  816.         jp mtchbz
  817.  
  818. ;
  819. ; Convert ASCII character in A to upper case,
  820. ; but don't change value of parity bit!
  821. ;
  822.  
  823. mapuc:  push bc
  824.         ld b,a
  825.         and 7fh
  826.         call mapuc2
  827.         ld c,a
  828.         ld a,b
  829.         and 80h
  830.         or c            ;OR in original parity bit
  831.         pop bc
  832.         ret
  833.  
  834. mapuc2: cp 61h
  835.         ret c
  836.         cp 7bh
  837.         ret nc
  838.         sub 32
  839.         ret
  840.  
  841. ;
  842. ; Return Cy set if (DE < HL)
  843. ;
  844.  
  845.  
  846. cmpdh:  ld a,d
  847.         cp h
  848.         ret nz
  849.         ld a,e
  850.         cp l
  851.         ret
  852.  
  853.  
  854. ;
  855. ; Print error message, but use the line number saved at "savnlc" instead
  856. ; of the standard "nlcnt" count:
  857. ;
  858.  
  859. perrsv: push    hl              ;save current text pointer
  860.         lhld    nlcnt           ;save current line count
  861.         push    hl
  862.         lhld    savnlc          ;get saved line count
  863.         shld    nlcnt           ;make it current just for this
  864.         call    perr
  865.         pop     hl              ;now restore everything
  866.         shld    nlcnt
  867.         pop     hl
  868.         ret                     ;and return
  869.  
  870.  
  871. ;
  872. ; Report error by first printing out the current line number followed
  873. ; by a colon and a space, and then printing out the string pointed to
  874. ; by DE on entry:
  875. ;
  876.  
  877. perr:   ld a,1
  878.         sta errf
  879.         lda prerrs      ;print error msgs?
  880.         or a
  881.         ret z           ;return if not
  882.         push hl
  883.         call pmodnc     ;print module name, colon, space
  884.         lhld nlcnt
  885.         call prhcs
  886.         call pstg
  887.         pop hl
  888.         ret
  889.  
  890.  
  891. ;
  892. ; Print out current module name, followed by a colon and space
  893. ;
  894.  
  895. pmodnc: call pmodnm
  896.         push af
  897.         ld a,':'
  898.         call outch
  899.         ld a,' '
  900.         call outch
  901.         pop af
  902.         ret
  903.  
  904. ;
  905. ; Print out current module name:
  906. ;
  907.  
  908. pmodnm: push hl
  909.         push de
  910.         lhld modstp
  911.         ld de,-14
  912.         add hl,de
  913.         ex de,hl
  914.         call pfnam2
  915.         pop de
  916.         pop hl
  917.         ret
  918.  
  919.  
  920. ;
  921. ; Print out filename of fcb at DE:
  922. ;
  923.  
  924.  
  925. pfnam2: push bc
  926.         ld a,(de)               ;get disk code
  927.         or a
  928.         jp z,pfnm3      ;if file on currently logged disk, don't print
  929.                         ;disk designator.
  930.  
  931. ;       ld c,gdisk      ;This section of code commented out to keep
  932. ;       push de         ;files on the currently logged drive from having
  933. ;       call bdos       ;a disk designator printed before their names.
  934. ;       pop de          ;uncomment the code to put this feature back
  935. ;       inc a           ;into action.
  936.  
  937. pfnm2:  add a,'@'               ;get A = 'A' for drive A, 'B' for B, etc.
  938.         call outch
  939.         ld a,':'
  940.         call outch
  941. pfnm3:  inc de
  942.         ld b,8
  943.         call pnseg
  944.         ld a,(de)
  945.         cp ' '
  946.         ld a,'.'        ;print dot only if filename has extension
  947.         call nz,outch
  948.         ld b,3
  949.         call pnseg
  950.         pop bc
  951.         ret
  952.  
  953. pnseg:  ld a,(de)
  954.         cp ' '
  955.         call nz,outch
  956.         inc de
  957.         dec b
  958.         jp nz,pnseg
  959.         ret
  960.  
  961.  
  962. ;
  963. ; Print out the null-terminated string pointed to by DE:
  964. ;
  965.  
  966. pstg:   ld a,(de)
  967.         or a
  968.         ret z
  969.         cp '+'
  970.         jp nz,pstg2
  971.         ld a,cr
  972.         call outch
  973.         ld a,lf
  974.         jp outch
  975.  
  976. pstg2:  call outch
  977.         inc de
  978.         jp pstg
  979.  
  980.  
  981. ;
  982. ; Output a string to console only:
  983. ;
  984.  
  985. pstgco: lda werrs
  986.         push af
  987.         xor a
  988.         sta werrs
  989.         call pstg
  990.         pop af
  991.         sta werrs
  992.         ret
  993.  
  994. ;
  995. ; Output a character of text to the console and/or PROGERRS.$$$ file:
  996. ;
  997.  
  998. outch:  push de
  999.         push bc
  1000.         push hl
  1001.         push af
  1002.  
  1003.         ld e,a          ;lde char to be output to E register
  1004.  
  1005.         lda werrs
  1006.         or a            ;if not writing errs to PROGERRS file,
  1007.         jp z,outch3     ;       go write to console
  1008.        
  1009.         lda errsin
  1010.         or a
  1011.         jp nz,outch1    ;if RED buffer initialized, go handle I/O
  1012.                         ;else initialize RED buffer:
  1013.         inc a
  1014.         sta errsin
  1015.  
  1016.         push de
  1017.         ld de,redfcb
  1018.         lda fcb
  1019.         ld (de),a
  1020.         call delf2      ;delete previous PROGERRS.$$$
  1021.         call create2    ;create new one
  1022. ;       call fopen2     ;open for output
  1023.         ld hl,redbuf
  1024.         shld redbp      ;initialize redbuf sector pointer
  1025.  
  1026.         ld de,stgeri    ;"RED error output initiated"
  1027.         call pstgco     ;print text to console only
  1028.         pop de
  1029.  
  1030. outch1: call redout     ;write char to red output file
  1031.  
  1032. outch3: ;ld c,conout
  1033.         ;call bdos
  1034.         ld a,e
  1035.         PRCHAR_
  1036.  
  1037.         pop af
  1038.         pop hl
  1039.         pop bc
  1040.         pop de
  1041.         ret
  1042.  
  1043. ; Write a character to RED output buffer, flushing if needed:
  1044.  
  1045. redout: lhld redbp      ;get redbuf pointer
  1046.         ld (hl),e               ;store char
  1047.         inc hl          ;bump pointer
  1048.         shld redbp      ;save pointer
  1049.         ld a,l          ;past end of buffer?
  1050.         cp (redbuf+128) and 0ffh
  1051.         ret nz          ;if not, return
  1052.  
  1053.  
  1054.  
  1055. redwrt: push de
  1056.         ld de,redbuf    ;set DMA address to redbuf for sector write
  1057.         ld c,sdma
  1058.         call bdos
  1059.  
  1060.         ld de,redfcb
  1061.         call writs2     ;write sector
  1062.  
  1063.         ld de,tbuff     ;set DMA address back for normal file i/o
  1064.         ld c,sdma
  1065.         call bdos
  1066.  
  1067.         ld hl,redbuf
  1068.         shld redbp     
  1069.         pop de
  1070.         ret
  1071.                
  1072.  
  1073. ; Wrap up error handling, exit if there were errors:
  1074.  
  1075. errwrp: call errwr1
  1076.         xor a
  1077.         sta werrs
  1078.         ret
  1079.  
  1080. errwr1: lda errf        ;were there any errors?
  1081.         or a
  1082.         ret z           ;return if no errors
  1083.  
  1084.         lda werrs       ;RED output enabled?
  1085.         or a
  1086.         jp z,errab2     ;if not, we're all done.
  1087.  
  1088. errwr2: lda errsin
  1089.         or a
  1090.         ld hl,stgie     ;if errf true but RED buf not initialized,
  1091.         call z,perrab   ; some kind of internal error
  1092.         ld e,1ah        ;ascii end-of-file
  1093.         call redout
  1094.         lhld redbp
  1095.         ld a,l
  1096.         cp redbuf and 0ffh      ;has buffer just been flushed?
  1097.         call nz,redwrt  ;if not, write buffer one last time
  1098.         ld de,redfcb
  1099.         call fclose2    ;close RED output buffer
  1100.         jp errab2
  1101.  
  1102.  
  1103. ;
  1104. ; Print a newline to the console:
  1105. ;
  1106.  
  1107. crlf:   push af
  1108.         ld a,cr
  1109.         call outch
  1110.         ld a,lf
  1111.         call outch
  1112.         pop af
  1113.         ret
  1114.  
  1115.  
  1116. ;
  1117. ; Print out the value in HL in hex, followed by a colon
  1118. ; and a space.
  1119. ; Upon entry, A non-0: print no leading spaces
  1120. ;              A == 0: print leading spaces making total textual output 4 chars
  1121. ;
  1122. ;
  1123.  
  1124. prhcs:  push hl
  1125.         push de
  1126.         push af
  1127.         call prh        ;convert HL to ascii at ascb
  1128.         pop af
  1129.         or a
  1130.         ld hl,ascb
  1131.         jp z,prhcs3     ;if printing leading spaces, go do it
  1132.  
  1133.         dec hl
  1134. prhcs1: inc hl
  1135.         ld a,(hl)
  1136.         cp ' '
  1137.         jp z,prhcs1     ;if all four digits, no leading spaces needed
  1138.  
  1139. prhcs3: ex de,hl                ;put text ptr in DE
  1140.         call pstg
  1141.         pop de
  1142.         pop hl
  1143.         ret
  1144.  
  1145.  
  1146. ;
  1147. ; Convert Hex value in HL to ASCII, at ASCB, followed by a colon
  1148. ; and a space. A kludgey gas-pump algorithm is used, since
  1149. ; no big numbers are ever printed (only line numbers):
  1150. ;
  1151.  
  1152.  
  1153. prh:    push de
  1154.         call prh00
  1155.         pop de
  1156.         ret
  1157.  
  1158. prh00:  push hl
  1159.         ld hl,'  '
  1160.         shld ascb
  1161.         ld hl,' 0'
  1162.         shld ascb+2
  1163.         pop hl
  1164.         inc hl
  1165. prh0:   ld a,h
  1166.         or l
  1167.         ret z
  1168.         dec hl
  1169.         push hl
  1170.         ld hl,ascb+3
  1171. prh1:   ld a,(hl)
  1172.         cp ' '
  1173.         jp nz,prh2
  1174.         ld a,'0'
  1175. prh2:   inc a
  1176.         cp '9'+1
  1177.         jp z,prh4
  1178. prh3:   ld (hl),a
  1179.         pop hl
  1180.         jp prh0
  1181. prh4:   ld (hl),'0'
  1182.         dec hl
  1183.         jp prh1
  1184.  
  1185.  
  1186. fopen:
  1187.         IF CPM
  1188.         ld de,fcb
  1189.  
  1190. fopen2: push de
  1191.         ld c,openfil
  1192.         call bdos
  1193.         cp 255
  1194.         pop de
  1195.         jp z,op2
  1196.         push hl ;clear nr field
  1197.         ld hl,32
  1198.         add hl,de
  1199.         ld (hl),0
  1200.         pop hl
  1201.         ret
  1202.         ENDIF
  1203.  
  1204.         IF NOT CPM
  1205.         ld c,m$open
  1206.         call msys
  1207.         sta marcfd
  1208.         ret z
  1209.         jp ferrab
  1210.         ENDIF
  1211.  
  1212. op2:    ld de,s1
  1213.         call pstg
  1214.         jp errab
  1215.  
  1216. fclose: ld de,fcb
  1217.  
  1218.         IF CPM
  1219. fclose2:
  1220.         push hl
  1221.         ld c,closefil
  1222.         call bdos
  1223.         ENDIF
  1224.  
  1225.         IF NOT CPM
  1226.         ld c,m$close
  1227.         lda marcfd
  1228.         call msys
  1229.         jp nz,ferrab
  1230.         ENDIF
  1231.  
  1232.         pop hl
  1233.         ret
  1234.  
  1235. writs:
  1236.         ld de,fcb
  1237.  
  1238.         IF CPM          ;write a sector under CP/M
  1239. writs2: push hl
  1240.         ld c,wsequen
  1241.         call bdos
  1242.         pop hl
  1243.         or a
  1244.         ret z
  1245.         ENDIF
  1246.  
  1247.         IF NOT CPM
  1248.         ld c,m$write
  1249.         lda marcfd
  1250.         call msys
  1251.         ret z
  1252.         jp ferrab
  1253.         ENDIF
  1254.  
  1255.         ld de,s2
  1256.         call pstg
  1257.         jp errab
  1258.  
  1259.  
  1260. reads:  push hl
  1261.        
  1262.         IF CPM
  1263.         ld de,fcb
  1264.         ld c,rsequen
  1265.         call bdos
  1266.         pop hl
  1267.         or a
  1268.         ret z
  1269.         scf
  1270.         ret
  1271.         ENDIF
  1272.  
  1273.         IF NOT CPM
  1274.         lda marcfd
  1275.         ld c,m$read
  1276.         ld hl,tbuff
  1277.         ld de,128
  1278.         call msys
  1279.         jp nz,ferrab
  1280.         pop hl
  1281.         ld a,e          ;end of file?
  1282.         or a
  1283.         ret nz          ;if not, return with Carry not set
  1284.         scf             ;else set Carry
  1285.         ret             ;and return
  1286.         ENDIF
  1287.  
  1288.  
  1289.                
  1290. delfil:
  1291.         IF CPM
  1292.         ld de,fcb
  1293. delf2:
  1294.         push de
  1295.         push hl
  1296.         ld hl,12
  1297.         add hl,de
  1298.         ld (hl),0
  1299.         ld c,delete
  1300.         call bdos
  1301.         pop hl
  1302.         pop de
  1303.         ret
  1304.         ENDIF
  1305.  
  1306.  
  1307. create: ld de,fcb
  1308. create2:
  1309.         push hl
  1310.         push de
  1311.         ld hl,12
  1312.         add hl,de
  1313.         ld (hl),0
  1314.         ld c,makfil
  1315.         call bdos
  1316.         pop de
  1317.  
  1318.         ld hl,32
  1319.         add hl,de
  1320.         ld (hl),0
  1321.         pop hl
  1322.  
  1323.         cp 255
  1324.         ret nz
  1325.  
  1326.         ld de,s6
  1327.         call pstg
  1328.         jp errab
  1329.  
  1330. ;
  1331. ; Write out the CRL file to disk:
  1332. ;
  1333.  
  1334. writf:  ld hl,fcb+9     ;make the extension "CRL"
  1335.         ld (hl),'C'
  1336.         inc hl
  1337.         ld (hl),'R'
  1338.         inc hl
  1339.         ld (hl),'L'
  1340.         call delfil     ;delete old versions
  1341.         call create     ;create new output file
  1342.  
  1343. ;       call fopen      ;open it under CP/M; under MARC, already open...
  1344.  
  1345.         lhld codp
  1346.         ex de,hl
  1347.         lhld cdao
  1348.         add hl,de
  1349.         ex de,hl
  1350.         lhld dirp
  1351.         ld (hl),80h
  1352.         inc hl
  1353.         ld (hl),e
  1354.         inc hl
  1355.         ld (hl),d
  1356.         ld hl,direc     ;write out CRL directory
  1357.  
  1358.         IF CPM
  1359.         call copys      ;(copy and write 4 sectors under CP/M)
  1360.         call writs
  1361.         call copys
  1362.         call writs
  1363.         call copys
  1364.         call writs
  1365.         call copys
  1366.         call writs
  1367.         ENDIF
  1368.  
  1369.         IF NOT CPM
  1370.         ld de,512       ;just write it all out under MARC (yey)
  1371.         call writs
  1372.         ENDIF
  1373.  
  1374.         lhld start      ;now write out the code
  1375.  
  1376.         IF CPM
  1377. writ2:  call copys
  1378.         push af
  1379.         call writs
  1380.         pop af
  1381.         jp nc,writ2
  1382.         call fclose
  1383.         ld hl,fcb+10
  1384.         ld (hl),'C'     ;delete the CCI file, if it exists
  1385.         inc hl
  1386.         ld (hl),'I'
  1387.         ENDIF
  1388.  
  1389.  
  1390.         IF NOT CPM
  1391.         call cmh
  1392.         ex de,hl
  1393.         lhld eofad
  1394.         add hl,de
  1395.         inc hl          ;HL is length of file to write out
  1396.         ex de,hl
  1397.         lhld start
  1398.         call writs      ;write out the CRL file in one shot (yey for MARC)
  1399.         call fclose
  1400.         ENDIF
  1401.  
  1402.         lda chainf
  1403.         or a            ;only attempt to delete if not chained
  1404.         call z,delfil   ;       to from CC1.
  1405.         ret
  1406.  
  1407. ;
  1408. ; Copy 128 bytes from mem at HL to tbuff:
  1409. ;       (Return C set on EOF)
  1410. ;
  1411.  
  1412.         IF CPM          ;only need this under CP/M
  1413. copys:  ld de,tbuff
  1414.         ld b,80h
  1415. copy1:  ld a,(hl)
  1416.         ld (de),a
  1417.         push de
  1418.         ex de,hl
  1419.         lhld eofad
  1420.         ld a,h
  1421.         cp d
  1422.         jp nz,copy2
  1423.         ld a,l
  1424.         cp e
  1425.         jp z,copy5
  1426. copy2:  ex de,hl
  1427.         pop de
  1428.         inc hl
  1429.         inc de
  1430.         dec b
  1431.         jp nz,copy1
  1432.         xor a
  1433.         ret
  1434.  
  1435. copy5:  pop de
  1436. copy5a: dec b
  1437.         jp z,copy7
  1438.         inc de
  1439.         ld a,1ah
  1440.         ld (de),a
  1441.         jp copy5a
  1442.  
  1443. copy7:  scf
  1444.         ret
  1445.         ENDIF
  1446.  
  1447.         IF MARC ;put this here so if the name overshoots, it'll
  1448. endnmp: ds 2            ;temporaries used in file renaming routine
  1449. dotflg: ds 1
  1450. nambuf: ds 40   ;just write into something we don't need...
  1451.         ENDIF
  1452.  
  1453. ;
  1454. ; This routine sees if anything has been typed at the console,
  1455. ; and if so, if it is a ^C then the compilation is aborted:
  1456. ;TODO
  1457.  
  1458. ckabrt: push hl
  1459.         push de
  1460.         push bc
  1461.         push af
  1462.        
  1463.         ;IF CPM
  1464.         ;lda conpol     ;if not polling console, don't so it.
  1465.         ;or a
  1466.         ;jp z,noabrt
  1467.         ;ld c,intcon
  1468.         ;call bdos
  1469.         ;or a
  1470.         ;jp z,noabrt
  1471.         ;ld c,coninp
  1472.         ;call bdos
  1473.         ;cp 3
  1474.         ;jp nz,noabrt
  1475.  
  1476.         ;ld de,stgabo
  1477.         ;call pstg
  1478.         ;jp errab      
  1479.         ;ENDIF
  1480.  
  1481.         IF NOT CPM
  1482.         ;ld c,m$ichec
  1483.         ;call msys
  1484.         ENDIF
  1485.  
  1486. noabrt: pop af
  1487.         pop bc
  1488.         pop de
  1489.         pop hl
  1490.         ret
  1491.  
  1492.         ;IF LASM
  1493.         ;link cc2b
  1494.         ;ENDIF
  1495.