INCLUDE BDS.LIB INCLUDE EPDATA newline equ 10 .request WADJUST .comment ` /* CSEQ and related functions Greg Lee, 2/84 */ /************************************************/ /* Processing of commands */ /* If a character is returned, it will */ /* be put in outbuf */ /************************************************/ char cseq() {/* int arg, typeval, measure, divisor; */ /* char dt3, dt4, dt5, eqref, havearg; */ eqref = FALSE; scanwhite(FALSE); /* first char of command */ dt1 = inbuf[inpoint]; /* if eol, continue to next */ if (!dt1 || dt1 == '\n') { newinline(); fgets(inbuf); return(0); } /* '\\' is '\' */ if (dt1 == ec) { inpoint++; scrncol++; return(dt1); } /* '}' is use all blocks on input line */ if (dt1 == '}' && brcpt[cc]) { inpoint++; scrncol++; allmode = mode; mode = brcstk[cc][--brcpt[cc]]; return(0); } if (dt1 == '{') { modepush(); return(0); } /* < is backspace */ if (dt1 == '<') {scanwhite(TRUE); return('\b'); } /* comment */ if (dt1 == '*') {inbuf[inpoint] = '\0'; return(0); } /* reference to value */ if (dt1 == '=') { scanwhite(TRUE); eqref = TRUE; dt1 = inbuf[inpoint]; } /* maybe a character given by numeric value */ if (isdigit(dt1)) { dt1 = numscan(); scanwhite(FALSE); dt2 = 0; } else { dt2 = inbuf[++inpoint]; scrncol++; dt3 = inbuf[inpoint+1]; if (isalpha(dt2) || dt2 == '0' || dt2 == '1') scanwhite(TRUE); else scanwhite(FALSE); } /* Now we have both command letters */ /* If both alphabetic, it's a run-off type command */ if (isalpha(dt1) && isalpha(dt2)) { dt1 = toupper(dt1); dt2 = toupper(dt2); if (isalpha(dt3) || dt3 == '-') getrlets(); typeval = valtp[dt1-'@'][dt2-'@']; arg = val[dt1-'@'][dt2-'@']; if (eqref) {inject(arg); return(0); } if (typeval & BRK) {brkflag = TRUE; prtsbuf(); } if (typeval & FLAGCH) return(arg); if (typeval & CHARG) { dt3 = inbuf[inpoint]; if (dt3 == '\n') dt3 = 0; val[dt1-'@'][dt2-'@'] = dt3; if (dt3) scanwhite(TRUE); return(0); } if (dt1 == 'I' && dt2 == 'M') { extract(fnbuf); strcat(fnbuf,".TXT"); /* ??? */ if (fopen(fnbuf) != ERROR) return(0); eperror(110); } if (dt1 == 'N' && dt2 == 'B') { brkflag = FALSE; prtsbuf(); return(0); } arg = TRUE; havearg = FALSE; measure = divisor = 0; if (isdigit(inbuf[inpoint])) { arg = numscan(); havearg = TRUE; if (inbuf[inpoint] == '/') { inpoint++; scrncol++; divisor = numscan(); } switch (toupper(inbuf[inpoint])) { case '.': measure = 1; break; case 'P': measure = POINT; break; case '"': if (typeval & HZNUM) measure = INCH; else if (typeval & VTNUM) measure = VINCH; break; default: inpoint--; scrncol--; break; } scanwhite(TRUE); } else if (inbuf[inpoint] == '=') { havearg = TRUE; scanwhite(TRUE); if (!isalpha(dt4 = toupper(inbuf[++inpoint]))) return(0); dt5 = dt2; if (!isalpha(dt2 = toupper(inbuf[++inpoint]))) return(0); if (isalpha(dt3 = inbuf[++inpoint]) || dt3 == '-') getrlets(); arg = val[dt4-'@'][dt2-'@']; dt2 = dt5; scrncol += 3; } else if (dt1 == 'F' && dt2 == 'O') arg = grabfont(); if (typeval & (HZNUM | VTNUM)) { if (!measure) measure = (typeval & VTNUM) ? PICA+sl : PICA; arg *= measure; if (divisor) arg = (arg + divisor - 1)/divisor; } if (typeval & EPSSYN) { dt1 = val[dt1-'@'][dt2-'@']; if (!arg) { dt2 = '0'; switch (dt1) { case 'E': case 'G': case 4: dt1++; break; case 'M': case 15: dt1 += 3; break; case 'S': case '0': dt1 = 'T'; break; } } else if (dt1 == '0') { dt1 = 'S'; dt2 = '0'; } epscommand(); return(0); } if (dt1 == 'B' && dt2 == 'E') { if (havearg) { brkflag = TRUE; prtsbuf(); } else { modepush(); if (arg) mode |= BENT; else mode &= ~BENT; return(0); } } val[dt1-'@'][dt2-'@'] = arg; if (dt1 == 'N' && dt2 == 'C') if (arg > 1) { for (cc = 1; cc <= nc; cc++) { brcpt[cc] = 1; brcstk[cc][0] = mode; } cc = 1; } else nc = 0; if (typeval & BRK) newoutline(); if (dt1 == 'C' && dt2 == 'L') gotocol(arg); else if (dt1 == 'S' && dt2 == 'K') skdots += arg; else if (dt1 == 'F' && dt2 == 'O') { modepush(); if (arg < 32 && attach[arg]) mode = attach[arg]; if (arg > 7) { arg = mode & 0x700; fo = arg >> 8; } else arg <<= 8; mode = (mode & 0xF8FF) | arg; } else if (dt1 == 'T' && dt2 == 'A') { modepush(); if (arg) mode |= TALL; else mode &= ~TALL; } else if (dt1 == 'I' && dt2 == 'F') { modepush(); if (arg) mode |= IGNORE; else mode &= ~IGNORE; } else if (dt1 == 'A' && dt2 == 'T') { if (!havearg) arg = fo; if (arg < 32) attach[arg] = mode; } } /* Otherwise, it's an Epson type command */ else epscommand(); return(0); } ` ext newinlin,newoutli,loadft,fprefix ext prtsbuf,gotocol,hzspace,inject,eperror,fgets ext fopen,strcat,strcmp,strcpy cseq:: push b ;keep dt1 in C and dt2 in B ;push location most common exit point so can use 'ret' instead of 'jmp' lxi h,csret0 push h cpi '\' jnz cs_control ; ; eqref = FALSE; mvi a,false sta eqref ; ; scanwhite(FALSE); ;A still FALSE call scanwhit ; ; /* first char of command */ ; dt1 = inbuf[inpoint]; call inbch cs_control: mov c,a ; ; /* if eol, continue to next */ ; if (!dt1 || dt1 == '\n') ; { newinline(); ; fgets(inbuf); ; return(0); ; } ora a jz cs1 cpi newline jnz cs2 cs1: lxi h,0 lda val + 54*('R'-'@') + 2*('L'-'@') ora a jnz $+6 shld inpoint xra a sta scrncol ;tab action will not be correct ; call newinlin ;don't want all newinline actions lhld inpoint ;usually 0 lxi d,inbuf dad d push h call fgets pop d ret ; ; /* '\\' is '\' */ ; if (dt1 == ec) ; { inpoint++; scrncol++; ; return(dt1); ; } cs2: lhld ec cmp l jnz cs3 call nxspnt pop h mov l,c mvi h,0 pop b ret ; ; /* '}' is use all blocks on input line */ ; if (dt1 == '}' && brcpt[cc]) ;(ch. so brcpt[cc]=0 does not prevent) ; { inpoint++; scrncol++; ; allmode = mode; ; mode = brcstk[cc][--brcpt[cc]]; ; return(0); ; } cs3: cpi '}' jnz cs4 call nxspnt lhld mode shld allmode call get_brc MOV A,E ;replaces "&& brcpt[cc]" ORA D rz dcx d mov m,d dcx h mov m,e xchg dad h PUSH H lhld cc lxi d,12 call usmul lxi d,brcstk dad d pop d dad d mov a,m inx h mov h,m mov l,a shld mode ret ; ; if (dt1 == '{') { modepush(); return(0); } cs4: cpi '{' jz modepush ; ; /* < is backspace */ ; if (dt1 == '<') {scanwhite(TRUE); return('\b'); } cs5: cpi '<' jnz cs6 ; mvi a,ttrue call scanwhit pop h lxi h,BCKFLAG ;was 8 pop b ret ; ; /* comment */ ; if (dt1 == '*') {inbuf[inpoint] = '\0'; return(0); } cs6: cpi '*' jnz cs7 call nxspnt ;scan over the '*' cs6a: pop h ;discard csret0 ret lxi h,0ffh ;signal end of input line pop b ret ; ; /* reference to value */ ; if (dt1 == '=') ; { scanwhite(TRUE); ; eqref = TRUE; ; dt1 = inbuf[inpoint]; ; } cs7: cpi '=' jnz cs8 mvi a,1 sta eqref call scanwhit call inbch mov c,a ; ; /* maybe a character given by numeric value */ ; if (isdigit(dt1)) ; { dt1 = numscan(); ; scanwhite(FALSE); ; dt2 = 0; ; } cs8: cpi '(' jnz cs8.1 call csterm jmp cs8.2 cs8.1: ;^char = '\=$char' cpi ' ' jnc cs8.1a ori '@' cpi 'Z' rnc mov l,a jmp cs12a.1 cs8.1a: cpi '^' jnz cs8a call nxspnt call inbch ani 1fh mov c,a call nxspnt ;use this char mov l,c cs8.2: pop d mvi h,0 pop b ret cs8a: call isdec jc cs9 call numscan mov a,l mov c,a cs8b: xra a mov b,a call scanwhit ;Change: now not to Epson if 20h mov l,c mvi a,' ' cmp l jnz cs12 ;rather use this char pop d mvi h,0 pop b ret ; else ; { dt2 = inbuf[++inpoint]; ; scrncol++; ; dt3 = inbuf[inpoint+1]; ; if (isalpha(dt2) || dt2 == '0' || dt2 == '1') ; scanwhite(TRUE); ; else scanwhite(FALSE); ; } cs9: call nxspnt mov a,c cpi '.' rz cpi '-' mvi l,SOFTHY jz cs8.2 cpi ',' jz sw1 call inbch mov b,a INX H MOV A,M STA DT3 mov a,b call up$alph jnc cs10 mov a,c cpi '$' jz cs12 ;check for Fdig cpi 'f' mov a,b jnz cs9a call isdec jc cs9a sui '0' mov l,a mvi h,0 shld arg inr a call scanwhit jmp cs_FO cs9a: ; mov a,b cpi '0' jz cs10 cpi '1' JZ CS10 xra a cs10: call scanwhit ; ; /* Now we have both command letters */ ; ; /* If both alphabetic, it's a run-off type command */ ; if (isalpha(dt1) && isalpha(dt2)) ; { dt1 = toupper(dt1); dt2 = toupper(dt2); ; if (isalpha(dt3) || dt3 == '-') getrlets(); cs12: mov a,c call up$alph jc epscomma mov l,a ;check for '$'digit cpi '@' jnz cs12a mov a,b call isdec jc cs12a call numscan ;$1->main file name inx h ;$1->1st com-line arg lda gargc dcr a cmp l rc dad h ;word array xchg lhld gargv dad d mov a,m inx h mov h,m mov l,a push h ; xra a ; call scanwhit call sw1 pop h jmp sdirect cs12a: mov a,b ;small letter followed by non-alpha is short for \=$ call up$alph jnc cs12b mov a,c cpi '$' jz cs12a.1 cpi 'a' jc cs12b cpi 'z'+1 jnc cs12b cs12a.1: mvi b,'$' mvi a,ttrue sta eqref sta dt3 cs12b: mov a,b call up$alph jc epscomma ;change the 2 letters to upper case mov b,a mov c,l lda dt3 cpi '-' jz cs13 call upalph jc cs13a cs13: call getrlets cs13a: ;allow for some synonyms lxi h,cs14 push h lxi h,..syns-2 cs13b: inx h inx h mov a,m ora a rz inx h mov d,m inx h cmp c jnz cs13b mov a,d cmp b jnz cs13b mov c,m inx h mov b,m ret ;(this ought to be made configurable) ..syns: db 'FI','CO' db 'LE','SL' db 'LM','AD' db 0 ; ; typeval = valtp[dt1-'@'][dt2-'@']; ; arg = val[dt1-'@'][dt2-'@']; ;cs14: varval: mov l,c mvi h,0 lxi d,-'@' dad d lxi d,27 call usmul PUSH H lxi d,valtp dad d push h mov l,b mvi h,0 lxi d,-'@' dad d pop d dad d MOV A,M STA TYPEVAL shld typvadr ;if macro, treat as '\=...' lxi h,eqref ani MCRO ora m mov m,a ;[dt1-'@'] POP H ;val is word array DAD H lxi d,val dad d ;val[dt1-'@'] push h mov l,b mvi h,0 lxi d,-'@' dad d ;...[dt2-'@'] word ref. dad h pop d dad d SHLD VLDTADR mov a,m inx h mov h,m mov l,a shld arg ret cs14: call varval shld oldarg ; ; if (eqref) {inject(arg); return(0); } LDA eqref ora a jz cs15 ;check for STRING here, and if so, redirect input ani MCRO jnz cs14s mvi a,'@' cmp c jnz cs14v cmp b jnz cs14s ;here it was '\=$$' call sundirect ; xra a ; jmp scanwhit jmp sw1 cs14v: cmp b jnz cs14a cs14s: ;arg still in HL mov a,h ora l ;if nothing stored for this string variable, ignore it jnz sdirect ret cs14a: ;arg still in HL push h call inject pop d ret ; ; if (typeval & BRK) {brkflag = TRUE; prtsbuf(); } cs15: LDA TYPEVAL mov e,a ani BRKAFT mov a,e jz cs15a sta bkaft cs15a: ANI BRK ; jz cs15b cnz csprtsbuf jmp cs15b ;the coming call to prtsbuf may lead to other cseq calls for ;headings or footings, so have to save some values now csprtsbuf: lhld vldtadr push h lhld arg push h lda typeval push psw lhld typvadr push h mvi a,1 sta brkflag call prtsbuf pop h shld typvadr pop psw sta typeval pop h shld arg shld oldarg pop h shld vldtadr ret ;check for no num. arg cs15b: lda typeval mov e,a ani ARGTRUE cpi ARGTRUE jnz cs16 lxi h,1 shld arg jmp cs56 ; ; if (typeval & FLAGCH) return(arg); cs16: ; LDA TYPEVAL ; mov e,a mov a,e ANI FLAGCH jz cs17 ;check for in-adjust and out-adjust lda pn ani 1 mov e,a mov a,c cpi 'I' jnz cs16o mov a,e xri 1 mov e,a jmp cs16p ; mov a,c cs16o: cpi 'O' jnz cs16a cs16p: mov a,b cpi 'A' jnz cs16a ;if even page and out-adjust, no action ; lda pn ; ani 1 mov a,e ora a rz cs16a: lda arg cpi PAFLAG jz getchar## pop h mov l,a mvi h,0 pop b ret ; ; if (typeval & CHARG) ; { dt3 = inbuf[inpoint]; ; if (dt3 == '\n') dt3 = 0; ; val[dt1-'@'][dt2-'@'] = dt3; ; if (dt3) scanwhite(TRUE); ; return(0); ; } ;(keep "dt3" in A) cs17: ; LDA TYPEVAL mov a,e ani CHARG jz cs20 call inbch call isdec jc cs17a call numscan mov a,l jmp cs18 ;(blanks will not be skipped after '0') cs17a: cpi newline jnz cs18 xra a cs18: lhld vldtadr mov m,a ora a jnz scanwhit ret ;to next csret0: lxi h,0 pop b ret cs20: ;this seems a good place to store a string mvi a,'@' cmp c jz cs$S cmp b jnz cs20a cs$S: push b ;use C for last char lhld _$point shld arg push h cs$L: call inbch ora a jz cs$d cpi 0ah jz cs$d pop h mov m,a mov c,a inx h push h call nxspnt jmp cs$L cs$d: pop h ;see if had '\' at eol lda ec cmp c jnz cs$e ;if so, back to store over it and continue with new input line dcx h push h call cs1 jmp cs$L ;else time to quit cs$e: mvi m,0 inx h shld _$point freram equ 011BH ;have we overlapped into font storage area? xchg lhld freram call albu jc cs$ok ;yes, we have -- allot 512 more bytes for string storage inr h inr h shld freram ;reset allocation pointers call freeall## ;mark any resident fonts as unallocated xra a mvi e,NUMFTS*2 lxi h,ftp cs$ua: mov m,a inx h dcr e jnz cs$ua cs$ok: pop b jmp cs56 ;go store arg in variable ; ; if (dt1 == 'I' && dt2 == 'M') ; { extract(fnbuf); ;add call to fprefix() ;extract changed so it will get extension, too ; strcat(fnbuf,".TXT"); /* ??? */ ; if (fopen(fnbuf) != ERROR) return(0); ; eperror(110); ; } cs20a: mov a,c cpi 'I' jnz cs22 mov a,b cpi 'M' jnz cs22 lxi h,fnbuf push h push h call fprefix pop d ;extract arg in HL = fnbuf, which was on stack pop h push h call extract pop h rc ;fnbuf address is still on the sttack ; lxi h,fnbuf push h call fopen pop d inx h mov a,h ora l rnz lxi h,110 push h call eperror ; ; if (dt1 == 'N' && dt2 == 'B') ; { brkflag = FALSE; ; prtsbuf(); ; return(0); ; } cs22: mov a,c cpi 'N' jnz cs23 mov a,b cpi 'B' jnz cs23 xra a sta brkflag jmp prtsbuf ; ; arg = TRUE; ; havearg = FALSE; ; measure = divisor = 0; cs23: xra a sta havearg call csnumini ; ; if (isdigit(inbuf[inpoint])) ; { arg = numscan(); havearg = TRUE; ; ; if (inbuf[inpoint] == '/') ; { inpoint++; scrncol++; ; divisor = numscan(); ; } ; ; switch (toupper(inbuf[inpoint])) ; { case '.': measure = 1; break; ; case 'P': measure = POINT; break; ; case '"': if (typeval & HZNUM) ; measure = INCH; ; else if (typeval & VTNUM) ; measure = VINCH; break; ; default: inpoint--; scrncol--; break; ; } ; ; scanwhite(TRUE); ; } call inbch sta argsign cpi '+' jz cs23a cpi '-' jnz cs23b cs23a: call scanwhit call inbch cs23b: call isdec jc cs35 lxi h,measure dcr m ;back to 0 call dimdnum jmp cs44a csnumini: lxi h,0 shld divisor inx h shld measure shld arg ret dimdnum: call numscan shld arg mvi a,1 sta havearg ;;- LDA TYPEVAL ;;- ANI HZNUM OR VTNUM ;;- JZ CS33 ;A = 0, so pass false to scanwhit call inbch cpi '/' jnz cs24 call nxspnt call numscan shld divisor cs24: call inbch call upalph lxi h,1 cpi '.' jz cs32 ;A not 0, so pass true to scanwhit lxi h,point cpi 'P' jz cs32 ;A not 0, so pass true to scanwhit cpi '"' mvi a,0 ;pass FALSE to scanwhit jnz cs33 ; case '"': if (typeval & HZNUM) ; measure = INCH; ; else if (typeval & VTNUM) ; measure = VINCH; break; lda typeval lhld typvadr ora m lxi h,VINCH ani VTNUM jnz cs32 lxi h,INCH cs32: inr a ;pass TRUE to scanwhite shld measure cs33: call scanwhit jmp dimension ; else if (inbuf[inpoint] == '=') ; { havearg = TRUE; ; scanwhite(TRUE); ; if (!isalpha(dt4 = toupper(inbuf[++inpoint]))) ; return(0); ; dt5 = dt2; ; if (!isalpha(dt2 = toupper(inbuf[++inpoint]))) ; return(0); ; if (isalpha(dt3 = inbuf[++inpoint]) || dt3 == '-') ; getrlets(); ; arg = val[dt4-'@'][dt2-'@']; ; dt2 = dt5; ; scrncol += 3; ; } cs35: ;'=' is implicit after \if mov a,c cpi 'I' jnz cs35a mov a,b cpi 'F' jz cs35b cs35a: call inbch cpi '=' jnz cs40 call scanwhit cs35b: mvi a,ttrue sta havearg call inbch call isdec jc cs35c ;here it's '... = number' call dimdnum jmp cs39b ;(if STRING here, will get pointer) cs35c: ;(moved above) ;; mvi a,ttrue ;; sta havearg push b ;save key letters call vvarval jmp cs39a vvarval: ;make sure contents of var is interpreted as dots or 'n' or 'b' ;;- lxi h,1 ;;- shld measure call inbch call up$alph jc funnyvar mov c,a call nxspnt ;scan over 1st letter call inbch call up$alph ;if c = @ and have digit here, may wish to test gargc jc funnyvar mov b,a call nxspnt ;scan over 2nd letter call inbch call up$alph jnc cs38 cpi '-' jnz cs39 cs38: call getrlets cs39: call sw1 ;;- lda typeval ;;- push psw mov a,b cpi 'P' jnz cs39np mov a,c cpi 'H' jnz cs39vp call getlindent## xchg lhld glen jmp cs39xp cs39vp: cpi 'V' jnz cs39np lhld vposition xchg lhld skdots cs39xp: dad d shld arg mov a,b ora a ret cs39np: lhld typvadr push h lhld vldtadr push h call varval pop h shld vldtadr pop h shld typvadr ;;- pop psw ;;- sta typeval ;if it was '... = ', signal to mark it as a macro mov a,c cpi '@' rz mov a,b cpi '@' ret cs39a: pop b ;get back key letters jz cs39c ;special case of var = string-var ;here we can expect the rest of an expression cs39b: call csexp1 ;;; jmp cs56 jmp cs44a csexp1: call cssterm call opletchk rnz ;well, here's a comparison operator push b ;save key letters mov c,a ;put op letter in C call nxspnt ;scan over it call inbch ;next possible op letter to B mov b,a call opletchk cz nxspnt ;if it is, scan it, too call sw1 ;over to beginning of next term call csterm ;set arg to val of next term push d ;save val of terms before comparison op call cssterm ;add or subtr any further terms ;cumulative returned in HL pop d call cscfterm ;determine value of comparison shld arg ;and that's the new arg pop b ;restore key letters ret cssterm: call csmterm cpi '+' jz $+6 cpi '-' rnz push psw call scanwhit call csterm push d call csmterm pop d pop psw cpi '+' jz $+6 call cmh dad d shld arg jmp cssterm csmterm: push h call inbch pop h cpi '*' jz $+6 cpi '/' rnz push psw call scanwhit call csterm pop psw cpi '*' jz $+9 call usdiv jmp $+6 call usmul shld arg jmp csmterm csterm: push h push d call inbch pop d pop h cpi '(' jnz csimple call scanwhit xra a sta vsflag call csterm push d call csexp1 call inbch cpi ')' jnz funnyvar call scanwhit lda vsflag ora a lhld arg pop d rz mov l,m mvi h,0 shld arg ret csimple: push b ;keep the op letters lhld arg ;save value of first term push h call inbch ;see if next is number call isdec jc cs39b.1 ;if not, must be a variable call csnumini call dimdnum jmp cs39b.2 cs39b.1: call vvarval jnz cs39b.2 sta vsflag cs39b.2: lhld arg ;this is value of 2nd term pop d ;this is first pop b ;here are the op letters ret vsflag: db 0 ;check if A has a possible comparison op letter opletchk: cpi '=' rz cpi '<' rz cpi '>' ret cscfterm: call eqwel mvi a,'=' jz .cft call albu mvi a,'<' jc .cft mvi a,'>' .cft: lxi h,1 cmp c rz cmp b rz dcx h ret cs39c: mvi a,MCRO sta typeval lhld typvadr mov m,a ;... and block further special actions in case redefining native word lxi b,0 ;... and go store argument jmp cs56 funnyvar: lxi h,146 push h call eperror## ; else if (dt1 == 'F' && dt2 == 'O') arg = grabfont(); cs40: mov a,c cpi 'G' jnz cs40a mov a,b cpi 'F' jz cs40b cs40a: mov a,c cpi 'F' jnz cs41 mov a,b cpi 'O' jnz cs41 xra a cs40b: sta gfflag call grabfont rc shld arg jmp cs56 ;? does not allow inc/dec ; ; if (typeval & (HZNUM | VTNUM)) ; { if (!measure) measure = ; (typeval & VTNUM) ? PICA+sl : PICA; ; arg *= measure; ; if (divisor) arg = (arg + divisor - 1)/divisor; ; } dimension: ;;- lda typeval ;;- mov e,a ;;- ani HZNUM or VTNUM ;;- rz lhld measure mov a,h ora l jnz cs44 lda typeval mov e,a ani VTNUM jnz cs42.0 mov a,e ani HZNUM inx h ;HL = 1 jz cs42 lxi h,PICA jmp cs42 cs42.0: lhld sl xchg lhld cheight dad d cs42: shld measure cs44: xchg lhld arg call usmul ;was smul shld arg lhld divisor mov a,h ora l rz push h ;make following divide a rounding operation xchg lhld arg dad d dcx h xchg ; DE = arg + (divisor - 1) pop h ; DE / divisor call usdiv ;was 'sdiv' shld arg ret cs41: ;here when no numerical argument lxi h,0 shld measure call dimension cs44a: ;get back type in case var. in expression had some different type lhld typvadr mov a,m sta typeval lhld arg xchg lhld oldarg lda argsign cpi '-' push psw cz cmd dad d pop psw jz cs44b cpi '+' jnz cs45 cs44b: shld arg sta havearg ; ; if (typeval & EPSSYN) ; { dt1 = val[dt1-'@'][dt2-'@']; ; if (!arg) ; { dt2 = '0'; ; switch (dt1) ; { case 'E': ; case 'G': ; case 4: ; dt1++; break; ; case 'M': ; case 15: ; dt1 += 3; break; ; case 'S': ; case '0': ; dt1 = 'T'; break; ; } ; } ; else if (dt1 == '0') { dt1 = 'S'; dt2 = '0'; } ; epscommand(); ; return(0); ; } cs45: lda typeval ani epssyn jz cs52 lhld vldtadr mov c,m lhld arg mov a,h ora l jnz cs50 mvi b,'0' mov a,c cpi 'E' jz cs46 cpi 'G' jz cs46 cpi 4 jz cs46 cpi 'M' jz cs47 cpi 15 jz cs47 cpi 'S' jz cs48 cpi '0' jz cs48 jmp cs51 cs46: inr a jmp cs50a cs47: adi 3 jmp cs50a cs48: mvi a,'T' jmp cs50a cs50: mov a,c cpi '0' jnz cs51 mvi b,'0' mvi a,'S' cs50a: mov c,a cs51: jmp epscomma ; ; if (dt1 == 'B' && dt2 == 'E') ; { if (havearg) ; { brkflag = TRUE; ; prtsbuf(); ; } ; else ; { modepush(); ; if (arg) mode |= BENT; ; else mode &= ~BENT; ; return(0); ; } ; } cs52: mov a,c cpi 'B' jnz cs56 mov a,b cpi 'E' jnz cs56 lda havearg ora a jz cs53 ; mvi a,1 ; sta brkflag ; call prtsbuf call csprtsbuf jmp cs56 cs53: call modepush lhld arg mov a,h ora l lhld mode jz cs54 ; lhld mode lxi d,bent mov a,h ora d mov h,a mov a,l ora e mov l,a jmp cs55 cs54: ; lhld mode lxi d,not bent ;0DFFFH mov a,h ana d mov h,a mov a,l ana e mov l,a cs55: shld mode ret ; ; val[dt1-'@'][dt2-'@'] = arg; cs56: lhld arg xchg lhld vldtadr mov m,e inx h mov m,d ; ; if (dt1 == 'N' && dt2 == 'C') ; if (arg > 1) ; { for (cc = 1; cc <= nc; cc++) ; { brcpt[cc] = 1; ; brcstk[cc][0] = mode; ; } ; cc = 1; ; } ; else nc = 0; mov a,c cpi 'N' jnz cs60 mov a,b cpi 'C' jnz cs60 lda arg cpi 2 jc cs59 lxi h,1 shld cc push b ;C = the column = 1 mov c,l ;B = nc + 1 inr a mov b,a cs57: xra a ;index from current C mov l,c mov h,a ;word index for brcpt dad h ;save a copy push h lxi d,brcpt dad d mvi m,1 inx h mov m,a pop h ;each col gets 6 words on stack lxi d,6 call usmul lxi d,brcstk dad d xchg lhld mode xchg mov m,e inx h mov m,d ;next col inr c mov a,c cmp b jnz cs57 cs58: pop b jmp cs60 cs59: lxi h,0 shld nc ; ; if (typeval & BRK) newoutline(); cs60: lda typeval mov e,a ani brk jz cs60.2 mov a,e ani HZNUM jz cs60.1 xra a sta mcinok cs60.1: call newoutli cs60.2: ;here begin various ad hoc actions for certain commands lxi h,.csTAB-3 .csSWLOOP: inx h inx h inx h mov a,m ora a rz inx h cmp c jnz .csSWLOOP mov a,m cmp b jnz .csSWLOOP inx h mov e,m inx h mov d,m xchg pchl .csTAB: db 'CL' dw cs_CL db 'TB' dw cs_TB db 'TS' dw cs_TB db 'HS' dw cs_HS db 'SK' dw cs_SK db 'SU' dw cs_SK db 'FO' dw cs_FO db 'TA' dw cs_TA db 'IF' dw cs_IF db 'AT' dw cs_AT db 'ER' dw cs_ER db 'GT' dw cs_GT db 'RU' dw cs_RU db 'WF' dw cs_WF db 'RL' dw cs_RL if lvers .request DRAW db 'NO' dw cs_NO db 'DR' dw cs_DR endif db 0 ; ; if (dt1 == 'C' && dt2 == 'L') gotocol(arg); cs_RL: lda arg ora a jz cs6a lhld inpoint shld rlpoint ret cs_CL: lhld arg push h call gotocol pop d ret if lvers cs_DR: jmp draw## cs_NO: lda arg cpi NUMLINES rnc mov l,a mvi h,0 lxi d,lilist dad h ;4 words each line dad h dad h dad d ;if one endpoint already defined, make this the other endpoint mov a,m inx h ora m dcx h jz $+7 inx h inx h inx h inx h ;enter v. position push h lhld vposition xchg lhld skdots dad d xchg pop h mov m,e inx h mov m,d inx h jmp .csRU1 endif cs_RU: lda arg cpi NUMRULES rnc mov l,a inr a sta grfflag ;; mov l,a cf. above mvi h,0 lxi d,rulist dad h ;2 words each rule (eventually 4?) dad h dad d ;if one endpoint already defined, make this the other endpoint mov a,m inx h ora m inx h jnz $+5 dcx h dcx h .csRU1: push h ;; call getlindent## call inover## xchg lhld mcoloffset dad d xchg jmp .csTB3 cs_CT: mvi e,32*2 xra a lxi h,utabs .csCT1: mov m,a inx h dcr e jnz .csCT1 ret cs_TB: mov d,a ;save 2nd letter lda arg mov e,a lda havearg ora a lxi h,nexttab jz $+4 mov m,e mov a,m inr m .csTB1: ;only 32 stops allowed cpi 32 rnc mov l,a mvi h,0 mov a,d lxi d,utabs dad h dad d ;HL -> value tab stop cpi 'S' jnz cs61v .csTB2: push h call getlindent## .csTB3: lhld glen dad d ;if 0, up a teeny bit so it counts as set mov a,h ora l jnz $+4 inx h xchg pop h mov m,e inx h mov m,d ret cs61v: mov e,m inx h mov d,m dcx h ;if no stop has been set, treat \tb as \ts (a la TEX) mov a,d ora e jz .csTB2 push d call gotocol pop d ret cs_HS: lhld arg push h call hzspace pop d ret cs_WF: lda havearg ora a lda arg jnz $+5 mvi a,100 call wadjust## shld st xchg shld sh ret ; else if (dt1 == 'S' && dt2 == 'K') skdots += arg; cs_SK: lhld skdots xchg lhld arg cpi 'U' ;was it skip-up? ;(added) ;check continuing vertical rules (will this work?) jnz docvrule## cz cmh dad d shld skdots ret ; else if (dt1 == 'F' && dt2 == 'O') ; { modepush(); ; ; if (arg < 32 && attach[arg]) mode = attach[arg]; ; ; if (arg > 7) ; { arg = mode & 0x700; ; fo = arg >> 8; ; } ; else arg <<= 8; ; ; mode = (mode & 0xF8FF) | arg; ; } cs_FO: call modepush lhld arg xchg lxi h,149 mov a,d ora a jnz cs_ER1 ;font >= 256? mov a,e cpi 32 jnc cs_ER1 xchg dad h lxi d,attach dad d mov a,m inx h mov h,m mov l,a ora h jz cs64 shld mode mov a,h ani 7 sta fo ret cs64: ;if no attachment, and arg > 7, that's an error lxi h,148 lda arg cpi 7+1 jnc cs_ER1 ;else OK, so enter into font var and mode sta fo mov e,a lda mode+1 ani 0f8h ora e jmp cs71 ; else if (dt1 == 'T' && dt2 == 'A') ; { modepush(); ; if (arg) mode |= TALL; ; else mode &= ~TALL; ; } cs_TA: call modepush LDA MODE+1 ANI (not tall) shr 8 MOV D,A lhld arg mov a,h ora l MOV A,D jz CS71 ;cs68 ORI tall shr 8 JMP CS71 ; else if (dt1 == 'I' && dt2 == 'F') ; { modepush(); ; if (arg) mode |= IGNORE; ; else mode &= ~IGNORE; ; } cs_IF: ;in case of 'if = ' remove macro designation lhld typvadr mvi m,0 ;if not looking a block in the face, just skip rest of line on false call inbch cpi '{' jz .csIF1 lhld arg mov a,h ora l rnz jmp cs6a ;return as for \* .csIF1: call modepush LDA MODE+1 ANI (not ignore) shr 8 MOV D,A lhld arg mov a,h ora l MOV A,D jnz cs71 ORI ignore shr 8 cs71: STA MODE+1 ret ; else if (dt1 == 'A' && dt2 == 'T') ; { if (!havearg) arg = fo; ; if (arg < 32) attach[arg] = mode; ; } cs_AT: LDA havearg ora a jnz cs74 lhld fo shld arg call dokern cs74: lhld arg mov a,h ora a rnz ;should be error mov a,l cpi 32 rnc ;should be error dad h lxi d,attach dad d xchg lhld mode xchg mov m,e inx h mov m,d ret dokern: mov e,l ;arg = fo lhld val + 2*('K'-'@') mov a,h ;no kern string defined? ora l rz mov a,m ;kern string null? ora a rz dcr e ;attach 0 request? rm push h mov l,e mvi h,0 dad h lxi d,klist dad d pop d mov m,e inx h mov m,d pop h ;escape from call ret ;new command ERror cs_ER: lxi h,300 cs_ER1: push h call eperror## cs_GT: ;eol in inbuf is where to append string from console call .fendin ;add a blank to separate from any preceding command name mvi m,' ' inx h ; push h call gets## ; pop h ;gets terminates it with a nul, but we want a newline, ; so find the new end .. call .fendin ;and supply the termination mvi m,0ah inx h mvi m,0 ret ;a little routine to find the end of the string or line ;in inbuf .fendin: lxi h,inbuf-1 .fei1: inx h mov a,m ora a rz cpi 0ah jnz .fei1 ret ; ; } ; ; /* Otherwise, it's an Epson type command */ ; else epscommand(); ; ; return(0); ;} ;isdig -- return c if A is digit .comment ` same as runtime routine isdec isdig: cpi '0' rc cpi '9'+1 cmc ret ` ; ;numscan() ;{ int n; ; ; n = atoi(inbuf+inpoint); ; while (isdigit(inbuf[inpoint])) ; { inpoint++; scrncol++; } ; return(n); ;} ;NUMSCAN is now modified version of ATOI .comment ` int atoi(n) char *n; { int val; char c; int sign; val=0; sign=1; while ((c = *n) == '\t' || c== ' ') ++n; if (c== '-') {sign = -1; n++;} while ( isdigit(c = *n++)) val = val * 10 + c - '0'; return sign*val; } ` numscan: ;val in HL, assumed 0 lxi h,0 ;loop here until no longer a digit push h ;can loop back to here with HL already pushed .ai4a: call inbch pop h call isdec rc sui '0' ;save binary of digit mov e,a mvi d,0 push d ;multiply val by 10 lxi d,10 call usmul ;(was smul) ;add in binary of digit pop d dad d ; ;point next char push h call nxspnt jmp .ai4a .comment ` /************************************************/ /* When '{', push mode onto brcstk */ /************************************************/ modepush() { if (inbuf[inpoint] == '{' && brcpt[cc] < (BSTKSIZE-1)) should be " < BSTKSIZE" { inpoint++; scrncol++; brcstk[cc][brcpt[cc]++] = mode; brccount = 0; } } ` modepush: call inbch cpi '{' rnz call nxspnt call pshbrc## lxi h,0 shld brccount ;mpu1: ret .comment ` /************************************************/ /* Set mode per Epson command */ /************************************************/ epscommand() { modepush(); switch (dt1) { case 'M': mode |= ELITE; break; /* Elite */ case 'P': mode &= ~ELITE; break; case '_': /* Underlined */ case '-': eparg(UNDRLN); break; case 15 : mode |= CMPRSSD; break; /* Compressed */ case 18 : mode &= ~CMPRSSD; break; case 'E': mode |= EMPHSZD; break; /* Emphasized */ case 'F': mode &= ~EMPHSZD; break; case 'G': mode |= DBLSTRK; break; /* Double Strike */ case 'H': mode &= ~DBLSTRK; break; case 'W': eparg(EXPNDD); break; /* Expanded */ case 4 : mode |= ITALIC; break; /* Slanted */ case 5 : mode &= ~ITALIC; break; case 'p': if (!mx) eparg(PRPTNL); break; /* Proportional */ case 'S': if (dt2 == '0') mode |= SUBSCRPT; else mode |= SUPSCRPT; break; case 'T': mode &= ~(SUPSCRPT | SUBSCRPT); break; default: if (dt2 > ' ') PTESCCH(dt1); if (dt2) PTCH(dt2); while ((dt1 = inbuf[inpoint]) != '\n') { if (isdigit(dt1)) PTCH(numscan()); else if (dt1 > ' ') { PTCH(dt1); inpoint++; } else scanwhite(TRUE); } break; } } ` epscomma: call modepush ; lda dt1 mov a,c lxi d,elite cpi 'M' jz emor lxi d,not elite cpi 'P' jz emand lxi d,undrln cpi '_' jz emarg cpi '-' jz emarg lxi d,cmprssd cpi 15 jz emor lxi d,not cmprssd cpi 18 jz emand lxi d,emphszd cpi 'E' jz emor lxi d,not emphszd cpi 'F' jz emand lxi d,dblstrk cpi 'G' jz emor lxi d,not dblstrk cpi 'H' jz emand LXI D,expndd cpi 'W' jz emarg lxi d,italic cpi 4 jz emor lxi d,not italic cpi 5 jz emand cpi 'p' jz em13 cpi 'S' jz em15 lxi d,not (supscrpt or subscrpt) ;0E7FFH cpi 'T' jz emand jmp em19 em13: lda mx ora a rnz lxi d,prptnl emarg: ; LDA dt2 mov a,b cpi '0' jnz emor CALL CMD dcx d ;undo 'inx d' in cmd emand: lhld mode mov a,h ana d mov h,a mov a,l ana e mov l,a shld mode RET em15: lxi d,subscrpt ; LDA dt2 mov a,b cpi '0' JZ EMOR lxi d,supscrpt emor: lhld mode mov a,h ora d mov h,a mov a,l ora e mov l,a shld mode RET em19: ; lda dt1 mov a,c cpi ' ' jc em19ne mvi a,27 call pr1## em19ne: ; lda dt1 mov a,c call pr1## ; lda dt2 mov a,b ora a jz em20 call pr1## em20: call inbch ; sta dt1 mov c,a cpi newline rz call isdec JC em21 call numscan mov a,l call pr1## jmp em20 ;em23 em21: CPI ' ' jc em22 call pr1## call nxpnt jmp em20 ;em23 em22: mvi a,ttrue call scanwhit jmp em20 ;(no longer used) ;/************************************************/ ;/* Epson type '0' or '1' argument */ ;/************************************************/ ;eparg(msk) ;int msk; ;{ ; if (dt2 == '0') mode &= ~msk; ; else mode |= msk; ;} ;/* end cseq related functtions */ ; .comment ` /************************************************/ /* Get 2 letters from long runoff commands */ /************************************************/ getrlets() { char c; /* scan any further alphas */ if (inbuf[inpoint] != '-') while ( isalpha(c = inbuf[++inpoint]) || c == SOFTHY ) ; /* compound name? */ if (inbuf[inpoint] == '-') { c = inbuf[inpoint+1]; if (isalpha(c)) { dt2 = toupper(c); while ( isalpha(c = inbuf[++inpoint]) || c == SOFTHY ) ; } } scanwhite(FALSE); } ` getrlets: call inbch cpi '-' jz gr3 call grsb cpi '-' jnz gr6 gr3: ; lhld inpoint ; inx h ; lxi d,inbuf ; dad d call inbch inx h mov a,m call up$alph jc gr6 ; sta dt2 mov b,a call grsb gr6: ; xra a ; jmp scanwhit jmp sw1 grsb: call nxspnt call inbch cpi softhy jz grsb cpi softhya jz grsb call up$alph jnc grsb ret .comment ` /********************************************************/ /* Condense compound names */ /********************************************************/ extract(name) char *name; { int i; char c, hycount; /* extract the name */ for (i = 0, hycount = 0; isalpha(c = inbuf[inpoint]) || isdigit(c) || c == '-' || c == SOFTHY || c == SOFTHYA ; inpoint++, scrncol++) if (c == '-') { hycount++; if (hycount == 1 && i > 4) i = 4; else if (hycount == 2 && i > 6) i = 6; else if (i > 7) i = 7; } else if (i < 8 && c != SOFTHY && c != SOFTHYA) name[i++] = toupper(c); scanwhite(FALSE); /* terminate string */ name[i] = '\0'; } ` extract: ;pointer to destination for processed name is passed in HL ;raw name comes from input stream or argv, if "$"n push b ;not in C vers.: find end of string to allow for possible file prefix shld orgetname et0: mov a,m inx h ora a jnz et0 dcx h shld etname ;call inbch, check for '$'digits, if so use *(gargv+2*number),->et1+3 ;i = 0 MVI B,0 ;hycount = 0 xra a sta ethy sta et$flag sta .xtflag et01: call inbch cpi '$' jnz et1b sta et$flag call nxspnt ;what if it's not a digit?? present code assumes 0 ; call inbch ; call isdec ;(possibly just a '$' should refer to next cmd. line arg) ; lxi h,1 ; jc $+6 call numscan ;$1->main file name inx h ;$1->1st com-line arg lda gargc dcr a cmp l pop d rc push d dad h ;word array xchg lhld gargv dad d mov a,m inx h mov h,m mov l,a shld etparm et1: lda et$flag ora a jz et1a lhld etparm mov a,m inx h shld etparm jmp et1b et1a: call nxspnt call inbch et1b: MOV C,A cpi ':' jnz et1ba dcr b jnz et8 lhld etname mov a,m lhld orgetname mov m,a inx h mvi m,':' inx h shld etname ;if already looking at cmd line arg, go scan next char lda et$flag ora a jnz et1 ;else scan over the ':' and go try for '$' again call nxspnt jmp et01 et1ba: lda .xtflag ora a jz et1c ;continue if not storing extension inr a sta .xtflag ;note one more ext. letter stored mov a,c call flchar mov c,a jnc et6a ;if good letter, go store it jmp et8 ;else exit et1c: mov a,c cpi '-' jz et2a ;was et2 cpi SOFTHY ;1EH jz et1 ;was et2 cpi SOFTHYA ;1FH jz et1 ;was et2 etnd: ora a jz et8 call flchar mov c,a ; jc et8 jnc et6 cpi '.' jnz et8 ;make sure no extension yet lxi h,.xtflag mov a,m ora a jnz et8 ;here start to append extension inr m jmp et6a ;et2: ; MOV A,C ; cpi '-' ; jnz et6 et2a: ;hycount++ LXI H,ETHY inr m mvi a,1 cmp m jnz et3 ;hycount is 1 mvi a,4 cmp b jc et5 et3: mvi a,2 cmp m jnz et4 mvi a,6 cmp b jc et5 et4: mvi a,7 cmp b jnc et1 et5: mov b,a jmp et1 et6: mov a,b cpi 8 jnc et1 ;now never get here with soft hyphen ; mov a,c ; cpi SOFTHY ;1EH ; jz et1 ; cpi SOFTHYA ;1FH ; jz et1 et6a: LHLD ETNAME MOV E,B MVI D,0 DAD D ;name[i] MOV M,C ; = c ;terminate after ea. c, so don't have to at end inx h mvi m,0 INR B ;i++ ;if storing file extension, see if all stored lda .xtflag cpi 4 jnz et1 ;if not, loop call nxspnt ;position at next char et8: ; xra a ;start with current char ; call scanwhit call sw1 pop b ora a ;clear carry signals "got one" ret etname: dw 0 orgetname: dw 0 ethy: db 0 et$flag: db 0 etparm: dw 0 .xtflag: db 0 .comment ` /********************************************************/ /* Process name after 'fo' */ /********************************************************/ grabfont() { int i, newreq; char gname[9]; extract(gname); /* already know about this one? */ for (i = 0; i < nextft && strcmp(ftname[i], gname); i++); /* if not, request load */ if (i == nextft) { if ((newreq = nextft) >= NUMFTS) i--; strcpy(ftname[i], gname); /* if newreq=NUMFTS, newreq-1= i will be loaded */ if (loadft(newreq) == ERROR) { /* mark out name */ ftname[i][0] = 0; return(-1); } nextft = i + 1; } /* and cause fo to be number of font + 1 */ return(i + 1); } ` grabfont: push b LXI H,GNAME mvi m,0 push h call extract pop h jnc gf01 pop b ret gf01: ;8th bit of 1st char is graphic font flag lda gfflag ora a mov a,m jz $+6 ori 80h mov m,a ;remove any file extension gf02: mov a,m ora a jz gf03 inx h cpi '.' jnz gf02 dcx h mvi m,0 gf03: xra a sta gfflag mov b,a gf1: LDA NEXTFT DCR A JM gf2 CMP B JC gf2 call getftn ;don't try to match a disk prefix call afterpref lxi d,gname xchg call afterpref xchg call strcmp mov a,h ora l jz gf2 INR B jmp gf1 afterpref: push h .aftu: mov a,m ora a jz .aftx cpi ':' inx h jnz .aftu xthl .aftx: pop h ret ; /* if not, request load */ ; if (i == nextft) gf2: LDA NEXTFT CMP B jnz gf5 ; { if ((newreq = nextft) >= NUMFTS) i--; ; LDA NEXTFT MOV C,A CPI NUMFTS jc gf3 DCR B ; strcpy(ftname[i], gname); gf3: call getftn lxi d,gname call strcpy ; /* if newreq=NUMFTS, newreq-1= i will be loaded */ ; if (loadft(newreq) == ERROR) MOV L,C MVI H,0 push h call loadft pop d inx h mov a,h ora l jnz gf4 ; { /* mark out name */ ; ftname[i][0] = 0; ; return(-1); ; } call getftn mvi m,0 lxi h,-1 jmp gf6 ; nextft = i + 1; ; } ; gf4: MOV A,B INR A sta nextft ; /* and cause fo to be number of font + 1 */ ; return(i + 1); ;} gf5: INR B MOV L,B MVI H,0 gf6: pop b ora a ret ;made external ;gname: db 0,0,0,0,0,0,0,0,0,0,0,0,0 .comment ` /************************************************/ /* discard white space in input line */ /************************************************/ scanwhite(next) int next; { char c; if (next) {inpoint++; scrncol++; } while ((c = inbuf[inpoint]) == ' ' || c == '\t' || c == SOFTSP) { inpoint++; scrncol++; if (c == '\t') while (scrncol & 7) scrncol++; } } ` ;(next in A) scanwhit: ora a cnz nxspnt sw1: call inbch cpi ' ' jz sw2 cpi 9 jz sw2 cpi SOFTSP rnz sw2: push psw call nxspnt pop psw cpi 9 jnz sw1 lxi h,scrncol mvi a,7 sw3: ana m jz sw1 inr m jmp sw3 ;point HL at current input character and get it in A inbch:: ;if no indirection, go get char from input line lda _$lev ora a jz .inbo ;when indirection: ; index the pointer on the indirection stack dcr a mov l,a mvi h,0 dad h lxi d,_$stack dad d mov e,m inx h mov d,m xchg ; and get the character here mov a,m ;(to extend the tab=end-of-field convention to arguments in ; strings, check here for tab char) ora a rnz ;if we're at the end of the string, ; check to see if scanning the argument to a macro .inbup: lxi h,_$upflag mov a,m mvi m,0 lxi h,_$lev dcr m ora a ; if not, down one level of indirection, and go get the char there jz inbch ; but if so, return up one level of indirection inr m inr m jmp inbch .inbo: ;get current tab char to check for end of arg field lda tc lhld inpoint lxi d,inbuf dad d ;if no tab char defined, can't be end of field ora a jz .inbnt ;if this is not the tab char, also can't be end of field cmp m jnz .inbnt ;if not scanning an arg string, also can't be end of field lda _$upflag ora a jz .inbnt ;aha! we're at end of field, so skip the tab char and ; return up one level (without zeroing the _$upflag) call nxspnt jmp .inbup .inbnt: mov a,m cpi 0ah ;if eol, check for '\$$' ref. rnz lda _$upflag ora a mvi a,0ah ;if not scanning arg, just return the newline rz ;else return up to the higher level of indirection call nxpnt ;to skip the nl jmp .inbup nxspnt:: lda _$lev ora a jz .nxso dcr a mov l,a mvi h,0 dad h lxi d,_$stack dad d mov e,m inx h mov d,m inx d mov m,d dcx h mov m,e xchg ret .nxso: lxi h,scrncol inr m nxpnt: lhld inpoint inx h shld inpoint ret ;temporarily cancel input redirect to pick up a string argument sundirect: lxi h,_$lev mov a,m ora a ;nop if no current redirection ;(a natural extension would be to get a string from the console) rz dcr m ;signal to come back up when reach eol sta _$upflag ret shfdown:: lxi h,_$upflag+1 mov a,m dcx h mov m,a ;called by processline when it hits a '\*' sddown:: lxi h,_$lev mov a,m ora a rz dcr m ret ;special version of sdirect for use during processing of ; heading and footing lines -- will go up one extra level ; to get past the level of a possible macro looking at ; an argument, then sddown will be called afterwards to get back shfdirect:: push h lxi h,_$upflag mov a,m mvi m,0 inx h mov m,a inx h ; lxi h,_$lev inr m lxi d,150 jmp .sdir0 ;redirect input to the string variable whose address is in HL sdirect:: push h ;message "string reference in argument" lxi d,151 lda _$upflag ora a jnz .sdirerr ;message "too much nesting" dcx d lxi h,_$lev .sdir0: mov a,m cpi MAXSNEST jz .sdirerr inr m mvi h,0 mov l,a dad h lxi d,_$stack dad d pop d mov m,e inx h mov m,d ret .sdirerr: push d call eperror _$upflag: db 0 db 0 _$lev: db 0 ;made external ;_$stack: dw 0,0,0,0,0,0,0,0,0,0 _$point: dw _$buf ;1024 bytes at end of externals up$alph: cpi '$' jnz upalph mvi a,'@' ret upalph: cpi 'A' rc ;not alpha if before A cpi 'z'+1 cmc rc ;not alpha if after z cpi 'Z'+1 cmc rnc ;alpha if from A to Z cpi 'a' rc ;not alpha if between Z and a sui 20H ;else lower case alpha, to upper ret ;carry must be clear, so signal alpha ;test if legal file character other than '.' flchar: cpi '!' rc cpi '*' jz fl0 cpi ',' jz fl0 cpi '.' jz fl0 CPI '9'+1 jc fl1 cpi '@' jc fl0 cpi '\' jz fl0 cpi '{' jz fl0 call upalph fl1: ora a ret fl0: ora a cmc ret ;hold addr of val[dt1-'@'][dt2-'@'] and valtp... vldtadr: dw 0 typvadr: dw 0 arg: dw 0 oldarg: dw 0 argsign: db 0 typeval: dw 0 measure: dw 0 divisor: dw 0 ;dt1: db 0 ;dt2: db 0 dt3: db 0 ;dt4: db 0 dt5: db 0 eqref: db 0 havearg: db 0 ;made external ;utabs: dw 0,0,0,0,0,0,0,0 ; dw 0,0,0,0,0,0,0,0 ; dw 0,0,0,0,0,0,0,0 ; dw 0,0,0,0,0,0,0,0 ; ;/************************************************/ ;/* Pop mode from brcstk */ ;/************************************************/ ;modepop() ;{ ; if (brcpt[cc]) ; { mode = brcstk[cc][--brcpt[cc]]; ; return(TRUE); ; } ; else return(FALSE); ;} modepop:: call get_brc xchg mov a,h ora l rz ;ret false in HL ;do the predecrement now dcx h ;save for below push h ;store it back xchg mov m,d dcx h mov m,e lhld cc ; lxi d,12 ; call usmul dad h ;*2 dad h ;*4 mov d,h mov e,l dad h ;*8 dad d ;*8 + *4 = *12 lxi d,brcstk dad d xchg ;col. base in DE ;now get back decremented brcpt[cc] pop h ;word address dad h ;and complete the index dad d mov a,m inx h mov h,m mov l,a shld mode lxi h,ttrue ret get_brc:: lhld cc dad h lxi d,brcpt dad d mov e,m inx h mov d,m ret getftn:: mov l,b mvi h,0 lxi d,LENFTN call usmul lxi d,ftname dad d ret end