home *** CD-ROM | disk | FTP | other *** search
- ' ASM48 VER. 1.3
- ' An 8748 source code assembler
- ' May 1, 1988
- ' By Vance Navarrette
- '
- ' This file assembles 8748 opcodes into an object listing
- ' from an source file. The source file must have NO FILE EXTENSION
- ' for the assembler to operate. The assembler produces the following
- ' outputs:
- ' 1. <filespec>.lst - assembled source listing
- ' 2. <filespec>.obj - binary object code
- ' 3. <filespec>.lst printout (optional)
- ' The file to be assembled must:
- ' 1. Use Intel standard 8748 op codes
- ' 2. note comments with ;
- ' 3. contain no special control codes, and must
- ' be an ascii coded file.
- '
- '
- '
- ' THIS BEGINS THE MAIN LOOP.
- '
- ' INPUT THE FILE TO BE ASSEMBLED, AND INITIALIZE THE SYSTEM
- '
- '
- ON ERROR GOTO ErrHan ' SETUP ERROR HANDLING
- PRINT CHR$(12): PRINT TAB(26);"ASM48: 8748 Cross Assembler"_
- :PRINT TAB(34);"Version 1.3":PRINT
- INPUT "Name of file to assemble";SOURCE$
- DEFINT A-Z' DEFINE INTEGER VARIABLES TO SPEED EXECUTION
- INPUT "Do you wish to print the source code listing (return=yes)";LST$
- PRINT:PRINT:PRINT "BEGINNING PASS 1":PRINT "Press F1 key to abort assembly."
- KEY (1) ON: ON KEY (1) GOSUB ASMABORT
- OPNUM=222: ' OPNUM=NUMBER OF LEGAL OPCODES
- PRINT:PRINT:PRINT : ADD=0 ' ADD=absolute assembly address offset
- LCNT=1: ECNT=0 :EF=0 : OF=0
- '
- ' ADD= MACHINE ADDRESS FOR ASSEMBLY
- ' LCNT=NUMBER OF LABELS FOUND IN SOURCE TEXT
- ' ECNT=NUMBER OF ERRORS FOUND DURING ASSEMBLY
- ' OF=ASSEMBLY ADDRESS OFFSET, USED BY PSUEDO-OPS
- ' BYTCNT=NUMBER OF BYTES REQUIRED BY A GIVEN OPCODE
- ' OPCD=DECIMAL VALUE OF AN OPCODE
- ' LABEL$=TEXT STRING FROM SOURCE CONTAINING A LABEL
- ' LVALUE=NUMERIC VALUE OF A LABEL
- ' OPCD$=TEXT STRING FROM SOURCE CONTAINING AN OPCODE NMEMONIC
- '
- DIM OPCD$(OPNUM),BYTCNT(OPNUM),OPCD(OPNUM),LABEL$(OPNUM),LVALUE(OPNUM)
- '
- ' READ ALL THE OPCODES IN TO AN ARRAY
- '
- FOR I=1 TO OPNUM: READ OPCD$(I),BYTCNT(I),OPCD(I)
- NEXT I
- '
- ' OPEN SOURCE FILE AND TEMPORARY FILE
- '
- Opensource:
- If Source$="" then ASMabort 'assembly cancelled
- OPEN"I",1,SOURCE$
- OPEN "O",2,SOURCE$+".TEM"
- '
- ' BEGIN MAIN ROUTINE FOR 1ST PASS
- '
- PassOne:
- IF EOF(1) THEN Donepass1
- GOSUB Inlin ' GO GET A LINE
- IF TEMP$="" THEN GOSUB Nulline ELSE Initstrings
- GOTO PassOne
- Initstrings:
- TLAB$="":TOP$="":TVAR$="":TCOM$="" ' INITIALIZE TEMPORARY_
- ' LABEL, OPCODE, VARIABLE AND COMMENT STRINGS
- GOSUB Subcom: ' SUBTRACT OFF ANY COMMENTS THAT ARE PRESENT
- GOSUB Leadspace: ' SUBTRACT ANY LEADING SPACES
- IF TEM$="" THEN GOSUB Svacmnt
- IF TEM$="" THEN PassOne ' NO OPCODE, SO TRY AGAIN
- GOSUB Opcheck: ' SEE IF NEXT WORD IS OPCODE
- IF CNT>0 THEN Opfound ' IF CNT>0, OPCODE WAS FOUND
- GOSUB Label:: ' IF NO OPCODE, SEE IF LABEL
- IF LFND=1 THEN GOSUB Leadspace ' IFLABLE FOUND, STRIP MORE SPACES
- GOSUB Opcheck: ' SEE IF THERE IS AN OPCODE
- IF CNT=0 AND OP$>"" THEN LFND=0 :TCOM$=";**UNKNOWN OPCODE**"_
- :Gosub lastspace
- If Cnt=0 and op$>"" Then Top$=Tem$ : GOTO UnKnOp 'OPCODE IS UNKNOWN
- Opfound:
- IF CNT>0 AND BYTCNT(CNT)>1_
- THEN GOSUB Variable : ' IF OPCODE NEEDS VARIABLE, GO FIND IT
- UnKnOp:
- IF LFND=0 AND CNT=0 THEN ECNT=ECNT+1 ' FOUND AN ERROR, SO INC'ENT COUNT
- If Bytcnt(Cnt)=4 then Gosub Psuedo 'See if there is a psuedo op
- GOSUB Svaln
- IF BYTCNT(CNT)=4 THEN GOSUB Deftxt ' Process Byte Psuedo op codes
- IF BYTCNT(CNT)<3 THEN ADD=ADD+BYTCNT(CNT)
- IF BYTCNT(CNT)=3 THEN ADD=ADD+2
- IF BYTCNT(CNT)=4 THEN ADD=ADD+OF:OF=0
- IF NOT EOF(1) THEN PassOne: ' PRINTED ASSEMBLED STRING, GO GET ANOTHER
- Donepass1:
- CLOSE (1): CLOSE (2): PRINT "BEGINNING PASS 2":GOTO Passtwo
- '
- ' subroutine: "subcom"
- '
- ' sutracts a comment designated by ";" from a line to be decoded
- '
- Subcom:
- For I=1 to LEN(TEMP$)
- IF MID$(TEMP$,I,1)=";" THEN TEM$=LEFT$(TEMP$,I-1)_
- :TCOM$=RIGHT$(TEMP$,LEN(TEMP$)-I+1):RETURN
- Next I
- TEM$=TEMP$: RETURN
- '
- ' subroutine: "leadspace"
- '
- ' SUBTRACTS LEADING SPACES, RETURNS WITH REST AS "TEM$"
- '
- Leadspace:
- For I=1 to LEN(TEM$)
- IF " "<MID$(TEM$,I,1) THEN TEM$=RIGHT$(TEM$,LEN(TEM$)-I+1)_
- : RETURN
- Next I
- TEM$="" : RETURN
- '
- ' subroutine: "opcheck"
- '
- ' looks for opcode in first 10 characters of tem$
- ' cnt=sequence number of opcode, 0 if no code found
- '
- Opcheck:
- OP$=LEFT$(TEM$,10): CNT=0 ' INITIALIZE LOCAL VARIABLES
- IF OP$<>"" THEN TEST=ASC(OP$):IF TEST>64 AND TEST<91_
- THEN J=(TEST-65)*7+1 ELSE RETURN 'Use first letter to speed search
- For I=J to OPNUM 'Look for Opcode in Opcode Table
- IF LEFT$(OP$,LEN(OPCD$(I)))=OPCD$(I) THEN_
- CNT=I:TOP$=OPCD$(I):TEM$=RIGHT$(TEM$,LEN(TEM$)-LEN(TOP$))_
- :RETURN
- Next I
- RETURN
- '
- ' subroutine: "label"
- '
- ' Insert string into label table, and return
- '
- ' return w/label in table, label subtracted from string
- '
- Label:
- LFND=0 'lfnd=1 means a label was succesfully found
- For I=1 to LEN(TEM$)
- IF RIGHT$(LEFT$(OP$,I),1)<=" " THEN Cont
- NEXT I
- Cont:
- LABEL$(LCNT)=LEFT$(OP$,(I-1))
- TEM$=RIGHT$(TEM$,LEN(TEM$)-I+1)
- If I>10 then Tcom$=";**LABEL TOO LONG**":_
- Lvalue(Lcnt)=Add:TLAB$=Left$(Label$(lcnt),10):Return
- LVALUE(LCNT)=ADD:LFND=1:TLAB$=LABEL$(LCNT):LCNT=LCNT+1
- FOR I=1 TO LCNT-2 ' LOOK FOR DUPLICATE LABELS
- IF LABEL$(LCNT-1)=LABEL$(I) THEN TCOM$=";**DUPLICATE DEFINITION**":ECNT=ECNT+1:RETURN
- NEXT I
- RETURN
- '
- '
- ' Last space routine
- '
- ' subtracts trailing spaces and tab charaters
- '
- '
- Lastspace:
- For I=Len(tem$) to 1 step -1
- if Mid$(tem$,i,1)>" " then tem$=left$(tem$,I):Return
- Next I
- Tem$="":Return
- '
- ' INPUT ROUTINE: INPUTS A SINGLE LINE FROM OPEN FILE #1
- ' TO BE PROCESSED. RETURNS WITH TEMP$=LINE FROM FILE
- '
- Inlin:
- LINE INPUT #1,TEMP$ ' GET THE STRING
- RETURN : ' GOT A STRING OR END OF FILE
- '
- ' SUBROUTINE "VARIABLE" STRIPS TRAILING SPACES OF VARIABLE
- '
- ' EXPECTS CNT>0 IF OPCODE FOUND, TEM$ CONTAINS VARIABLE
- ' RETURNS CNT, LFND =0 IF VARIABLE NOT FOUND
- '
- Variable:
- GOSUB Leadspace ' STRIP LEADING SPACES
- For I=1 to Len(tem$)' INITIALIZE LOCAL LOOP COUNTER
- IF LEFT$(RIGHT$(TEM$,I),1)>" " THEN_
- TVAR$=LEFT$(TEM$,LEN(TEM$)-I+1):RETURN
- Next I
- TCOM$=";**MISSING VARIABLE**":LFND=0:CNT=0:RETURN
- '
- '
- ' THIS SUBROUTINE HANDLES PSUEDO OPCODES
- '
- ' ORG 0A ; SETS ADDRESS COUNTER=0A HEX
- '
- ' LABEL1 EQU 05 ; SETS "LABEL1" EQUAL TO 05H
- ' DS A0 ; DEFINES SPACE OF A0 BYTES
- ' DT "BYE" ; DEFINES ASCII TEXT: BYE
- ' DB 01,AF ; DEFINES BYTES OF STORAGE, FILLED
- ' WITH HEX NUMBERS 01H, AFH
- Psuedo:
- If Tvar$="" then return 'No variable to process, so done.
- IF TOP$<>"ORG" THEN Defspc
- FOR I=1 TO LCNT-2' CHECK FOR VARIABLE
- IF TVAR$=LABEL$(I) THEN ADD=LVALUE(I) :RETURN
- NEXT I
- T$=TVAR$: GOSUB Hexc ' GOT THIS FAR, SO IT MUST BE A HEX VARIABLE
- ADD=CHEX : RETURN
- '
- ' HANDLES DS (DEFINE SPACE) PSUEDO OP
- '
- Defspc:
- IF TOP$<>"DS" THEN Equ
- FOR I=1 TO LCNT-2 ' SEE IF VARIABLE IS A LABEL
- IF TVAR$=LABEL$(I) THEN OF=LVALUE(I):RETURN
- NEXT I
- T$=TVAR$: GOSUB Hexc: ' IT MUST BE HEX, SO GO CONVERT IT
- OF=CHEX: RETURN
- '
- ' PSUEDO-OP "EQU"
- '
- '
- Equ:
- If Top$<>"EQU" then return
- FOR I=1 TO LCNT-2
- IF TVAR$=LABEL$(I) THEN LVALUE(LCNT-1)=LVALUE(I):RETURN
- NEXT I
- T$=TVAR$: GOSUB Hexc ' GOT THIS FAR, SO IT MUST BE HEXADECIMAL
- LVALUE(LCNT-1)=CHEX : RETURN
- '
- ' HANDLES DT (DEFINE TEXT) PSUEDO OP
- '
- Deftxt:
- If Tvar$="" Then Return ' No variable, so all done
- IF TOP$<>"DT" THEN Defbyt
- OF=LEN(TVAR$)
- FOR I=1 TO OF
- Byte=ASC(RIGHT$(LEFT$(TVAR$,I),1))
- GOSUB Svabyt
- NEXT I
- RETURN
- '
- ' HANDLES THE DB PSUEDO OP (DEFINE BYTE(S))
- '
- Defbyt:
- If Top$<>"DB" then return ' not DB or DT, so return
- TVAR$=TVAR$+" ":N=LEN(TVAR$)
- For I=1 to N ' Fetch each byte, and calculate Hex number
- IF Mid$(TVAR$,I,1)<="/"_
- THEN T$=MID$(TVAR$,I-2,2):GOSUB Hexc : B(I\3)=Chex
- If Tcom$=";**ILLEGAL VARIABLE**" Then Gosub Svacmnt : Exit For
- Next I
- If I<3 then return
- For J=1 to I\3 ' Go print the Hex data
- Byte=B(J) : Gosub Svabyt
- NEXT J
- OF=I\3 : RETURN ' Calculate OF (offset) for address computation
- '
- ' SUBROUTINE HEXC "CONVERT FROM ASCII HEX TO DECIMAL NUMBER"
- '
- ' EXPECTS VARIABLE TO BE CONVERTED AS "T$"
- ' RETURNS WITH CHEX; DECIMAL VALUE OF HEX STRING "T$"
- '
- Hexc:
- CHEX=0' INITIALIZE VARIABLES
- FOR J=0 TO LEN(T$)-1
- H=ASC(LEFT$(RIGHT$(T$,J+1),1))-48
- IF 0<=H AND H<=9 THEN CHEX=CHEX+H*16^J
- IF J>2 OR H>22 OR H<0 OR (H>9 AND H<17) THEN_
- TCOM$=";**ILLEGAL VARIABLE**":ECNT=ECNT+1:RETURN
- IF 17<=H AND H<=22 THEN CHEX=CHEX+(H-7)*16^J
- NEXT J
- RETURN
- '
- ' PRINT# SUBROUTINES FOLLOW
- ' THESE ROUTINES OUTPUT STRINGS TO THE TEMPORARY
- ' WORK FILE .
- '
- '
- ' SUBROUTINE NULLINE
- Nulline:
- PRINT#2,"": RETURN
- '
- ' SUBROUTINE SAVE-A-LINE (Svaln)
- '
- Svaln:
- IF BYTCNT(CNT)=0 THEN PRINT#2,"|";"|";"|";TLAB$;"|";TOP$;_
- "|";TVAR$;"|";TCOM$ :RETURN
- PRINT#2,ADD;"|";BYTCNT(CNT);"|";OPCD(CNT);"|";TLAB$;"|";
- PRINT#2,TOP$;"|";TVAR$;"|";TCOM$
- RETURN
- '
- ' SUBROUTINE SAVE-A-COMMENT (Svacmnt)
- '
- Svacmnt:
- PRINT#2,"|";"|";"|";"|";"|";"|";TCOM$
- RETURN
- '
- ' SUBROUTINE SAVE-A-BYTE (svabyt)
- '
- Svabyt:
- PRINT#2,"|";"|";BYTE;"|";"|";"|";"|"
- RETURN
-
-
- ' BEGINNING OF PASS TWO
- '
- ' PASS TWO DOES THE FOLLOWING:
- ' A. CREATES LISTING FILE AND PRINTS IT
- ' B. CREATES INTEL FORMAT OBJECT FILE (HEX)
- ' C. INSERTS OPCODES FOR MULTIBYTE INSTRUCTIONS
- '
- ' OPEN FILES, INPUT A LINE
- '
- Passtwo:
- OPEN "I",#1,SOURCE$+".TEM":OPEN "O",#2,SOURCE$+".OBJ":LIS=0
- IF LST$="" OR LST$="Y" OR LST$="y" THEN LIS=1
- OPEN "O",#3,SOURCE$+".LST"
- PRINT#3, TAB(35);SOURCE$: PRINT#3, "ADD";TAB(8);"OPCODE";TAB(20);"LABEL";TAB(30);"MNEMONIC";TAB(40);"VARIABLE";TAB(50);"COMMENT"
- ADDTEMP=0 :CKSUM=0:STADD=0' INITIALIZE TEMP ADDRESS, CHECKSUM, START ADD
- LPCNTR=0 ' LPCNTR IS USED AS FLAG TO INDICATE START OF NEW DATA RECORD
- '
- ' START OF MAIN LOOP FOR PASS TWO
- '
- Looptwo:
- IF EOF(1) THEN Doneloop2
- TEMP$=""' CLEAR THE VARIABLES PRIOR TO INPUT
- GOSUB Inlin: ' GET A LINE FROM THE FILE
- IF TEMP$="" THEN PRINT#3,"":GOTO Looptwo ' OUTPUT A NULL TO LISTING
- GOSUB Parse ' GO PARSE THE STRING
- GOSUB Objfile : ' WRITE HEX OBJECT CODE TO FILE
- IF BYTCNT=3 THEN BYTCNT=2: ' SET BYTCNT TO ACTUAL # OF BYTES
- GOSUB listfile : ' OUTPUT A LINE TO THE LIST FILE
- GOTO Looptwo ' END OF LOOP FOR PASS 2
-
- Doneloop2:
- GOSUB Inhex ' OUTPUT LAST LINE FOR INTEL HEX FILE
- PRINT#2, ":0000000000"+CHR$(13)+CHR$(10);' OUTPUT END OF RECORD
- PRINT#3,:PRINT#3,:PRINT#3,
-
- ' PRINT LABEL TABLE TO LIST FILE
- FOR I=1 TO LCNT-1 STEP 4:
- FOR J=0 TO 3
- PRINT#3, LABEL$(I+J);SPC(3);HEX$(LVALUE(I+J));TAB((J+1)*20)
- IF I+J=LCNT-1 THEN Cont2
- NEXT J
- PRINT#3,
- NEXT I
- Cont2:
- PRINT#3,:PRINT#3,:PRINT#3, "TOTAL ERRORS THIS ASSEMBLY: ";ECNT
- CLOSE #1,#2,#3: 'DONE, SO CLOSE PRIOR TO LISTING
- Kill Source$+".TEM" ' Delete temporary file
- IF ECNT>0 THEN KILL SOURCE$+".OBJ": ' IF ERROR, DELETE OBJECT CODE
- IF LIS<>1 THEN Closefiles: ' NO LISTING REQUESTED, SO GO QUIT
- '
- ' DONE WITH PASS 2, SO GO DO LISTING IF NEEDEED
- '
- OPEN "I",1,SOURCE$+".LST"
- '
- ' LINE PRINTER LIST ROUTINE (LPTLST)
- '
- Lptlst:
- IF EOF(1) THEN Closefiles
- LINE INPUT#1,T$:LPRINT T$
- GOTO Lptlst' SEE IF THERE IS ANOTHER LINE TO LIST
- Closefiles:
- CLOSE #1 ' IF LIS=1 THEN CLOSE 1
- PRINT:PRINT:PRINT:PRINT"TOTAL ERRORS THIS ASSEMBLY: ";ECNT
- Done:
- END
- ' SUBROUTINE PARSE
- ' PARSES A STRING FROM THE TEMP FILE
- Parse:
- GOSUB Stringcut
- TADD=VAL(T$):TADD$=T$
- GOSUB Stringcut
- BYTCNT=VAL(T$):BYT$=T$
- GOSUB Stringcut
- TOP=VAL(T$):TOP$=T$
- GOSUB Stringcut
- TLAB$=T$
- GOSUB Stringcut
- TMNEM$=T$
- GOSUB Stringcut
- TVAR$=T$
- TCOM$=TEMP$
- RETURN
- '
- ' SUBROUTINE STRINGCUT
- ' DIVIDE STRING AT "|" CHARACTER
- '
- Stringcut:
- J=Len(Temp$)
- For I=1 to J
- IF MID$(TEMP$,I,1)="|" THEN T$=LEFT$(TEMP$,I-1):TEMP$=RIGHT$(TEMP$,J-I):RETURN
- Next I
- Return
- '
- ' SUBROUTINE PROCVAR
- '
- ' PROCESSES VARIABLES AND RETURNS WITH THE NUMERIC VALUE
- '
- Procvar:
- FOR I=1 TO LCNT-1
- IF LABEL$(I)=TVAR$ THEN TVAR=LVALUE(I) :RETURN
- NEXT I
- ' GOT THIS FAR, SO IT MUST BE A HEX NUMBER
- T$=TVAR$: GOSUB Hexc
- TVAR=CHEX
- RETURN
- '
- ' SUBROUTINE PROCJMP
- '
- ' PROCESSES JUMP AND CALL INSTRUCTIONS
- '
- Procjmp:
- GOSUB Procvar ' FIND OUT VALUE OF VARIABLE TO JUMP TO
- UPADD=TVAR AND 1792: UPADD=UPADD/8 ' GET UPPER 3 BITS
- TOP=TOP OR UPADD: TVAR=TVAR AND 255
- RETURN
- '
- ' SUBROUTINE TESTRANGE
- ' TESTS FOR RANGE VIOLATIONS ON JUMP INSTRUCTIONS
- '
- Testrange:
- IF BYTCNT=3 AND TVAR>&H7FF THEN TCOM$=";**ADDRESS OVERFLOW**"_
- :ECNT=ECNT+1: RETURN
- IF BYTCNT=2 AND (ASC(TMNEM$)=68 OR ASC(TMNEM$)=74) THEN Cont3_
- ELSE RETURN
- Cont3:
- IF (TADD AND &H700)>TVAR OR (TADD OR &HFF)<TVAR THEN_
- ECNT=ECNT+1:TCOM$=";**PAGE VIOLATION**":RETURN
- RETURN
- '
- ' SUBROUTINE OBJFILE
- ' OUTPUT HEX ASCII CODE TO OBJECT FILE
- '
- Objfile:
- IF BYTCNT=3 THEN GOSUB Procjmp: ' IT'S A BRANCH, SO BIT TWIDDLE.
- IF TOP$="" THEN RETURN: ' NO CODE TO PRINT, SO RETURN
- IF BYT$<>"" AND BYTCNT=0 AND TOP=0 THEN RETURN
- IF BYTCNT=2 THEN GOSUB Procvar: ' IT NEEDS A VARIABLE, GO GET IT.
- IF BYTCNT=2 OR BYTCNT=3 THEN GOSUB Testrange: ' CHECK RANGE ON JMP INSTR
- IF TADD=ADDTEMP AND LPCNTR=1 THEN Cont4
- IF TADD$>"" AND TADD<>ADDTEMP THEN ADDTEMP=TADD: GOSUB Inhex:
- IF TADD$="" AND LPCNTR=1 THEN Cont4
- IF TADD$="" AND LPCNTR=0 THEN LPCNTR=1: STADD=ADDTEMP: GOTO Cont4
- IF BYTCNT<4 THEN ADDTEMP=TADD:STADD=ADDTEMP:LPCNTR=1' SAVE STARTING ADDRESS FOR THIS RECORD
- Cont4:
- IF BYTCNT=4 THEN RETURN ELSE ADDTEMP=ADDTEMP+1:INHEX$=INHEX$+RIGHT$("0"+HEX$(TOP),2)_
- :CKSUM=CKSUM+TOP ' IF ITS A PSEUDO OP RETURN, ELSE GET OPCODE
- IF (ADDTEMP AND &H3F)=0 THEN GOSUB Inhex:' OUTPUT IF ADDRESS ROLLS OVER
- IF BYTCNT>1 AND LPCNTR=0 THEN STADD=ADDTEMP:LPCNTR=1 ' OUTPUT SECOND BYTE IF NEEDED
- IF BYTCNT<=1 THEN RETURN ELSE ADDTEMP=ADDTEMP+1:INHEX$=INHEX$+RIGHT$("0"+HEX$(TVAR),2):CKSUM=CKSUM+TVAR
- IF (ADDTEMP AND &H3F)=0 THEN GOSUB Inhex: ' SECOND BYTE DONE, SO RET
- RETURN
- '
- ' SUBROUTINE INHEX
- ' OUTPUTS A DATA RECORD TO INTEL HEX FILE
- '
- Inhex:
- CKSUM=-(CKSUM+STADD+(LEN(INHEX$)/2))+1 AND 255' COMPUTE CHECKSUM
- PRINT#2, ":";RIGHT$("0"+HEX$(LEN(INHEX$)/2),2);RIGHT$_
- ("000"+HEX$(STADD),4);"00";INHEX$;RIGHT$("0"+HEX$(256-CKSUM),2);_
- CHR$(13);CHR$(10);
- LPCNTR=0: CKSUM=0:INHEX$="":RETURN
- '
- ' SUBROUTINE LISTFILE
- ' PRINTS OUTPUT TO LISTING FILE FOR PRINTING
- listfile:
- TTOP$=RIGHT$("0"+HEX$(TOP),2)
- TTVAR$=RIGHT$("0"+HEX$(TVAR),2)
- TADD$=RIGHT$("00"+HEX$(TADD),3): ' CONVERT TO 3 PLACE HEX
- '
- ' CHANGED OPCODE AND VARIABLES TO TWO BYTE FORMAT
- ' SO GO OUTPUT TO LISTING FILE.
- '
- IF BYTCNT=1 THEN PRINT#3,TADD$;TAB(8);TTOP$ ;TAB(20);TLAB$;TAB(30);_
- TMNEM$;TAB(42);TVAR$;TAB(50);TCOM$:RETURN
- IF BYTCNT=2 THEN PRINT#3,TADD$;TAB(8);TTOP$;TAB(13);TTVAR$;TAB(20);_
- TLAB$;TAB(30);TMNEM$;TAB(42);TVAR$;TAB(50);TCOM$: RETURN
- IF TOP$="" THEN PRINT#3, TAB(20);TLAB$;TAB(30);TMNEM$;TAB(42);_
- TVAR$;TAB(50);TCOM$:RETURN
- IF BYT$="" THEN PRINT#3, TAB(8);TTOP$;TAB(20);TLAB$;TAB(30);TMNEM$;_
- TAB(42);TVAR$;TAB(50);TCOM$:RETURN
- IF BYTCNT=0 THEN PRINT#3, TAB(20);TLAB$;TAB(30);TMNEM$;TAB(42);TVAR$;_
- TAB(50);TCOM$:RETURN
- IF BYTCNT=4 THEN PRINT#3,TADD$;TAB(20);TLAB$;TAB(30);TMNEM$;TAB(42);_
- TVAR$;TAB(50);TCOM$
- RETURN
- ' ERROR HANDLING
- '
- ' THIS GIVES ERROR MESSAGE AND TERMINATES EXECUTION
- '
- ErrHan:
- IF ERR=57 OR ERR=27 THEN PRINT:PRINT_
- "Printer is off line or out of paper."_
- :PRINT "List file was created but not printed.":GOTO Closefiles
- IF ERR=53 THEN PRINT:PRINT "The file you specified cannot be found."_
- :INPUT "Re-enter file name to try again or <ENTER> to cancel.",_
- SOURCE$: GOTO Opensource
- IF ERR=61 THEN PRINT: PRINT _
- "The disk in use is full. Assembly was aborted.":END
- IF ERR=71 Or Err=70 THEN PRINT: PRINT_
- "The specified disk drive is not ready."_
- :PRINT "Assembly was aborted.":END
- ON ERROR GOTO 0:END
- '
- '
- ' Subroutine ASMABORT
- '
- ' Aborts assembly at user request
- '
- '
- Asmabort:
- Print:Print:Print "Aborting assembly at user request."
- Close 'Close all open files
- End ' End of program
- '
- ' DATA TABLES FOR 8748 OPCODES, BYTECOUNTS AND BINARY CODE
- '
- DATA"ADD A,R0",1,&H68,"ADD A,R1",1,&H69,"ADD A,R2",1,&H6A,"ADD A,R3",1,&H6B
- DATA"ADD A,R4",1,&H6C,"ADD A,R5",1,&H6D,"ADD A,R6",1,&H6E,"ADD A,R7",1,&H6F
- DATA"ADD A,@R0",1,&H60,"ADD A,@R1",1,&H61
- DATA "ADD A,#",2,&H03,"ADDC A,R0",1,&H78,"ADDC A,R1",1,&H79
- DATA "ADDC A,R2",1,&H7A,"ADDC A,R3",1,&H7B,"ADDC A,R4",1,&H7C
- DATA "ADDC A,R5",1,&H7D,"ADDC A,R6",1,&H7E,"ADDC A,R7",1,&H7F
- DATA "ADDC A,@R0",1,&H70,"ADD A,@R1",1,&H71
- DATA "ADDC A,#",2,&H13
- DATA "ANL A,R0",1,&H58,"ANL A,R1",1,&H59,"ANL A,R2",1,&H5A
- DATA "ANL A,R3",1,&H5B,"ANL A,R4",1,&H5C,"ANL A,R5",1,&H5D
- DATA "ANL A,R6",1,&H5E,"ANL A,R7",1,&H5F
- DATA "ANL A,@R0",1,&H50,"ANL A,@R1",1,&H51
- DATA "ANL A,#",2,&H53,"ANL BUS,#",2,&H98
- DATA "ANL P1,#",2,&H99,"ANL P2,#",2,&H9A
- DATA "ANLD P4,#",1,&H9C,"ANLD P5,#",1,&H9D
- DATA "ANLD P6,#",1,&H9E,"ANLD P7,#",1,&H9F
- DATA "CLR A",1,&H27,"CLR C",1,&H97,"CLR F1",1,&HA5,"CLR F0",1,&H85
- DATA "CPL A",1,&H37,"CPL C",1,&HA7,"CPL F0",1,&H95,"CPL F1",1,&HB5
- DATA "CALL",3,&H14
- DATA "DA A",1,&H57,"DEC A",1,&H07,"DEC R0",1,&HC8,"DEC R1",1,&HC9
- DATA "DEC R2",1,&HCA,"DEC R3",1,&HCB,"DEC R4",1,&HCC,"DEC R5",1,&HCD
- DATA "DEC R6",1,&HCE,"DEC R7",1,&HCF,"DIS I",1,&H15,"DIS TCNTI",1,&H35
- DATA "DT",4,&H00,"DS",4,&H00,"DB",4,&H00,"EQU",4,&H00
- DATA "DJNZ R0",2,&HE8,"DJNZ R1",2,&HE9,"DJNZ R2",2,&HEA,"DJNZ R3",2,&HEB
- DATA "DJNZ R4",2,&HEC,"DJNZ R5",2,&HED,"DJNZ R6",2,&HEE,"DJNZ R7",2,&HEF
- DATA "EN I",1,&H05,"EN TCNTI",1,&H25,"ENT0 CLK",1,&H75
- DATA "IN A,P1",1,&H09,"IN A,P2",1,&H0A
- DATA "INC A",1,&H17,"INC R0",1,&H18,"INC R1",1,&H19,"INC R2",1,&H1A
- DATA "INC R3",1,&H1B
- DATA "INC R4",1,&H1C,"INC R5",1,&H1D,"INC R6",1,&H1E,"INC R7",1,&H1F
- DATA "INC @R0",1,&H10,"INC @R1",1,&H11,"INS A,BUS",1,&H08
- DATA "JC",2,&HF6,"JF0",2,&HB6,"JF1",2,&H76,"JMPP @A",1,&HB3
- DATA "JNC",2,&HE6,"JNI",2,&H86,"JNT0",2,&H26,"JNT1",2,&H46
- DATA "JNZ",2,&H96,"JTF",2,&H16,"JT0",2,&H36,"JT1",2,&H56,"JZ",2,&HC6
- DATA "JB0",2,&H12,"JB1",2,&H32,"JB2",2,&H52,"JB3",2,&H72
- DATA "JB4",2,&H92,"JB5",2,&HB2,"JB6",2,&HD2,"JB7",2,&HF2
- DATA "JMP",3,&H04,"EQU",4,&H00
- DATA "MOV A,#",2,&H23,"MOV A,PSW",1,&HC7,"MOV A,R0",1,&HF8
- DATA "MOV A,R1",1,&HF9,"MOV A,R2",1,&HFA,"MOV A,R3",1,&HFB
- DATA "MOV A,R4",1,&HFC,"MOV A,R5",1,&HFD,"MOV A,R6",1,&HFE
- DATA "MOV A,R7",1,&HFF,"MOV A,@R0",1,&HF0,"MOV A,@R1",1,&HF1
- DATA "MOV A,T",1,&H42,"MOV PSW,A",1,&HD7,"MOV R0,A",1,&HA8
- DATA "MOV R1,A",1,&HA9,"MOV R2,A",1,&HAA,"MOV R3,A",1,&HAB
- DATA "MOV R4,A",1,&HAC,"MOV R5,A",1,&HAD,"MOV R6,A",1,&HAE
- DATA "MOV R7,A",1,&HAF,"MOV R0,#",2,&HB8,"MOV R1,#",2,&HB9
- DATA "MOV R2,#",2,&HBA,"MOV R3,#",2,&HBB,"MOV R4,#",2,&HBC
- DATA "MOV R5,#",2,&HBD,"MOV R6,#",2,&HBE,"MOV R7,#",2,&HBF
- DATA "MOV @R0,A",1,&HA0,"MOV @R1,A",1,&HA1,"MOV @R0,#",2,&HB0
- DATA "MOV @R1,#",2,&HB1,"MOV T,A",1,&H62,"MOV A,P4",1,&H0C
- DATA "MOV A,P5",1,&H0D,"MOV A,P6",1,&H0E,"MOV A,P7",1,&H0F
- DATA "MOV P4,A",1,&H3C,"MOV P5,A",1,&H3D,"MOV P6,A",1,&H3E
- DATA "MOV P7,A",1,&H3F,"MOVP A,@A",1,&HA3,"MOVP3 A,@A",1,&HE3
- DATA "MOVX A,@R0",1,&H80,"MOVX A,@R1",1,&H81,"MOVX @R0,A",1,&H90
- DATA "MOVX @R1,A",1,&H91,"NOP",1,&H00,"ORG",4,&H00,"ORL A,R0",1,&H48
- DATA "ORL A,R1",1,&H49,"ORL A,R2",1,&H4A,"ORL A,R3",1,&H4B
- DATA "ORL A,R4",1,&H4C,"ORL A,R5",1,&H4D,"ORL A,R6",1,&H4E
- DATA "ORL A,R7",1,&H4F,"ORL A,@R0",1,&H40,"ORL A,@R1",1,&H41
- DATA "ORL A,#",2,&H43,"ORL BUS,#",2,&H88,"ORL P1,#",2,&H89
- DATA "ORL P2,#",2,&H8A,"ORLD P4,A",1,&H8C,"ORLD P5,A",1,&H8D
- DATA "ORLD P6,A",1,&H8E,"ORLD P7,A",1,&H8F
- DATA "OUTL BUS,A",1,&H02,"OUTL P1,A",1,&H39,"OUTL P2,A",1,&H3A
- DATA "RETR",1,&H93,"RET",1,&H83,"RL A",1,&HE7,"RLC A",1,&HF7
- DATA "RR A",1,&H77,"RRC A",1,&H67,"SEL MB0",1,&HE5,"SEL MB1",1,&HF5
- DATA "SEL RB0",1,&HC5,"SEL RB1",1,&HD5,"STOP TCNT",1,&H65
- DATA "STRT CNT",1,&H45,"STRT T",1,&H55,"SWAP A",1,&H47,"XCH A,R0",1,&H28
- DATA "XCH A,R1",1,&H29,"XCH A,R2",1,&H2A,"XCH A,R3",1,&H2B,"XCH A,R4",1
- DATA &H2C,"XCH A,R5",1,&H2D,"XCH A,R6",1,&H2E,"XCH A,R7",1,&H2F
- DATA "XCH A,@R0",1,&H20,"XCH A,@R1",1,&H21,"XCHD A,@R0",1,&H30
- DATA "XCHD A,@R1",1,&H31,"XRL A,R0",1,&HD8,"XRL A,R1",1,&HD9
- DATA "XRL A,R2",1,&HDA,"XRL A,R3",1,&HDB,"XRL A,R4",1,&HDC,"XRL A,R5",1
- DATA &HDD,"XRL A,R6",1,&HDE,"XRL A,R7",1,&HDF,"XRL A,@R0",1,&HD0
- DATA "XRL A,@R1",1,&HD1,"XRL A,#",2,&HD3