;.he PRETTY.Z80 v2.3 Source Code Case Improver --CHR$(13)10MAR86 -#- ; ;v2.3 Stupid little Somewhere in the v2.2 work, I put a ; bug. counter fetch immediately before a ; BDOS call. The counter is put into b ; to control the number of records to ; read in... BDOS started committing ; suicide by telling the 16KBOX machine ; to overwrite it. That's fixed. ; While I was at it, I cleaned up the ; handling of '*'... if it's the first ; print character in the line, the line ; is a comment now. Used to be it had to ; be in the leftmost column. ; ; --CHR$(13)10MAR85 ; ;v2.2 Switch What I thought was a major malfunction ; improvement. turned out to be an input file that had ; no 'MOV' instruction within the first ; 16k... so I fixed that instead. PRETTY ; now looks for 'MOV', 'MVI' or 'LXI' in ; the first 16k as a trigger to switch ; to the LASM3 tables. It also looks for ; an 'LD' instruction as a cue to stop ; wasting time looking for nonexistent ; 8080 mnemonics in a Zilog program. ; The program now accepts 'Z' or 'L' as ; command tail, allowing you to force it ; either way (why did you use LXI as a ; label in a Zilog program, anyway?). I ; also cleaned up the detection scheme ; so you don't have to rename L.ASM when ; you're done. The '#' tail character ; still works, in case anybody got too ; well trained to it in the week it was ; there to learn 'L'. ; One more minor annoyance remains: the ; '*'-comment detection scheme only ; works on first-column stars. I'll get ; to that in v2.5. ; ; --CHR$(13)04MAR86 ; ;v2.1 Bug fix. A '*'-marked full-line comment is now ; correctly interpreted, and no longer ; causes the program to lock up. My ; apologies for this one; I blew it. ; (Fix: in FLUSH, call FORWHS.) ; ; --CHR$(13)01MAR86 ; ;v2.0 Intel too. Added recognition tables for LASM3, with ; unique codes from Allen Ashley's MAKRO ; thrown in for good measure. LINLUP now ; loads de from variables (TAB1 etc), thus ; allowing these addresses to be altered ; behind its back. Sorry about the speed ; penalty (LDED is a prefix-annunciated ; opcode ...sigh). ; The first bufferful of input is now tested ; for: ; MOVr ; where is space or tab, and r is ; a register designator. If that's found, ; the LASM3 tables are used. ; NUMBER now lowercases ANY trailing letter, ; as promised. ; FINXT and COMWSP now treat '!' (bang) as ; a line-terminator, if not in a comment or ; chaperoned by ticks. There's a lot of ; code out there with this relic of the ED ; era... ; Lines beginning with '*' are now recognized ; as full-line comments. ; There's the possibility, in 8080 program files ; with massive preambles, that there won't ; be a MOV instruction in the first 16k. I'm ; not satisfied with the solution, but here ; it is... ; ; >pretty infile.typ outfile.typ # ; ; The '#' as the last byte in the typed ; line forces Intel mode. Of course, it may ; also become part of the output filename.typ, ; so, for, instance, with a command line of ; ; >pretty tethered.got # ; ; be prepared to rename the output file, ; #.GOT. ; ; --CHR$(13)28FEB86 ; ;v1.1 Bug fixes: Now recognizes lowercase codes...thus ; (as it should be) when PRETTY is run on ; the product of a previous PRETTY run, ; nothing changes case. ; Table 1 now has IM0,IM1,IM2 as well as IM. ; TABS.COM shortened a few spaces in FCBs ; to ; I changed 'em back. ; A little bit of speed bought with longer ; code: jp nnnn takes 10 states, jr nnnn ; takes 12 states. (Thanks to Keith Barr ; for pointing that out.) ; Also, stuck an ISCHAR macro into MATCH for ; speed (call nnnn: 17 states, ret: 10.) ; ISWHSP now returns either carry or zero, ; but not both. This fixes the problem ; where everything between two occurrences ; of EX AF,AF' was treated as tick-bounded ; string. ; What else did I do wrong? ; ; --CHR$(13)24FEB86 ; ;v1.0 Initial release. Z80 source only. ; ; --CHR$(13)23FEB86 ; ; ;WHY: ; ; I dislike Zylog mnemonics. They're ugly, deceptively logical ;(because the CPU they represent isn't ...ld c (de)?), and they ;take more typing than ASM (both ways). They strongly remind me of ;some of the early converts to the Pascal religion. ("Such ;discipline is good for you!" Right; bring on the whips, chains ;and leather, but leave my bike alone. I'd rather code with BD ;than with B&D. At least Leor knows how to hack.) ; ; I HATE UPPER-CASE-ONLY Z80 CODE. It's nearly impossible to ;read unless it's daisy-wheeled, and those ribbons cost a fortune. ; ; This program enforces my own tastes in case convention, ;making Z80 code tolerable to me. If you like it different, you ;can modify this program to do it your way... but you'll have to ;read my code to do it. ; ; This program is also a test case for a long-buffer code ;mechanism that can be used in such public-domain utilities as ;XLATE... Briefly, bring in a large buffer's-worth of input, find ;the last logical endpoint within that (the last in this ;case), perform the process up to there, ship the product out, ;then copy down the unprocessed records, copy in more input to ;fill up the buffer again, and, starting at the next source byte ;after that selected endpoint, do it all again. In this program ;there's no change in the source code other than case, so only one ;buffer is needed, but the machinery is there in this source for ;adaptation. I used ZASM (from DISASM.LBR) to assemble this, and ;MLOAD to load it. CDOS owners can use ASMB. Anybody else will ;have to do "+80h" to the last byte of every DM-declared string. ; ; Lots of otherwise decent assemblers can't deal with ;lowercase code; written for TTY? Irv Hoff's FORM does a good job ;of uppercasing input source for those assemblers, allowing their ;users to preserve the readability of their source. Up until now, ;though, nothing was available to take things the other way (FORM ;is indiscriminant if asked to lowercase; it does it to everything ;except verbatim strings and comments, giving everything a C-food ;flavor). Now there's PRETTY. Silly name, but NEAT was already in ;use and CASE has misleading implications. ; ;NEXT: ; ; I'm planning the following upgrades, on a don't-hold-your- ;breath timetable... ; ;v2.5 Wildcard expansion within a single DU:. ; ;v3.0 Will accept a table-designator in its command line, ; pull that table-set down into place, then get to work. ; I specifically have 8051 code in mind for this (it's ; also insufferable when it's uppercase), but the ; intended machinery will accept as many tables as can ; fit in the TPA (overlay files get lost too easily). ; ;73 & GH de WB1HKU/6 Carroll R. Bryan III (ok in buk fer nw) ; ;================================================================== ; ; FALSE equ 0 TRUE equ NOT FALSE ; CPM equ TRUE ;True if for CP/M2.2-ZCPR3 system. ;False if for CDOS or CP/M1.4. ; DEBUG equ FALSE ;debugging tracers for 16KBOX ; (outer machine) DBUG2 equ FALSE ;debugging tracers for actual ;translation routines DBUG3 equ FALSE ;ditto ; MALICE equ FALSE ;True if intimidating users. ; BDOS equ 5 LF equ 10 CR equ 13 EOF equ 1Ah FCB equ 5Ch DFDMA equ 80h ; LIMREC equ 80h ;16k of records. Could be more, but... ;Run on an Ampro Z80 Little Board, ;the program actually leaves the ;drives alone long enough for the ;access lights to go out. Bit of a ;change from XLATE, eh? That's with ;a minimum of copying, too. ; org 100h ; ; IF CPM ; ld (STAKS),sp ld sp,STAKS ld c,19h ;get current disk call BDOS ld (CURDSK),a ld e,0FFh ld c,20h ;get/set user code call BDOS ld (CURUSR),a call START ;call into program proper. ; EXIT: ld c,20h ;get/set user code ld a,(CURUSR) ld e,a ;On the way home from a normal call BDOS ;operation, reset to original site. ; ld c,0Eh ;select disk ld a,(CURDSK) ld e,a call BDOS ; QUIT: ld sp,(STAKS) ;here we drop our toys and run. ret ; ELSE ;CPM ; ld sp,STAKS ld c,19h ;get current disk call BDOS ld (CURDSK),a ld (USRDSK),a ;set default call START ; EXIT: ld c,0Eh ;select disk ld a,(CURDSK) ld e,a call BDOS QUIT: jp 0 ; ENDIF ;CPM ; START: call ILPRT ; dm 1Dh,9,'***-----PRETTY.COM' db 'v2.3-----***' ; IF DEBUG OR DBUG2 OR DBUG3 ; db 1Dh,9,'*',1Fh,6,'version under test',1Fh,5,'*' ; ENDIF ;DEBUG OR DBUG2 OR DBUG3 ; ; IF CPM ; dm 1Dh,9,'*',1Fh,5,'ZCPR/CPM2+' db 'version',1Fh,6,'*' ; ELSE ;CPM ; dm 1Dh,9,'*',1Fh,4,'CDOS/CPM1.4' db ' version',1Fh,5,'*' ; ENDIF ;CPM ; dm 1Dh,9,'*',1Fh,29,'*' dm 1Dh,9,'*',1Fh,5,'Source' dm 'code' dm 'typographic' dm '*',1Dh,9,'*' dm 'case' dm 'formatter.' dm ' Lowercases' dm '*',1Dh,9,'*' dm 'opcodes,' dm 'low-level' dm 'pseudos;' dm '*',1Dh,9,'*' dm 'uppercases' dm 'symbols,' dm ' labels' dm '*',1Dh,9,'*' dm 'and' dm 'numbers' dm '''A''' dm 'thru' dm '''F''.' dm 1Fh,2,'*',1Dh,9,'*',1Fh,29,'*',1Dh,9,'***--' db '--CHR$(13)10MAR86-----***' ; ;Fair warning... ; IF MALICE ; db 1Dh,9,9,9,'heh',1Dh ; ENDIF ;MALICE ; db 1Dh,LF,0,0 ; ;Is this a real invocation or is this a Sears invocation? ; ld a,(DFDMA) or a jr z,XPLAIN ld a,(FCB+1) cp '?' jr z,XPLAIN cp ' ' jr z,XPLAIN cp '/' jp nz,BIZNES ld a,(FCB+2) cp '/' jp nz,BIZNES ; XPLAIN: call ILPRT ; dm 'Cases' dm 'Zilog' dm 'or' dm '8080-style' dm 'LASM3' dm 'source.' dm 'Switches' dm 'to' dm 1Dh,'LASM3' dm 'on' dm 'finding' dm 'MOV,' dm 'MVI' dm 'or' dm 'LXI' dm 'instruction' dm 'in' dm 'first' dm 1Dh,'16k,' dm 'or' dm 'is' dm 'forced' dm 'by' dm ''' L''' dm 'command' dm 'tail.' dm 'Invocation:',1Dh,LF,9,'>pretty' dm '[du:]infile.typ' dm '[du:outfile.typ]' dm '[' dm 'L]',1Dh,8Ah,' ...as' dm 'a' dm 'convenience,' dm 'OUTFILE' dm 'or' dm 'its' dm 'TYP' dm 'may' dm 'be' dm '''*'',' dm 1Dh,'referring' dm 'to' dm 'that' dm 'section' dm 'of' dm 'INFILE.TYP.' dm 'If' dm 'no' dm 'output' dm 1Dh,'spec' dm 'is' dm 'typed,' dm 'output' dm 'file' dm 'takes' dm 'INFILE.TYP' dm 'and' dm 'input' dm 1Dh,'file' dm 'becomes' db 'INFILE.BAK.',1Dh,0 ; ret ; BIZNES: ; ;First the table-designator, if any, then the drivespecs. ; IF CPM ; ld hl,0FFFFh ld (INDSK),hl ld (OUTDSK),hl ;set blanks in paired DSK/USR bytes. ; ld ix,DFDMA ld hl,DFDMA ;get specs from the buffered line ld c,(hl) ;at 80h. This means, by the way, ld b,0 ;that you have to leave WordStar3.0 add ix,bc ;to run PRETTY. 3.3, I dunno. ld a,(ix+0) ld (STASH),a cp '#' jr z,NWSPAC cp 'L' jr z,NWSPAC cp 'Z' jr nz,NVRMND NWSPAC: ld a,(ix-1) cp ' ' jr nz,NVRMND dec bc dec bc ld a,(STASH) ld (TABTYP),a NVRMND: add hl,bc ld b,c GESPEP: ld a,(hl) ;Loop-top. We're decrementing hl. If cp ' ' ;we find a space before we find a jr nz,NOTSPC ;given colon, the DU: there must be ld (SPFLAG),a ;for the input file. jr NOCO NOTSPC: cp ':' jr nz,NOCO call COLON ld a,(SPFLAG) or a jr nz,ISOUT ld a,b cp 3 jr c,ISIN ISOUT: ld (OUTDSK),de ;(OUTDSK)=e, (OUTUSR)=d jr NOCO ; ISIN: ld (INDSK),de ;guess. NOCO: dec hl djnz GESPEP ; ;Any fish? ; ;OUTFILE's defaults come from INFILE. INFILE's defaults come from ; CURRENT, the DU: in effect at invocation. ; ; IF DBUG3 ; call ILPRT db 1Dh,'@ STASH: ',0 ld a,(STASH) call PHEX call CRLF ; ENDIF ;DBUG3 ; ld a,(INDSK) inc a jr nz,GOTIDK ld a,(CURDSK) ld (INDSK),a GOTIDK: ld a,(OUTDSK) inc a jr nz,GOTODK ld a,(INDSK) ld (OUTDSK),a GOTODK: ld a,(INUSR) inc a jr nz,GOTIUS ld a,(CURUSR) ld (INUSR),a GOTIUS: ld a,(OUTUSR) inc a jr nz,GOTOUS ld a,(INUSR) ld (OUTUSR),a GOTOUS: equ $ ; ELSE ;CPM ; ;CDOS doesn't want to know about ld a,(FCB) ;any user numbers, and it vomits or a ;out any program that tries to jr z,SAMIDV ;ask. Nasty temper, my, my... dec a ld (INDSK),a SAMIDV: ld a,(FCB+16) or a jr z,SAMODV dec a ld (OUTDSK),a SAMODV: equ $ ; ENDIF ;CPM ; ; ; ;Copy the filenames up into their FCBs. First, the source. ; xor a ld (DIFFLG),a ;DIFFerence FLaG. ; ld hl,FCB+1 ld de,INFCB+1 ld bc,11 ldir ; ;Write default values into the output FCB. ; ld hl,FCB+1 ld de,OUTFCB+1 ld bc,11 ldir ; ;Any output declaration? ; ld hl,FCB+17 ld a,(hl) cp ' ' jr z,NOONAM cp '?' jr z,NOONAM ; ; IF DBUG3 ; ld a,8 ld (DMPCTR),a push hl call ILPRT db 1Dh,'Check out byte ',0 ld hl,FCB+17 call PHL call ILPRT db '.',1Dh,0 ld hl,FCB call DUMPR pop hl ; ENDIF ;CBUG3 ; ld a,(TABTYP) or a jr z,CPOUTF ld ix,FCB+17 cp (ix+0) jr nz,CPOUTF ld a,(ix+1) cp ' ' jr z,NOONAM ; CPOUTF: ld de,OUTFCB+1 ld bc,8 ldir ld (DIFFLG),a ;says there's a name difference. ; ;How 'bout a filetype? ; NOONAM: ld hl,FCB+25 ld a,(hl) cp ' ' jr z,NOOTYP cp '?' jr z,NOOTYP ld de,OUTFCB+9 ld bc,3 ldir ld (DIFFLG),a ;says there's a name difference. ; NOOTYP: ld a,(DIFFLG) or a jr nz,OKDIF ld hl,INDSK ld a,(OUTDSK) cp (hl) jr nz,SETDIF ; IF CPM ; inc hl ld a,(OUTUSR) cp (hl) jr nz,SETDIF ; ENDIF ;CPM ; ld hl,2424h ;*.$$$ filetype. In and out files ld (OUTFCB+9),hl ;have same name, so we'll go through ld (OUTFCB+10),hl ;the old file-rename routine. jr OKDIF ; ; SETDIF: ld a,0FFh ld (DIFFLG),a ;...or a DU: difference. ; ;We have FCBs filled out. Now go there. ; OKDIF: ; IF DEBUG ; call ILPRT db 1Dh,LF,'Here''re the FCBs... INFCB first.',1Dh,0 ld a,0Eh ld (DMPCTR),a ld hl,INFCB call DUMPR call CRLF ld a,0Eh ld (DMPCTR),a ld hl,OUTFCB call DUMPR call CRLF ; ENDIF ;DEBUG ; call ILPRT dm 1Dh,9,'Input: ' db 0 ld a,(INDSK) add 'A' call PCHAR ; IF CPM ; ld a,(INUSR) call PNIB ; ENDIF ;CPM ; ld a,':' call PCHAR ld hl,INFCB+1 call HLPRT call ILPRT dm 1Dh,9,'Output:' db 0 ld a,(OUTDSK) add 'A' call PCHAR ; IF CPM ; ld a,(OUTUSR) call PNIB ; ENDIF ;CPM ; ld a,':' call PCHAR ld hl,OUTFCB+1 call HLPRT call CRLF ; IF CPM ; ld c,0Dh ;reset disk system. The SINGLE call BDOS ;virtue of CDOS is, it does it ;for you. Null this out if you're ;hard-disk-only, but don't pass ;it around. I want to eradicate ;BDOS ERR ON B: R/O. ; ENDIF ;CPM ; call GOIN ;go to input DU:. ; ld de,INFCB ld c,0Fh ;open file call BDOS inc a jp nz,OPENOK call ILPRT dm 1Dh,9,7,'+++' ; IF MALICE ; dm 'NO' dm 'SUCH' dm 'FILE,' dm 'O' dm 'GREAT' dm 'INFALLIBLE' dm 'CARBON-BASED' dm 'LIFE-FORM.' db '+++',1Dh,0 ld hl,0 WLPA: dec hl ld a,l or h jr nz,WLPA call CHUCKL ; ELSE ;MALICE ; dm 'No' dm 'File' db '+++',1Dh,0 ; ENDIF ;MALICE ; ret ; OPENOK: ; IF DEBUG ; call ILPRT db 1Dh,'Gonna create an output file now.',0 ; ENDIF ;DEBUG ; ld a,(DIFFLG) or a call nz,GOOUT ; ld de,OUTFCB ld c,13h ;delete file call BDOS ; sub a ld (OUTFCB+12),a ld (OUTFCB+32),a ld de,OUTFCB ld c,16h ;make file call BDOS inc a jr nz,MAKOK call ILPRT dm 1Dh,9,7,'+++' dm 'Directory' dm 'Full' db '+++',1Dh,0 ret MAKOK: ; IF DEBUG ; call ILPRT db CR,LF,'Files open okay. Now for INLUP.',CR,LF,0 ; ENDIF ;DEBUG ; ld a,(DIFFLG) or a call nz,GOIN ;to input DU: xor a ld (FIRSTM),a ;signals that an opcode test in in order ld hl,BUFFER ld (CURSOR),hl ld b,LIMREC ;maximum record count ld de,BUFFER INLUP: ld hl,80h add hl,de ld (DMADDR),hl push bc ; IF DBUG3 ; call ILPRT dm 1Dh,'DMADDR:' db 0 ex de,hl call PHL ex de,hl ; ENDIF ;DBUG3 ; ld c,1Ah ;set DMA address call BDOS ; ld de,INFCB ld c,14h ;read sequential call BDOS pop bc ;get back the loop counter or a jp nz,REDERR ld hl,(DMADDR) ex de,hl djnz INLUP ; IF DEBUG ; call ILPRT db CR,LF,'16k in, it says here. DMADDR: ',0 push de pop hl call PHL call ILPRT db 1Dh,'LIMIT (BUFFER+4000h): ',0 ld hl,BUFFER+4000h call PHL call CRLF ; ENDIF ;DEBUG ; ; ;We've read in a full buffer's-worth, 16k. ;Come out of that with DMADDR = BUFFER + LIMIT... First free address ; after what was read in. Backing from there, look for . ; ld hl,(DMADDR) dec hl ;from NEXT to LBAD ld bc,0 ;we'll get a count from this. ld a,CR cpdr inc hl ;cpdr steps to below . ld (LIMBAD),hl ;Lastbyte address for the process. ld de,BUFFER ;try it on first. or a sbc hl,de jp c,NOCR ;Not a single in the buffer. ld (NEGOFS),bc add hl,hl ;Shift left. Now h = whole record count. ld a,h ld (RECNT),a ;stash it for the output stuff. ; IF DBUG3 ; call ILPRT db 1Dh,'RECNT for output: ',0 ld a,(RECNT) call PHEX call CRLF ; ENDIF ;DBUG3 ; ; ;Do process, stopping at the limit-address. ; ; IF DEBUG ; call ILPRT db 'LIMBAD: ',0 ld hl,(LIMBAD) call PHL call ILPRT db 1Dh,'Now calling PROCESS from within the loop.',1Dh,0 ; ENDIF ;DEBUG ; call PROCES ;<-------------***** ; IF DEBUG ; call ILPRT db 1Dh,'Did that. Now OUTIT.',0 ; ENDIF ;DEBUG ; ; ;Now write that out and get the next batch. ; OUTIT: ld a,(DIFFLG) or a call nz,GOOUT ;go to output DU:. ; IF DEBUG ; call ILPRT db 1Dh,'Called GOOUT.',0 ; ENDIF ;DEBUG ; ld a,(RECNT) ld b,a ld de,BUFFER OUTLUP: ld hl,80h add hl,de push bc ;save the loopcounter from BDOS ld (DMADDR),hl ;store next cycle's DMA address ld c,1Ah ;set DMA address call BDOS ld de,OUTFCB ld c,15h ;write sequential call BDOS or a pop bc jp nz,WRTERR ld hl,(DMADDR) ex de,hl ;de = DMA aDDRess djnz OUTLUP ; ;Are we done? ; ; IF DEBUG ; call ILPRT db 1Dh,'Did OUTLUP.',0 ; ENDIF ;DEBUG ; ld a,(ENDFLG) ;set by REDERR or a jp nz,WEDUN ; ; IF DEBUG ; call ILPRT db 1Dh,'ENDFLG isn''t set.',0 ; ENDIF ;DEBUG ; ; ;de = first byte of unshipped records. ; ; IF DEBUG ; push de call ILPRT db 1Dh,'BUFFER: ',0 ld hl,BUFFER call PHL call CRLF pop de ; ENDIF ;DEBUG ; ld hl,BUFFER+4000h ;one byte past top of buffer or a sbc hl,de ;hl = BYCT to move down. ld (STASHW),hl ;save a copy. push hl pop bc ;throw it into bc ld hl,BUFFER ex de,hl ;now de = start of buffer, ; hl = start of unshipped stuff, ; bc = copydown BYCT ; IF DEBUG ; ld (STASHH),hl ld (STASHD),de ld (STASHB),bc push hl push de push bc call ILPRT db 'We''re about to copy down.',CR,LF db 'HL: ',0 ld hl,(STASHH) call PHL call ILPRT db 1Dh,'DE: ',0 ld hl,(STASHD) call PHL call ILPRT db 1Dh,'BC: ',0 ld hl,(STASHB) call PHL call CRLF pop bc pop de pop hl ; ENDIF ;DEBUG ; ldir ;copy down the uncompleted chunk. ;It's whole records with a process- ;resume address inside the first one. ; ;de = starting DMADDR for next input burst. Must be preserved. ; push de pop hl ;copy de into hl ld bc,(NEGOFS) add hl,bc ;hl->new address of last processed inc hl ;step to the ld a,(hl) cp LF jr nz,NOTLF ;don't start PROCESS at a . inc hl NOTLF: ld (CURSOR),hl ;set the pointer push de ;chuck de into the attic ld a,(DIFFLG) or a call nz,GOIN ;go to input DU:. pop de ;pull it down... BDOS didn't see it. ld a,(RECNT) ;(I just moved this.) Now BDOS ld b,a ;doesn't mess with this either. ; IF DEBUG ; call ILPRT db 'We''re about to jump back to INLUP.',CR,LF,0 ; ENDIF ;DEBUG ; jp INLUP ; ;Something's wrong, there's not a in the whole buffer. ; Is it from a C program? Run FULLEOL on it to add s. ; NOCR: call ILPRT dm 1Dh,7,9,'+++' ; IF MALICE ; dm 'THAT''S' dm 'NOT' dm 'A' dm 'TEXT' dm 'FILE,' dm 'O' dm 'CLEVER' dm 'HOMONID.' db '+++',1Dh,0 ld hl,0 WLPB: dec hl ld a,l or h jr nz,WLPB call CHUCKL ; ELSE ;MALICE ; dm 'Not' dm 'A' dm 'Text' dm 'File' db '+++',1Dh,0 ; ENDIF ;MALICE ; jp QUIT ; ; ;We hit end-of-file, signalled by a read error. If it's ; not an empty file, it's last hits. ; REDERR: ld a,0FFh ld (ENDFLG),a ; ld a,LIMREC cp b jp nz,LASREC ; ; call ILPRT dm 1Dh,7,9,'+++' ; IF MALICE ; dm 'THAT''S' dm 'AN' dm 'EMPTY' dm 'FILE,' dm 'O' dm 'LOFTY' dm 'ONE.' db '+++',1Dh,0 ld hl,0 WLP: dec hl ld a,l or h jr nz,WLP call CHUCKL ; ELSE ;MALICE ; dm 'Empty' dm 'File' db '+++',1Dh,0 ; ENDIF ;MALICE ; jp QUIT ; ; ;DMADDR = BUFFER + (real records) + 80h. ; LASREC: ; IF DEBUG ; call ILPRT db 'We hit LASREC. Last orders, please.',CR,LF,0 ; ENDIF ;DEBUG ; ld de,-80h ld hl,(DMADDR) add hl,de dec hl ld (LIMBAD),hl ;LIMBAD = LBAD inc hl ld de,-BUFFER add hl,de add hl,hl ;shift left ld a,h ld (RECNT),a ; ; IF DEBUG ; call ILPRT db 'Now we call PROCES.',CR,LF,0 ; ENDIF ;DEBUG ; call PROCES ; jp OUTIT ; ; ;Close the files and head home. If input and output files ; have the same intended DU:FILENAME.TYP, we don't have to ; change DU:, but that's when we have to do some renaming. ; WEDUN: ; IF DEBUG ; call ILPRT db 'WEDUN here: closing.',CR,LF,0 ; ENDIF ;DEBUG ; ld a,(DIFFLG) or a call nz,GOIN ; ld de,INFCB ld c,10h ;close file call BDOS ; ld a,(DIFFLG) or a call nz,GOOUT ; ; ld de,OUTFCB ld c,10h ;close file call BDOS ; ld a,(DIFFLG) or a ret nz ; ;We've got some renaming to do before we can head for home. ; Blind-delete INFILE.BAK ...then ; INFILE.TYP becomes INFILE.BAK; ; OUTFILE.$$$ becomes OUTFILE.TYP. ; ld hl,INFCB+9 ld de,OUTFCB+25 ld bc,3 ldir ; ld hl,BAK$ ld de,INFCB+25 ld bc,3 ldir ; ld hl,INFCB+1 ld de,INFCB+17 ld bc,8 ldir ; ld hl,OUTFCB+1 ld de,OUTFCB+17 ld bc,8 ldir ; ; ld hl,INFCB+1 ld de,KILFCB+1 ld bc,8 ldir ; ld de,KILFCB ld c,13h ;delete file call BDOS ; ld de,INFCB ld c,17h ;rename file call BDOS ; ld de,OUTFCB ld c,17h ;rename file call BDOS ; ret ; BAK$: db 'BAK' ; ; -=:*:=- INNER MACHINE -=:*:=- ; ;Here, it's a case-enforcer. Could be anything, tho. ; ;Until LIMIT, run forward through the buffer. ;Call with hl->first char of line. ; PROCES: ; IF DBUG2 ; call ILPRT db 1Dh,'BUFFER = ',0 ld hl,BUFFER call PHL call ILPRT db 1Dh,'CURSOR = ',0 ld hl,(CURSOR) call PHL call CRLF ; ENDIF ;DBUG2 ; ;First time through, test the input text. If it has ; MOVX ...where X is A-Z or a-z, and ; it's an 8080 register designator, ; it's Intel idiom, and the LASM3 tables are used. ; ld a,(FIRSTM) or a jp nz,NOTFST ; ld a,(TABTYP) or a jr z,GUESS cp '#' jp z,LASMIS cp 'L' jp z,LASMIS jp ISZILG ; GUESS: ld hl,BUFFER MOVTSP: call FINXT jp nc,NOTCRY cp EOF jp z,ISZILG NOTCRY: call CHKLIM jp c,ISZILG jp z,ISZILG ld de,MOVTAB call SSMTCH ;returns w/hl unchanged. jp z,GMA call FORWHS ;move it across, so FINXT will jp MOVTSP ;have to move forward. ; GMA: ; IF DBUG2 ; push hl call ILPRT db '<>',1Dh,0 pop hl push hl ld a,0Fh ld (DMPCTR),a call DUMPR pop hl ; ENDIF ;DBUG2 ; call FORWHS jp c,MOVTSP ITIS: ; IF DBUG2 ; call ILPRT db 7,CR,LF,LF,'We got a MOV...',CR,LF,LF,0 ; ENDIF ;DBUG2 ; inc de ld a,(de) cp 1Ah jr z,ISZILG ; IF DBUG2 ; call ILPRT db 1Dh,7,9,'We''re casing Intel stuff.',1Dh,0 ; ENDIF ;DBUG2 ; LASMIS: ld hl,TABL1L ld (TAB1),hl ld hl,TABL2L ld (TAB2),hl ld hl,TABL3L ld (TAB3),hl ld hl,TABL4L ld (TAB4),hl ISZILG: ld a,0FFh ld (FIRSTM),a ; NOTFST: ld hl,(CURSOR) ; PRLOOP: push hl PRINLP: call ISWHSP jp nz,WHATIS inc hl jp PRINLP WHATIS: cp '*' jp z,COMLIN cp ';' jp nz,NOCMLN COMLIN: pop bc ;flush it WHFLSH: call FORWHS call FINXT jp nc,WHFLSH jp DUNLIN ; NOCMLN: pop hl call LINLUP DUNLIN: ld a,(EOFLAG) or a ret nz push hl ; IF DBUG2 ; push hl call CRLF ld a,0Ch ld (DMPCTR),a push de ld de,-20h add hl,de pop de call DUMPR pop hl ; ENDIF ;DBUG2 ; call CHKLIM pop hl jp nc,PRLOOP ret ; ;Found 'end'. Everything from there to EOF is to be treated as ; comments. ; GOTEND: call LOCASB ;lowercase the 'END'. pop bc ;flush one call layer, bypassing ld a,EOF ;PRLOOP, and get lost. ld (EOFLAG),a ; IF DEBUG OR DBUG2 ; call ILPRT db 7,9,'GOTEND.',CR,LF,0 ; ENDIF ;DEBUG OR DBUG2 ; ret ; ; GOTEOF: ld a,EOF ld (EOFLAG),a ret ; ; LINLUP: ld a,(hl) ;is it End-Of-File (^Z)? and 7Fh ;mask ws bit cp EOF jp z,GOTEOF ; cp ';' ; jp z,SFLUSH ; cp '*' ;is it the full-line commenter? ; jp nz,NOSTAR ;SFLUSH: call FORWHS ; call FINXT ; ret c ; jp SFLUSH ; NOSTAR: call ISWHSP ;is it a label? jp z,NOLAB ISLAB: call UPLABL ;uppercase any first-column label NOLAB: call FINXT ;step to next alphanumeric ret c ;carry set if ld de,TABLE5 ;"END". call SSMTCH jp z,GOTEND ld de,(TAB2) ;db,ds,etc call SSMTCH jp z,DULO ld de,(TAB1) call SSMTCH ;string-match. opcode? jp nz,NOTOP call LOCASB ;lowercase the opcode. inc de ld a,(de) ;ld c,(de)? No? Then it isn't ld c,a ;really logical. call FINXT ret c dec c jp z,NOCLP ;1. No argument expected. dec c jp z,NOTOP ;2. Symbol or number only. dec c jp z,ALOLUP ;3. Register arguments. ld de,(TAB4) call SSMTCH ;4. Branch conditions. jp nz,NOTOP call LOCASB ;lowercase any argument, then jp NOTOP ; format the address/symbol. ; ALOLUP: ld de,(TAB3) call FINXT ;walk around '(', ',', etc. ret c ;if . call SSMTCH ;is it a register argument? Z=yes. call z,LOCASB ;returns with zero set. call nz,UPLABL call PASCMA NOC: jp z,ALOLUP ;zero set if comma NOCLP: call FINXT ret c ; NOTOP: call UPLABL ;uppercase until whitespace jp NOCLP ; DULO: call LOCASB ;lowercase for (b) jp NOCLP ; ; ;Pass to Comma ;Call with hl->chars. Steps hl to either comma or whsp. ; Returns with zero set on comma. Returns with carry set ; if EOF, ';', '''', or . ; PASCMA: ; IF DBUG2 ; call ILPRT db '[PASCMA]',0 ; ENDIF ;DBUG2 ; ld a,(hl) cp ',' ret z call ISWHSP jp z,DEALCM inc hl jp PASCMA ; DEALCM: or a jp z,CMZEXT cp CR jp z,SCFEXT cp EOF jp z,SCFEXT cp '''' jp z,SCFEXT cp ';' jp z,SCFEXT or a ;reset zero flag ret ; SCFEXT: or a scf ret ; CMZEXT: dec a ret ; ; ;Limit-Check ;Compares hl with LIMBAD. On return, carry set if hl > (LIMBAD). ; CHKLIM: ; IF DBUG2 ; call ILPRT db '[CHKLIM]',0 ; ENDIF ;DBUG2 ; ex de,hl push hl or a ld hl,(LIMBAD) sbc hl,de pop hl ex de,hl ret ; ; ;Lowercaser ;Call with hl->first char, b=BYCT. ; Returns with hl->next char. ; LOCASB: ; IF DBUG2 ; call ILPRT db '[LOCASB]',0 ; ENDIF ;DBUG2 ; ; ld a,(hl) and 5Fh cp 'Z'+1 jp nc,SKPLO cp 'A' jp c,SKPLO ld a,(hl) or 20h ;lowercase it ld (hl),a SKPLO: inc hl djnz LOCASB cp a ;set zero flag ret ; ; ;Label Uppercaser ;Call with hl->first char of label or number. ;Uppercases until whitespace or colon if not standard-rules number. ; UPLABL: ; IF DBUG2 ; call ILPRT db '[UPLABL]',0 ; ENDIF ;DBUG2 ; call ISDIGT ;first char a digit? jp c,NUMBER ;it's a number. UPLBLP: call ISCHAR ;a=(hl)&5Fh jp nc,NXUPLB ld (hl),a NXUPLB: call COLWSP ret z inc hl jp UPLBLP ; ;Forward whitespace finder ;Call with hl-> first non-whitespace char of word. ;Returns with hl-> whitespace above that word, ; b = bytecount including that whitespace byte. ; FORWHS: ; IF DBUG2 ; call ILPRT db '[FORWHS]',0 ; ENDIF ;DBUG2 ; ld b,1 FRWHLP: call ISWHSP ret c ret z inc b inc hl jr FRWHLP ; ;Whitespace test ;Call with hl-> char to test. ; Returns with zero set if ,,,,. ; Returns with carry set if EOF, ";" or "'". ; ISWHSP: ; IF DBUG2 ; call ILPRT db '[ISWHSP:',0 push hl call PHL pop hl call ILPRT db ']',0 ; ENDIF ;DBUG2 ; ld a,(hl) and 7Fh cp ' ' ret z cp 'I'-40h ;tab ret z cp CR ret z cp LF ret z cp 'Z'-40h ;eof jp z,RETCF cp ';' jp z,RETCF cp '''' jp z,RETCF or a ;reset zero (unless ) ret RETCF: or a ;reset zero flag scf ;and set carry ret ; ; ;Number Caser ;Call with hl-> first digit of an expected hexadecimal ; number. Uppercases 'a'-'f' within it, lowercases ; ANY trailing letter. Rolls right over any illegal char. ;Returns with hl-> first whitespace above, zero set, except ; Returns with carry set if that boundary is ";","'" or EOF. ; ; NUMBER: ; IF DBUG2 ; call ILPRT db '[NUMBER]',0 ; ENDIF ;DUBG2 ; inc hl call COMWSP ret z call ISDIGT jp c,NUMBER call MTCHDN ;is this a trailing letter? jp z,NMTRAI call ISAF jp nc,NUMBER ld a,(hl) and 5Fh ld (hl),a jp NUMBER NMTRAI: call ISCHAR jp nc,INCRET ld a,(hl) or 20h ld (hl),a INCRET: inc hl ret ; ; ; ;Find Next Alphanumeric Code Character ;Moves hl to point to 'A'-'Z', 'a'-'z', '0'-'9'. ;Returns with hl->alpha and zero set. ;Steps across tick-bounded strings and ';'-to- ; comments. ;Returns with carry set if or bang. ; FINXT: ; IF DBUG2 ; call ILPRT db '[FINXT:',0 push hl call PHL pop hl call ILPRT db ']',0 ; ENDIF ;DBUG2 ; call ISCHAR jp c,FNX call ISDIGT jp c,FNX cp ';' jp z,COMNT cp '''' jp z,TICKR cp CR jp z,FNXCR cp '!' jp z,FNBANG inc hl jp FINXT ; COMNT: inc hl ld a,(hl) cp CR jp nz,COMNT FNXCR: inc hl ld a,(hl) cp LF jp nz,FNXTDN inc hl jp FNXTDN ; TICKR: inc hl ld a,(hl) cp CR jp z,FNXTDN ;partial fix cp '''' jp nz,TICKR inc hl ld a,(hl) cp '''' jp nz,FINXT jp TICKR ; FNX: cp a ;set zero, reset carry ret ; FNBANG: inc hl ;step across bang. FNXTDN: scf ;set carry. Caller should give ret ;that higher priority than Zero. ; ; ; ;Tests (hl). Returns with carry flag set if byte is ; 'A'-'Z' or 'a'-'z'. ; ISCHAR: ; IF DBUG2 ; call ILPRT db '.A.',0 ; ENDIF ;DBUG2 ; ld a,(hl) and 5Fh cp 'Z'+1 ret nc cp 'A' ccf ret ; ; ;Tests (hl). Returns with carry flag set if byte is ; '0'-'9'. ; ISDIGT: ; IF DBUG2 ; call ILPRT db '.9.',0 ; ENDIF ;DBUG2 ; ld a,(hl) cp '9'+1 ret nc cp '0' ccf ret ; ; ;Tests (hl). Returns with carry flag set if byte is ; 'A'-'F' or 'a'-'f'. ; ISAF: ld a,(hl) and 5Fh cp 'F'+1 ret nc cp 'A' ccf ret ; ; ;Table Searcher to Null First-Byte ;Call with hl->string to match, de->first byte of match- ; table of string entries in ascending ASCII order, with ; at most one non-null control byte trailing each string, ; the table terminated by a null. Each string entry has the ; top bit set on the last character. ;On find, returns with zero set, bytecount in b, de->lastbyte of ; entry. Concept is from SYMSCH in REZ (Dave Barker). ; ; SSMTCH: ; IF DBUG2 ; call ILPRT db '',0 ; ENDIF ;DBUG2 ; push hl ;save the starting address call MATCH jp z,SSMTDN jp c,SSMTDN jp SSTRY SSINLP: inc de ;match fell off, so we gotta SSTRY: ld a,(de) ;cripple over to next entry. cp 80h jp c,SSINLP SSKP: inc de ;Found the top-bit. Next is null? ld a,(de) ;then that's it for the table. or a jp nz,KPTRYN dec a ;roll it to 0FFh, set carry, reset zero. SSMTDN: pop hl ;get starting address back ret KPTRYN: cp ' ' ;Next is control? Skip. (Table 1) jp c,SSKP pop hl jp SSMTCH ; ; ;String Comparator to Hibit ;Call with hl->string to match, de->table entry. ; On match, returns with zero set, de->last byte of entry. ; Ticks up b as a bytecount for case-manipulation. ;On non-match return, carry is set if test string is higher ; in value than table entry (SYMSCH Done w/o match). ;Match must be complete: hl$ to whsp, de$ to topbit. ; ; MATCH: ld b,1 ;initialize bytecounter MTCHLP: ld a,(de) ; and 7Fh ld c,a call ISCHAR ;a = *hl & 5Fh. We need that mask. ld a,(hl) and 5Fh cp 'Z'+1 jp nc,NOPCHR cp 'A' jp nc,YUPCHR ;Only if it's alpha, though. NOPCHR: ld a,(hl) ;Otherwise, get an unblemished copy. YUPCHR: cp c ;carry set if *hl < *de jp nz,WHICH ld a,(de) cp 80h ;last char of table entry has jp nc,MTCHDN ;d7 set. inc hl inc de inc b jp MTCHLP ; WHICH: ret nc call COMWSP ;hl$ shorter than table entry? scf ;then there're more possible ret nz ;table entries; carry would or a ;preclude their test. ret ; MTCHDN: push hl ;hl$ longer than table entry? inc hl ;then we didn't match the whole call COMWSP ;thing. pop hl ret z or a ;reset carry and zero. ret ; ; ;Test *hl for whsp, comma, paren, bang ; COMWSP: call ISWHSP ret z cp ',' ret z cp ')' ret z cp '!' ret ; ; ; ;Test *hl for whsp, colon, comma, paren, bang ; COLWSP: call ISWHSP ret z cp ',' ret z cp ')' ret z cp '!' ret z cp ':' ret ; ; ;Go to input DU:. ; GOIN: ld a,(INDSK) ld e,a ld c,0Eh ;select disk call BDOS ; IF CPM ; ld a,(INUSR) ld e,a ld c,20h ;get/set user call BDOS ; ENDIF ;CPM ; ret ; ; ;Go to output DU:. ; GOOUT: ld a,(OUTDSK) ld e,a ld c,0Eh ;select disk call BDOS ; IF CPM ; ld a,(OUTUSR) ld e,a ld c,20h ;get/set user call BDOS ; ENDIF ;CPM ; ret ; ; ; IF CPM ; ;DU: decoder. ;Call with hl -> colon. ;Returns with hl -> DU:, b decremented to match. ; d = usr: ; e = drv: (A: = 0h) ;0FFh in either means no value was found for it. ; COLON: dec hl ;units digit, or letter ld de,0FFFFh ;set up default values ld a,(hl) cp '0' jr c,JUSLET cp '9'+1 jr nc,JUSLET sub '0' ld d,a dec hl dec b ld a,(hl) cp '0' jr c,ONENUM cp '9'+1 jr nc,ONENUM sub '0' push de ;save the units value ld d,a ;tens value * 10 add a,a add a,a add a,d add a,a pop de add a,d ;add 'em together. ld d,a ONENUM: ld a,(hl) dec hl dec b JUSLET: cp 'a' jr c,UPPER cp 'z'+1 ret c and 5Fh UPPER: cp 'A' ret c cp 'Z'+1 ret nc sub 'A' ld e,a ;move usr: into position ret ; ENDIF ;CPM ; ; ; WRTERR: call ILPRT dm 1Dh,9,7,'+++' dm 'WRITE' dm 'ERROR' db '+++',0 jp QUIT ; ;-------------------------- ; IF MALICE ; CHUCKL: ld e,'H' call CBD ld e,'A' call CBD ld e,' ' call CBD ld e,7 call CBD ld c,0Bh ;constat call BDOS or a jr z,CHUCKL ld c,1 ;conin call BDOS ret ; CBD: ld c,2 jp BDOS ; ENDIF ;MALICE ; ; ; ;String-packer's version of ILPRT. ; ; ; d7 set: Trailing space ; 1Fh: Next byte is space-count ; 1Dh: ; ; ;TRACER calls CONSTAT and CONIN; PCHAR doesn't. ;TRACER takes more time, then, but it's easier to snag a program ; gone off the rails without hitting reset if it's there...even ; though I usually end up resetting anyway, because BDOS has been ; trashed. ; ILPRT: ex (sp),hl call HLPRT ex (sp),hl ret ; HLPRT: push de push bc push af ILLUP: ld a,(hl) inc hl cp 80h push af ;save the flags and 7Fh or a jp z,ILDUN cp 1Fh jp z,TABBIE cp 1Dh jp nz,SHIPIT ld a,0Dh ; IF DEBUG OR DBUG2 ; call TRACER ; ELSE ; call PCHAR ; ENDIF ;DEBUG OR DBUG2 ; ld a,0Ah SHIPIT: ; IF DEBUG OR DBUG2 ; call TRACER ; ELSE ; call PCHAR ; ENDIF ;DEBUG OR DBUG2 ; pop af jp c,ILLUP ;resume ld a,' ' ; IF DEBUG OR DBUG2 ; call TRACER ; ELSE ; call PCHAR ; ENDIF ;DEBUG OR DBUG2 ; jp ILLUP ; ILDUN: pop af ;get that extra off pop af pop bc pop de ret ; TABBIE: ld b,(hl) dec b TABLUP: ld a,' ' ; IF DEBUG OR DBUG2 ; call TRACER ; ELSE ; call PCHAR ; ENDIF ;DEBUG OR DBUG2 ; djnz TABLUP inc hl ld a,' ' jp SHIPIT ; CRLF: push hl push de push bc push af ld a,CR ; IF DEBUG OR DBUG2 ; call TRACER ; ELSE ; call PCHAR ; ENDIF ;DEBUG OR DBUG2 ; ld a,LF ; IF DEBUG OR DBUG2 ; call TRACER ; ELSE ; call PCHAR ; ENDIF ;DEBUG OR DBUG2 ; pop af pop bc pop de pop hl ret ; PCHAR: push hl push de push bc push af ld e,a ld c,2 call BDOS pop af pop bc pop de pop hl ret ; ;Tracepkg's ILPRT is REMmed out. It's less powerful. ; IF FALSE ; ;========== TRACER PACKAGE ======================START ; ILPRT: ex (sp),hl push af ILLUP: ld a,(hl) inc hl or a jr z,ILDUN call TRACER jr ILLUP ILDUN: pop af ex (sp),hl ret ; ENDIF ;FALSE ; IF DEBUG OR DBUG2 OR DBUG3 ; DMPCTR: db 0 DMPTIC: db 0 DUMPHL: dw 0 ; DUMPR: push bc push de DUMPIN: ld (DUMPHL),hl call PHL call ILPRT db ': ',0 ld hl,(DUMPHL) ld e,16 DUMPHX: ld a,(hl) inc hl push hl push de call PHEX ld a,' ' call TRACER pop de pop hl dec e jr nz,DUMPHX ld hl,(DUMPHL) ld e,16 DUMPAS: ld a,(hl) inc hl push hl push de and 7Fh cp ' ' jr nc,ASOK ld a,'.' ASOK: call TRACER pop de pop hl dec e jr nz,DUMPAS ld a,CR call TRACER ld a,LF call TRACER ; ld de,16 ld hl,(DUMPHL) add hl,de ld (DUMPHL),hl ld a,(DMPCTR) inc a ld (DMPCTR),a and 0Fh jr z,DUMPUP cp 8 jr nz,DUMPIN ld a,CR call TRACER ld a,LF call TRACER jr DUMPIN DUMPUP: pop de pop bc xor a ld (DMPCTR),a ld (DMPTIC),a ret ; ENDIF ;DEBUG OR DBUG2 OR DBUG3 ; PHL: push hl ld a,h call PHEX pop hl ld a,l PHEX: push af rrca rrca rrca rrca call PNIB pop af PNIB: and 0Fh add a,90h daa adc a,40h daa TRACER: push bc push de push hl push af ld e,a ld c,2 call BDOS ld c,0Bh call BDOS or a jr z,NOCSN CSN: ld c,1 call BDOS cp 'S'-40h jr z,CSN cp 'C'-40h jp z,0 NOCSN: pop af pop hl pop de pop bc ret ; ;======= TRACER PACKAGE ============================END ; ; ; ;Z80TABL.Z80 ; ;Simple tables for PRETTY. ; TABLE1: ; ;Z80 mnemonics are lowercased, since they are translated directly ; into program bytes on a one-to-one basis. ; ;Numeric arguments: ; ; 0 End Of Table. ; 1 no arguments expected. ; 2 value/symbol argument. ; 3 use table 3 for casing arguments. ; 4 use table 4 for casing arguments. ; ; dm 'ADC' db 3 dm 'ADD' db 3 dm 'AND' db 3 dm 'BIT' db 3 dm 'CALL' db 4 dm 'CCF' db 1 dm 'CP' db 3 dm 'CPD' db 1 dm 'CPDR' db 1 dm 'CPI' db 1 dm 'CPIR' db 1 dm 'CPL' db 1 dm 'DAA' db 1 dm 'DEC' db 3 dm 'DI' db 1 dm 'DJNZ' ; db 2 dm 'EI' db 1 dm 'EX' db 3 dm 'EXX' db 1 dm 'HALT' db 1 dm 'IM' db 2 dm 'IM0' db 1 dm 'IM1' db 1 dm 'IM2' db 1 dm 'IN' ; db 3 dm 'INC' db 3 dm 'IND' db 1 dm 'INDR' db 1 dm 'INI' db 1 dm 'INIR' db 1 dm 'JP' db 4 dm 'JR' db 4 dm 'LD' db 3 dm 'LDD' db 1 dm 'LDDR' db 1 dm 'LDI' db 1 dm 'LDIR' db 1 dm 'NEG' db 1 dm 'NOP' db 1 dm 'OR' db 3 dm 'OTDR' db 1 dm 'OTIR' db 1 dm 'OUT' db 3 dm 'OUTD' db 1 dm 'OUTI' db 1 dm 'POP' db 3 dm 'PUSH' db 3 dm 'RES' db 3 dm 'RET' ; db 4 dm 'RETI' db 1 dm 'RETN' db 1 dm 'RL' db 3 dm 'RLA' db 3 dm 'RLC' db 3 dm 'RLCA' db 3 dm 'RLD' db 3 dm 'RR' db 3 dm 'RRA' db 3 dm 'RRC' db 3 dm 'RRCA' db 3 dm 'RRD' db 3 dm 'RST' db 2 dm 'SBC' db 3 dm 'SCF' db 1 dm 'SET' db 3 dm 'SLA' db 3 dm 'SRA' db 3 dm 'SRL' db 3 dm 'SUB' db 3 dm 'XOR' db 3 dw 0 ; ; TABLE2: ; ;These are pseudo-ops that I choose to lowercase, since they ; are at the heart of the program's nature and cause simple ; one-for-one translation of listed ASCII into program and ; data bytes. Other pseudo-ops control assembler machinery ; of some complexity; they're uppercased to stand out. ; dm 'DB' dm 'DL' ;define label, same as 'SET' in ASM. dm 'DM' ;db with d7 set on last byte dm 'DS' ; dm 'DW' dm 'EQU' dm 'ORG' dw 0 ; ; TABLE3: ; ;Register names are lowercased since they are merely extensions ; of the mnemonics in Table 1. ; dm 'A' dm 'AF' dm 'AF''' dm 'B' dm 'BC' dm 'C' dm 'D' dm 'DE' dm 'E' dm 'H' dm 'HL' dm 'I' dm 'IX' dm 'IY' dm 'L' dm 'R' dm 'SP' dw 0 ; ; TABLE4: ; ;Program-transfer conditions are lowercased since they are ; merely extensions of the mnemonics in Table 1. ; dm 'C' dm 'M' dm 'NC' dm 'NZ' dm 'P' dm 'PE' dm 'PO' dm 'Z' dw 0 ; ; TABLE5: dm 'END' ;off by itself. It's not only lowercased, ;it declares the remainder of the file to ;be comment lines. ; dw 0 ; ;-------------LASM3 TABLES--------------- ;LASMTABL.Z80 ;Tables for PRETTY ; ;Opcode mnemonics for LASM3 by Steve Schlaifer et al, and ; MAKRO by Allen Ashley (hey, Allen-- lowercase!! Us hackers ; shouldn't have to do it all!!) ; ; 0 End Of Table. ; 1 No argument expected. ; 2 Symbol or numeric argument. ; 3 Use table 3, registers, for argument casing. ; 4 Not used here... Branch instructions incorporate ; conditions into the primary mnemonic. ; TABL1L: dm 'ACI' db 2 dm 'ADC' db 3 dm 'ADCX' db 2 dm 'ADCY' db 2 dm 'ADD' db 3 dm 'ADDX' db 2 dm 'ADDY' db 2 dm 'ADI' db 2 dm 'ANA' db 3 dm 'ANDX' db 2 dm 'ANDY' db 2 dm 'ANI' db 2 dm 'BIT' db 3 dm 'BITX' db 2 dm 'BITY' db 2 dm 'CAD' ;Ashley db 3 dm 'CALL' db 2 dm 'CC' db 2 dm 'CCD' db 1 dm 'CCDR' db 1 dm 'CCI' db 1 dm 'CCIR' db 1 dm 'CIN' ;Ashley db 3 dm 'CM' db 2 dm 'CMA' db 1 dm 'CMC' db 1 dm 'CMP' db 3 dm 'CMPX' db 2 dm 'CMPY' db 2 dm 'CNC' db 2 dm 'CNZ' db 2 dm 'COUT' ;Ashley db 3 dm 'CP' db 2 dm 'CPE' db 2 dm 'CPI' db 2 dm 'CPII' ;Ashley db 1 dm 'CPO' db 2 dm 'CZ' db 2 dm 'DAA' db 1 dm 'DAD' db 3 dm 'DADC' db 3 dm 'DADX' db 3 dm 'DADY' db 3 dm 'DCR' db 3 dm 'DCRX' db 2 dm 'DCRY' db 2 dm 'DCX' db 3 dm 'DCXX' db 1 dm 'DCXY' db 1 dm 'DI' db 1 dm 'DJNZ' db 2 dm 'DSBB' db 3 dm 'EI' db 1 dm 'EX' ;Ashley db 1 dm 'EXAF' db 1 dm 'EXX' db 1 dm 'HLT' db 1 dm 'IM0' db 1 dm 'IM1' db 1 dm 'IM2' db 1 dm 'IN' db 2 dm 'IND' db 1 dm 'INDR' db 1 dm 'INI' db 1 dm 'INIR' db 1 dm 'INP' db 3 dm 'INR' db 3 dm 'INX' db 3 dm 'INXX' db 1 dm 'INXY' db 1 dm 'JC' db 2 dm 'JM' db 2 dm 'JMP' db 2 dm 'JNC' db 2 dm 'JNZ' db 2 dm 'JP' db 2 dm 'JPE' db 2 dm 'JPO' db 2 dm 'JR' db 2 dm 'JRC' db 2 dm 'JRNC' db 2 dm 'JRNZ' db 2 dm 'JZ' db 2 dm 'LBCD' db 2 dm 'LDA' db 2 dm 'LDAI' db 1 dm 'LDAR' db 1 dm 'LDAX' db 3 dm 'LDD' db 1 dm 'LDDR' db 1 dm 'LDED' db 2 dm 'LDI' db 1 dm 'LDIR' db 1 dm 'LHLD' db 2 dm 'LIXD' db 2 dm 'LIYD' db 2 dm 'LSPD' db 2 dm 'LXI' db 3 dm 'LXIX' db 2 dm 'LXIY' db 2 dm 'MOV' db 3 dm 'MOVX' db 3 dm 'MOVY' db 3 dm 'MVI' db 3 dm 'MVIX' db 2 dm 'MVIY' db 2 dm 'NEG' db 1 dm 'NOP' db 1 dm 'ORA' db 3 dm 'ORI' db 2 dm 'ORX' db 2 dm 'ORY' db 2 dm 'OTDR' db 1 dm 'OTIR' db 1 dm 'OUT' db 2 dm 'OUTD' db 1 dm 'OUTDR' ;Ashley db 1 dm 'OUTI' db 1 dm 'OUTIR' ;Ashley db 1 dm 'OUTP' db 1 dm 'PCHL' db 1 dm 'PCIX' db 1 dm 'PCIY' db 1 dm 'POP' db 3 dm 'PUSH' db 3 dm 'RAL' db 1 dm 'RALR' db 3 dm 'RALX' db 2 dm 'RALY' db 2 dm 'RAR' db 1 dm 'RARR' db 3 dm 'RARX' db 2 dm 'RARY' db 2 dm 'RC' db 1 dm 'RES' db 3 dm 'RESX' db 2 dm 'RESY' db 2 dm 'RET' db 1 dm 'RETI' db 1 dm 'RETM' db 1 dm 'RL' ;Ashley db 3 dm 'RLC' db 1 dm 'RLCR' db 3 dm 'RLCX' db 2 dm 'RLCY' db 2 dm 'RLD' db 1 dm 'RM' db 1 dm 'RNC' db 1 dm 'RNZ' db 1 dm 'RP' db 1 dm 'RPE' db 1 dm 'RPO' db 1 dm 'RR' ;Ashley db 3 dm 'RRC' db 1 dm 'RRCR' db 3 dm 'RRCX' db 2 dm 'RRCY' db 2 dm 'RRD' ;Ashley db 1 dm 'RST' db 2 dm 'RZ' db 1 dm 'SAL' db 1 dm 'SALR' db 3 dm 'SALX' db 2 dm 'SALY' db 2 dm 'SAR' db 1 dm 'SARR' db 3 dm 'SARX' db 2 dm 'SARY' db 2 dm 'SBB' db 3 dm 'SBC' ;Ashley db 3 dm 'SBBX' db 2 dm 'SBBY' db 2 dm 'SBCD' db 2 dm 'SBI' db 2 dm 'SDED' db 2 dm 'SET' db 3 dm 'SETX' db 2 dm 'SETY' db 2 dm 'SHLD' db 2 dm 'SIXD' db 2 dm 'SIYD' db 2 dm 'SLA' ;Ashley db 3 dm 'SLC' ;Ashley db 3 dm 'SLR' db 1 dm 'SLRR' db 3 dm 'SLRX' db 2 dm 'SLRY' db 2 dm 'SPHL' db 1 dm 'SPIX' db 1 dm 'SPIY' db 1 dm 'SRA' ;Ashley db 3 dm 'SRC' ;Ashley db 3 dm 'SRL' ;Ashley db 3 dm 'SSPD' db 2 dm 'STA' db 2 dm 'STAI' db 1 dm 'STAR' db 1 dm 'STAX' db 3 dm 'STB' ;Ashley db 3 dm 'STC' db 1 dm 'STX' db 3 dm 'STY' db 3 dm 'SUB' db 3 dm 'SUBX' db 2 dm 'SUBY' db 2 dm 'SUI' db 2 dm 'XCHG' db 1 dm 'XORX' db 2 dm 'XORY' db 2 dm 'XRA' db 3 dm 'XRI' db 2 dm 'XTHL' db 1 dm 'XTIX' db 1 dm 'XTIY' db 1 dw 0 ; ; ; TABL2L: dm 'DB' dm 'DS' dm 'DW' dm 'EQU' dm 'NOW' dm 'ORG' dw 0 ; ; ; TABL3L: dm 'A' dm 'B' dm 'C' dm 'D' dm 'E' dm 'H' dm 'IV' ;Ashley dm 'IX' ;Ashley dm 'IY' ;Ashley dm 'L' dm 'M' dm 'PSW' dm 'RP' ;Ashley dm 'SP' dm 'X' dm 'Y' dw 0 ; ; ; ; TABL4L: dw 0 ;no call condition tests, the mnemonics ;incorporate them. ; ; MOVTAB: dm 'LD' db 1Ah dm 'LXI' db 0Ch dm 'MOV' db 0Ch dm 'MVI' db 0Ch dw 0 ; ; ; TAB1: dw TABLE1 TAB2: dw TABLE2 TAB3: dw TABLE3 TAB4: dw TABLE4 TAB5: dw TABLE5 ; ; TABTYP: db 0 ;if nonzero, is table-selection char. INTEL: db 0 ;nonzero if we're to use LASM3 tables FIRSTM: db 0 ;true if input file's idiom is not yet tested. SPFLAG: db 0 ;true if we found a blank in command line DIFFLG: db 0 ;true if drive, user, name or type specified ; for OUTFILE is different from INFILE. EOFLAG: db 0 ;if nonzero, we got CPMEOF (^Z). ENDFLG: db 0 ;if nonzero, we got read-error (EOF). ; ;------------------- ; INFCB: db 0,' ',' ',0,0,0,0 dw 0,0,0,0,0,0,0,0,0,0,0 ; OUTFCB: db 0,' ','$$$',0,0,0,0 dw 0,0,0,0,0,0,0,0,0,0,0 ; 12345678 KILFCB: db 0,' ','BAK',0,0,0,0 dw 0,0,0,0,0,0,0,0,0,0,0 ; ; ds 100h STAKS: ds 2 DMADDR: ds 2 CURSOR: ds 2 LIMBAD: ds 2 NEGOFS: ds 2 STASHW: ds 2 ; IF DEBUG ; STASHH: ds 2 STASHD: ds 2 STASHB: ds 2 ; ENDIF ;DEBUG ; STASH: ds 1 RECNT: ds 1 CURDSK: ds 1 CURUSR: ds 1 INDSK: ds 1 INUSR: ds 1 OUTDSK: ds 1 OUTUSR: ds 1 BUFFER: equ $ ; end ; eof PRETTY.Z80/Ampro[8051.965]--CHR$(13)14FEB86