;Comet to ASCII / ASCII to Comet suite ;------------------------------------- ; ; © 1995 Simon Cooke ;Comet to ASCII: Completed. ;ASCII to Comet: Puts all comments on a separate line to the ; the code at the moment, splits lines ; indescriminately... ;To Do: Make this work using files instead of all in ; memory all the time. ; Prettify the comment handling - make it go on ; more than one line if necessary? ; Auto-fix DEFM and DEFB lines that should be ; of the other form... eg ; DM "DIOJDEOJ"+128 should be DEFM "daopjda" ; DB "J"+128 ;Errors: 0 - All ok ; 1 - Invalid character in input file ; 2 - Invalid character in label ; 3 - Label too long ORG 40960 DUMP 40960 lmpr: EQU &FA hmpr: EQU &FB vmpr: EQU &FC lf: EQU 10 cr: EQU 13 origin.length: EQU 64 space: EQU 32 quote: EQU 34 comment: EQU ";" label.len: EQU 15 label.tag: EQU ":" start: JP c.to.a ;comet to ascii JP a.to.c ;ascii to comet ret.to.basic: ;restore basic LD A,(lmpr.store) OUT (lmpr),A LD SP,(sp.store) LD A,(error.stat) LD C,A ;return error on stack LD B,0 ;(passed by BC) EI RET c.to.a: ;comet to ascii DI IN A,(lmpr) LD (lmpr.store),A LD (sp.store),SP LD SP,alt.stack LD HL,(comet.addr) LD (input.a),HL LD A,(comet.page) OR 32 LD (input.p),A LD HL,(ascii.addr) LD (output.a),HL LD A,(ascii.page) OR 32 LD (output.p),A LD HL,0 LD (length.a),HL XOR A LD (length.p),A XOR A ;no errors yet... LD (error.stat),A main.loop: LD HL,output.buffer LD DE,output.buffer+1 LD (HL),space LD BC,origin.length-1 LDIR XOR A LD (comment.flag),A LD (position.flag),A LD (quote.flag),A LD HL,tab.table LD (tabs),HL LD HL,(input.a) LD A,(input.p) OUT (lmpr),A PUSH HL LD HL,(tabs) LD E,(HL) INC HL LD D,(HL) POP HL LD DE,output.buffer LD B,(HL) ;get line counter INC HL LD C,(HL) INC HL LD A,B OR C JP Z,ret.to.basic ;check for end of source DEC BC DEC BC line.loop: LD A,B OR C JP Z,end.of.line LD A,(position.flag) CP 1 JR NZ,not.move2 PUSH HL LD HL,(tabs) INC HL INC HL LD (tabs),HL LD E,(HL) INC HL LD D,(HL) POP HL LD A,2 LD (position.flag),A not.move2: LD A,(comment.flag) RRA JP C,comment.now LD A,(HL) INC HL CP quote JR NZ,not.toggle LD A,(quote.flag) CPL LD (quote.flag),A LD A,quote not.toggle: CP comment JP Z,comment.line not.comment: CP label.len JP C,label.handle CP 128 JP C,plain.vanilla ;ascii, not token EX AF,AF' LD A,(position.flag) OR A JR NZ,not.incpos PUSH HL LD HL,(tabs) INC HL INC HL LD (tabs),HL LD E,(HL) INC HL LD D,(HL) POP HL LD A,1 LD (position.flag),A not.incpos: EX AF,AF' LD IX,token.table ;find token pointed to... AND &7F ;token data terminated by find.token: ; bit 7 set... OR A JR Z,pass.data ixer.loop: BIT 7,(IX) JR NZ,end.of.token INC IX JR ixer.loop end.of.token: INC IX DEC A JR find.token pass.data: LD A,(IX) BIT 7,A JR NZ,end.of.token2 LD (DE),A LD A,(colour) INC A LD (colour),A AND 17 PUSH BC LD BC,&00F8 OUT (C),A POP BC INC DE INC IX JR pass.data end.of.token2: AND &7F LD (DE),A INC DE JP next.char label.handle: LD (looper+1),A label.l: LD A,(HL) DEC BC LD (DE),A INC HL INC DE looper: LD A,&00 DEC A LD (looper+1),A JR NZ,label.l LD A,label.tag LD (DE),A INC DE JR next.char comment.line: LD A,(comment.flag) BIT 7,A JR NZ,not.quotes LD A,(quote.flag) OR A JR Z,not.quotes LD A,comment JP not.comment not.quotes: LD A,129 LD (comment.flag),A JP next.char comment.now: LD A,(HL) INC HL PUSH HL LD L,A LD H,0 DEC L ADD HL,DE EX DE,HL POP HL LD A,128 LD (comment.flag),A LD A,comment plain.vanilla: ;ascii char... LD (DE),A INC DE next.char: DEC BC JP line.loop end.of.line: BIT 6,H JR Z,not.overf RES 6,H LD A,(input.p) INC A LD (input.p),A not.overf: LD (input.a),HL LD DE,(output.a) LD A,(output.p) OUT (lmpr),A LD A,(lfcr) OR A JR NZ,dynamic.length LD BC,64 LD HL,output.buffer LDIR ;copy to output stream LD BC,64 JR not.lf dynamic.length: LD HL,0 LD (line.length),HL LD HL,output.buffer+origin.length-1 LD B,64 loop1: LD A,(HL) CP space JR NZ,found.end.l DEC HL DJNZ loop1 JR put.end.char found.end.l: LD C,B LD B,0 LD (line.length),BC LD HL,output.buffer LDIR ;copy to output stream put.end.char: LD BC,(line.length) LD A,(lfcr) BIT 0,A JR Z,not.cr EX AF,AF' LD A,cr LD (DE),A EX AF,AF' INC DE INC BC not.cr: BIT 1,A JR Z,not.lf EX AF,AF' LD A,lf LD (DE),A EX AF,AF' INC DE INC BC not.lf: BIT 6,D JR Z,not.overf2 RES 6,D LD A,(output.p) INC A LD (output.p),A not.overf2: LD (output.a),DE LD HL,(length.a) ADD HL,BC BIT 6,H JR Z,not.overf3 RES 6,H LD A,(length.p) INC A LD (length.p),A not.overf3: LD (length.a),HL JP main.loop ;ASCII to COMET routines a.to.c: DI IN A,(lmpr) LD (lmpr.store),A LD (sp.store),SP LD SP,alt.stack CALL init.atoc ;initialise variables LD A,(eoltype) OR A JR Z,autodetecteol CP 2 JR C,forcecrlf LD HL,noeols seteoljump: LD (eoljump),HL JR main.atoc forcecrlf: LD HL,eolchars JR seteoljump autodetecteol: CALL scan4eol ;scan for eol characters main.atoc: LD HL,(input.length) LD A,(input.page) OR H OR L JR NZ,data.remains ;hit end of ASCII file... put end tag, and exit. LD (output.buffer),HL INC HL INC HL LD (line.length),HL CALL send.line JP ret.to.basic ;read data from ascii file data.remains: LD HL,input.buffer LD DE,input.buffer+1 LD BC,256 LD (HL),0 LDIR ;clear input buffer... LD HL,(eoljump) ;bring data into input buffer CALL jumptohl CALL convert.line JR main.atoc jumptohl: JP (HL) ;CALL (HL) ;Bring line into the input.buffer ;-------------------------------- ;Converted line terminated by a null (0) char eolchars: XOR A LD (eolflag),A LD DE,input.buffer LD HL,(input.a) LD A,(input.p) OUT (lmpr),A LD BC,(input.length) readc.eolc: LD A,(input.page) ;check for end of data OR B OR C JR Z,eol2.eol LD A,(HL) CP cr JR NZ,notcreol LD (eolflag),A JR getnextceol notcreol: CP lf JR Z,endofline.eol LD A,(eolflag) OR A JR NZ,eol2.eol LD A,(HL) CALL conv.stream LD (DE),A INC DE getnextceol: INC HL BIT 6,H JR Z,nvrfceol RES 6,H IN A,(lmpr) INC A OUT (lmpr),A nvrfceol: CALL declength JR readc.eolc endofline.eol: CALL declength INC HL BIT 6,H JR Z,eol2.eol RES 6,H IN A,(lmpr) INC A OUT (lmpr),A eol2.eol: XOR A LD (DE),A IN A,(lmpr) LD (input.p),A LD (input.a),HL LD (input.length),BC RET ;Bring in a line if we're not expecting eol characters... noeols: LD DE,input.buffer LD HL,(input.a) LD A,(input.p) OUT (lmpr),A LD BC,(input.length) LD A,(linewidth) readc.neol: EX AF,AF' LD A,(input.page) OR B OR C JR Z,eol2.neol LD A,(HL) CALL conv.stream LD (DE),A INC DE INC HL BIT 6,H JR Z,nvrfneol RES 6,H IN A,(lmpr) INC A OUT (lmpr),A nvrfneol: CALL declength EX AF,AF' DEC A JR NZ,readc.neol eol2.neol: XOR A LD (DE),A IN A,(lmpr) LD (input.p),A LD (input.a),HL LD (input.length),BC RET ;Decrement length counter ;------------------------ declength: LD A,B OR C JR NZ,lengtheol LD BC,16384 LD A,(input.page) DEC A LD (input.page),A lengtheol: DEC BC RET ;Convert incoming data stream to an intermediate format ;------------------------------------------------------ ;Codes >127 become "?"s ; <32 become spaces ; all others left as is. conv.stream: CP " " ;is it < 32? JR C,controlcd CP 128 ;in range? RET C LD A,"?" ;make possible dodgy codes become "?"s RET controlcd: LD A," " RET ;Initialise ascii to comet variables ;----------------------------------- init.atoc: LD HL,(comet.addr) LD (output.a),HL LD A,(comet.page) OR 32 LD (output.p),A LD HL,(ascii.addr) LD (input.a),HL LD A,(ascii.page) OR 32 LD (input.p),A LD HL,0 LD (length.a),HL XOR A LD (length.p),A LD (error.stat),A RET ;Scan for end of line characters ;------------------------------- ;Check the first 256 bytes (or less) of a file. ;If there is no lf or cr characters in that time, it is assumed ;that the file is of Outwrite type, and has no eol markers. ;If there is either an lf or cr char, then it is assumed that ;there are line separators all the way through. scan4eol: LD A,(input.p) OUT (lmpr),A LD HL,(input.a) LD BC,(input.length) LD DE,eolchars LD A,(input.page) OR A JR Z,lt16k ;if file is less than 16k, ;jump lt16k2: LD BC,256 ;definitely 256 bytes availbl JR scanloop lt16k: LD A,B CP 1 JR NC,lt16k2 scanloop: LD A,(HL) CP lf JR Z,eolcharf CP cr JR Z,eolcharf INC HL DEC BC LD A,B OR C JR NZ,scanloop LD DE,noeols eolcharf: LD (eoljump),DE RET ;Convert data line into Comet format ;----------------------------------- convert.line: LD B,0 ;First of all, strip spaces from the end of the line LD HL,input.buffer+255 strip.end: LD A,(HL) OR A JR Z,nextstrp CP " " JR Z,nextstrp INC HL LD (HL),0 ;put in a new end-of-line code JR nextop1 ;do next operation ;Either still counting spaces or eol codes. nextstrp: DEC HL DJNZ strip.end nextop1: ;now we reduce the number of spaces within a line to one per gap LD HL,input.buffer LD DE,input.buffer XOR A LD B,A LD (space.flag),A LD (comment.flag),A LD (quote.flag),A compactloop: LD A,(HL) LD (DE),A OR A ;hit end of line? JR Z,endofcompact CP " " ;is it a space? JR NZ,notaspace LD A,(space.flag) ;are we already compacting? OR A JR NZ,inc2compact LD A,(quote.flag) ;if not, check if we're in LD C,A ;a string or a comment... LD A,(comment.flag) OR C ;if we ARE in a string or JR NZ,notaspace ;comment, don't compact... CPL LD (space.flag),A JR inccompact notaspace: XOR A ;clear compact status LD (space.flag),A LD A,(quote.flag) ;are we currently in quotes? OR A JR NZ,notinquotec LD A,(HL) CP comment JR NZ,notinquotec LD (comment.flag),A notinquotec: LD A,(HL) CP quote ;in a quote? if so, toggle JR NZ,inccompact ;quote flag LD A,(quote.flag) XOR 1 LD (quote.flag),A inccompact: INC DE inc2compact: INC HL JR compactloop endofcompact: XOR A LD (parse.flag),A CALL flushoutput LD HL,input.buffer LD DE,output.buffer+2 LD A,(HL) OR A JR Z,blankline CALL check.alpha ;labels must start with an JR NZ,check4tokens;alpha character (a-z, A-Z) JR notblankl ;Hit a blank line... blankline: LD HL,output.buffer+2 LD B,2 countloop: LD A,(HL) CP &FF JR Z,endofoutput INC HL INC B JR countloop endofoutput: LD H,B LD L,0 LD (output.buffer),HL LD H,L LD L,B LD (line.length),HL CALL send.line RET notblankl: LD B,0 LD HL,input.buffer LD DE,output.buffer+3 labelloop: LD A,(HL) CALL ck4.separator JR Z,exitll LD (DE),A INC DE INC HL INC B JR labelloop exitll: LD A,1 LD (parse.flag),A LD A,(HL) CP " " JR Z,installabel OR A JR Z,installabel CP ":" JR Z,installabel CP ";" JR Z,installabel ;Error code 2: - invalid code in a label. error2: LD A,2 JR errorout ;Error code 3: - label too long error3: LD A,3 errorout: LD (error.stat),A JP ret.to.basic installabel: LD A,B CP 15 JR NC,error3 ;label is too long! LD (output.buffer+2),A ;insert label length LD A,(HL) ;hit end of data? OR A JR Z,blankline CP ":" JR Z,skipdata CP " " JR Z,skipdata JR check4tokens skipdata: INC HL ;Tokenise and fiddle data stream from here on in... check4tokens: LD (input.pos),HL ;store it for later LD (output.pos),DE rebuildloop: LD HL,tokenbuild ;clear the token building LD DE,tokenbuild+1;area... LD BC,15 LD (HL),B LDIR XOR A LD (decflag),A LD IX,tokenbuild LD HL,(input.pos) LD DE,(output.pos) LD B,0 ;token length finder... buildloop: LD A,(decflag) OR A LD A,(HL) JR Z,alphastart CALL ck4.separator JP NZ,addtobuild JR dontadd alphastart: CALL check.alpha EX AF,AF' LD A,1 LD (decflag),A EX AF,AF' dectoken: JP Z,addtobuild dontadd: LD A,(tokenbuild) ;no token at all?? OR A ;jump to separator pass... JP Z,separatorchk ;(we must have hit a ;separator straight away) LD (tempipos),HL ;Scan for word in build area in token table LD C,128 LD DE,token.table scantokenl1: LD HL,tokenbuild scantokenl2: LD A,(DE) CP &FF JR Z,endoftokens AND %01111111 CP (HL) JR NZ,notthistoken LD A,(DE) BIT 7,A JR Z,notendoftoken INC HL ;if we've hit end of token LD A,(HL) ;in table, AND next char in OR A ;build area is null, we've JR Z,foundtoken ;matched a token. notthistoken: LD A,(DE) INC DE BIT 7,A JR NZ,fnexttoken JR notthistoken fnexttoken: INC C JR scantokenl1 notendoftoken: INC HL LD A,(HL) OR A JR Z,notthistoken INC DE JR scantokenl2 foundtoken2: INC DE LD A,(DE) LD C,A foundtoken: LD HL,(output.pos) LD (HL),C INC HL LD (output.pos),HL LD HL,(tempipos) LD (input.pos),HL LD A,1 LD (parse.flag),A JP rebuildloop ;check for more tokens.. ;Ran out of tokens in the first list... check the second one endoftokens: ;Scan through second table... LD DE,token.table2 scantokenl3: LD HL,tokenbuild scantokenl4: LD A,(DE) AND %01111111 CP (HL) JR NZ,notthistoke2 LD A,(DE) BIT 7,A JR Z,notendoftoke2 INC HL ;if we've hit end of token LD A,(HL) ;in table, AND next char in OR A ;build area is null, we've JR Z,foundtoken2 ;matched a token. notthistoke2: LD A,(DE) CP &FF JR Z,notatoken INC DE BIT 7,A JR NZ,fnexttoke2 JR notthistoke2 fnexttoke2: INC DE ;skip decoded byte JR scantokenl3 notendoftoke2: INC HL LD A,(HL) OR A JR Z,notthistoke2 INC DE JR scantokenl4 ;not a token, or overflow of tokenbuild area... just copy from ;input stream to output stream until we hit a separator. notatoken: LD DE,(output.pos) LD HL,(input.pos) copyacross: LD A,(HL) CALL ck4.separator JR Z,finished.blit INC HL LD (DE),A INC DE JR copyacross finished.blit: LD A,1 LD (parse.flag),A LD (input.pos),HL LD (output.pos),DE separatorchk: LD A,(HL) CP " " JR NZ,skipspace spaceloop: INC HL LD A,(HL) CP " " JR Z,spaceloop LD (input.pos),HL JP rebuildloop skipspace: LD (input.pos),HL OR A ;hit end of input line? JP Z,blankline ;if so, output it to memory CP comment JR Z,handlecomment CP quote JP Z,handlequotes ;Convert #'s to &'s to indicate start of a hex number? EX AF,AF' LD A,(hashtype) ;0 - convert # to & OR A ;1 - don't convert JR NZ,skiphash EX AF,AF' CP "#" JR NZ,ignorehashcode LD A,"&" LD (HL),A EX AF,AF' skiphash: EX AF,AF' ignorehashcode: CP "&" ;just put an ampersand - bring in hex JR Z,allhex CP "%" JR Z,binarynum LD A,(HL) CALL check.number JP Z,convnum ;convert between different ;number styles... ;If we've hit a separator it doesn't recognise, stash it and ;carry on... LD (DE),A INC DE INC HL LD (input.pos),HL LD (output.pos),DE JP rebuildloop handlecomment: LD A,(parse.flag) ;if parseflag is zero, OR A ;there's only a comment on JR Z,justcomment ;this line commentloop: LD (input.pos),HL CALL blankline ;flush the output buffer CALL flushoutput LD HL,(input.pos) justcomment: LD B,63 LD DE,output.buffer+2 LD A,";" ;should be a " LD (DE),A INC DE LD A,1 ;put xpos LD (DE),A INC DE INC HL computloop: LD A,(HL) ;end of comment... flush the buffer OR A JP Z,blankline LD (DE),A INC DE INC HL DJNZ computloop LD (input.pos),HL LD A,(HL) OR A JP Z,blankline JR commentloop ;Parse numbers... ;---------------- ;This is a fun and tricky one... ;Accepts numbers of the type: ;0x0000, 0000h, 000000b and 0353 ;if octals are out of range, just pass as decimals ;otherwise convert to hex. ;NB: hex numbers must be capitalised allhex: LD (DE),A INC HL INC DE hexiloop: LD A,(HL) OR A JP Z,blankline CALL check.number JR Z,putouthexd CALL check.alpha JR NZ,parsepass AND %11011111 ;make uppercase CP "G" JR NC,parsenumerical putouthexd: LD (DE),A INC HL INC DE JR hexiloop binarynum: LD (HL),A INC HL LD (DE),A INC DE JR parsenumerical parsenum2: LD HL,(input.pos) LD DE,(output.pos) parsenumerical: LD A,(HL) CALL ck4.separator JR Z,hitsepar parsepass: LD (DE),A INC HL INC DE JR parsenumerical hitsepar: LD (input.pos),HL LD (output.pos),DE JP rebuildloop addtobuild: AND %11011111 ;force to uppercase LD (IX),A INC IX INC HL INC B LD A,B CP 15 JP Z,notatoken JP buildloop ;hit quotes... parse until eol or next quote found, then ;go back into tokeniser. handlequotes: LD (DE),A INC DE INC HL quoteloop: LD A,(HL) OR A ;hit eol? if so, flush buffer JP Z,blankline INC HL LD (DE),A INC DE CP quote JR NZ,quoteloop LD (input.pos),HL LD (output.pos),DE JP rebuildloop convnum: EX AF,AF' XOR A LD (numflag),A EX AF,AF' CP "0" ;is the first number a zero? JR NZ,notchex ;if not, it's not an octal ;or hexadecimal string which is ;prefixed by 0 or 0x LD (numflag),A LD (DE),A ;store it in case... INC HL LD A,(HL) OR A JP Z,blankline AND %11011111 ;if the next character isn't CP "X" ;an X, it's not a C style hex JR NZ,notchex2 ;string LD A,(numtype) BIT 2,A JR NZ,checkhex passback: DEC HL ;just feed chars across - JR parsenumerical ;we're not allowed to check ;for C style hex numbers... checkhex: INC HL LD A,"&" ;stick in an ampersand prefix LD (DE),A INC DE JP hexiloop ;must be Non-postfixed octal then... notchex2: DEC HL notchex: LD (output.pos),DE LD (input.pos),HL numberbuild: EQU tokenbuild LD DE,numberbuild LD B,0 copyoctal: LD A,(HL) CALL check.number JR NZ,parseoctalnpf stillin2: LD (DE),A INC HL INC DE INC B LD A,B CP 18 JP NC,parsenum2 JR copyoctal stillinnum: DEC HL LD A,(HL) AND %11011111 JR stillin2 parseoctalnpf: CALL check.alpha ;hit separator, not alpha JR NZ,octalnpfsep INC HL LD A,(HL) ;is next byte a separator? CALL ck4.separator ;if not, we're still inside JR NZ,stillinnum ;a possible number... DEC HL LD A,(HL) INC HL AND %11011111 CP "H" JR Z,postfixhex CP "B" JP Z,postfixbin CP "O" JR Z,postfixoctal octalnpfsep: LD (tempipos),HL LD A,(numflag) ;did we get a leading zero? OR A JP Z,parsenum2 ;if not, parse as ordinary ;number. LD A,(numtype) ;are we allowed to decode BIT 3,A ;octal? JP Z,parsenum2 ;if not, scoot back up there postfixopass: LD DE,(output.pos) LD A,"&" LD (DE),A INC DE LD IX,numberbuild LD HL,0 octalfeed: LD A,(IX) ;make sure it's all numbers, INC IX ;between 0 and 7. CP "0" JP C,parsenum2 CP "8" JP NC,parsenum2 SUB "0" ADD HL,HL ADD HL,HL ADD HL,HL OR L LD L,A DJNZ octalfeed LD A,H OR A CALL NZ,outputhex LD A,L CALL outputhex LD HL,(tempipos) LD (input.pos),HL LD (output.pos),DE JP rebuildloop postfixoctal: LD (tempipos),HL LD A,(numtype) ;are we allowed to convert BIT 4,A ;postfix octal? JR NZ,postfixopass JP parsenum2 postfixhex: LD (tempipos),HL LD A,(numtype) BIT 1,A JP Z,parsenum2 LD DE,(output.pos) LD A,"&" LD (DE),A INC DE LD HL,numberbuild numbloop: LD A,(HL) ;make sure it's all in range CP "0" JP C,parsenum2 CP "9"+1 JR C,isnumhex CP "A" JP C,parsenum2 CP "G" JP NC,parsenum2 isnumhex: LD (DE),A INC HL INC DE DJNZ numbloop LD HL,(tempipos) LD (input.pos),HL LD (output.pos),DE JP rebuildloop postfixbin: LD (tempipos),HL LD A,(numtype) ;can we decode post fix bins? RRA JP NC,parsenum2 LD DE,(output.pos) LD A,"%" LD (DE),A INC DE LD HL,numberbuild num2loop: LD A,(HL) ;make sure it's all in range CP "0" JP C,parsenum2 CP "2" JP NC,parsenum2 LD (DE),A INC HL INC DE DJNZ num2loop LD HL,(tempipos) LD (input.pos),HL LD (output.pos),DE JP rebuildloop ;Convert number in A to hex form in (DE), (DE+1). ;Exits with DE=DE on entry +2 outputhex: PUSH AF SRL A SRL A SRL A SRL A CALL numouthex POP AF AND &0F CALL numouthex RET numouthex: CP 10 JR C,noh2 ADD A,"A"-10 LD (DE),A INC DE RET noh2: ADD A,"0" LD (DE),A INC DE RET ;Check for alphabetical character ;-------------------------------- check.alpha: CP "A" RET C CP "Z"+1 JR C,alpha CP "a" RET C CP "z"+1 JR C,alpha CP "z" RET alpha: CP A RET ;Check for numerical character ;----------------------------- check.number: CP "0" RET C ;will be !="0" if it's <"0" anyway CP "9"+1 JR C,number notnumber: CP "0" RET number: CP A RET ;Check for invalid character in label / token ;------------------------------------------ ck4.separator: PUSH HL PUSH BC LD B,invalnumber LD HL,invallist cksepl: LD C,(HL) CP C JR Z,exitck4sep INC HL DJNZ cksepl AND A exitck4sep: POP BC POP HL RET invallist: DEFB 0 DEFB " ","$","%","&","'","(",")","-","+","*" DEFB "/","\",",",":",";",quote,"#" invalnumber: EQU $-invallist ;Copy line to output file ;------------------------ send.line: LD A,(colour) ;cycle colours to let user INC A ;know we're still alive... LD (colour),A LD BC,&00F8 AND 34 OUT (C),A LD BC,(line.length) LD DE,output.buffer LD HL,(output.a) LD A,(output.p) OUT (lmpr),A slinel: LD A,(DE) LD (HL),A INC HL INC DE BIT 6,H JR Z,nooverfsl RES 6,H IN A,(lmpr) INC A OUT (lmpr),A nooverfsl: DEC BC LD A,B OR C JR NZ,slinel LD (output.a),HL IN A,(lmpr) LD (output.p),A LD HL,(line.length) LD DE,(length.a) ADD HL,DE BIT 6,H JR Z,nooverfsl2 RES 6,H LD A,(length.p) INC A LD (length.p),A nooverfsl2: LD (length.a),HL RET flushoutput: LD HL,output.buffer LD DE,output.buffer+1 LD BC,255 LD (HL),C LDIR RET token.table: MDAT "detoken" DEFB &FF ;Token table 2 works with the format: ;Token to look for, value to replace with. ;Terminated by &FF byte. Tokens are terminated by bit 7 being ;set. dbtoken: EQU 149 dmtoken: EQU 150 dstoken: EQU 151 dwtoken: EQU 152 mdattoken: EQU 184 inctoken: EQU 167 token.table2: DEFB "D","B"+128,dbtoken ;replace DB with DEFB DEFB "D","M"+128,dmtoken ;replace DM with DEFM DEFB "D","S"+128,dstoken ;replace DS with DEFS DEFB "D","W"+128,dwtoken ;replace DW with DEFW DEFM "INCBI" DEFB "N"+128,mdattoken ;replace INCBIN with MDAT DEFM "INCLUD" DEFB "E"+128,inctoken ;replace INCLUDE with INC DEFB &FF tab.table: tab.zero: DEFW output.buffer tab.one: DEFW output.buffer+15 tab.two: DEFW output.buffer+20 lfcr: DEFB 1 ;1 = CR ;2 = LF ;3 = LF+CR ;0 = NONE eoltype: DEFB 0 ;0 - autodetect, 1 - force CR/LF detect ;2 - force no eols detect hashtype: DEFB 0 ;0 - convert #'s to &'s ;1 - don't convert them ;Number conversion is done by setting bits to decide which ones ;to do... numtype: DEFB %10111;0 - don't convert numbers ;1 - convert 01010b to %01010 (pfix b) ;2 - convert 3Fh to &3F (postfix hex) ;4 - convert 0x03F1 to &03F1 (C hex) ;8 - convert 010 to &8 (octal to hex) ;16- convert 10o to &8 (octal to hex) linewidth: DEFB 64 ;width for line if no line separator DEFM "(C) 1995 Simon Cooke, Entropy" DEFM ". Entropy is a trademark of Simon Cooke." DEFM " All rights reserved." end.of.saved: EQU $ ;end of data that has to be saved. length.to.save:EQU $-start ;rest is heap space... comet.addr: DEFW 0 comet.page: DEFB 2 ascii.addr: DEFW 0 ascii.page: DEFB 9 input.length: DEFW 1365 input.page: DEFB 0 input.a: DEFW 0 input.p: DEFB 0 output.a: DEFW 0 output.p: DEFB 0 length.a: DEFW 0 length.p: DEFB 0 comment.flag: DEFB 0 position.flag: DEFB 0 quote.flag: DEFB 0 tabs: DEFW 0 line.length: DEFW 0 decflag: DEFB 0 numflag: DEFB 0 eolflag: DEFB 0 space.flag: EQU eolflag parse.flag: EQU eolflag input.pos: DEFW 0 output.pos: DEFW 0 tempipos: DEFW 0 eoljump: DEFW 0 colour: DEFB 0 lmpr.store: DEFB &00 sp.store: DEFW &0000 error.stat: DEFB &00 DEFS 256 alt.stack: EQU $ output.buffer: DEFS 256 input.buffer: DEFS 257 tokenbuild: DEFS 18 inputfileaddr: EQU $