A2osX/SCMASM.30/SCMASM.S.ASMGEN.txt

370 lines
12 KiB
Plaintext
Raw Normal View History

NEW
AUTO 3,1
*--------------------------------------
* ASSEMBLER MAIN DRIVER
*--------------------------------
ASM
* LDX #0 X=0 FROM COMMAND DISPATCHER
STX PASS SET TO PASS 1
STX ERROR.COUNT
STX ERROR.COUNT+1
* STX MACRO.LEVEL ALREADY DONE IN GNL
* STX PARAM.PNTR ALREADY DONE IN GNL
* STX PAGE.LENGTH ALREADY DONE IN GNL
STX PAGE.NUMBER
STX PAGE.NUMBER+1
JSR STINIT INITIALIZE SYMBOL TABLE
JSR RESTORE IF IN INCLUDE, RESTORE
*--------------------------------
* PERFORM NEXT PASS OF ASSEMBLY
*--------------------------------
ASM1 LDA ERROR.COUNT
ORA ERROR.COUNT+1
BEQ .1
JMP ASM.END PRINT # ERRORS AND ABORT ASSEMBLY
.1 LDX #1 INIT 2-BYTE VARIABLES
.2 LDA PP,X POINT TO BEGINNING OF SOURCE PROGRAM
STA SRCP,X
STA MACSTK,X
LDA #0
STA CALL.CNTR,X TOTAL # MACRO CALLS
STA CALL.NUM,X CURRENT MACRO CALL #
STA ORGN+2,X HIGH 16 OF ORIGIN
DEX
BPL .2
*---Following = $FF--------------
STX DO.STACK SET OUTER LEVEL TRUE (=$FF)
STX LF.CONDITIONAL do not list false sets (=$FF)
*---Following = $00--------------
STA DUMMY.FLAG NOT IN DUMMY SECTION
STA PHASE.FLAG NOT IN PHASE
STA DO.INDEX SET DO.STACK TO EMPTY
STA LF.ALL turn on main listing
STA LF.MACRO list macro expansions too
STA LF.XTRA.BYTES list all bytes, use extra lines
STA TF.FLAG not in ".TF"
STA DO.SKIP.CNT not in ".DO"
STA FLAG.MA not in ".MA"
STA NYBBLE.FLAG .AC odd/even
STA ORGN ORIGIN = $0800
STA TRGT TARGET = $0800
*---Following = $08--------------
LDA #$08
STA ORGN+1
STA TRGT+1
JSR ASM.INIT Initialize for particular assembler
*--------------------------------
* MOVE NEXT LINE INTO WORKING BUFFER
*--------------------------------
ASM2 LDA $C000 CHECK FOR ABORT WITHOUT
CMP #CHR.RETURN CLEARING STROBE
BNE .1
JMP JMP.SOFT YES, STOP RIGHT NOW
.1 LDX #$FF INITIALIZE STACK POINTER
TXS
INX MAKE X=0
STX EMIT.COLUMN
STX EXP.UNDEF CLEAR UNDEFINED FLAG
JSR SETUP.NEXT.LINE
BCC .2 GOT A LINE
JMP ENDM NO MORE LINES, ACT LIKE .EN FOUND
*---CHECK CURRENT CONDITION------
.2 LDA DO.STACK CURRENT LEVEL IN SIGN BIT
BMI ASSEMBLE.ONE.LINE TRUE, SO ASSEMBLE
*--------------------------------
* SKIP TO .FIN OR .ELSE
*--------------------------------
SKIP.TO.FIN
JSR SCAN.TO.OPCODE
BCS .3
LDX #DIR.QT.DO
JSR DIR.SCAN.OR.FAIL
BCC .1 NOT .DO
INC DO.SKIP.CNT .DO
BNE .3 ...ALWAYS
.1 LDY DO.SKIP.CNT
BNE .2 INSIDE A NESTED .DO, IGNORE .ELSE'S
JSR DIR.SCAN.OR.FAIL
BCS ASSEMBLE.ONE.LINE FOUND .ELSE
.2 LDX #DIR.QT.FI
JSR DIR.SCAN.OR.FAIL
BCC .3 NOT .FIN
LDY DO.SKIP.CNT .FIN, SEE IF NESTED ONE
BEQ ASSEMBLE.ONE.LINE NO, ASSEMBLE THIS .FIN
DEC DO.SKIP.CNT YES, POP OFF THIS NEST
.3 BIT LF.CONDITIONAL LIST CONDITIONAL LINES?
BMI ASM2 NO, SKIP IT
JSR CRLF.IF.LISTING YES, NEW LINE
JMP CMNT AND LIST IT
*--------------------------------
* ANALYZE SOURCE LINE
*--------------------------------
ASSEMBLE.ONE.LINE
JSR CRLF.IF.LISTING
JSR PACK.MACRO.LINE
BCS CMNT ...only list if MACRO definition line
JSR GNC.UC.START not MACRO line, get first char
BCS CMNT ...empty line
BEQ .3 ...blank, so no label
JSR CHECK.COMMENT.CHAR
BEQ CMNT ...comment (* or ;)
JSR LABL PROCESS LABEL DEFINITION
.3 JSR GNNB Scan to opcode field
BCS CMNT ...none, only label on this line
JSR CHECK.COMMENT.CHAR might be a comment with no opcode
BEQ CMNT ...yes, there is a comment
CMP #'> CHECK IF MACRO OPCODE
BEQ .4 ...YES
CMP #'_ CHECK IF MACRO OPCODE
BEQ .4 ...YES
CMP #'='
BEQ .5 '=' is synonym for .EQ
STA SEARCH.KEY FIRST OPCODE CHAR
JSR GNC.UC
STA SEARCH.KEY+1 2ND OPCODE CHAR
JSR GNC.UC
STA SEARCH.KEY+2 3RD OPCODE CHAR
LDA SEARCH.KEY
CMP #'. IS IT A DIRECTIVE?
BNE .6 NO, TRY NORMAL OPCODES
LDA #OPTBL.DIR
LDY /OPTBL.DIR
CLC INITIAL SEARCH
JSR SEARCH.COMPRESSED.TABLE
BCC OPER ...NOT FOUND IN TABLE
JSR PERFORM.DIRECTIVE
JMP CMNT
.4 JMP MACRO.CALL
.5 JSR PSEQ "=" is synonym for .EQ
JMP CMNT
.6 JSR ASM.PARTICULAR
*--------------------------------
CMNT LDA EXP.UNDEF
BPL .1 NO UNDEFINED EXPRESSIONS ON THIS LINE
LDA PASS
BEQ .1 IF WE GOT THIS FAR, OKAY IN PASS 1
JMP UNDF
.1 JSR LIST.SOURCE.IF.LISTING
JMP ASM2 NEXT LINE
*--------------------------------
*--------------------------------
PERFORM.DIRECTIVE
INY POINT AT HIGH BYTE OF ADDRESS
LDA (OPTBL.PNTR),Y
PHA
DEY
LDA (OPTBL.PNTR),Y
PHA
RTS
*--------------------------------
OPER LDY #QER2 ERROR--BAD OPCODE
JMP SOFT.ERROR
*--------------------------------
* EMIT ONE BYTE OF OBJECT CODE
*
* IF IN PASS TWO THEN
* ! IF LISTING THEN <LIST>
* ! IF IN ".TF" THEN
* ! ! <WRITE BYTE ON DISK>
* ! ELSE IF NOT IN DUMMY SECTION THEN
* ! ! ! IF IN PROTECTED AREA THEN
* ! ! ! ! <ABORT ASSEMBLY>
* ! ! ! ELSE <STORE BYTE IN TARGET>
* INCREMENT ORIGIN AND ORIGIN.SAVE
* IF NOT IN DUMMY SECTION THEN INCREMENT TARGET
*--------------------------------
EMIT.ZERO
LDA #0
EMIT LDY PASS CHECK WHICH PASS
BEQ .5 PASS 1, JUST INCREMENT LOCATION
STA OBJ.BYTE SAVE OBJECT BYTE
*---LIST THE BYTE----------------
JSR P.EMITTED.BYTE
*---STORE THE BYTE---------------
BIT DUMMY.FLAG No output inside dummy section
BMI .6 ...only increment the origin
LDA OBJ.BYTE GET OUTPUT BYTE
BIT TF.FLAG SEE IF IN ".TF"
BMI .4 YES
JSR USER.OBJECT.BYTE
JMP .5 ...ALWAYS
.4 JSR DOUT WRITE ON TARGET FILE
*---INCREMENT LOCATION-----------
.5 LDA DUMMY.FLAG IF IN DUMMY SECTION,
BMI .6 THEN ONLY INCREMENT ORGN
>INCD TRGT BUMP TARGET ADDRESS
>INCD ORIGIN.SAVE AND ORIGIN OUTSIDE .PH
.6 >INCD ORGN BUMP CURRENT ORIGIN
RTS
*--------------------------------
STORE.OBJECT.BYTE
LDA TRGT+1 TARGET PAGE
BNE .1 NOT PAGE ZERO
LDA TRGT ALLOW $00-$1E
CMP #$1F
BCC .4 SAFE
BCS .3 NOT SAFE
*---ALLOW $300-$3CF--------------
.1 CMP #$03 IN PAGE 3?
BNE .2 NO
LDA TRGT BELOW $3D0?
CMP #$D0
BCC .4 YES, SAFE
BCS .3 NO, NOT SAFE
.DO AUXMEM
*---ALLOW $800-MACSTK------------
.2 CMP #$08 BELOW PAGE 8?
BCC .3 YES, NOT SAFE
LDA TRGT
CMP MACSTK
LDA TRGT+1
SBC MACSTK+1
BCC .4 BELOW MACSTK, SAFE
.ELSE
*---ALLOW $800-MACLBL------------
.2 CMP #$08 BELOW PAGE 8?
BCC .3 YES, NOT SAFE
LDA TRGT NO, COMPARE TO MACLBL
CMP MACLBL
LDA TRGT+1
SBC MACLBL+1
BCC .4 BELOW MACLBL, SO SAFE
*---ALLOW EOT-MACSTK-------------
LDA EOT
CMP TRGT
LDA EOT+1
SBC TRGT+1
BCS .3 BELOW EOT, NOT SAFE
LDA TRGT
CMP MACSTK
LDA TRGT+1
SBC MACSTK+1
BCC .4 BELOW MACSTK, SAFE
.FIN
*---NOT SAFE, CHECK USER RANGE---
.3 LDA TRGT
CMP USER.MEM.LO
LDA TRGT+1
SBC USER.MEM.LO+1
BCC .5 DEFINITELY OUT OF BOUNDS
LDA USER.MEM.HI
CMP TRGT
LDA USER.MEM.HI+1
SBC TRGT+1
BCC .5 DEFINITELY OUT OF BOUNDS
.4 LDY #0
LDA OBJ.BYTE
STA (TRGT),Y
RTS
.5 LDY #QMEMPRO
JMP FIRM.ERROR
*--------------------------------
* LIST SOURCE LINE
*--------------------------------
LIST.SOURCE.IF.LISTING
JSR CHECK.IF.LISTING
LIST.SOURCE.REGARDLESS
JSR P.MARGIN PRINT BLANKS TILL MARGIN
LIST.SOURCE.AT.MARGIN
JSR CONVERT.LINE.NUMBER.PRINT
LDY MACRO.LEVEL
BEQ .2
LDA #'>'
.1 JSR CHO
DEY
BNE .1 ...UNTIL Y=0
.2 LDA #' ' ...NOW Y=0
.3 JSR CHO
INY
LDA WBUF-1,Y
BNE .3
RTS
*--------------------------------
* PRINT CRLF IF IN PASS 2 AND IF LISTING IS ON
*--------------------------------
CRLF.CAUSED.FORM.FEED
JSR FORM.FEED
CRLF.IF.LISTING
JSR CHECK.IF.LISTING
CRLF.WITH.PAGING
JSR CRLF
INC LINE.COUNT
LDA PAGE.LENGTH
BEQ .1 ...NOT TITLING
CMP LINE.COUNT
BCC CRLF.CAUSED.FORM.FEED ...END OF PAGE
.1 RTS
*--------------------------------
* PROCESS LABEL DEFINITION
*--------------------------------
LABL JSR PACK PACK AND CHECK SYMBOL
BCC ERR.BS BAD SYMBOL
JSR STSRCH SEE IF DEFINED
BCC ERR.DD YES, DOUBLE DEFINITION
JMP STADD ADD TO SYMBOL TABLE
*--------------------------------
ERR.DD LDY PASS ERROR IN PASS 1
BEQ ERR.DBLDF OK IN PASS 2
LDY #6 SET FLAG FOR TESTING FWD REFS
>SYM LDA,STPNTR
ORA #$40
>SYM STA,STPNTR
LDY WBUF LOOK AT COLUMN 1
CPY #': IF PRIVATE LABEL...
BEQ .2 ...THEN DON'T UPDATE C.M.LABEL
LDA STPNTR SAVE POINTER TO THIS MAJOR LABEL
STA CURRENT.MAJOR.LABEL
LDA STPNTR+1
STA CURRENT.MAJOR.LABEL+1
.2 RTS
ERR.DBLDF
LDY #QER4 DOUBLE DEFN
.HS 2C SKIP 2 BYTES
ERR.BS LDY #QER7 BAD SYMBOL
JMP SOFT.ERROR
*--------------------------------
* Search Compressed Opcode Table
* If carry clear, (Y,A) = address of table
* If carry set, continue searching same table
*
* Return with carry set if found, else carry clear.
* (OPTBL.PNTR),Y points at 16-bit value
* of entry which matched.
*--------------------------------
SEARCH.COMPRESSED.TABLE
BCS .6 ...Continue searching same table
STA OPTBL.PNTR
STY OPTBL.PNTR+1
*---Try matching 2nd letter------
LDY #0
.1 LDA (OPTBL.PNTR),Y Possible match
ORA #$40 Make it ASCII
CMP SEARCH.KEY+1 same as 2nd letter?
BEQ .6 ...yes, matched.
BNE .3 ...no
*---Scan to next 8-bit entry-----
.2 INY
INY
.3 INY
LDA (OPTBL.PNTR),Y
BMI .2 ...another 24-bit entry
ASL check if beyond our sub-group
BPL .1 ...no, valid 2nd letter option
.4 CLC ...no match in table, carry clear
RTS
*---Try matching 3rd letter------
.5 INY
.6 INY
LDA (OPTBL.PNTR),Y
BPL .4 ...no more options, not in table
INY point at data
EOR #$C0 make like ASCII
CMP SEARCH.KEY+2 compare to 3rd letter
BNE .5 ...did not match, try another
RTS ...found it, return carry set
*--------------------------------------
MAN
SAVE usr/src/scmasm.30/scmasm.s.asmgen
LOAD usr/src/scmasm.30/scmasm.s
ASM