Subversion Repositories NedoOS

Rev

Rev 630 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1. ;
  2. ; CC1: the first pass of the C compiler...
  3. ; MARC-generalized  version
  4. ;
  5. ; 7/17/82: added -w to write debugger info file and insert restarts
  6. ; 7/18/82: changed -w to -k<n>  (for Kirkland), taking n as the restart
  7. ;          vector to use (1-7), defaults to 6.
  8. ; 8/22/82: Fixed mvtxt to not overflow stack in recursion
  9. ; 9/9/82:  Added search path mechandsm to cc2.com auto-load, made FF def.
  10. ;          disk and user use "current" as default
  11. ; 10/6/82: added auto-".c" on main file feature
  12. ; 11/85:   Added -z option to use RST 1 - RST 5 for value-fetch optimization
  13. ; 12/85:   Added RED logic to write out PROGERRS.$$$ error file
  14. ;
  15. ;
  16.  
  17.         IF NOT LASM AND NOT SLRMAC
  18.         maclib cc
  19.         ENDIF
  20.  
  21.         jp cc1         
  22.  
  23.         db cr,lf
  24.         db 'Copyright (c) 1982, 83, 84 by Leor Zolman'
  25.         db cr,lf,lf
  26.         db 'Please don''t rip me off.'
  27.         db cr,lf,lf,1ah
  28. patch0: db 0,0,0,0,0,0,0,0              ;space to expand message
  29.  
  30.         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  31.         ;       Configuration block area:
  32.         ;
  33.  
  34. defdsk: db 0ffh         ;default library disk drive
  35. defusr: db 0ffh         ;default library user area
  36.  
  37. defsub: db 00h          ;default disk to find submit file on
  38. conpol: db 1            ;true to poll the console for interrupts
  39. wboote: db 0            ;true to always do warm-boot on exit
  40. ;zenvf: ds 1            ;true if Z environment
  41. ;                       ;new for v1.51:
  42. pstrip: db 1            ;true to strip parity when reading source file
  43.  
  44.         IF ALPHA
  45. nouser: db 1            ;true to disable all user-area operations performed
  46.         ENDIF           ; by CC, for special kinds of systems that like it
  47.  
  48.         IF NOT ALPHA
  49. nouser: db 0            ;false to allow user area changes
  50.         ENDIF
  51.  
  52. werrs:  db 0            ;write errors flag, for RED interface
  53.  
  54. optim:  db 80h          ;0: optimize for speed, use all long code sequences
  55.                         ;b7 true: optimize for space, in general
  56.                         ;b0-b6 true: use RST1-RST7 (respectively)
  57.                         ; for -Z optimization through restart vectors
  58.  
  59. krst:   db 6            ;default CDB restart vector
  60.  
  61. zenvf:  ds 1            ;true if Z environment
  62.  
  63.         ;
  64.         ; End Configuration Block
  65.         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  66.  
  67. patch:  dw 0,0,0,0,0,0,0,0      ;patch space
  68. patch2: dw 0,0,0,0,0,0,0,0
  69. patch3: dw 0,0,0,0,0,0,0
  70.  
  71.         ;
  72.         ;       Beginning of compiler code:
  73.         ;
  74.  
  75. cc1:
  76.         OS_HIDEFROMPARENT
  77.         ld e,6 ;textmode
  78.         OS_SETGFX
  79.        
  80.         ;shld zenvad ;TODO remove       ;save Z environment pointer
  81.         ;ld hl,0                ;save current SP for possible use in returning to CCP
  82.         ;add hl,sp
  83.         ;shld spsav
  84.         ;ld sp,stack    ;set up private stack
  85.  
  86.         call ccinit     ;perform general initializations
  87.  
  88.         IF CPM AND NOT ALPHA
  89.         call chkusr     ;check for user number on main filename
  90.         ENDIF
  91.  
  92.         call comlin     ;process command line options
  93.         call readf      ;read in file(s), strip comments
  94.         call prep       ;process #define lines
  95.         call pitext     ;print out intermediate text if specified
  96.         call pass1      ;convert keywords,constants,strings
  97.         call lblpr      ;process labels and references
  98.         call passx      ;proccess constant expressions
  99.         call bst        ;build symbol table
  100.         call passc      ;process control structure
  101.         call fixt       ;purge FF's and stuff from text
  102.         call mkfnt      ;make function name table
  103.         call wst4db     ;write symbol table for debugger
  104.         call chopst     ;chop off 1st 8 bytes of st entries
  105.         call mvfnt      ;lde func name table adj to text
  106.         call errwrp     ;wrap up error handling
  107.         call usage      ;print out memory usage diagnostic
  108.         call writf      ;write out file
  109.  
  110.         jp exit ;all done
  111.  
  112.  
  113. ;
  114. ; Static data area:
  115. ;
  116.  
  117.         IF CPM
  118. ;spsav: ds 2    ;save stack pointer for non-booting return
  119. ccpok:  ds 1    ;true if CCP still intact
  120. erasub: ds 1    ;true if erasing submit files
  121. curusr: ds 1            ;current disk (CP/M)
  122. origusr: ds 1
  123. curdsk: ds 1            ;current user area (CP/M)
  124. origdsk: ds 1
  125. cc2dsk: ds 1    ;default disk to search for cc2
  126. cc2usr: ds 1    ;default user area to search for cc2
  127. dodotc: ds 1    ;true to try ".C" if no ext given and file not found
  128.         ENDIF
  129.  
  130. curtop: ds 2    ;end of availlable TPA memory
  131. preflag:ds 1    ;true when still pre-processing
  132. pflag:  ds 1    ;print intermediate text flag ("p" option)
  133. sdisk:  ds 1    ;disk # where source came from
  134. chainf: ds 1    ;true if we want to chain to CC2
  135. loadad: ds 2    ;load address
  136. eflag:  ds 1    ;true if -e option given
  137. exaddr: ds 2    ;value given to -e option
  138. cnflag: ds 1    ;true if comments nest
  139. okflag: ds 1    ; "readm" routine success flag
  140. mapucv: ds 1    ;no upper case mapping in "stcmp" routine flag
  141.  
  142.         IF CPM
  143. cfcb:    db 0,'CC2     COM',0,0,0,0
  144. subfile: db 1,'$$$     SUB',0,0,0,0
  145.  
  146. redfcb:  db 0,'PROGERRS$$$',0,0,0,0
  147.          ds 17  ;rest of fcb for RED error file
  148. redbuf: ds 128  ;text buffer for RED error file
  149. redbp:  ds 2    ;pointer into text buffer
  150. errsin: ds 1    ;true if RED output is active
  151. nomore: ds 1    ;true if future red error output is disabled
  152.         ENDIF
  153.  
  154. modstk: ds (fnlen + 2) * (nestmax + 1)
  155. modstp: ds 2    ;pointer to currently active filename
  156. modstc: ds 1    ;counter
  157.  
  158. casoff: ds 1    ;case overflow flag
  159. esctmp: ds 1
  160. errad:  ds 2
  161. eradf:  ds 1
  162. scc:    ds 1    ;string character count for psstg
  163. stgcct: ds 2    ;points to where length byte goes for psstg
  164. nlflag: ds 2    ;used in the pitext routine  for something or other
  165. nltmp2: ds 1
  166. nltmp:  ds 2
  167. modaf:  ds 1    ;whether to modify st ptrs after wrapup or not
  168. inadsv: ds 2    ;some more kludgery to allow multiple struct
  169.                 ;elements to have same name in separate structs
  170. stsiz:  ds 2
  171. coda:   ds 2
  172. fndtmp: ds 1
  173. mvtmp:  ds 1
  174. errf:   ds 1
  175. cmntf:  ds 1
  176. udiag:  ds 1
  177. stgf:   ds 1
  178. csf:    ds 1
  179. sf:     ds 1
  180. flev:   ds 1
  181. fixfl:  ds 1
  182. pdfd:   ds 1  ;previously declared func. def. flag
  183. pdfdno: ds 2    ;symbol # for above
  184. stor:   ds 2
  185. strsz:  ds 2
  186. mxsiz:  ds 2
  187. tmplf:  ds 2
  188. tmpbs:  ds 1
  189. tmpsu:  ds 1
  190. fbufp:  ds 2
  191. opena:  ds 2
  192. stno:   ds 2
  193. fntp:   ds 2
  194. fnts:   ds 2
  195. fnc:    ds 2
  196. lbln:   ds 2
  197. eofad:  ds 2
  198. meofad: ds 2    ;max eofad for elbowroom announcement
  199. nlcnt:  ds 2
  200. nlcnts: ds 2    ;save nlcnt when in #include file
  201. ptfnf:  ds 1
  202. type:   ds 1
  203. stelf:  ds 1
  204. forml:  ds 1
  205. what:   ds 1
  206. lind:   ds 1
  207. clev:   ds 1
  208. clevb:  ds 1
  209. clevt:  ds 1
  210. unflg:  ds 1
  211. newid:  ds 1    ;used for flagging undefined structure identifiers
  212. adrs:   ds 2
  213. size:   ds 2
  214. dmsiz:  ds 2
  215. tempd:  ds 2
  216. tempdp: ds 2
  217. tmpa:   ds 2
  218. savsta: ds 2
  219. tmpfr:  ds 2
  220. fndad:  ds 2
  221. extsa:  ds 2
  222. stp:    ds 2
  223. mtpln:  ds 2
  224. symno:  ds 2
  225. funcf:  ds 2
  226. z80f:   ds 1
  227. frmrf:  ds 1
  228. esadr:  ds 2
  229. lcnt:   ds 1    ;used by parameterized #define preprocessor
  230. operad: ds 2    ;where option error begins
  231. odisk:  ds 1    ;output disk designation
  232. semiok: ds 1
  233. nlfnd:  ds 1    ;used by decf routine
  234. kflg:   ds 1    ;true if "-k" option given to write CDB file
  235. signm:  ds 1    ;used by "passx", put here just to be safe...
  236. cpyend: ds 2    ;parameter to "copy" routine showing end address
  237. bcnstf: ds 1    ; (readf, pass1) true when bad char constants must
  238.                 ;                be flagged as an error
  239.  
  240. ascb:   ds 4
  241.         db ': ',0
  242.  
  243.         ds 10
  244. ;stkchk:        ds 2    ;if this ever gets clobbered, stack has overflowed
  245.  
  246. ;       ds 320
  247. ;stack: equ $
  248.  
  249. stg2:   db 'Close error+'
  250. stg3:   db 'File output error; dir or disk full?+'
  251. stgoer: db '": option error+'
  252. stg10:  db 'Encountered EOF unexpectedly',cr,lf
  253.         db ' (check curly-brace balance)+'
  254. stg12:  db 'Unmatched right brace+'
  255. stg14:  db 'Undeclared identifier: ',0
  256. stg15:  db 'Illegal external statement+'
  257. stg16:  db 'Bad declaration syntax+'
  258. stg17:  db 'Missing legal identifier+'
  259. stg19:  db 'Function definition not external+'
  260. stg20:  db 'Need explicit dimension size+'
  261. stg21:  db 'Too many dimensions+'
  262. stg22:  db 'Bad dimension value+'
  263. stg23:  db 'Bad parameter list element+'
  264. stg24:  db 'Redeclaration of: ',0
  265. stg25:  db 'Missing semicolon+'
  266. stg27:  db 'Expecting "{" in struct or union def+'
  267. stg28:  db 'Illegal structure or union id+'
  268. stgbft: db 'Bad function type+'
  269. stg28a: db 'Undefined structure id+'
  270. stgdu:  db '*Unnamed'
  271. stg40:  db 'Expecting "("+'
  272. stgbp:  db 'Unmatched left parenthesis+'
  273.  
  274. stgstk: db 'Stack Overflow: '                   ; keep these two together
  275. stgov:  db 'Sorry; out of memory+'
  276.  
  277. stgtc:  db 'I''m totally confused. '
  278.         db 'Check your control structure!+'
  279. stgom:  db 'Out of symbol table space; specify more...+'
  280. stgtmf: db 'Too many functions (63 max)',0
  281. stgmq:  db 'String too long (or missing quote)+'
  282. stgbsd: db 'Attribute mismatch from previous declaration+'
  283. stgelb: db 'elbowroom',cr,0
  284. stgunu: db 'unused',cr,0
  285. oshit:  db 'Internal Error...Call BDS+'
  286.  
  287. stgcce: db cr,lf
  288.         IF CPM
  289.         db 'Can''t find CC2.COM; writing CCI file to disk'
  290.         ENDIF
  291.         db cr,lf,0
  292.  
  293. stgiep: db 'Include @',0
  294. stgilc: db 'Illegal "{" encountered externally',0
  295. stgtmi: db 'Declaration too complex+'
  296. stgbfd: db 'Missing from formal parameter list: ',0
  297. stgabo: db 'Compilation aborted by ^C+'
  298. stgeri: db cr,lf,'RED error output initiated+',0
  299.  
  300. ;
  301. ; passc error messages:
  302. ;
  303.  
  304. stgc1:  db 'Mismatched control structure',cr,lf,0
  305. stgc2:  db 'Expecting "while"',cr,lf,0
  306. stgc7:  db 'Illegal break or continue',cr,lf,0
  307. stgc6:  db 'Bad "for" syntax',cr,lf,0
  308. stgc8:  db 'Expecting "{" in switch statement',cr,lf,0
  309. stgc9:  db 'Bad "case" constant',cr,lf,0
  310. stgc10: db 'Illegal statement',cr,lf,0
  311. stgcof: db 'Too many cases (200 max per switch)',cr,lf,0
  312. stgddf: db 'Can''t have more than one `default:''',cr,lf,0
  313.  
  314.  
  315. ;
  316. ; Initialize compiler flags and variables:
  317. ;
  318.  
  319. ccinit: call zsetup
  320.  
  321.         lhld protm ;0 there!!! who must write there???
  322.         shld curtop
  323.  
  324.         lhld errbyt
  325.         ld (hl),0               ;no error by default
  326.  
  327.         ld hl,stg0      ;print sign-on message
  328.         call pstgco     ;print to console only
  329.  
  330.         ;ld c,gdisk     ;get current disk and user area
  331.         ;call bdos
  332.          xor a ;TODO getpath
  333.         sta curdsk      ;store current disk
  334.         sta origdsk     ;and save as original disk upon invokation of CC
  335.  
  336.         IF NOT ALPHA
  337.         ;ld c,sguser    ;set/get user area
  338.         ;ld e,0ffh
  339.         ;lda nouser
  340.         ;or a
  341.         ;call z, bdos
  342.          xor a
  343.         sta curusr      ;store current user area
  344.         sta origusr     ;and save as original user area upon invoking CC
  345.         ENDIF
  346.  
  347.         lda defdsk      ;set cc2 search path
  348.         inc a           ;first set disk
  349.         sta cc2dsk
  350.         lda defusr
  351.         cp 0ffh ;and user area. default to current?
  352.         jp nz,cc2
  353.         lda curusr      ;if so, set to current user area
  354. cc2:    sta cc2usr
  355.         lda defsub
  356.         inc a           ;if FF, make current; else, make explicit disk code
  357.         jp nz,cc3               ;if not set to find submit files on current disk, don't
  358.         lda curdsk      ;else set current disk as explicit disk byte in SUB.$$$
  359.         inc a           ;     fcb in case we abort in the middle of file read
  360. cc3:    sta subfile     ;set disk to find $$$.SUB on
  361.  
  362.         lda pstrip      ;does user want parity stripped on input file?
  363.         or a
  364.         jp nz,cc3a              ;if so, do nothing (strips by default)
  365.  
  366.         IF IMPURE
  367.         ld a,0          ;IMPURE CODE: *** NOP ***
  368.         sta stripp
  369.         ld a,0b7h       ;IMPURE CODE: *** or A  ***
  370.         sta stripp+1   
  371.         ENDIF
  372.  
  373. cc3a:
  374.         IF CPM          ;initialize some CP/M-only parameters
  375.         lda fcb         ;get source disk #
  376.         sta sdisk       ;save it
  377.         sta odisk
  378.         ld de,tbuff     ;set tbuff explicitly, to facilitate debugging
  379.         ld c,sdma       ;of the 4200h version on my 0-based system
  380.         call bdos
  381.         ENDIF
  382.  
  383.         xor a           ;initialize following flags to FALSE:
  384.         sta kflg        ;no debugger features by default
  385.         sta eflag       ;no -e option yet
  386.         sta errf        ;error ocurred flag
  387.         sta eradf
  388.         sta mapucv      ;no-upper-case-mapping on string-compare flag
  389.         sta pflag
  390.         sta z80f        ;false for 8080, true for Z80
  391.         sta semiok
  392.         sta nomore      ;allow RED output for starters
  393.  
  394.         IF CPM
  395.         sta cfcb
  396.         sta erasub      ;don't bother erasing SUBMIT files unless -x given
  397.         sta errsin      ;no RED error file active yet
  398.         ENDIF
  399.  
  400.         inc a           ;initialize following flags to TRUE:
  401.  
  402.         sta preflag
  403.         sta chainf
  404.  
  405.         IF CPM
  406.         sta cnflag      ;assume comments nest for starters
  407.         sta ccpok       ;CCP intact at first under CP/M
  408.         ENDIF
  409.  
  410.         ld a,2          ;find out if we're on Z80 or 8080
  411.         inc a
  412.         jp pe,cc1z      ;if on Z80,
  413.         sta z80f        ;will come here to set z80 flag.
  414.  
  415. cc1z:   ld hl,dfstsz    ;default symbol table size
  416.         shld stsiz
  417.         ld hl,tpa       ;default load address for generated code
  418.         shld loadad
  419.         ld hl,0a55ah    ;for stack overflow check
  420.         shld stkchk
  421.         ld hl,0         ;reset label counter
  422.         shld lbln
  423.         ret
  424.  
  425.         IF CPM AND NOT ALPHA
  426. chkusr:
  427.         ld de,fcb+1     ;check to see if user area given on filename
  428.         call gdec       ;number?
  429.         ret c           ;if not, no problem
  430.         ld a,(de)
  431.         cp '/'          ;user area prefix character?
  432.         ret nz
  433.         ld hl,stgnua    ;can't give user area
  434.         jp pstgab
  435.         ENDIF
  436.  
  437. zsetup: xor a
  438.         sta zenvf       ;not z environment by default
  439.         ld hl,errdum
  440.         shld errbyt     ;dummy error byte by default
  441.         ld a,1
  442.         sta oktort      ;ok to return to ccp, despite ccpok for now
  443.         lhld zenvad ;TODO remove
  444.         push hl
  445.         ld de,1bh
  446.         add hl,de
  447.         ld e,(hl)
  448.         inc hl
  449.         ld d,(hl)               ;get reflexive env addr from env
  450.         pop hl          ;original Z env value
  451.         call cmphd      ;save as reflexive address?
  452.         jp nz,setp2a    ;if not z system, set top of memory
  453.  
  454.         ld a,1
  455.         sta zenvf       ;Z system.
  456.         push hl         ;save env pointer
  457.         ld de,3fh       ;get potential ccp address
  458.         add hl,de
  459.         ld a,(hl)
  460.         inc hl
  461.         ld h,(hl)
  462.         ld l,a
  463.         shld ccpad
  464.  
  465.         pop hl          ;get env pointer
  466.  
  467.         push hl
  468.         ld de,22h
  469.         add hl,de
  470.         ld a,(hl)
  471.         inc hl
  472.         ld h,(hl)
  473.         ld l,a          ;HL -> message buffer
  474.         ld de,6         ;get address of error byte
  475.         add hl,de
  476.         shld errbyt     ;save the address
  477.         pop hl
  478.  
  479.         ld de,8         ;get type
  480.         add hl,de
  481.         ld a,(hl)
  482.         sta envtyp
  483.        
  484.         and 80h         ;b7 hi?
  485.         lhld ccpad
  486.         jp nz,setup3    ;if so, use ccpad as ccp address
  487. setp2a: lhld ram+1      ;else calculate the old way
  488.         ld de,-1603h
  489.         add hl,de
  490.  
  491. setup3: xor a           ;clear 'ccp volatile' flag
  492.         sta ccpok       ;and CCP INTACT flag
  493.         ex de,hl                ;put ccp address in DE
  494.         ld hl,NEDOOSMEMTOP;lhld bdosp
  495.         ld l,0          ;zero out low-order byte
  496.         call cmphd      ;set Cy if [BASE+6,7] < CCP
  497.         jp c,setup4     ;if BASE+6 < CCP, use BASE+6 as end of prot mem
  498.         ex de,hl                ;else use CCP as end of prot. mem.
  499.         ld a,1          ;and set ccp volatile flag
  500.         sta ccpok       ;and set ccpok
  501.         xor a           ;NOT ok to return to ccp despite ccpok
  502.         sta oktort
  503. setup4: shld protm
  504.         ret
  505.  
  506.  
  507. envtyp: ds 1
  508.  
  509. ;zenvf          ;is after wboote
  510. zenvad: ds 2    ;address of Z3 environment block
  511. ccpad:  ds 2    ;address of CCP for type 80h ZCPR3
  512. protm:  ds 2    ;start of protected memory
  513. oktort: ds 1    ;ok to return to ccp despite ccpok flag?i
  514. errbyt: ds 2    ;message buffer error byte address
  515. errdum: ds 1    ;in case we're NOT under ZCPR3...
  516.  
  517.  
  518. ;
  519. ; Process command line options:
  520. ;
  521.  
  522. comlin:
  523.         ld hl,st        ;init symbol table free space pointer
  524.         shld stp
  525.  
  526.         IF CPM
  527.         ;lda tbuff
  528.         ;add a,81h
  529.         ;ld l,a
  530.         ;ld h,tbuff/100h
  531.         ;ld (hl),0              ;place 00 at end of command line
  532.         ld de,tbuff;+1  ;DE will be text pointer as we process
  533.         ;call igsp      ;find source file name ;skip spaces in (de) (z=end of line, nz=text found)
  534.         call fspac ;skip word in (de) (z=end of line, nz=text found)
  535.         ld hl,stg1      ;is it there?
  536.         jp z,pstgab     ;if not, error.
  537.          ld (filenameaddr),de
  538.         call fspac      ;pass it, and any blanks after it.
  539.         ENDIF
  540.  
  541.         IF CPM
  542. cc11:   call igsp       ;done processing line?
  543.         ex de,hl
  544.         shld operad     ;save in case of error
  545.         ex de,hl
  546.         ENDIF
  547.  
  548. cc111:  ret z           ;if so, go compile
  549.         cp '-'          ;dash?
  550.         jp nz,operr     ;if not, operand error
  551.         inc de          ;get option character
  552.         ld a,(de)
  553.         call mapuc      ;convert to upper case
  554.         inc de          ;advance pointer past option character
  555.  
  556. cc12a:
  557.         IF NOT ALPHA
  558.         cp 'K'
  559.         jp nz,cc12d
  560.         call gdec       ;get optional restart param
  561.         jp nc,cc12b     ;param given?
  562.         lda krst        ;if not, use default value
  563.         jp cc12c        ;if not, make it 6
  564.  
  565. cc12b:  cp 8
  566.         jp nc,operr     ;if >=8, error...else OK
  567.  
  568. cc12c:  sta kflg        ;set debugging mode with restart value
  569.         jp cc11
  570.  
  571. cc12d:  cp 'W'          ;flip error file activity?
  572.         jp nz,cc12
  573.         lda werrs       ;get write error flag
  574.         xor 1           ;logically invert
  575.         sta werrs       ;and save it back
  576.         jp cc11
  577.         ENDIF
  578.  
  579. cc12:   cp 'O'          ;optimize for speed flag?
  580.         jp nz,cc13
  581.         xor a           ;if so, no longer optimizing for space
  582.         sta optim
  583.         jp cc11
  584.  
  585. cc13:   cp 'Z'          ;RST optimization flag?
  586.         jp nz,cc13z
  587.  
  588.         ld a,(de)
  589.         call legdd      ;any parameters given?
  590.         jp nc,cc13c     ;if not, assume full optimization
  591.  
  592.         ld a,0bfh       ;if not, assume we're using all RST locations
  593.         sta optim
  594.         jp cc11
  595.  
  596. cc13c:  ld b,a
  597.         ld a,80h        ;paramters supplied. Activate only
  598.         sta optim       ;those optimizations with supplied parameters
  599.         ld a,b
  600.  
  601. cc13a:  or a            ;check for range between 1-7
  602.         jp z,operr
  603.         cp 8
  604.         jp nc,operr            
  605.  
  606.         ld b,a          ;save rst code in B
  607.         ld c,80h        ;start walking bit at left, to be rotated into low bit
  608. cc13b:  ld a,c          ;shift bit left
  609.         rlca
  610.         ld c,a
  611.         dec b  
  612.         jp nz,cc13b     ;loop till done shifting
  613.         lda optim
  614.         or c
  615.         or 80h          ;set space optimization bit, just in case
  616.         sta optim
  617.         inc de
  618.         ld a,(de)               ;any more vector specifications?
  619.         call legdd
  620.         jp nc,cc13a
  621.         jp cc11 ;else all done
  622.        
  623.  
  624. cc13z:  cp 'P'          ;print flag?
  625.         jp nz,cc14
  626.         sta pflag
  627.         jp cc11
  628.  
  629. cc14:   cp 'R'          ;symbol reservation option?
  630.         jp nz,cc15
  631.         call gdec       ;get A=decimal number, 0-19
  632.         cp 7
  633.         jp c,operr      ;if < 7 or >19 then error.
  634.         cp 20
  635.         jp nc,operr
  636.         add a
  637.         add a
  638.         ld h,a
  639.         ld l,0
  640.         shld stsiz      ;set symbol table size to nK
  641.         jp cc11
  642.  
  643. cc15:
  644.         IF CPM         
  645.         cp 'A'          ;auto-load option? (CP/M only)
  646.         jp nz,cc16
  647.         call gdskc      ;get disk code, 1-16, or 0 for 'Z'
  648.         sta cfcb        ;set disk field of cc2 fcb
  649.         sta chainf      ;if 0, this prevents auto-chaining
  650.         sta cc2dsk      ;set default cc2 search disk
  651.         call gdec       ;user number given?
  652.         jp c,cc11
  653.         sta cc2usr      ;if so, set default cc2 search search area
  654.         jp cc11
  655.         ENDIF
  656.  
  657.         IF CPM
  658. cc16:   cp 'D'          ;output disk specification?
  659.         jp nz,cc16a     ;if not, check for other options
  660.         call gdskc      ;get disk letter
  661.         or a
  662.         jp z,operr      ;don't allow 'Z'
  663.         sta odisk
  664.         jp cc11
  665.         ENDIF
  666.  
  667.         IF CPM
  668. cc16a:  cp 'X'
  669.         jp nz,cc17
  670.         ld a,1
  671.         sta erasub      ;erase submit files
  672.         jp cc11
  673.         ENDIF
  674.  
  675. cc17:  
  676.         IF NOT ALPHA
  677.         cp 'M'          ;load address specifier?
  678.         jp nz,cc18
  679.         call ghxarg     ;get hex arg in HL
  680.         jp c,operr
  681.         shld loadad
  682.         jp cc11
  683.         ENDIF
  684.  
  685. cc18:   cp 'E'          ;set external address?
  686.         jp nz,cc19      ;if not, illegal option
  687.         sta eflag       ;set external address specified flag
  688.         call ghxarg     ;get value
  689.         jp c,operr
  690.         shld exaddr
  691.         jp cc11
  692.  
  693. cc19:   cp 'C'
  694.         jp nz,operr
  695.  
  696.         IF CPM
  697.         xor a
  698.         ENDIF
  699.  
  700.         sta cnflag      ;now comments don't nest under CPM, and DO
  701.         jp cc11 ;               nest under MARC
  702.  
  703.  
  704. ghxarg: call igsp       ;yes. check for hex arg
  705.         scf
  706.         ret z           ;return error (c set) if no arg
  707.         call leghd
  708.         ret c           ;if not legal hex digit, error
  709.  
  710.         ld hl,0         ;else prepare to accumulate value in HL
  711. cc17a:  ld a,(de)
  712.         call leghd
  713.         jp nc,cc17b     ;end of value text?
  714.         xor a
  715.         ret             ;yes. clear carry and return value in HL       
  716. cc17b:  add hl,hl               ;no. multiply accumulator by 16
  717.         add hl,hl
  718.         add hl,hl
  719.         add hl,hl
  720.         ld c,a          ;and add new digit
  721.         ld b,0
  722.         add hl,bc      
  723.         inc de          ;and go to next character
  724.         jp cc17a
  725.  
  726. operr:  ld a,'"'
  727.         call outch
  728.         lhld operad
  729. operr1: ld a,(hl)
  730.         or a
  731.         jp z,operr2
  732.         call outch
  733.         inc hl
  734.         ld a,l
  735.         dec a
  736.         cp e
  737.         jp nz,operr1
  738. operr2: ld hl,stgoer    ;op error string
  739.         jp pstgab      
  740.  
  741.  
  742.         IF CPM
  743. gdskc:  call igsp
  744.         jp z,operr
  745.         sub 'A'-1
  746.         cp 27
  747.         jp nc,operr
  748.         inc de          ;bump past the char
  749.         cp 26           ;change 'Z' to zero
  750.         ret nz
  751.         xor a
  752.         ret
  753.         ENDIF
  754.  
  755. ;skip spaces in (de) (z=end of line, nz=text found)
  756. igsp:   ld a,(de)
  757.         or a
  758.         ret z
  759.         call mapuc
  760.         cp ' '
  761.         ret nz
  762.         inc de
  763.         jp igsp
  764.  
  765.         IF CPM
  766. ;skip word in (de) (z=end of line, nz=text found)
  767. fspac:  ld a,(de)
  768.         or a
  769.         ret z
  770.         inc de
  771.         cp ' '
  772.         jp nz,fspac
  773.         jp igsp
  774.         ENDIF
  775.  
  776. gdec:   ld b,0
  777.         call igsp
  778.         call legdd
  779.         ld a,0
  780.         ret c  
  781. gdec1:  ld a,(de)
  782.         call legdd
  783.         ld a,b
  784.         ccf
  785.         ret nc
  786.         add a           ;get A = 10 * B
  787.         add a           ;(*4)
  788.         add a           ;(*8)
  789.         add b           ;(*9)
  790.         add b           ;(*10)
  791.         add c           ;now add new digit value in C
  792.         ld b,a          ;put into B
  793.         inc de
  794.         jp gdec1        ;and go for more
  795.  
  796. ;
  797. ; Check for legal decimal digit, return Cy set if illegal,
  798. ; else the binary value of the digit in A:
  799. ;
  800.  
  801. legdd:  call mapuc
  802.         sub '0'
  803.         ld c,a
  804.         ret c
  805.         cp 10
  806.         ccf    
  807.         ret
  808.  
  809. ;
  810. ; Check for legal hex digit:
  811. ;
  812.  
  813. leghd:  call legdd
  814.         ret nc
  815.         cp 11h
  816.         ret c
  817.         cp 17h
  818.         ccf
  819.         ret c
  820.         sub 7
  821.         ret                    
  822.  
  823.  
  824. usage:  ld hl,ascb+4
  825.         ld (hl),'K'
  826.  
  827.         IF CPM
  828.         ld hl,NEDOOSMEMTOP;lhld bdosp   ;get pointer to top of memory
  829.         ld l,0
  830.         ENDIF
  831.  
  832.         ex de,hl                ;into DE
  833.         lhld meofad     ;get highest addr used
  834.         call cmh        ;negate
  835.         add hl,de               ;and add to top of mem to give free ram
  836.         ld a,h          ;divide by 1K
  837.         rra
  838.         rra
  839.         and 3fh
  840.         ld l,a
  841.         ld h,0
  842.         dec hl
  843.  
  844.         xor a
  845.         call prhcs      ;print out
  846.         ld hl,stgelb    ;"elbowroom"
  847.         lda lbln
  848.         and 0fh         ;little hack here!
  849.         jp nz,cc1b
  850.         ld hl,stgunu    ;"unused"
  851. cc1b:   call pstg
  852.         ret
  853.  
  854. ; Wrap up error handling, exit if there were errors:
  855.  
  856. errwrp: lda errsin      ;error output initialized?
  857.         or a
  858.         jp z,errwr3     ;if not, don't try to close RED output file
  859.  
  860.         ld e,1ah        ;ascii end-of-file
  861.         call redout
  862.         lhld redbp
  863.         ld a,l
  864.         cp redbuf and 0ffh      ;has buffer just been flushed?
  865.         call nz,redwrt  ;if not, write buffer one last time
  866.         ld de,redfcb
  867.         call close2     ;close RED output buffer
  868.  
  869. errwr3: lda errf        ;if there were real errors (not just warnings)
  870.         or a            ;then exit
  871.         jp nz,errab2
  872.         inc a
  873.         sta nomore      ;no more RED output
  874.         ret             ;else return
  875.  
  876.  
  877.                
  878. ;
  879. ; Set up environment for a pass through the text (DE becomes
  880. ; text pointer)
  881. ;
  882.  
  883. initps: ld hl,0
  884.         shld nlcnt
  885.  
  886. ;       shld lbln               ;arghh. WHY did this WORK for so LONG?
  887.                                 ;(after lblpr, mustn't reset lbln anymore)
  888.  
  889.         ld hl,modstk
  890.         shld modstp
  891.         xor a
  892.         sta clev
  893.         sta modstc      ;at very top level
  894.         lhld coda
  895.         ex de,hl
  896.         ret
  897.  
  898.  
  899. ;
  900. ;
  901. ; Passc: control structure processor:
  902. ; This pass preprocesses control statements (like while, do,
  903. ; if...else, etc.) and twists them into a form much easier to digest
  904. ; by cc2. E.g., All the `case' statments are relded from a `switch'
  905. ; construct and a table of constants and `symbolic labels' is formed.
  906. ; If...else statments are turned into simple `if' statments (using some
  907. ; added braces and goto's...One may be able to get away from goto's
  908. ; in a C program, but it's a bit harder to avoid them at the compiler-
  909. ; design level!
  910. ;
  911. ; Note that at this point, all declarations have been purged from
  912. ; the text, leaving only the function definitions. If we ever finish
  913. ; up with a function and find something other than another function
  914. ; or EOF after it, somethings really screwed up...
  915. ;
  916.  
  917. passc:  call initps     ;initialize general pass procecure variables
  918.         ld hl,cntt      ;init control table pointer (this is where
  919.         shld cntp       ; the "break" and "continue" labels are stored)
  920.         ld hl,fbuf
  921.         shld fbufp
  922.         xor a
  923.         sta clev
  924.         dec de
  925.  
  926. pasc1:  inc de
  927. pasc2:  call igsht      ;done with text?
  928.         jp nz,pasc3
  929.         lda clev        ;yes. at top level?
  930.         or a
  931.         ret z           ;if so, OK
  932.  
  933. pasc2a: ld hl,stg10     ;==ERROR==
  934.         jp fatal        ;probably mismatched {}s
  935.  
  936. pasc3:  cp varcd        ;a variable? (i.e., function definition?)
  937.         jp z,pasc4
  938.  
  939. pasc3a: call fsemi
  940.         jp pasc1       
  941.  
  942. ;       ld hl,stgtc     ;if not, somethings screwy
  943. ;       jp fatal
  944.  
  945. pasc4:  inc de          ;ok, we found a function
  946.         inc de
  947.         inc de
  948.         call mtchp      ;pass over the arg list
  949.         call state      ;process the body as a statment
  950.         jp pasc2        ;and go back for another function
  951.  
  952. ;
  953. ; Here it is, the routine to process a statment...
  954. ;
  955.  
  956. state:  call ckabrt     ;check for user typing control-C
  957.         call chkstk     ;and check for stack overflow
  958.  
  959.         call igsht
  960.         jp z,pasc2a     ;if expecting a statement and get EOF, error
  961.  
  962.         call cdtst      ;if it starts with a code, ignore the code
  963.         jp c,state0
  964.         inc de          ;ignore it, since its probably a label
  965.         inc de          ;code or something trivial.
  966.         inc de
  967.         jp state
  968.  
  969. state0: inc de          ;now, does it start with a `{'?
  970.         cp lbrcd
  971.         jp nz,state2
  972.  
  973. state1: call igsht      ;yes. do each statment inside the compound.
  974.         cp rbrcd        ;hit the `}' yet?
  975.         inc de
  976.         ret z           ;if so, all done
  977.         dec de          ;else just another statment
  978.         call state     
  979.         jp state1       ;and keep a 'goin
  980.  
  981. state2: cp ifcd ;now we hit the real statements. IF?
  982.         jp z,sif
  983.  
  984.         cp whlcd        ;WHILE?
  985.         jp z,swhl
  986.  
  987.         cp docd ;DO?
  988.         jp z,sdo
  989.  
  990.         cp forcd        ;FOR?
  991.         jp z,sfor
  992.  
  993.         cp swtcd        ;SWITCH?
  994.         jp z,sswt
  995.  
  996.         cp brkcd        ;BREAK?
  997.         jp z,sbrk
  998.  
  999.         cp cntcd        ;CONTINUE?
  1000.         jp z,scnt
  1001.  
  1002.         cp rencd        ;RETURN?
  1003.         jp z,state3
  1004.  
  1005.         cp gotcd        ;GOTO?
  1006.         jp z,state3
  1007.  
  1008.         cp cascd        ;CASE? if so, bad news!
  1009.         jp z,sterr      ; Only the SWITCH processor should see these!
  1010.  
  1011.         cp elscd        ;while only the IF processor should see ELSEs
  1012.         jp z,sterr
  1013.  
  1014.         cp defcd        ;and only the SWITCH processor, again, should
  1015.         jp z,sterr      ;see DEFAULTs
  1016.  
  1017.         dec de          ;at this point we assume we have an expression
  1018. state3: ld a,1          ;statment (or a really screwy error.)
  1019.         sta eradf
  1020.         lhld nlcnt
  1021.         shld errad
  1022.         call fsemi      ;this phase can ignore expression statements.
  1023.         xor a
  1024.         sta eradf
  1025.         inc de
  1026.         call igsht
  1027.         ret
  1028.  
  1029. sterr:  ld hl,stgc10    ;seeing a CASE outside of a SWITCH, and other stuff
  1030.         jp fatal        ;like that, are good enough reasons to abort.
  1031.  
  1032. ;
  1033. ; routine to pass over a statement, I guess because I need to
  1034. ; look ahead sometimes to figure out what's going on. Geez,
  1035. ; I can't remember what the hell I used this for...
  1036. ;
  1037. ; (In case you're wondering, these comments are being written about
  1038. ; 11 months after the code. I just now got WORDMASTER going on my
  1039. ; bee-YOU-tea-full H19 terminal, and need no longer get uptight over
  1040. ; the chilling prospect of documenting 150K of source using ED...)
  1041. ;
  1042.  
  1043. passt:  call igsht
  1044.         jp z,pasc2a
  1045.         call cdtst      ;ignore labels and such
  1046.         jp c,past0
  1047.         inc de
  1048.         inc de
  1049.         inc de
  1050.         jp passt
  1051.  
  1052. past0:  cp lbrcd        ;left brace?
  1053.         jp nz,past2
  1054.         inc de
  1055.  
  1056. past1:  call igsht
  1057.         cp rbrcd
  1058.         jp nz,past1a
  1059.         inc de
  1060.         call igsht
  1061.         ret
  1062.  
  1063. past1a: call passt      ;yes; pass statement
  1064.         jp past1
  1065.  
  1066. past2:  cp ifcd
  1067.         jp nz,past3     ;if statement?
  1068.         inc de          ;yes.
  1069.         call mtchp      ;pass expr
  1070.         call passt      ;pass statement
  1071.         cp elscd        ;else?
  1072.         ret nz
  1073.         inc de          ;yes. pass statement
  1074.         call passt
  1075.         ret
  1076.  
  1077. past3:  cp whlcd        ;while?
  1078.         jp z,pst5b
  1079.         cp cascd        ;case?
  1080.         jp z,past3a
  1081.         cp defcd        ;default?
  1082.         jp nz,past4
  1083. past3a: ld a,colon      ;yes; find a colon
  1084.         call findc
  1085.         inc de          ;pass it
  1086.         call passt      ;pass next statement
  1087.         call igsht
  1088.         ret
  1089.  
  1090. past4:  cp docd
  1091.         jp nz,past5     ;do statement?
  1092.         inc de          ;yes.
  1093.         call passt      ;pass statement
  1094.         cp whlcd        ;while?
  1095.         jp z,pst4a
  1096.         ld hl,stgc2     ;if not, error
  1097.         call perr
  1098.  
  1099.  
  1100. pst4a:  inc de          ;pass expr
  1101.         call mtchp
  1102.         cp semi
  1103.         call nz,insrts  ;if no semi, insert one automagically.
  1104.         inc de
  1105.         call igsht
  1106.         ret
  1107.  
  1108. past5:  cp forcd        ;for statement?
  1109.         jp nz,past6
  1110.         sta semiok      ;yes. allow semis in text for now.
  1111.  
  1112. pst5b:  inc de
  1113.         call mtchp      ;pass expr(s)
  1114.         xor a
  1115.         sta semiok
  1116.         call passt      ;pass statment
  1117.         ret
  1118.  
  1119. past6:  cp swtcd        ;switch?
  1120.         jp z,pst5b
  1121.         or a            ;no. EOF?
  1122.         jp z,pasc2a
  1123.  
  1124.         call fsemi      ;no. go search for a semicolon
  1125.         inc de
  1126.         call igsht
  1127.         ret
  1128.  
  1129. ;
  1130. ; push continue-break data stack, adding two new labels:
  1131. ;
  1132.  
  1133. cnpsh:  push de
  1134.         ex de,hl
  1135.         lhld cntp
  1136.         ld (hl),e
  1137.         inc hl
  1138.         ld (hl),d
  1139.         inc hl
  1140.         inc de
  1141.         ld (hl),e
  1142.         inc hl
  1143.         ld (hl),d
  1144.         inc hl
  1145.         shld cntp
  1146.         lda clev
  1147.         inc a
  1148.         sta clev
  1149.         ex de,hl
  1150.         dec hl
  1151.         pop de
  1152.         ret
  1153.  
  1154. ;
  1155. ; Pop continue-break data stack:
  1156. ;
  1157.  
  1158. cnpop:  lhld cntp
  1159.         dec hl
  1160.         dec hl
  1161.         dec hl
  1162.         dec hl
  1163.         shld cntp
  1164.         lda clev
  1165.         dec a
  1166.         sta clev
  1167.         ret
  1168.  
  1169. cklev:  lda clev
  1170.         or a
  1171.         ret nz
  1172.         ld hl,stgc7
  1173.         call perr
  1174.         pop hl
  1175.         jp sbrk3
  1176.  
  1177. ;
  1178. ; Define a symbolic label given in HL at current location in text:
  1179. ;
  1180.  
  1181. insll:  ld a,-3 and 255
  1182.         call mvtxt
  1183. insls:  ld a,lblcd
  1184.         jp insr2
  1185.  
  1186. ;
  1187. ; Install a symbolic label REFERENCE to label in HL at
  1188. ; current location in text:
  1189. ;
  1190.  
  1191. inslr:  ld a,-3 and 255
  1192.         call mvtxt
  1193. insrs:  ld a,labrc
  1194.  
  1195. insr2:  ld (de),a
  1196.         inc de
  1197.         ld a,l
  1198.         ld (de),a
  1199.         inc de
  1200.         ld a,h
  1201.         ld (de),a
  1202.         inc de
  1203.         ret
  1204.  
  1205. ;
  1206. ; Install a new label definition at current location in text:
  1207. ;
  1208.  
  1209. lblni:  call glbl
  1210.         jp insll
  1211.  
  1212. ;
  1213. ; Install a new label reference at current place in text:
  1214. ;
  1215.  
  1216. lblri:  call glbl
  1217.         jp inslr
  1218.  
  1219. ;
  1220. ; Get a new label value in HL:
  1221. ;
  1222.  
  1223. glbl:   lhld lbln
  1224.         inc hl
  1225.         shld lbln
  1226.         dec hl
  1227.         ret
  1228.  
  1229. ;
  1230. ; Process a "for" statement:
  1231. ;
  1232.  
  1233. sfor:   dec de
  1234.         ld a,lbrcd      ;left curly-brace to delimit entire for statement
  1235.         ld (de),a
  1236.         inc de
  1237.         call igsht
  1238.         cp open
  1239.         jp z,sfor2
  1240.         ld hl,stgc6
  1241.         call perr
  1242.  
  1243. sfor2:  ld a,0ffh
  1244.         ld (de),a
  1245.         call chsbp
  1246.         call passt
  1247.         ld a,-5 and 255
  1248.         call mvtxt
  1249.         ld a,whlcd
  1250.         ld (de),a
  1251.         inc de
  1252.         call glbl       ;get lbl z (object of the goto later)
  1253.         push hl
  1254.         call insls
  1255.         call glbl       ;get lbl x
  1256.         call cnpsh
  1257.         push hl         ;push lbl x
  1258.         ld a,open
  1259.         ld (de),a
  1260.         inc de
  1261.         call igsht
  1262.         cp semi
  1263.         jp nz,sfor3
  1264.         ld a,-3 and 255
  1265.         call mvtxt
  1266.         ld a,concd
  1267.         ld (de),a
  1268.         inc de
  1269.         ld a,1
  1270.         ld (de),a
  1271.         inc de
  1272.         ld a,0
  1273.         ld (de),a
  1274.         inc de
  1275.         jp sfor4
  1276.  
  1277. sfor3:  call chsbp
  1278.         call fsemi
  1279. sfor4:  ld a,close
  1280.         ld (de),a
  1281.         inc de
  1282.         call glbl       ;get lbl y
  1283.         ex (sp),hl              ;HL = lbl x, stack = lbly
  1284.         push hl         ;push lbl x
  1285.         push de
  1286.         ld a,negone
  1287.         call mvtxt
  1288.         ld a,open
  1289.         ld (de),a
  1290.         push de
  1291.         inc de
  1292.         lhld nlcnt
  1293.         shld nltmp
  1294.         call igsht
  1295.         cp close
  1296.         jp z,sfor4a
  1297.         pop de
  1298.         jp sfor4b
  1299. sfor4a: ld a,-3 and 255
  1300.         call mvtxt
  1301.         ld a,concd
  1302.         ld (de),a
  1303.         inc de
  1304.         ld a,1
  1305.         ld (de),a
  1306.         inc de
  1307.         xor a
  1308.         ld (de),a
  1309.         pop de
  1310.  
  1311. sfor4b: call mtchp
  1312.         lhld nlcnt
  1313.         push de
  1314.         ex de,hl
  1315.         lhld nltmp
  1316.         call cmh
  1317.         add hl,de
  1318.         pop de
  1319.         ld a,l
  1320.         sta nltmp2
  1321. sfor5:  pop hl
  1322.         push hl
  1323.         push hl
  1324.         call cmh
  1325.         add hl,de
  1326.         pop de
  1327.         shld tmplf
  1328.         lhld fbufp
  1329.         ld b,h
  1330.         ld c,l
  1331.         ex (sp),hl
  1332.         push hl
  1333.         lhld tmplf
  1334.         ld h,l
  1335.  
  1336. sfor6:  ld a,(de)
  1337.         ld (bc),a
  1338.         inc de
  1339.         inc bc
  1340.         dec l
  1341.         jp nz,sfor6
  1342.         push hl
  1343.         ld h,b
  1344.         ld l,c
  1345.         shld fbufp
  1346.         pop hl
  1347.         pop de
  1348.         ld a,lbrcd
  1349.         ld (de),a
  1350.         inc de
  1351.         ld a,h
  1352.         push af
  1353.         push af
  1354.         dec a
  1355.         call mvtxt
  1356.         lda nltmp2
  1357.         push af
  1358.         cpl
  1359.         inc a
  1360.         call mvtxt
  1361.         pop af
  1362. sf6a:   or a
  1363.         jp z,sf6b
  1364.         push af
  1365.         ld a,nlcd
  1366.         ld (de),a
  1367.         inc de
  1368.         pop af
  1369.         dec a
  1370.         jp sf6a
  1371.  
  1372. sf6b:   call state
  1373.         call cnpop
  1374.         pop af
  1375.         cpl
  1376.         sub 14
  1377.         call mvtxt
  1378.         ld a,semi
  1379.         ld (de),a
  1380.         inc de
  1381.         pop af
  1382.         pop hl
  1383.         ld b,h
  1384.         ld c,l
  1385.         shld fbufp
  1386.         pop hl          ;get lbl x
  1387.         push af
  1388.         push bc
  1389.         call insls      ;define lbl x here
  1390.         pop bc
  1391.         pop af
  1392.         ld h,a
  1393. sfor7:  ld a,(bc)               ;now copy the saved increment portion
  1394.         cp nlcd ;back into the text
  1395.         jp nz,sfor7a    ;but watch out for newlines
  1396.         dec de          ;and especially FAKE newlines (a la Somos)
  1397.         ld a,(de)
  1398.         inc de          ;if a newline found, make sure it isn't
  1399.         call cdtst      ;just the operand of a 3-byte code
  1400.         ld a,(bc)
  1401.         jp nc,sfor7a    ;if it is, leave it as it is
  1402.         ld a,0ffh       ;it isn't, so turn it into a garbage space
  1403. sfor7a: ld (de),a
  1404.         inc de
  1405.         inc bc
  1406.         dec h
  1407.         jp nz,sfor7
  1408.         ld a,semi
  1409.         ld (de),a
  1410.         inc de
  1411.         ld a,rbrcd
  1412.         ld (de),a
  1413.         inc de
  1414.         pop hl          ;get lbl y
  1415.         ex (sp),hl
  1416.         ld a,gotcd      ;put in the kludge "goto" to go with the "while"
  1417.         ld (de),a
  1418.         inc de
  1419.         call insrs
  1420.         ld a,semi
  1421.         ld (de),a
  1422.         inc de
  1423.         pop hl
  1424.         call insls
  1425.         ld a,rbrcd
  1426.         ld (de),a
  1427.         inc de
  1428.         ret
  1429.  
  1430. chsbp:  push de
  1431.         lhld nlcnt
  1432.         push hl
  1433. chsbp1: call pascd
  1434.         cp semi
  1435.         jp z,chsok
  1436.         cp open
  1437.         jp z,chsbpp
  1438.         cp close
  1439.         jp nz,chsbp2
  1440.         pop hl
  1441.         shld nlcnt
  1442.         ld hl,stgc6
  1443.         jp perrab
  1444.  
  1445. chsok:  pop hl
  1446.         shld nlcnt
  1447.         pop de
  1448.         ret
  1449. chsbp2: inc de
  1450.         jp chsbp1
  1451. chsbpp: call mtchp
  1452.         jp chsbp1
  1453.  
  1454. ;
  1455. ; Process a "switch" statement:
  1456. ;
  1457.  
  1458. sswt:   call mtchp
  1459.         push de
  1460.         lhld cntp
  1461.         push hl
  1462.         dec hl
  1463.         dec hl
  1464.         dec hl
  1465.         ld b,(hl)
  1466.         dec hl
  1467.         ld c,(hl)
  1468.         pop hl
  1469.         ld (hl),c
  1470.         inc hl
  1471.         ld (hl),b
  1472.         inc hl
  1473.         ex de,hl
  1474.  
  1475.         call glbl
  1476.         shld defp       ;set "default" default label
  1477.  
  1478.         push af
  1479.         xor a
  1480.         sta defflg      ;haven't encountered default: yet
  1481.         pop af
  1482.  
  1483.         ex de,hl
  1484.         ld (hl),e
  1485.         inc hl
  1486.         ld (hl),d
  1487.         inc hl
  1488.         shld cntp
  1489.         pop de
  1490.         lhld defp
  1491.         push hl
  1492.         push de
  1493.         cp lbrcd
  1494.         jp z,ssw0
  1495.         ld hl,stgc8
  1496.         call perr
  1497.         call fsemi
  1498.         pop hl
  1499.         pop hl
  1500.         ret
  1501.  
  1502. ssw0:   lhld nlcnt
  1503.         shld tmpnl
  1504.         xor a
  1505.         sta swtc
  1506.         sta casoff
  1507.         ld hl,swtt
  1508.         shld swtp
  1509.         ld hl,clev
  1510.         inc (hl)
  1511.         inc de
  1512.  
  1513. ssw0a:  call igsht
  1514. ssw1:   ld a,(de)
  1515.         cp lblcd
  1516.         jp nz,ssw1a
  1517.         inc de
  1518.         inc de
  1519.         inc de
  1520.         jp ssw0a
  1521.  
  1522. ssw1a:  cp cascd
  1523.         jp z,sscas
  1524.         cp defcd
  1525.         jp z,ssdef
  1526.         cp rbrcd
  1527.         jp z,ssdon
  1528. ssw2:   call passt
  1529.         jp ssw1
  1530.  
  1531. sscas:  inc de
  1532.         push de
  1533.         call pasff
  1534.         cp concd
  1535.         jp z,ccas2
  1536.         pop de
  1537.         ld hl,stgc9
  1538. ccas1:  call perr
  1539.         jp ssw2
  1540.  
  1541. ccas2:  inc de
  1542.         lhld swtp
  1543.         ld a,(de)
  1544.         ld (hl),a
  1545.         inc de
  1546.         inc hl
  1547.         ld a,(de)
  1548.         ld (hl),a
  1549.         inc hl
  1550.         inc de
  1551. pasloop:
  1552.         ld b,c
  1553.         call pasff
  1554.         push af
  1555.         ld a,b
  1556.         add c
  1557.         ld c,a
  1558.         pop af
  1559.         cp nlcd
  1560.         jp nz,ccas2a
  1561.         ld a,c
  1562.         or 80h
  1563.         ld c,a
  1564.         inc de
  1565.         jp pasloop
  1566. ccas2a:
  1567.         cp colon
  1568.         jp z,ccas3
  1569.  
  1570. ccas4:  ld hl,stgc9
  1571.         jp ccas1
  1572.  
  1573. ccas3:  ex de,hl
  1574.         call glbl
  1575.         ex de,hl
  1576.         ld (hl),e
  1577.         inc hl
  1578.         ld (hl),d
  1579.         inc hl
  1580.         lda casoff
  1581.         or a
  1582.         jp nz,ccas3a
  1583.         shld swtp
  1584. ccas3a: ex de,hl
  1585.         pop de
  1586.         dec de
  1587.         ld a,c
  1588.         add a,2
  1589.         jp p,ccas3c
  1590.         and 7fh
  1591.         ld c,a
  1592.         ld a,nlcd
  1593.         ld (de),a
  1594.         inc de
  1595.         ld a,c
  1596. ccas3c: call mvtxt
  1597.         call insls
  1598.         lda casoff
  1599.         or a
  1600.         jp nz,ccas3b
  1601.         ld hl,swtc
  1602.         inc (hl)
  1603.         ld a,(hl)
  1604.         cp 201
  1605.         jp c,ccas3b
  1606.         sta casoff
  1607.         dec (hl)
  1608.         ld hl,stgcof
  1609.         call perr
  1610. ccas3b: jp ssw0a
  1611.  
  1612. pasff:  ld c,0
  1613. pasff1: ld a,(de)
  1614.         cp 0ffh
  1615.         ret nz
  1616.         inc c
  1617.         inc de
  1618.         jp pasff1
  1619.  
  1620. ssdef:  push de
  1621.         inc de
  1622.         call pasff
  1623.         cp colon
  1624.         pop de
  1625.         jp nz,ccas4
  1626.         ld a,2
  1627.         add c
  1628.         call mvtxt
  1629.         call lblni
  1630.         shld defp
  1631.         lda defflg      ;default previously defined?
  1632.         or a            ;set NZ if so
  1633.         ld a,1
  1634.         sta defflg      ;it is now, anyway
  1635.  
  1636.         ld hl,stgddf    ;duplicate default message
  1637.         call nz,perr    ;if default previously defined, bitch
  1638.         jp ssw0a
  1639.  
  1640.  
  1641. ssdon:  pop de
  1642.         lda swtc
  1643.         ld l,a
  1644.         ld h,0
  1645.         add hl,hl
  1646.         add hl,hl
  1647.         push hl
  1648.         inc hl
  1649.         inc hl
  1650.         inc hl
  1651.         inc hl
  1652.         call bexp
  1653.         ld a,swtbc
  1654.         ld (de),a
  1655.         inc de
  1656.         lda swtc
  1657.         ld (de),a
  1658.         inc de
  1659.         ld hl,swtt
  1660.         pop bc
  1661. ssdn1:  ld a,b
  1662.         or c
  1663.         jp z,ssdn2
  1664.         ld a,(hl)
  1665.         ld (de),a
  1666.         inc de
  1667.         inc hl
  1668.         dec bc
  1669.         jp ssdn1
  1670.  
  1671. ssdn2:  lhld defp
  1672.         ld a,l
  1673.         ld (de),a
  1674.         inc de
  1675.         ld a,h
  1676.         ld (de),a
  1677.         inc de
  1678.         lhld tmpnl
  1679.         shld nlcnt
  1680.         call state
  1681.         pop hl
  1682.         call insll
  1683.         call cnpop
  1684.         ret
  1685.  
  1686. ;
  1687. ; Process IF statement:
  1688. ;
  1689.  
  1690. sif:    call mtchp
  1691.         call state
  1692.         call igsht
  1693.         cp elscd
  1694.         ret nz
  1695.         inc de
  1696.         call state
  1697.         ret
  1698.  
  1699. ;
  1700. ; Process a "while" statement:
  1701. ;
  1702.  
  1703. swhl:   call lblni
  1704.         push hl
  1705.         call cnpsh
  1706.         call mtchp
  1707.         call glbl
  1708.         push hl
  1709.         call state
  1710.         pop hl
  1711.         ex (sp),hl
  1712.         ld a,-5 and 255
  1713.         call mvtxt      ;insert a forced "goto" to before the condition
  1714.         ld a,gotcd      ;test, so that things don't get messed up when
  1715.         ld (de),a               ;single-statement control structure is nested in
  1716.         inc de          ;a very peculiar way.
  1717.         call insrs
  1718.         ld a,semi
  1719.         ld (de),a
  1720.         inc de
  1721.         pop hl
  1722.         call insll
  1723.         call cnpop
  1724.         ret
  1725.  
  1726. ;
  1727. ; Process "do" statement:
  1728. ;
  1729.  
  1730. sdo:    call lblni
  1731.         inc hl
  1732.         call cnpsh
  1733.         push hl
  1734.         inc hl
  1735.         inc hl
  1736.         shld lbln
  1737.         call state
  1738.         call igsht
  1739.         cp whlcd
  1740.         jp z,sdo2
  1741.         ld hl,stgc2
  1742.         call perr
  1743. sdo2:   inc de
  1744.         pop hl
  1745.         call insll
  1746.         call mtchp
  1747.         push hl
  1748.         call esemi
  1749.         inc de
  1750.         pop hl
  1751.         inc hl
  1752.         call insll
  1753.         call cnpop
  1754.         ret
  1755.  
  1756. ;
  1757. ; Process "break" statement:
  1758. ;
  1759.  
  1760. sbrk:   call cklev
  1761.         dec de
  1762.         ld a,gotcd
  1763.         ld (de),a
  1764.         inc de
  1765.         lhld cntp
  1766.  
  1767. sbrk2:  dec hl
  1768.         ld a,(hl)
  1769.         dec hl
  1770.         ld l,(hl)
  1771.         ld h,a
  1772.         call inslr
  1773.  
  1774. sbrk3:  lhld nlcnt
  1775.         shld esadr
  1776.         call esemi
  1777.         inc de
  1778.         call igsht
  1779.         ret
  1780.  
  1781. ;
  1782. ; Process "continue" statement:
  1783. ;
  1784.  
  1785. scnt:   call cklev
  1786.         dec de
  1787.         ld a,gotcd
  1788.         ld (de),a
  1789.         inc de
  1790.         lhld cntp
  1791.         dec hl
  1792.         dec hl
  1793.         jp sbrk2
  1794.  
  1795.  
  1796.         IF LASM
  1797.         link ccb
  1798.         ENDIF
  1799.