home *** CD-ROM | disk | FTP | other *** search
Text File | 1984-04-29 | 34.3 KB | 1,672 lines |
- ;
- ; 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 <TAB>
- 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 <SP> AND <TAB> CHARS FOUND UNTIL A NON-<SP> AND NON-<TAB>
- ; ENCOUNTERED
- ;
- OUTWHITE:
- LD A,(HL) ;GET CHAR
- CP ' ' ;<SP>?
- JR Z,OW1 ;OUTPUT IT
- CP 9 ;<TAB>?
- 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 <TAB>; IF >6, THEN NEW LINE AND <TAB>
- ;
- 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 ;<CR>
- CALL DOUTCHAR
- LD A,0AH ;<LF>
- CALL DOUTCHAR
- ;
- ; OUTPUT <TAB> AFTER LABEL TO DISK
- ;
- GOP7:
- LD A,9 ;<TAB>
- 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 <TAB>
- ;
- 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 ' ' ;<SP>?
- JR Z,ONO5C2 ;DONE IF SO
- CP 9 ;<TAB>?
- 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 <TAB> 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 <TAB> 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 <SP>
- 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 <RP>' TO 'ADD HL,<RP>'
- ;
- DO81:
- CALL OUTNEWOP5CH ;OUTPUT 'ADD<TAB>'
- LD HL,DO81S ;OUTPUT 'HL,'
- CALL OUTSTR
- JP RPCHECK ;OUTPUT <REG PAIR>
- 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<TAB>'
- LD HL,DO82S ;OUTPUT 'A,'
- JP DO8F1 ;04C7H
- DO82S:
- DB 'A,',0
- ;
- ; THIS CONVERTS 'LDA <ADR>' TO 'LD A,(<ADR>)'
- ; AND 'IN <ADR>' TO 'IN A,(<ADR>)'
- ;
- DO83:
- CALL OUTNEWOP5CH
- LD HL,DO83S
- JR OUTCLP
- DO83S:
- DB 'A,(',0
- ;
- ; THIS CONVERTS 'LDAX <RP>' TO 'LD A,(<RP>)'
- ;
- 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 <ADR>' TO 'LD HL,(<ADR>)'
- ;
- 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<TAB>(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 <ADR>' TO 'LD (<ADR>),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 <ADR>' TO 'LD (<ADR>),A'
- ; AND 'OUT <ADR>' TO 'OUT (<ADR>),A'
- ;
- DO8C:
- CALL OUTNEWOP5CH
- LD A,'(' ;OUTPUT '('
- ;
- ; THIS OUTPUTS '<OPERAND>),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 <RP>' TO 'LD (<RP>),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 <TAB> 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 <CR>
- 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 ' ' ;<SP> 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 <SP>
- 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 <SP>
- 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-<SP>, NON-<TAB>)
- ; ENCOUNTERED
- ;
- SKIPWHITE:
- LD A,(HL) ;GET CHAR
- CP ' ' ;<SP>?
- JR Z,SKPWH1 ;SKIP IF SO
- CP 9 ;<TAB>?
- 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,' ' ;<SP>
- LD (DE),A ;STORE FIRST <SP>
- LD H,D ;MAKE HL PT TO 1ST <SP>
- 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 <SP>?
- 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 <LF> AND <NULL>
- ;
- ENDBLINE:
- INC HL ;PT TO NEXT POSITION
- LD (HL),0AH ;STORE <LF>
- INC HL
- LD (HL),0 ;STORE <NULL>
- 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 <CR> <LF> 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 <CRLF> AND FINISH UP
- ;
- ENDERR:
- PUSH DE ;SAVE PTR
- LD DE,CRLFSTR ;PRINT <CRLF>
- 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 <RETURN> 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 <CR> 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 <TAB> IF STRING ENABLED
- XLT1:
- DB '#ENDIF',9,9,9,'ENDIF',0DH,0AH,0
- XLT2ON:
- DB 0 ;THIS BYTE IS SET TO <TAB> IF STRINGENABLED
- XLT2:
- DB 'ICL',9,9,9,'*INCLUDE',0DH,0AH,0
- XLT3ON:
- DB 0 ;THIS BYTE IS SET TO <TAB> IF STRING ENABLED
- XLT3:
- DB 'LST <operands>',9,9,'LIST <valid ASMB operands>'
- DB 0DH,0AH,0
- XLT4ON:
- DB 0 ;THIS BYTE IS SET TO <TAB> 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 <CR> <LF> <NULL>
- ; 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
-