?login_element?

Subversion Repositories NedoOS

Rev

Rev 632 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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