; ; Program: XLATE2 ; Author: Richard Conn ; Derivation: Disassembled XLATE.COM of Cromemco's CDOS and Modified ; into XLATE2; XLATE.COM was Version 2.40 ; Version: 1.1 ; Date: 21 July 82 ; Previous Versions: 1.0 (3 May 82) ; ; XLATE2 inputs an Intel-Standard 8080 Assembly Language Source File ; and converts it into a Zilog-Standard Z80 Assembly Language Source File. ; VERS EQU 11 ;VERSION NUMBER ; ; USE ZILOG MNEMONICS AND ABSOLUTE SEGMENTS ; .Z80 ASEG ; ; CP/M CONSTANTS ; WBOOT EQU 0 BDOS EQU 5 DEFFCB EQU 5CH FCB2 EQU 6CH ; ; START OF PROGRAM ; ORG 100H CALL HCHECK ;CHECK FOR HELP REQUEST LD SP,OBUFLPOS ;INIT STACK PTR CALL INIT ;INIT THE PROGRAM LOOP: CALL BUILDLINE ;BUILD THE NEXT INPUT LINE CALL PROCESSOPS ;CONVERT THE OP CODES JR LOOP ; ; MAIN PROCESSING MODULE ; PROCESSOPS: CALL GETOP ;EXTRACT THE NEXT OP CODE JP Z,FLUSHLINE ;IF NONE, FLUSH ; LD HL,OCS1 ;PROCESS OP CODE SET 1 LD BC,10 ;10 CHARS/DUAL ENTRY (OLD OP = 5, NEW OP = 5) CALL CMPOP ;SCAN FOR MATCH IN INLN BUFFER JP Z,DOOCS1 ;PROCESS IF FOUND ; LD HL,OCS2 ;PROCESS OP CODE SET 2 LD BC,10 ;10 CHARS/DUAL ENTRY CALL CMPOP ;SCAN FOR MATCH JP Z,DOOCS2 ;PROCESS ; LD HL,OCS3 ;PROCESS OP CODE SET 3 LD BC,10 ;10 CHARS/DUAL ENTRY CALL CMPOP ;SCAN FOR MATCH JP Z,DOOCS3 ;PROCESS ; LD HL,OCS4 ;PROCESS (EXTENDED RET) OP CODE SET 4 LD BC,5 ;5 CHARS/SINGLE ENTRY CALL CMPOP ;SCAN FOR MATCH CALL Z,DOOCS4 ;CONVERT INTO STANDARD RET FORMS IF MATCH ; LD HL,RETS ;PROCESS (NORMAL RET) OP CODE SET 5 LD BC,5 ;5 CHARS/SINGLE ENTRY CALL CMPOP ;SCAN FOR MATCH JP Z,DORETS ;PROCESS ; LD HL,CALLS ;PROCESS (CALL) OP CODE SET 6 LD BC,5 ;5 CHARS/SINGLE ENTRY CALL CMPOP ;SCAN FOR MATCH JP Z,DOCALLS ;PROCESS ; LD HL,JMPS ;PROCESS (JMP) OP CODE SET 7 LD BC,5 ;5 CHARS/SINGLE ENTRY CALL CMPOP ;SCAN FOR MATCH JP Z,DOJMPS ;PROCESS ; LD HL,OCS8 ;PROCESS OP CODE SET 8 LD BC,12 ;12 CHARS/DUAL ENTRY CALL CMPOP ;SCAN FOR MATCH JP Z,DOOCS8 ;PROCESS ; ; NO MATCH IN OP CODE SETS -- PASS TARGET OP CODE AS IS ; LD B,5 ;5 CHARS IN TARGET LD HL,TARGOP ;POINT TO TARGET POPS1: LD A,(HL) ;GET CHAR CP ' ' ;END OF OP? JR Z,POPS2 ;OUTPUT TAB CHAR IF SO CP 9 ;END OF OP? JR Z,POPS2 ;OUTPUT TAB CHAR IF SO CALL DOUTCHAR ;OUTPUT OP CHAR INC HL ;PT TO NEXT DJNZ POPS1 ;CONTINUE FOR 5 CHARS MAX POPS2: LD A,9 ;END OP WITH CALL DOUTCHAR ;OUTPUT TO DISK ; ; COPY REST OF INPUT LINE AS-IS ; COPYARGS: LD HL,(INLNPTR) ;PT TO NEXT CHAR CARGS1: LD C,0 CARGS2: LD A,(HL) ;GET CHAR CP ' ' ;END OF OPERANDS? JR Z,CARGS4 ;SKIP WHITE SPACE AND OUTPUT REST IF SO CP 9 ;END OF OPERANDS? JR Z,CARGS4 ;SKIP WHITE SPACE AND OUTPUT REST IF SO CP 0DH ;END OF LINE? JR Z,FLUSHLINE ;FLUSH IF SO CP ';' ;BEGINNING OF COMMENT = END OF OPERANDS? JR Z,CARGS5 ;COPY REST IF SO CP '''' ;SINGLE QUOTE? JR NZ,CARGS3 DEC C JR Z,CARGS3 LD C,1 CARGS3: CALL DOUTCHAR ;OUTPUT CHAR IN A TO DISK INC HL ;PT TO NEXT JR CARGS2 CARGS4: PUSH HL CALL SKIPWHITE ;SKIP TO NEXT NON-WHITE CHAR POP HL CP 0DH ;END OF LINE? JR Z,FLUSHLINE ;FLUSH IF SO CP ';' ;COMMENT? JR Z,CARGS5 ;PROCESS COMMENT IF SO CALL OUTWHITE ;OUTPUT A TAB JR CARGS2 ;RESTART PROCESSING CARGS5: DEC C INC C JR NZ,CARGS3 CALL SKIPWHITE LD B,41 CARGS6: LD A,(OBUFLPOS) ;CHECK POSITION IN OUTPUT LINE CP B JR NC,FLUSHLINE DEC A ;BACK UP IN OUTPUT LINE AND 0F8H ;ARTIFICALLY TAB ADD A,9 CP B JR Z,FLUSHLINE JR C,CARGS7 LD A,' ' JR CARGS8 CARGS7: LD A,9 CARGS8: CALL DOUTCHAR JR CARGS6 ; ; WRITE REST OF INLN TO DISK ; FLUSHLINE: CALL OUTSTR LD A,1 ;RESET POSITION COUNTER LD (OBUFLPOS),A RET ; ; PRINT PDOT FOR EVERY TEN LINES ; PDOT: LD A,(LCOUNT) ;GET LINE COUNT DEC A ;COUNT DOWN LD (LCOUNT),A ;PUT LINE COUNT RET NZ ;DONE IF NOT ZERO LD A,'.' ;PRINT PDOT CALL PCHAR LD A,10 ;RESET COUNT LD (LCOUNT),A LD A,(NLCOUNT) ;NEW LINE? DEC A LD (NLCOUNT),A RET NZ LD DE,CRLFSTR ;PRINT NEW LINE CALL PMSG LD A,60 ;RESET COUNTER LD (NLCOUNT),A RET ; ; OUTPUT STRING PTED TO BY HL TO DISK (STRING ENDS IN 0) ; OUTSTR: LD A,(HL) ;GET CHAR AND A ;DONE? RET Z ;RET IF SO CALL DOUTCHAR INC HL ;PT TO NEXT CHAR JR OUTSTR ; ; OUTPUT ALL AND CHARS FOUND UNTIL A NON- AND NON- ; ENCOUNTERED ; OUTWHITE: LD A,(HL) ;GET CHAR CP ' ' ;? JR Z,OW1 ;OUTPUT IT CP 9 ;? RET NZ ;DONE IF NOT OW1: CALL DOUTCHAR ;OUTPUT CHAR IN A TO DISK INC HL ;PT TO NEXT CHAR JR OUTWHITE ;CONTINUE ; ; EXTRACT OP CODE FOR INPUT LINE AND PLACE IN BUFFER ; GETOP: LD HL,INLN ;PT TO INPUT LINE LD A,(HL) ;GET 1ST CHAR IN LINE CP ' ' ;NO LABEL? JR Z,GOP3 ;SKIP TO OP CODE CP 9 ;NO LABEL? JR Z,GOP3 ;SKIP TO OP CODE CP ';' ;COMMENT? RET Z ;DONE IF SO ; ; LINE BEGINS WITH A LABEL -- PROCESS IT ; GOP1: LD C,0 ;SET LABEL CHAR CNT GOP2: LD A,(HL) ;GET NEXT CHAR OF LABEL CP ':' ;END OF LABEL? JR Z,GOP4 CP 9 ;END OF LABEL? JR Z,GOP5 CP 0DH ;END OF LABEL AND NO FURTHER PROCESSING? JR Z,GOP5 CP ';' ;END OF LABEL AND NO FURTHER PROCESSING? JR Z,GOP5 CP ' ' ;END OF LABEL? JR Z,GOP5 CALL DOUTCHAR ;OUTPUT LABEL CHAR TO DISK INC HL ;PT TO NEXT CHAR INC C ;INCR LABEL CHAR CNT JR GOP2 ; ; NO LABEL -- SKIP TO OP CODE ; GOP3: CALL SKIPWHITE ;SKIP OVER WHITE SPACE PUSH HL CALL FTODLM CP ':' POP HL JR Z,GOP1 JR GOP7 ; ; END OF LABEL BY ':' CHAR ; GOP4: INC HL ;SKIP ':' CALL DOUTCHAR ;OUTPUT THE ':' LD A,(HL) ;CHECK FOR EOL CP 0DH ;DON'T DOUBLE NEW LINE (SKIP NEW LINE AFTER GOP6) JR Z,GOP8 ;JUST CONTINUE PROCESSING WITH NO TAB JR GOP6 ;NOT NEW LINE, SO PROCESS FOR NEW LINE IF LONG LABEL ; ; OUTPUT ':' AT END OF LABEL ; GOP5: LD A,':' ;OUTPUT THE ':' CALL DOUTCHAR ; ; SEE IF LABEL IS LESS THAN 7 CHARS LONG ; IF <7, THEN TERMINATE WITH ; IF >6, THEN NEW LINE AND ; GOP6: LD A,C ;GET LABEL CHAR CNT CP 7 ;LESS THAN 7? JR C,GOP7 ;JUST TAB IF LESS THAN 7 LD A,0DH ; CALL DOUTCHAR LD A,0AH ; CALL DOUTCHAR ; ; OUTPUT AFTER LABEL TO DISK ; GOP7: LD A,9 ; CALL DOUTCHAR ; ; SKIP TO OP CODE FIELD AND EXTRACT IT IF PRESENT ; GOP8: CALL SKIPWHITE ;SKIP TO OP CODE FIELD LD A,(HL) ;GET FIRST NON-WHITE CHAR CP ';' ;NO OP CODE IF COMMENT RET Z ;DONE IF COMMENT CP 0DH ;NO OP CODE IF EOL RET Z ;DONE IF EOL LD (ILTOP),HL ;SAVE PTR TO TARGET OP CODE LD B,5 ;5 CHARS MAX IN OP CODE LD DE,TARGOP ;COPY TO TARGOP BUFFER CALL COPYTODELIM ;COPY UNTIL DELIMITER ENCOUNTERED CALL SKIPWHITE ;SKIP OVER WHITE SPACE WHICH FOLLOWS LD (INLNPTR),HL ;SAVE PTR SUB A INC A ;A=1 AND NZ RET ; ; COMPARE OP CODE PTED TO BY HL WITH TARGET OP CODE; RET WITH Z SET IF ; MATCH, NZ IF NO MATCH ; CMPOP: LD A,(HL) ;NO OP CODE TO COMPARE? AND A ;A=0 IF SO JR Z,CMPOP1 ;FAILURE IF SO PUSH BC LD B,5 ;COMPARE 5 BYTES LD DE,TARGOP ;PT TO TARGET OP CODE CALL COMPHLDE ;COMPARE POP BC RET Z ;DONE IF MATCH ADD HL,BC ;PT TO NEXT OP CODE IN TABLE JR CMPOP CMPOP1: INC A ;A=1 AND NZ RET ; ; PROCESS OP CODES IN SET 1 -- OPERAND AND COMMENTS FIELDS ARE UNCHANGED ; HL PTS TO OP CODE TABLE ENTRY, 2ND ELT OF WHICH IS TO BE OUTPUT TO DISK ; DOOCS1: CALL OUTNEWOP5CH ;OUTPUT NEW OP CODE JP COPYARGS ;COPY OPERAND AND COMMENT FIELDS AS-IS ; ; OUTPUT 2ND 5-CHAR-MAX OP CODE FIELD PTED TO BY HL TO DISK AND END IN ; OUTNEWOP5CH: LD BC,5 ;SKIP FIRST 5 CHARS ADD HL,BC ;PT TO 2ND 5-CHAR FIELD ; ; ENTRY PT TO COPY 5-CHAR-MAX FIELD PTED TO BY HL ; ONO5C0: LD B,5 ONO5C1: LD A,(HL) ;GET NEXT CHAR CP ' ' ;? JR Z,ONO5C2 ;DONE IF SO CP 9 ;? JR Z,ONO5C2 ;DONE IF SO CALL DOUTCHAR ;OUTPUT CHAR TO DISK INC HL ;PT TO NEXT DJNZ ONO5C1 ;COUNT DOWN ONO5C2: LD A,9 ;OUTPUT TO DISK JP DOUTCHAR ;OUTPUT TO DISK ; ; PROCESS OP CODES IN SET 2 - OPERAND IS 1 REG OR '(HL)' ; HL PTS TO OP CODE TABLE ENTRY, 2ND ELT OF WHICH IS TO BE OUTPUT TO DISK ; DOOCS2: CALL OUTNEWOP5CH ;OUTPUT NEW 5-CHAR-MAX OP CODE LD HL,(INLNPTR) ;PT TO OPERAND FIELD ATHLCHECK: LD A,(HL) ;CHECK FOR '(HL)' REFERENCE CP 'M' ;TAKES THE FORM OF 'M' IN 8080 MNEMONICS JP NZ,CARGS1 ;OUTPUT NORMALLY IF NOT INC HL ;PT TO CHAR AFTER PUSH HL ;SAVE PTR LD HL,ATHL ;OUTPUT '(HL)' CALL OUTSTR ;OUTPUT TO DISK POP HL ;GET PTR JP CARGS1 ;PROCESS REST OF LINE NORMALLY ATHL: DB '(HL)',0 ; ; PROCESS OP CODES IN SET 3 - OPERAND IS BC, DE, HL, OR PSW REG PAIR ; HL PTS TO OP CODE TABLE ENTRY, 2ND ELT OF WHICH IS TO BE OUTPUT TO DISK ; DOOCS3: CALL OUTNEWOP5CH ;OUTPUT NEW OP CODE RPCHECK: LD HL,(INLNPTR) ;PT TO OPERAND FIELD PUSH HL ;SAVE PTR LD A,(HL) ;GET OPERAND CP 'B' ;FOR BC? JR Z,PRBC ;OUTPUT BC IF SO CP 'D' ;FOR DE? JR Z,PRDE ;OUTPUT DE IF SO CP 'H' ;FOR HL? JR Z,PRHL ;OUTPUT HL IF SO CP 'P' ;FOR PSW? JR NZ,L0309 ;OUTPUT WHATEVER'S THERE IF NOT INC HL ;MAKE SURE IT IS 'PSW' LD A,(HL) CP 'S' JR NZ,L0309 ;OUTPUT WHAT'S THERE IF NOT INC HL LD A,(HL) CP 'W' JR NZ,L0309 ;OUTPUT WHAT'S THERE IF NOT POP HL ;IT IS 'PSW', SO CLEAR STACK AND PT INC HL ; ... TO CHAR AFTER 'PSW' INC HL PUSH HL LD HL,AFSTR ;PRINT 'AF' JR PRREGPAIR ;DO PRINT PRBC: LD HL,BCSTR ;PRINT 'BC' JR PRREGPAIR PRDE: LD HL,DESTR ;PRINT 'DE' JR PRREGPAIR PRHL: LD HL,HLSTR ;PRINT 'HL' PRREGPAIR: CALL OUTSTR ;PRINT STRING PTED TO BY HL AND MAKE HL ON STACK POP HL ; ... PT TO NEXT CHAR INC HL PUSH HL L0309: POP HL ;PRINT WHATEVER OTHER OPERAND IT IS JP CARGS1 ;PRINT THE OPERAND AFSTR: DB 'AF',0 BCSTR: DB 'BC',0 DESTR: DB 'DE',0 HLSTR: DB 'HL',0 ; ; PROCESS OP CODE SET 4 - EQ, NE, LT, GE RETS, CALLS, AND JMPS ; HL PTS TO OP CODE TABLE ENTRY, 2ND ELT OF WHICH IS TO BE OUTPUT TO DISK ; DOOCS4: LD A,(TARGOP+1) ;LOOK AT 2ND LETTER OF TARGET OP LD HL,ZFLG ;PREP FOR ZERO CP 'E' ;IF 'E', THEN FORM IS 'EQ' JR Z,ZCPUT ;CHANGE FORM TO 'XZ ', WHERE X=R,C,J LD HL,NZFLG ;PREP FOR NOT ZERO CP 'N' ;IF 'N', THEN FORM IS 'NE' JR Z,ZCPUT LD HL,CFLG ;PREP FOR CARRY CP 'L' ;IF 'L', THEN FORM IS 'LT' JR Z,ZCPUT LD HL,NCFLG ;FORM MUST BE 'GE', SO NO CARRY ZCPUT: LD A,(HL) ;GET FIRST CHAR LD (TARGOP+1),A ;STORE IT INC HL ;PT TO 2ND CHAR LD A,(HL) ;GET IT LD (TARGOP+2),A ;STORE IT RET ZFLG: DB 'Z ' NZFLG: DB 'NZ' CFLG: DB 'C ' NCFLG: DB 'NC' ; ; PROCESS OP CODE SET 5 -- RETURN FORMS ; HL PTS TO OP CODE TABLE ENTRY, 2ND ELT OF WHICH IS TO BE OUTPUT TO DISK ; DORETS: LD HL,RETSTR ;PT TO STR TO COPY CALL COPY5 ;COPY WITH OPTIONAL COND JP COPYARGS ;COPY REST OF OPERAND FIELD AND COMMENTS AS-IS RETSTR: DB 'RET ',0 DOCALLS: LD HL,CALLSTR JR CP5WITHCOMMA ;COPY AND FOLLOW WITH COMMA CALLSTR: DB 'CALL ',0 DOJMPS: LD HL,JPSTR ;FALL THRU TO DO JP FORMS ; ; COPY STRING AT HL FOLLOWED BY CONDITION CODE, A COMMA, AND REST OF ; OPERAND FIELD ; CP5WITHCOMMA: CALL COPY5 LD A,',' CALL DOUTCHAR ;OUTPUT COMMA TO DISK JP COPYARGS ;COPY REST OF OPERAND FIELD JPSTR: DB 'JP ',0 ; ; COPY 5-CHAR-MAX STRING PTED TO BY HL FOLLOWED BY AND 2-CHAR COND ; COPY5: CALL ONO5C0 ;COPY 5-CHAR-MAX STRING PTED TO BY HL LD A,(TARGOP+1) ;OUTPUT FIRST CHAR OF COND CALL DOUTCHAR LD A,(TARGOP+2) ;OUTPUT 2ND CHAR OF COND IF NOT CP ' ' RET Z JP DOUTCHAR ; ; PROCESS OP CODE SET 8 - THIS TABLE CONTAINS THE SERVICE ROUTINE ADR ; EMBEDDED IN IT AFTER EACH OP CODE PAIR; ; HL PTS TO OP CODE TABLE ENTRY, 2ND ELT OF WHICH IS TO BE OUTPUT TO DISK ; DOOCS8: PUSH HL ;SAVE PTR TO OLD (1ST) OP LD BC,10 ;PT TO ADR OF SERVICE ROUTINE ADD HL,BC LD C,(HL) ;BC=ROUTINE ADDRESS INC HL LD B,(HL) POP HL ;PT TO OLD (1ST) OP PUSH BC ;ROUTINE ADDRESS ON STACK RET ;JMP TO ROUTINE ; ; THIS CONVERTS 'DAD ' TO 'ADD HL,' ; DO81: CALL OUTNEWOP5CH ;OUTPUT 'ADD' LD HL,DO81S ;OUTPUT 'HL,' CALL OUTSTR JP RPCHECK ;OUTPUT DO81S: DB 'HL,',0 ; ; THIS CONVERTS 'ADD R' TO 'ADD A,R' ; AND 'ADC R' TO 'ADC A,R' ; AND 'SBC R' TO 'SBC A,R' ; DO82: CALL OUTNEWOP5CH ;OUTPUT THE 'IN' LD HL,DO82S ;OUTPUT 'A,' JP DO8F1 ;04C7H DO82S: DB 'A,',0 ; ; THIS CONVERTS 'LDA ' TO 'LD A,()' ; AND 'IN ' TO 'IN A,()' ; DO83: CALL OUTNEWOP5CH LD HL,DO83S JR OUTCLP DO83S: DB 'A,(',0 ; ; THIS CONVERTS 'LDAX ' TO 'LD A,()' ; DO84: CALL OUTNEWOP5CH ;OUTPUT OP CODE LD HL,(INLNPTR) ;PT TO OPERAND LD A,(HL) ;GET 1ST CHAR OF OPERAND CP 'B' ;BC REG PAIR? JR Z,DO841 ;PROCESS IT CP 'D' ;DE REG PAIR? JR Z,DO842 ;PROCESS IT JP CARGS1 ;SOMETHING FUNNY -- PROCESS NORMALLY DO841: LD HL,DO841S JP DO8D3 DO842: LD HL,DO842S JP DO8D3 DO841S: DB 'A,(BC)',0 DO842S: DB 'A,(DE)',0 ; ; THIS CONVERTS 'LHLD ' TO 'LD HL,()' ; DO85: CALL OUTNEWOP5CH LD HL,DO85S ; ; THIS OUTPUTS THE STRING PTED TO BY HL, OUTPUTS THE REST OF THE OPERAND ; FIELD, OUTPUTS A CLOSING ')', AND OUTPUTS THE REST OF THE INPUT LINE ; OUTCLP: CALL OUTSTR ;01F9H CALL OUTOPER ;04D5H LD A,')' ;29H CALL DOUTCHAR ;0631H JP CARGS1 ;0198H DO85S: DB 'HL,(',0 ; ; THIS CONVERTS 'MOV R,R' TO 'LD R,R' ; DO86: CALL OUTNEWOP5CH LD HL,(INLNPTR) ;PT TO 1ST CHAR OF OPERAND FIELD LD A,(HL) ;GET IT CP 'M' ;CONVERT 'M' TO '(HL)'? JR NZ,DO862 ;NO CONVERSION NECESSARY PUSH HL LD HL,ATHL ;OUTPUT '(HL)' CALL OUTSTR POP HL ; ; OUTPUT ',' FOLLOWED BY '(HL)' OR 'R' ; DO861: INC HL ;OUTPUT COMMA AND THEN 2ND R LD A,(HL) ;GET COMMA CALL DOUTCHAR INC HL ;PT TO 2ND R JP ATHLCHECK ;OUTPUT '(HL)' OR R ; ; OUTPUT 'R,' FOLLOWED BY '(HL)' OR 'R' ; DO862: CALL DOUTCHAR ;OUTPUT 'R' JR DO861 ;OUTPUT REST ; ; THIS CONVERTS 'PCHL' TO 'JP(HL)' ; DO88: CALL OUTNEWOP5CH LD HL,ATHL ;OUTPUT THE '(HL)' JP DO8F1 ; ; THIS CONVERTS 'RST N' TO 'RST NNH' ; DO89: CALL OUTNEWOP5CH LD HL,DO89S JP DO8F1 DO89S: DB '8*',0 ;MULTIPLY RESTART NUMBER BY 8 FOR Z80 ; ; THIS CONVERTS 'SHLD ' TO 'LD (),HL' ; DO8A: CALL OUTNEWOP5CH LD A,'(' ;OUTPUT OPENING '(' CALL DOUTCHAR CALL OUTOPER ;OUTPUT OPERAND PUSH HL LD HL,DO8AS ;OUTPUT '),HL' JR DO8C2 DO8AS: DB '),HL',0 ; ; THIS CONVERTS 'SPHL' TO 'LD SP,HL' ; DO8B: CALL OUTNEWOP5CH LD HL,DO8BS JR DO8F1 DO8BS: DB 'SP,HL',0 ; ; THIS CONVERTS 'STA ' TO 'LD (),A' ; AND 'OUT ' TO 'OUT (),A' ; DO8C: CALL OUTNEWOP5CH LD A,'(' ;OUTPUT '(' ; ; THIS OUTPUTS '),A' ; DO8C1: CALL DOUTCHAR ;OUTPUT CHAR IN A CALL OUTOPER ;OUTPUT OPERAND FIELD PUSH HL LD HL,DO8CS ;OUTPUT '),A' DO8C2: CALL OUTSTR ;OUTPUT STRING PTED TO BY HL POP HL ;CLEAR STACK JP CARGS1 ;OUTPUT REST OF INPUT LINE DO8CS: DB '),A',0 ; ; THIS CONVERTS 'STAX ' TO 'LD (),A' ; DO8D: CALL OUTNEWOP5CH LD HL,(INLNPTR) ;PT TO 1ST CHAR OF OPERAND LD A,(HL) ;GET IT CP 'B' ;BC REG PAIR? JR Z,DO8D1 ;OUTPUT IT IF SO CP 'D' ;DE REG PAIR? JR Z,DO8D2 ;OUTPUT IT IF SO JP CARGS1 ;ELSE, OUTPUT WHAT'S THERE DO8D1: LD HL,DO8D1S JR DO8D3 DO8D2: LD HL,DO8D2S DO8D3: CALL OUTSTR LD HL,(INLNPTR) ;PT TO AFTER 'B' OR 'D' INC HL JP CARGS1 DO8D1S: DB '(BC),A',0 DO8D2S: DB '(DE),A',0 ; ; THIS CONVERTS 'XCHG' TO 'EX DE,HL' ; DO8E: CALL OUTNEWOP5CH LD HL,DO8ES JR DO8F1 DO8ES: DB 'DE,HL',0 ; ; THIS CONVERTS 'XTHL' TO 'EX (SP),HL' ; DO8F: CALL OUTNEWOP5CH LD HL,DO8FS DO8F1: CALL OUTSTR ;01F9H JP COPYARGS ;0195H DO8FS: DB '(SP),HL',0 ; ; OUTPUT REST OF OPERAND FIELD UP TO WHITE SPACE BEFORE ENDING COMMENT ; OR END OF LINE ; OUTOPER: LD HL,(INLNPTR) ;PT TO NEXT CHAR IN INPUT LINE BUFFER OOL1: LD A,(HL) ;GET NEXT CHAR CP ';' ;BEGINNING OF COMMENT? JR Z,OOL2 ;CHECK FOR REST OF OPERAND CP 0DH ;END OF LINE? JR Z,OOL2 ;CHECK FOR REST OF OPERAND INC HL ;CONTINUE UNTIL EITHER COMMENT OR EOL FOUND JR OOL1 OOL2: DEC HL ;BACK UP (OVER WHITE SPACE?) LD A,(HL) ;GET CHAR CP ' ' ;WHITE? JR Z,OOL2 ;CONTINUE BACKING CP 9 ;WHITE? JR Z,OOL2 ;CONTINUE BACKING INC HL ;PT TO FIRST WHITE CHAR EX DE,HL ;SAVE PTR IN DE LD HL,(INLNPTR) ;PT TO START OF SCAN OOL3: LD A,D ;ALL OF OPERAND FIELD FLUSHED? CP H ;CHECK FOR PTR MATCH JR NZ,OOL4 ;NO MATCH, SO FLUSH NEXT CHAR LD A,E ;REST OF MATCH? CP L RET Z ;DONE IF ALL MATCH OOL4: LD A,(HL) ;OUTPUT OPERAND CHAR TO DISK CALL DOUTCHAR INC HL ;PT TO NEXT OPERAND CHAR JR OOL3 ;CONTINUE UNTIL OPERAND ALL OUT ; ; THE FOLLOWING TURNS ON VARIOUS MESSAGES FOR MANUAL TRANSLATION ; DO91: LD A,9 ;ENDIFS LD (XLT1ON),A ;STORE TO ENABLE JR DO941 DO92: LD A,9 ;INCLUDES LD (XLT2ON),A JR DO941 DO93: LD A,9 ;LISTS LD (XLT3ON),A JR DO941 DO94: LD A,9 ;MACROS LD (XLT4ON),A DO941: CALL OUTNEWOP5CH ;OUTPUT NEW CODE LD A,0DH ;TURN ON PRINTED ERR MESSAGE LD (ERR5ON),A ;TURN ON FLAG BY STARTING WITH JP COPYARGS ;COPY REST OF CODE ; ; THE FOLLOWING CHECKS FOR THE SPECIFICATION OF A HELP OPTION AND ; PRINTS THE HELP MESSAGE IF SO ; HCHECK: LD A,(DEFFCB+1) ;GET FIRST CHAR OF FILE NAME CP '/' ;OPTION? RET NZ ;NO HELP REQUESTED IF NOT OPTION LD DE,HEADER ;PRINT PROGRAM BANNER CALL PMSG LD DE,HMSG1 ;PRINT HELP MESSAGE CALL PMSG LD C,1 ;GET ANY CHAR CALL BDOS LD DE,HMSG2 ;PRINT REST OF HELP MESSAGE CALL PMSG POP DE ;CLEAR STACK RET ;RETURN TO CP/M ; ; THE FOLLOWING INITIALIZES THE PROGRAM FOR EXECUTION ; INIT: LD DE,HEADER ;PRINT PROGRAM BANNER CALL PMSG LD A,10 ;INIT PDOT PRINT (LINE) COUNT LD (LCOUNT),A LD A,60 ;INIT NEW LINE PRINT COUNT LD (NLCOUNT),A LD A,1 ;INITIALIZE OUTPUT BUFFER LINE POSITION LD (OBUFLPOS),A CALL MAKEFNS ;SET UP FILE NAMES CALL OPENIN ;OPEN INPUT FILE CALL OPENOUT ;OPEN OUTPUT FILE LD HL,FHDR ;OUTPUT '.Z80' AND 'ASEG' TO MAC FILE INIT1: LD A,(HL) ;GET CHAR OR A ;DONE? JR Z,INIT2 CALL DOUTCHAR ;OUTPUT TO DISK INC HL ;PT TO NEXT JR INIT1 INIT2: LD A,(FCB2+1) ;2ND FILE NAME PRESENT? CP ' ' ; IF NOT RET NZ ;DONE IF SO XOR A ;A=0 LD (OCS4),A ;TURN OFF WEIRD OP CODE SCAN (REQ, ETC) LD (NOXLT),A ;TURN OFF SCAN FOR ENT, NAME, RAM, ROG LD (NOXLT2),A ;TURN OFF SCAN FOR IFC, ICL, MAC, LST RET ; ; SET UP FILE NAMES ; MAKEFNS: LD HL,DEFFCB ;COPY INPUT FILE NAME FROM COMMAND LD DE,FCBASM ;INTO THIS FCB FOR USE LD BC,9 ;9 BYTES LDIR ;COPY LD A,(HL) ;FILE TYPE SPECIFIED? CP ' ' ;NONE IF JR Z,MFN1 LD BC,3 ;3 MORE BYTES LDIR MFN1: LD HL,FCB2+1 ;2ND FILE SPECIFIED? LD A,(HL) ;GET FIRST BYTE OF FILE NAME DEC HL ;PT TO FIRST BYTE OF FCB CP ' ' ;NO 2ND FILE NAME? JR NZ,MFN2 ;SKIP RELOAD OF HL IF THERE IS A 2ND FILE NAME LD HL,DEFFCB ;COPY FILE NAME INTO OUTPUT FCB MFN2: LD DE,FCBZ80 ;OUTPUT FCB LD BC,9 ;9 BYTES LDIR ;COPY LD HL,FCB2+9 ;PT TO FILE TYPE LD A,(HL) ;CHECK FOR A FILE TYPE CP ' ' ;NONE IF JR Z,MFN3 LD BC,3 ;THERE IS ONE, SO COPY IT OVER LDIR MFN3: LD DE,PRFNM1 ;PRINT PART 1 OF FILE NAME MESSAGE CALL PMSG LD HL,FCBASM ;PRINT NAME OF SOURCE FILE CALL PRFNAME LD DE,PRFNM2 ;PRINT PART 2 OF FILE NAME MESSAGE CALL PMSG LD HL,FCBZ80 ;PRINT NAME OF DESTINATION FILE CALL PRFNAME LD DE,CRLFSTR ;END LINE CALL PMSG RET ; ; PRINT FILE NAME MESSAGE ; PRFNAME: LD A,(HL) ;GET DISK NUMBER ADD A,'@' ;ADD IN ASCII BIAS CALL PCHAR LD A,':' ;PRINT COLON CALL PCHAR INC HL ;PT TO FIRST CHAR OF FILE NAME LD B,8 ;8 CHARS CALL PRFNC LD A,'.' ;DOT CALL PCHAR LD B,3 ;3 CHARS CALL PRFNC RET PRFNC: LD A,(HL) ;GET NEXT CHAR INC HL ;PT TO NEXT CALL PCHAR ;PRINT CHAR DJNZ PRFNC RET ; ; OPEN INPUT FILE FOR PROCESSING ; OPENIN: LD DE,FCBASM ;OPEN FILE FOR INPUT LD C,0FH CALL BDOS CP 0FFH ;ERROR? JR Z,OIERR ;ABORT WITH ERROR MESSAGE IF SO LD A,80H ;INIT CHAR COUNT FOR BUFFER LD (IBUFCNT),A RET OIERR: LD DE,ERR2 ;INPUT FILE ERROR MESSAGE JP ENDERR ;ABORT ; ; OPEN FILE FOR OUTPUT ; OPENOUT: LD DE,FCBZ80 ;OPEN OUTPUT FILE LD C,0FH CALL BDOS CP 0FFH ;ERROR? JR NZ,OOERR2 ;ABORT IF NO ERROR (OVERWRITE OLD FILE) OPENO1: LD DE,FCBZ80 ;ELSE CREATE OUTPUT FILE LD C,16H CALL BDOS CP 0FFH ;ERROR? JR Z,OOERR1 LD DE,FCBZ80 ;NOW OPEN OUTPUT FILE (REDUNDANT WITH MAKE) LD C,0FH CALL BDOS LD A,80H ;INIT COUNT OF BYTES REMAINING LD (OBUFBACKCNT),A ;SET COUNT LD HL,OBUF ;INIT ADDRESS OF NEXT BYTE LD (OBUFPTR),HL ;SET PTR RET OOERR1: LD DE,ERR3 ;DISK FULL JP ENDERR ;ABORT ERROR OOERR2: LD DE,ERR4 ;ATTEMPT TO OVERWRITE EXISTING FILE CALL PMSG LD C,1 ;GET RESPONSE CALL BDOS CALL CAPS ;CAPITALIZE CP 'Y' ;CONTINUE IF YES LD DE,ERR4A ;PREP FOR ABORT JP NZ,ENDERR ;ABORT ERROR LD DE,CRLFSTR ;NEW LINE CALL PMSG LD DE,FCBZ80 ;DELETE OLD FILE LD C,19 ;BDOS DELETE FILE CALL BDOS JR OPENO1 ;CREATE NEW FILE AND CONTINUE ; ; CHECK TO SEE IF CHAR PTED TO BY HL IS A DELIMITER AND FLUSH CHARS UNTIL ; IT IS; RET WITH ZERO FLAG SET WHEN DONE ; FTODLM: ;Flush TO DeLiMiter PUSH BC CALL DLIMSCAN ;DO SCAN POP BC RET Z ;MATCH, SO ABORT INC HL ;PT TO NEXT CHAR JR FTODLM ;CONTINUE SCAN ; ; COPY (HL) TO (DE) FOR B BYTES OR UNTIL A DELIMITER IS ENCOUNTERED ; COPYTODELIM: LD C,B ;LET BC=OLD B (FOR LDI INSTR) LD B,0 PUSH BC ;SAVE REGS PUSH DE PUSH HL CALL SPFILL ;FILL DESTINATION BUFFER WITH SPACES (PTED TO BY DE) POP HL ; ... AND C BYTES LONG POP DE POP BC CTD1: PUSH BC ;SAVE COUNT CALL DLIMSCAN ;SCAN FOR DELIMITER IF ENCOUNTERED POP BC RET Z ;DONE IF SO LDI ;COPY NEXT CHAR INTO DESTINATION BUFFER JP PO,DLIMSCAN ;FINAL DELIMITER SCAN IF DONE JR CTD1 ; ; ADVANCE BUFFER POINTER HL UNTIL NON-WHITE (NON-, NON-) ; ENCOUNTERED ; SKIPWHITE: LD A,(HL) ;GET CHAR CP ' ' ;? JR Z,SKPWH1 ;SKIP IF SO CP 9 ;? RET NZ ;DONE IF NOT SKPWH1: INC HL ;PT TO NEXT CHAR JR SKIPWHITE ; ; CHECK TO SEE IF CHAR PTED TO BY HL IS A DELIMITER ; DLIMSCAN: PUSH DE EX DE,HL ;PT TO CHAR WITH DE LD HL,DLIMS ;PT TO TABLE OF DELIMITERS CALL DELIMCHS ;DO SCAN IN GENERAL EX DE,HL ;PT TO CHAR WITH HL LD A,(HL) ;GET CHAR IN A POP DE RET ; ; TABLE OF VALID DELIMITERS ; DLIMS: DB 1,1 ;SCAN 1 BYTE AT A TIME, AND SKIP 1 BYTE IF NO MATCH DB ',' ;DELIMITERS ... DB ':' DB '+' DB '-' DB '/' DB '*' DB ' ' DB ')' DB ';' DB 0DH DB 9 ; ... TO HERE DB 0 ;END OF TABLE ; ; SCAN FOR DELIMITER -- RETURN WITH NZ IF NOT FOUND OR PT TO DELIMITER ; WITH Z IF FOUND; ON INPUT, TABLE PTED TO BY HL WITH 1ST 2 BYTES ; GIVING NUMBER OF BYTES TO CHECK AND NUMBER OF BYTES TO SKIP, RESP, ; ON EACH PARTIAL SCAN ; DELIMCHS: CALL SPCHSCAN ;DO SCAN OF TABLE RET NZ ;NOT FOUND LD C,B ;CHAR OFFSET COUNT IN BC LD B,0 ADD HL,BC ;PT TO CHAR SUB A ;SET ZERO FLAG RET ; ; SCAN SPECIAL CHAR TABLE PTED TO BY HL FOR STRING PTED TO BY DE; ; NUMBER OF SIGNIFICANT BYTES TO SCAN AS FIRST ENTRY IN TABLE, ; NUMBER OF BYTES TO SKIP ON FAILURE AS 2ND ENTRY IN TABLE; ; TABLE ENDS IN A BINARY 0 ; SPCHSCAN: LD B,(HL) ;B=NUMBER OF BYTES TO SCAN INC HL LD C,(HL) ;C=NUMBER OF BYTES TO SKIP ON FAILURE INC HL ;PT TO FIRST VALID BYTE IN TABLE ; ; MAIN SCANNING LOOP ; SPCH1: LD A,(HL) ;CHECK FOR END OF TABLE AND A ;ZERO? JR Z,SPCH2 ;DONE IF SO CALL COMPHLDE ;DO COMPARE RET Z ;RETURN IF MATCH LD A,C ;POINT TO NEXT TABLE ENTRY CALL ADDHLA ;HL=HL+(SIZE OF TABLE ENTRY) JR SPCH1 ; ; NO MATCH -- RETURN NZ ; SPCH2: INC A ;A=1 AND NZ RET ; ; COMPARE CHARS PTED TO BY DE WITH THAT PTED TO BY HL FOR B BYTES ; RET WITH ZERO FLAG SET IF COMPLETE MATCH, NZ IF NO MATCH; ; HL, DE, BC NOT AFFECTED ; COMPHLDE: PUSH HL ;SAVE REGS PUSH DE PUSH BC CMPHD1: LD A,(DE) ;GET DE CHAR CP (HL) ;COMPARE TO HL CHAR JR NZ,CMPHD2 ;NO MATCH INC HL ;PT TO NEXT INC DE DJNZ CMPHD1 ;COUNT DOWN -- ZERO FLAG SET ON END CMPHD2: POP BC ;RESTORE REGS POP DE POP HL RET ; ; HL=HL+A ; ADDHLA: ADD A,L ;DO IT LD L,A RET NC INC HL RET ; ; FILL MEMORY PTED TO BY DE WITH SPACES FOR BC BYTES ; SPFILL: LD A,' ' ; LD (DE),A ;STORE FIRST LD H,D ;MAKE HL PT TO 1ST LD L,E INC DE ;DE PTS TO NEXT BYTE DEC BC ;BC IS 1 BYTE LESS LDIR ;COPY USING LDIR RET ; ; OUTPUT CHAR IN A TO DISK FILE ; DOUTCHAR: PUSH HL ;SAVE REGS PUSH DE PUSH BC PUSH AF LD HL,(OBUFPTR) ;GET ADDRESS OF NEXT CHAR POS IN OUT BUFFER LD (HL),A ;STORE CHAR INTO OUT BUFFER CP 9 ;CHECK FOR TAB JR NZ,NOTABOUT ;NOT TAB -- DON'T UPDATE COUNT LD A,(OBUFLPOS) ;TAB -- UPDATE LOCATION IN LINE DEC A ;A=OUT BUFFER LINE POSITION - 1 AND 0F8H ;MASK FOR TAB ADD A,9 ;AND ADD 9 JR DOUT1 ; NOT A TAB -- JUST INCR POSITION COUNT NOTABOUT: LD A,(OBUFLPOS) ;GET ADDRESS OF NEXT CHAR POS IN OUT BUFFER INC A ;ADD 1 TO IT DOUT1: LD (OBUFLPOS),A ;UPDATE OUT BUFFER LINE POSITION INC HL ;INCREMENT BUFFER PTR LD A,(OBUFBACKCNT) ;GET BUFFER BYTE COUNT DEC A ;BUFFER NOW FULL? JR NZ,DOUT2 ;CONTINUE IF NOT LD DE,OBUF ;WRITE BUFFER TO DISK IF SO LD C,1AH ;SET DMA ADDRESS CALL BDOS LD DE,FCBZ80 ;WRITE BLOCK CALL WRITEBLK LD HL,OBUF ;RESET OUTPUT BUFFER PTR TO 1ST BYTE LD A,80H ;RESET BUFFER BYTE COUNT DOUT2: LD (OBUFPTR),HL ;UPDATE OUTPUT BUFFER PTR LD (OBUFBACKCNT),A ;UPDATE BUFFER BYTE COUNT POP AF ;RESTORE REGS POP BC POP DE POP HL RET ; ; WRITE BLOCK WHOSE FCB IS PTED TO BY DE TO DISK ; WRITEBLK: LD C,15H ;CP/M BDOS WRITE BLOCK CALL BDOS AND A ;ERROR? RET Z ;OK IF NONE LD DE,ERR1 ;ELSE PRINT ERROR MESSAGE AND ABORT JP ENDERR ; ; FILL LAST BLOCK WITH ^Z AND CLOSE OUTPUT FILE ; CTRLZFILL: LD A,(OBUFBACKCNT) ;GET REMAINING COUNT CP 80H ;FULL? JR Z,CLOSEOUT ;CLOSE FILE THEN LD A,1AH ;ELSE WRITE ^Z CALL DOUTCHAR JR CTRLZFILL ; ; CLOSE OUTPUT FILE ; CLOSEOUT: LD DE,FCBZ80 ;OUTPUT FCB LD C,10H ;CLOSE FILE JP BDOS ; ; EXTRACT NEXT INPUT LINE FOR DISK FILE AND PLACE IT AS A 0-TERMINATED ; STRING IN BUFFER 'INLN' ; BUILDLINE: CALL PDOT ;PRINT ACTIVITY DOT XOR A ;A=FALSE OR 0 LD (INCMT),A ;TURN IN COMMENT FLAG OFF LD (INQUOTE),A ;TURN IN QUOTE FLAG OFF LD HL,INLN ;PT TO INLN BUFFER LD B,80 ;80 CHARS MAX ; ; MAIN BUILD LOOP ; NXTLCHAR: LD DE,(IBUFPTR) ;PT TO NEXT CHAR IN FILE LD A,(IBUFCNT) ;CHECK TO SEE IF BUFFER EMPTY CP 80H ;80H IF SO JR NZ,PUTCHAR ;NOT EMPTY, SO PLACE CHAR IN LINE EXX ;SAVE REGS LD DE,IBUFFER ;READ NEXT BLOCK FROM INPUT FILE LD C,1AH ;SET DMA ADDRESS CALL BDOS LD DE,FCBASM ;READ THE BLOCK LD C,14H CALL BDOS DEC A ;ERROR? JP Z,ENDALL ;DONE IF SO (ASSUME EOF) EXX ;GET REGS BACK LD DE,IBUFFER ;SET PTR TO 1ST BYTE OF BLOCK SUB A ;CHAR COUNT = 0 ; ; PLACE CHAR PTED TO BE DE INTO INLN ; PUTCHAR: LD (IBUFCNT),A ;SAVE CHAR COUNT LD A,(DE) ;GET CHAR INC DE ;PT TO NEXT LD (IBUFPTR),DE ;SAVE PTR PUSH HL LD HL,IBUFCNT ;INCR CHAR COUNT INC (HL) POP HL CALL PCAPS ;CAPITALIZE CHAR OPTIONALLY LD (HL),A ;SAVE CHAR FROM FILE INTO INLN CP 0DH ;END OF LINE? JR Z,ENDBLINE ;DONE IF SO CP 9 ;TAB EXPAND? JR Z,CONTBLINE ;PROCESS AS NORMAL CHAR IF SO CP ' ' ;LESS THAN ? JR C,NXTLCHAR ;DON'T PROCESS IF SO CONTBLINE: DEC B ;IS BUFFER FULL? INC HL ;PT TO NEXT CHAR IN INLN BUFFER JR NZ,NXTLCHAR ;CONTINUE PROCESSING IF NOT FULL INC B ;WRITE OVER LAST CHAR FOR REST OF LINE DEC HL JR NXTLCHAR ;CONTINUE ; ; OPTIONALLY CAPITALIZE CHAR IN A ; PCAPS: PUSH AF ;SAVE CHAR LD A,(INCMT) ;IN A COMMENT? OR A ;0=NO JR NZ,PCAPS5 ;DONE IF SO AND DON'T CAPITALIZE LD A,(INQUOTE) ;IN A QUOTE? OR A ;0=NO JR NZ,PCAPS1 ;DON'T CAPITALIZE IF SO POP AF ;NOT IN COMMENT OR QUOTE, SO CAPITALIZE CALL CAPS JR PCAPS2 PCAPS1: POP AF ;GET CHAR PCAPS2: CP ';' ;COMING INTO A COMMENT? JR NZ,PCAPS3 PUSH AF ;SAVE CHAR LD A,0FFH ;SET INCMT FLAG LD (INCMT),A JR PCAPS5 ;DONE PCAPS3: PUSH AF ;SAVE CHAR LD A,(INQUOTE) ;IN A QUOTE? OR A ;0=NO JR Z,PCAPS4 POP AF ;GET CHAR -- WE ARE IN A QUOTE PUSH AF ;SAVE IT AGAIN CP '''' ;ARE WE LEAVING THE QUOTE? JR NZ,PCAPS5 XOR A ;A=0 LD (INQUOTE),A ;YES, SO SET NOT IN QUOTE JR PCAPS5 PCAPS4: POP AF ;GET CHAR PUSH AF ;SAVE CHAR ONE LAST TIME CP '''' ;COMING INTO A QUOTE? JR NZ,PCAPS5 LD A,0FFH ;SET INQUOTE FLAG LD (INQUOTE),A PCAPS5: POP AF ;GET CHAR RET ;DONE ; ; STORE ENDING AND ; ENDBLINE: INC HL ;PT TO NEXT POSITION LD (HL),0AH ;STORE INC HL LD (HL),0 ;STORE LD (IBUFPTR),DE ;SAVE INPUT FILE PTR ; ; IF LINE STARTS WITH AN ASTERISK (COMMENT LINE), MAKE IT START WITH A ; SEMICOLON ; LD A,(INLN) ;LOOK AT FIRST CHAR CP '*' ;ASTERISK? JR NZ,ENDBL1 LD A,';' ;REPLACE WITH SEMICOLON LD (INLN),A ; ; CHECK FOR EMPTY LINE AND JUST OUTPUT NEW LINE IF SO; ELSE RETURN ; ENDBL1: LD A,B ;LINE EMPTY? SUB 80 ;START OVER IF SO RET NZ ;DONE IF NOT EMPTY LD A,0DH ;OUTPUT TO FILE FOR EMPTY LINE CALL DOUTCHAR LD A,0AH CALL DOUTCHAR JP BUILDLINE ;DO NEXT LINE ; ; CAPITALIZE CHAR IN A ; CAPS: AND 7FH ;MASK OUT MSB CP 61H ;DO NOTHING IF LESS THAN SMALL A RET C CP 7AH+1 ;CAP IF BETWEEN SMALL A AND Z, RESP RET NC AND 5FH ;CAPITALIZE RET ; ; END OF PROCESSING ; ENDALL: CALL CTRLZFILL ;FILL BUFFER WITH ^Z LD DE,ERR5ON ;OPTIONALLY PRINT EACH ERROR MESSAGE IF SET CALL PMSG LD DE,XLT1ON CALL PMSG LD DE,XLT2ON CALL PMSG LD DE,XLT3ON CALL PMSG LD DE,XLT4ON CALL PMSG LD DE,MSG2 ; ; PRINT MESSAGE PTED TO BY DE WITH PRECEEDING AND FINISH UP ; ENDERR: PUSH DE ;SAVE PTR LD DE,CRLFSTR ;PRINT CALL PMSG POP DE CALL PMSG ;PRINT MESSAGE JP WBOOT ;DONE ; ; PRINT STRING PTED TO BY DE AND ENDING IN 0 ; PMSG: LD A,(DE) ;GET CHAR AND A ;ENDING 0? RET Z ;DONE IF SO CALL PCHAR ;OUTPUT CHAR IN A INC DE ;PT TO NEXT CHAR JR PMSG ;CONTINUE ; ; PRINT CHAR IN A ON CON: ; PCHAR: PUSH AF ;SAVE REGS PUSH BC PUSH DE PUSH HL LD E,A ;CHAR IN E LD C,2 ;CON: OUTPUT CALL BDOS POP HL ;RESTORE REGS POP DE POP BC POP AF RET ; ; **** OP CODE TABLE, MESSAGE, AND BUFFER AREA **** ; ; ; OP CODE TABLES ; OCS1: DB 'ANI AND ' DB 'CMA CPL ' DB 'CMC CCF ' DB 'CPI CP ' DB 'HLT HALT ' DB 'JMP JP ' DB 'ORI OR ' DB 'RAL RLA ' DB 'RAR RRA ' DB 'RLC RLCA ' DB 'RRC RRCA ' DB 'STC SCF ' DB 'SUI SUB ' DB 'XRI XOR ' POPS: DB 'DB DEFB ' DB 'DS DEFS ' DB 'DW DEFW ' DB 'SET DEFL ' NOXLT: DB 'ENT ENTRY' DB 'NAM NAME ' DB 'RAM DATA ' DB 'ROG REL ' DB 0 ;END OF TABLE FOR OCS 1 OCS2: DB 'ANA AND ' DB 'CMP CP ' DB 'DCR DEC ' DB 'INR INC ' DB 'MVI LD ' DB 'ORA OR ' DB 'SUB SUB ' DB 'XRA XOR ' DB 0 ;END OF TABLE FOR OCS 2 OCS3: DB 'DCX DEC ' DB 'INX INC ' DB 'LXI LD ' DB 'POP POP ' DB 'PUSH PUSH ' DB 0 ;END OF TABLE FOR OCS 3 OCS4: DB 'REQ RNE RLT RGE CEQ ' DB ' CNE CLT CGE JEQ JNE ' DB ' JLT JGE ' DB 0 ;END OF TABLE FOR OCS 4 RETS: DB 'RC RNC RZ RNZ RP ' DB ' RM RPE RPO ' DB 0 ;END OF TABLE FOR RETS CALLS: DB 'CC CNC CZ CNZ CP ' DB ' CM CPE CPO ' DB 0 ;END OF TABLE FOR CALLS JMPS: DB 'JC JNC JZ JNZ JP ' DB ' JM JPE JPO ' DB 0 ;END OF TABLE FOR JMPS OCS8: DB 'DAD ADD ' DW DO81 DB 'ADD ADD ' DW DO82 DB 'ADC ADC ' DW DO82 DB 'SBB SBC ' DW DO82 DB 'ADI ADD ' DW DO82 DB 'ACI ADC ' DW DO82 DB 'SBI SBC ' DW DO82 DB 'IN IN ' DW DO83 DB 'LDA LD ' DW DO83 DB 'LDAX LD ' DW DO84 DB 'LHLD LD ' DW DO85 DB 'MOV LD ' DW DO86 DB 'PCHL JP ' DW DO88 DB 'RST RST ' DW DO89 DB 'SHLD LD ' DW DO8A DB 'SPHL LD ' DW DO8B DB 'STA LD ' DW DO8C DB 'OUT OUT ' DW DO8C DB 'STAX LD ' DW DO8D DB 'XCHG EX ' DW DO8E DB 'XTHL EX ' DW DO8F NOXLT2: DB 'IFC IF ' DW DO91 DB 'ICL *INCL' DW DO92 DB 'LST LIST ' DW DO93 DB 'MAC MACRO' DW DO94 DB 0 ;END OF TABLE FOR OCS8 AND NOXLT2 ; ; VARIOUS MESSAGES AND PROGRAM HEADER ; HEADER: DB 'XLATE2 -- 8080-to-Z80 Translator, Version ' DB VERS/10+'0','.',(VERS MOD 10)+'0' DB 0DH,0AH,0 ; HELP MESSAGES HMSG1: DB 0DH,0AH,0AH DB ' XLATE2 translates 8080 assembly language source',0DH,0AH DB 'code into Zilog-Standard Z80 assembly language',0DH,0AH DB 'source code. It is invoked by a command of the',0DH,0AH DB 'following form:',0DH,0AH,0AH DB ' XLATE2 d:SRCFILE.typ d:destfile.typ',0DH,0AH,0AH DB ' All characters in lower case are optional, and,',0DH,0AH DB 'if omitted, the following values are assumed:',0DH,0AH,0AH DB ' . The Source File will have a type of ASM',0DH,0AH DB ' . The Destination File will have the same name',0DH,0AH DB ' as the Source File',0DH,0AH DB ' . The Destination File will have a type of MAC',0DH,0AH,0AH DB 'Type to Continue - ',0 HMSG2: DB 0DH,0AH,0AH DB 'The following are examples of its use:',0DH,0AH,0AH DB ' XLATE2 DEMO1 <-- Translates DEMO1.ASM to DEMO1.MAC' DB 0DH,0AH DB ' XLATE2 DEMO1 DEMO2 <-- DEMO1.ASM to DEMO2.MAC' DB 0DH,0AH DB ' XLATE2 DEMO1.TXT DEMO2.GGG <-- DEMO1.TXT to DEMO2.GGG' DB 0DH,0AH,0AH DB 'The following functions are also performed by XLATE2:' DB 0DH,0AH,0AH DB ' . The M80 Pseudo-Ops .Z80 and ASEG will be inserted ' DB 'at the front',0DH,0AH DB ' of the MAC File',0DH,0AH DB ' . The text in the Destination File will be ' DB 'capitalized',0DH,0AH DB ' . All comment lines beginning with an asterisk will ' DB 'begin with',0DH,0AH DB ' a semicolon instead',0DH,0AH,0AH DB 0 ; FILE NAME MESSAGES PRFNM1: DB 'Source File: ',0 PRFNM2: DB ' Destination File: ',0 ; FIRST TWO LINES OF MAC FILE FHDR: DB 9,'.Z80',0DH,0AH ;USE ZILOG MNEMONICS DB 9,'ASEG',0DH,0AH ;USE ABSOLUTE SEGMENTS DB 0 ERR1: DB 'Output File Write Error',0DH,0AH,7,0 ERR2: DB 'No Source File Found',0DH,0AH,7,0 ERR3: DB 'No Directory Space',0DH,0AH,7,0 ERR4: DB 'Output File Already Exists -- Delete It and Continue (Y/N)? ' DB 0 ERR4A: DB 'XLATE2 Aborting to CP/M',0 MSG2: DB 'XLATE2 Processing Complete',0 CRLFSTR: DB 0DH,0AH,0 ; ; VARIOUS ERROR MESSAGES ; ERR5ON: DB 0 ;THIS BYTE IS SET TO IF STRING ENABLED ERR5: DB 0AH DB 'The following pseudo-ops ' DB 'have been used in your source ' DB 'and have not',0DH,0AH DB 'been ' DB 'fully translated. You must ' DB 'complete the translation ' DB 'using an editor.',0DH,0AH DB 9,'Original:',9,9,'Must Be Translated To:',0DH,0AH DB 0 ;END OF STRING XLT1ON: DB 0 ;THIS BYTE IS SET TO IF STRING ENABLED XLT1: DB '#ENDIF',9,9,9,'ENDIF',0DH,0AH,0 XLT2ON: DB 0 ;THIS BYTE IS SET TO IF STRINGENABLED XLT2: DB 'ICL',9,9,9,'*INCLUDE',0DH,0AH,0 XLT3ON: DB 0 ;THIS BYTE IS SET TO IF STRING ENABLED XLT3: DB 'LST ',9,9,'LIST ' DB 0DH,0AH,0 XLT4ON: DB 0 ;THIS BYTE IS SET TO IF STRING ENABLED XLT4: DB 'MAC <$parameters>',9,'MACRO <#parameters>',0DH,0AH DB 9,'[ ... ]',9,9,9,'MEND',0DH,0AH DB 9,'#macro-call',9,9,'macro-call',0DH,0AH,0 ; ; INPUT FILE FCB ; FCBASM: DB 0,0,0,0,0,0,0,0,0,'ASM',0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0 ; ; OUTPUT FILE FCB ; FCBZ80: DB 0,0,0,0,0,0,0,0,0,'MAC',0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0 ; ; BUFFERS ; ; STACK AREA DS 128 ; CURRENT POSITION IN LINE OF OUTPUT BUFFER OBUFLPOS: DS 1 ; COUNTER FOR EVERY 10 LINES LCOUNT: DS 1 ; COUNTER FOR EVERY 60*10 LINES NLCOUNT: DS 1 ; IN COMMENT FLAG -- 0 MEANS NOT INCMT: DS 1 ; IN QUOTE FLAG -- 0 MEANS NOT INQUOTE: DS 1 ; PTR TO TARGET OP CODE IN INPUT LINE ILTOP: DS 2 ; OP CODE TO MATCH AGAINST TARGOP: DS 5 ; PTR TO CURRENT POSITION IN CURRENT INPUT LINE INLNPTR: DS 2 ; PTR TO CURRENT POSITION IN OUTPUT BUFFER (BLOCK) OBUFPTR: DS 2 ; COUNT OF CHARS REMAINING IN OUTPUT BUFFER OBUFBACKCNT: DS 1 ; OUTPUT BUFFER (BLOCK) OBUF: DS 128 ; CURRENT INPUT LINE BUFFER INLN: DS 80 ;80 CHARS IN LINE DS 3 ;3 EXTRA FOR ; PTR TO CURRENT POSITION IN INPUT BUFFER IBUFPTR: DS 2 ; COUNT OF NUMBER OF CHARS LEFT IN INPUT BUFFER IBUFCNT: DS 1 ; INPUT BUFFER (BLOCK) IBUFFER: DS 128 END