Linker/pass2.asm

1 line
31 KiB
NASM
Raw Normal View History

keep obj/pass2 mcopy pass2.mac **************************************************************** * * Pass 2 * * This module contains the subroutines used to do pass 2 * processing of the input files and creation of the output * files. * **************************************************************** copy directPage **************************************************************** * * Align - align the code to a byte boundary * * Inputs: * sp - pointer to the opcode * pc - current program counter * * Outputs: * sp - pointer to the next opcode * pc - new program counter * **************************************************************** * Align private ldy #1 get the alignment factor lda [sp],Y sta r0 iny iny lda [sp],Y sta r2 add4 sp,#5 skip the alignment opcode and operand jsr DefineAlign do the align rts end **************************************************************** * * BExpr - evaluate a local bank expression * * Inputs: * sp - pointer to the opcode * pc - current program counter * * Outputs: * sp - pointer to the next opcode * pc - new program counter * **************************************************************** * BExpr private using ExpCommon using OutCommon using Common stz saveSegment saveSegment := false lda [sp] update the PC xba and #$00FF sta expLength lb1 add4 sp,#2 skip the op code and expression length ph4 sp evaluate the expression jsr Evaluate sta expValue stx expValue+2 add4 loadOrg,pc,val1 make sure bank bytes match lda symbolRelocatable beq lb2 add4 loadOrg,expValue,val2 bra lb2a lb2 move4 expValue,val2 lb2a stz mask stz mask+2 short M ldx expLength beq lb4 cpx #4 bge lb4 ldx #3 lda #$FF lb3 sta mask,X dex cpx expLength bge lb3 lb4 long M lda mask and val1 sta val1 lda mask+2 and val1+2 sta val1+2 lda mask and val2 cmp val1 bne lb5 lda mask+2 and val2+2 cmp val1+2 beq lb6 lb5 ph4 #0 ph2 #10 jsr Error bra lb10 lb6 lda expSegment if the expression uses values in another beq lb10 segment then cmp loadNumber beq lb10 lda expLength if the expression is too short for cmp #3 a legal interseg reference then bge lb7 ph4 #0 flag the error ph2 #10 jsr Error bra lb10 skip to "normal" processing lb7 lda symbolRelocatable if the expression is relocatable then beq lb9 jsr DictInterseg create a dictionary entry sta saveSegment save the save segment flag lda shiftFlag if the value is shifted then beq lb8 move4 shiftValue,expValue use the unshifted value lb8 anop lb9 lda expSegment if the segment is dynamic then jsr IsDynamic bcc lb11 ph4 #0 flag the error ph2 #17 jsr Error bra lb11 else lb10 lda symbolRelocatable if the expression is relocatable then beq lb11 jsr DictReloc create a dictionary entry lb11 anop endif jsr PutValue write an expression value lda saveSegment if saveSegment then beq lb12 sec save the segment number lda op sbc saveSegment sta r0 lda op+2 sbc #0 sta r2 short M clc lda expSegment sta [r0] long M lb12 brl SkipExpression skip the expression ; ; Local data ; val1 ds 4 first address val2 ds 4 second address mask ds 4 bank mask saveSegment ds 2 save segment number flag end **************************************************************** * * Const - constant bytes * * Inputs: * sp - pointer to the opcode * pc - current program counter * * Outputs: * sp - pointer to the next opcode * pc - new program counter * **************************************************************** * Const private lda [sp] update the program counter and #$00FF tay clc adc pc sta pc bcc lb1 inc pc+2 lb1 inc4 sp skip the op code tyx save the length tya move the bytes lsr A bcc lb2 short M dey lda [sp],Y sta [op],Y long M lb2 dey dey bmi lb3a lb3 lda [sp],Y sta [op],Y dey dey bpl lb3 lb3a anop txa update the output pointer clc adc op sta op bcc lb4 inc op+2 lb4 txa update sp clc adc sp sta sp bcc lb5 inc sp+2 lb5 rts end **************************************************************** * * DefineAlign