.NLIST TTM,BEX .TITLE MC68000 CROSS ASSEMBLER SUPPORT ; ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; ASSEMBLY LANGUAGE SUBROUTINES FOR MC68000 CROSS-ASSEMBLER. ; FORTRAN LINKAGE TO THESE ROUTINES IS AS FOLLOWS: ; 1. RETURN VIA 'RTS PC'. ; 2. R5 POINTS TO PARAMETER LIST WITH FOLLOWING: ; A. NUMBER OF PARAMETERS. ; B. ADDRESS OF FIRST PARAMETER ; C. ADDRESS OF SECOND PARAMETER, ETC. ; 3. FUNCTION SUBROUTINES (INTEGER) RETURN VALUE IN R0. ; ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; ** I4CLR ** ; ; CLEAR LOW AND HIGH WORDS OF DOUBLE PRECISION VARIABLE ; ADR OF LOW WORD PASSED VIA (R5) ; I4CLR:: TST (R5)+ MOV R0,-(SP) MOV (R5),R0 CLR (R0)+ CLR (R0) MOV (SP)+,R0 RTS PC ; ; ** GETBIT ** ; ; SUBROUTINE TO CONVERT 4 LSB OF A INTEGER*2 VARIABLE TO A HEX ; ASCII DIGIT. THE INTEGER IS IN THE FIRST PARAMETER AND THE ; HEX DIGIT IS RETURNED IN THE SECOND PARAMETER (BYTE). THE ; INTEGER IS SHIFTED RIGHT BY 4 BEFORE RETURNING. ; CNVTBL: .ASCII '0123456789ABCDEF' GETBIT:: MOV R0,-(SP) ; MOV @2(R5),R0 ;GET WORD BIC #177760,R0 ;MASK OUT 4 LSB MOVB CNVTBL(R0),@4(R5) ;CONVERT AND RETURN MOV @2(R5),R0 ;SHIFT INPUT INTEGER ASH #-4,R0 ; RIGHT BY 4. MOV R0,@2(R5) ; MOV (SP)+,R0 ; RTS PC ;RETURN .PAGE ; ; ** ICKVAL ** ; ; INTEGER FUNCTION TO CHK IF I*2 VARIABLE IS IN THE RANGE ; -64,63. IF IT IS A VALUE OF 0 IS RETURNED, OTHERWISE ; A VALUE OF ONE IS RETURNED ; ICKVAL:: MOV @2(R5),R0 BIT #177600,R0 BEQ 10$ BIC #177,R0 CMP R0,#177600 BEQ 10$ MOV #1,R0 RTS PC 10$: CLR R0 RTS PC .PAGE ; ; THE FOLLOWING INTEGER*4 ARITHMETIC ROUTINES ARE USED INSTEAD ; OF F4P CALLS TO PERMIT THE CROSS ASSEMBLER TO RUN WITHOUT ; MODIFICATIONS ON EITHER RT-11 OR RSX-11 SYSTEMS ; JADD:: CLR R0 ;INITIALIZE FOR NORMAL EXIT TST (R5)+ ;SKIP COUNT ARG MOV (R5)+,R4 ;ADDR OF OPERAND 1 MOV (R5)+,R3 ;ADDR OF OPERAND 2 MOV (R5)+,R1 ;ADDR OF RESULT MOV (R4)+,R2 ;GET LOW ORDER OP 1 ADD (R3)+,R2 ;ADD IN LOW ORDER OP 2 MOV @R4,R5 ;GET HIGH ORDER OP 1 ADC R5 ;ADD IN CARRY BVS 1$ ADD @R3,R5 ;ADD IN HIGH ORDER OP 2 BVC 2$ 1$: CLR R2 ;SET RESULT TO 0 CLR R5 MOV #-2,R0 ;INDICATE OVERFLOW 2$: MOV R2,(R1)+ ;STORE RESULT MOV R5,@R1 RTS PC .PAGE ; ; INTEGER*4 SUBTRACTION ; JSUB:: CLR R0 ;INITIALIZE FOR NORMAL EXIT TST (R5)+ ;SKIP COUNT ARG MOV (R5)+,R4 ;ADDR OF OPERAND 1 MOV (R5)+,R3 ;ADDR OF OPERAND 2 MOV (R5)+,R1 ;ADDR OF RESULT MOV (R4)+,R2 ;GET LOW ORDER OP 1 SUB (R3)+,R2 ;SUBTRACT LOW ORDER OP 2 MOV @R4,R5 ;GET HIGH ORDER RESULT SBC R5 ;SUBTRACT CARRY BVS 1$ SUB @R3,R5 ;SUBTRACT HIGH ORDER OP 2 BVC 2$ 1$: CLR R2 ;SET RESULT TO 0 CLR R5 MOV #-2,R0 ;INDICATE OVERFLOW 2$: MOV R2,(R1)+ ;STORE RESULT MOV R5,@R1 RTS PC .PAGE ; ; INTEGER*4 MULTIPLICATION ; JMUL:: TST (R5)+ ;SKIP COUNT ARG CLR -(SP) ;INIT SIGN FLAG MOV (R5)+,R4 ;ADDR OF OPERAND 1 MOV (R4)+,R1 ;GET LOW ORDER OP 1 MOV @R4,R3 ;GET HIGH ORDER OP 1 BPL 1$ ;BRNCH IF POSITIVE NEG R3 ;TAKE ABSOLUTE VALUE NEG R1 SBC R3 INC @SP ;AND SET SIGN FLAG 1$: MOV (R5)+,R4 ;ADDR OF OPERAND 2 MOV (R4)+,R0 ;LOW ORDER OF OP 2 MOV @R4,R2 ;HIGH ORDER OF OP 2 BPL 2$ ;BRAANCH IF POSITIVE INC @SP ;SET SIGN FLAG NEG R2 ;AND TAKE ABSOLUTE VALUE NEG R0 SBC R2 2$: BEQ 3$ ;BRANCH IF HIGH PART OF OP 2 IS 0 TST R3 ;IF WASN'T OP 2 MUST BE OP 1 BNE OVRFL ;BRANCH IF RESULT WILL BE TOO BIG MOV R0,R4 ;OTHERWISE SWITCH OPS MOV R1,R0 MOV R4,R1 MOV R2,R3 CLR R2 3$: CLR R4 ;RESULT WILL END UP IN R2:R4 4$: ROR R0 ;SHIFT BIT OUT OF MULTIPLIER BCC 5$ ;BRANCH IF 0 ADD R1,R4 ;ADD LOW PARTS TOGETHER ADC R2 ;ADD IN CARRY BVS OVRFL ;BRANCH IF OVERFLOW ADD R3,R2 ;ADD HIGH PARTS TOGETHER BVS OVRFL ;BRANCH IF OVERFLOW TST R0 ;ANY MORE OF MULTIPLIER LEFT? 5$: BEQ DONE ;BRANCH IF FINISHED ASL R1 ;SHIFT MULTIPLICAND LEFT ROL R3 BVC 4$ ;LOOP OVRFL: MOV #-2,R0 ;SET OVEFLOW INDICATOR CLR R2 ;SET RESULT TO 0 CLR R4 DONE: ROR (SP)+ ;GET RESULT SIGN INTO C BCC 1$ ;BRANCH IF TO BE POSITIVE NEG R2 ;NEGATE RESULT NEG R4 SBC R2 1$: MOV @R5,R1 ;ADDR OF RESULT MOV R4,(R1)+ ;STORE LOW ORDER MOV R2,@R1 ;STORE HIGH ORDER RTS PC .PAGE ; ; INTEGER*4 DIVISION ; JDIV:: CLR -(SP) ;SET SUCCCESSFUL EXIT FLAG MOV (R5)+,-(SP) ;SAVE ARG COUNT MOV (R5)+,R4 ;ADDR OF NUMERATOR MOV (R5)+,R1 ;ADDR OF DENOMINATOR MOV R5,-(SP) ;SAVE ADDR OF RESULT MOV #33.,-(SP) ;SET SHIFT COUNTER MOV (R1)+,R0 ;GET LOW ORDER DENOM MOV @R1,R1 ;GET HIGH ORDER DENOM BPL 1$ ;BRANCH IF POSITIVE NEG R1 ;TAKE ABSOLUTE VALUE NEG R0 SBC R1 ADD #100000,@SP ;AND SET SIGN FLAG 1$: BNE 2$ ;BRANCH IF DENOM CAN'T BE 0 TST R0 ;MAKE SURE LOW DENOM ISN'T 0 BEQ ZDIV ;BRANCH IF ZERO DIVIDE 2$: MOV (R4)+,R2 ;LOW ORDER OF NUM MOV @R4,R3 ;HIGH ORDER OF NUM BPL 3$ ;BRANCH IF POSITIVE ADD #40000,@SP ;SET SIGN FLAG NEG R3 ;AND TAKE ABSOLUTE VALUE NEG R2 SBC R3 3$: CLR R5 ;QUOTIENT ENDS UP IN R3:R2 CLR R4 ;REMAINDER ENDS UP IN R5:R4 4$: ROL R4 ;EXPOSE NEW BIT OF NUMERATOR ROL R5 CMP R1,R5 ;DOES DENOM FIT? BHI 6$ ;BRANCH IF NOT, C=0 BNE 5$ ;BRANCH IF YES CMP R0,R4 ;HIGH PARTS SAME, CHECK LOW BHI 6$ ;BRANCH IF NOT, C=0 5$: SUB R0,R4 ;SUBTRACT DENOM FROM REMAINDER SBC R5 SUB R1,R5 SEC ;INDICATE NEW QUOTIENT BIT 6$: ROL R2 ;SHIFT IN NEW BIT OF QUOTIENT ROL R3 DECB @SP ;CHECK LOOP COUNT BGT 4$ ;BRANCH TO LOOP ENDCOD: ASL @SP ;PUT QUOTIENT RESULT SIGN IN V BVC 1$ ;BRANCH IF TO BE POSITIVE NEG R3 ;NEGATE QUOTIENT NEG R2 SBC R3 1$: TST (SP)+ ;GET REMAINDERS SIGN BPL 2$ ;BRANCH IF REMAINDER TO BE POSITIVE NEG R5 ;NEGATE REMAINDER NEG R4 SBC R5 2$: MOV (SP)+,R0 ;GET ARG LIST POINTER AGAIN MOV (R0)+,R1 ;ADDR OF QUOTIENT RESULT CMPB #3,(SP)+ ;CHECK NUMBER OF ARGUMENTS BEQ 3$ ;BRANCH IF ONLY 3 PASSED MOV @R0,R0 ;GET ADDR REMAINDER RESULT MOV R4,(R0)+ ;STORE LOW MOV R5,@R0 ;STORE HIGH 3$: MOV R2,(R1)+ ;STORE LOW QUOTIENT RESULT MOV R3,@R1 ;STORE HIGH TST (SP)+ RTS PC ZDIV: CLR R4 ;SET REMAINDER TO 0 CLR R5 CLR R2 ;SET QUOTIENT TO 0 CLR R3 MOV #-3,6(SP) ;SET ZDIV ERROR INDICATOR BR ENDCOD ;GO SET RESULTS .PAGE ; ; INTEGER*4 LOGICAL AND ; JAND:: TST (R5)+ ;SKIP COUNT ARGUMENT MOV (R5)+,R0 ;ADR OF NUMBER MOV (R5)+,R1 ;ADR OF NUMBER TO BE ANDED MOV (R5)+,R2 ;ADR OF DESTINATION MOV (R0)+,R3 ;GET VAL OF HIGH PART OF NUMBER MOV (R1)+,R4 ;GET VAL OF HIGH PART OF MASK COM R4 ;INVERT MASK BITS BIC R4,R3 ;AND 'EM MOV R3,(R2)+ ;STORE RESULT IN DESTINATION MOV (R0),R3 ;GET VAL OF LOW PART OF NUMBER MOV (R1),R4 ;GET VAL OF LOW PART OF MASK COM R4 ;INVERT MASK BITS BIC R4,R3 ;AND 'EM MOV R3,(R2) ;STORE RESULT IN DESTINATION CLR R0 ;CLR VAL OF FUNCTION RTS PC .PAGE ; ; INTEGER*4 INCLUSIVE OR ; JOR:: TST (R5)+ ;SKIP OVER ARGUMENT COUNT MOV (R5)+,R0 ;ADR OF NUMBER MOV (R5)+,R1 ;ADR OF NUMBER TO BE OR'ED MOV (R5)+,R2 ;ADR OF DESTINATION MOV (R0)+,R3 ;GET VAL OF HIGH PART OF NUMBER MOV (R1)+,R4 ;GET VAL OF HIGH PART OF OR MASK BIS R4,R3 ;OR 'EM MOV R3,(R2)+ ;STORE RESULT IN DESTINATION MOV (R0),R3 ;GET VAL OF LOW PART OF NUMBER MOV (R1),R4 ;GET VAL OF LOW PART OF OR MASK BIS R4,R3 ;OR 'EM MOV R3,(R2) ;STORE RESULT IN DESTINATION CLR R0 ;STD FUNCTION RETURN VAL RTS PC .PAGE ; ; ** JLSHF ** ; ; INTEGER*4 LEFT SHIFT (UNSIGNED) ; JLSHF:: TST (R5)+ ;SKIP OVER ARGUMENT COUNT MOV (R5),R0 ;SRC ADR MOV @2(R5),R1 ;NUMBER OF BITS TO SHIFT IT MOV 4(R5),R2 ;DEST ADR MOV (R0)+, (R2) ;MOVE SRC TO DEST MOV (R0) ,2(R2) TST R1 BEQ 99$ ;SHIFTING 0 BITS IS SILLY CMP R1,#40 BHI 99$ ;CAN'T SHIFT MORE THAN 32 BITS 1$: CLC ;MAKE SURE CARRY IS CLEAR ROL (R2) ;SHIFT LO HALF 1 BIT ROL 2(R2) ;SHIFT HI WRD 3$: DEC R1 ;DECR #BITS TO SHIFT BNE 1$ ;LOOP IF NON ZERO ; 99$: CLR R0 RTS PC .PAGE ; ; ** JRSHF ** ; ; INTEGER*4 RIGHT SHIFT (UNSIGNED) ; JRSHF:: TST (R5)+ ;SKIP OVER ARGUMENT COUNT MOV (R5),R0 ;ADR OF NUMBER TO SHIFT MOV @2(R5),R1 ;NUMBER OF BITS TO SHIFT IT MOV 4(R5),R2 ;DESTINATION ADDRESS MOV (R0)+, (R2) ;MOVE SRC TO DEST MOV (R0) ,2(R2) TST R1 BEQ 99$ ;SHIFTING 0 BITS IS SILLY CMP R1,#40 BHI 99$ ;CAN'T SHIFT MORE THAN 32 BITS 1$: CLC ;MAKE SURE CARRY IS CLEAR ROR 2(R2) ;SHIFT HI HALF 1 BIT ROR (R2) ;SHIFT LO WRD DEC R1 ;DECR #BITS TO SHIFT BNE 1$ ;LOOP IF NON ZERO ; 99$: CLR R0 RTS PC .PAGE ; ; ** JICMP ** ; ; COMPARE A 32 BIT SIGNED NUMBER WITH A 16 BIT SIGNED NUMBER ; FUNCTION RETURNS A VALUE OF ZERO IF THE NUMBERS ARE EQUIVALENT ; JICMP:: TST (R5)+ MOV (R5)+,R0 ;ADR OF I*4 VALUE MOV @(R5)+,R1 ;VALUE OF I*2 NUMBER TST R1 ;SEE IF VAL NEGATIVE BPL 1$ ; CMP (R0),#177777 ;SEE IF NUMBER NEGATIVE BNE 99$ ;NUMBER NOT NEGATIVE BR 2$ 1$: TST (R0) ;IF I*2 NUMBER NOT NEG THEN HI WORD BNE 99$ ;MUST BE ZERO 2$: CMP 2(R0),R1 ;CMP THE TWO NUMBERS BNE 99$ CLR R0 RTS PC ;NUMBERS ARE EQUAL 99$: MOV #1,R0 ;NUMBERS NOT EQUAL RTS PC .PAGE ; ; ** JMOV ** ; ; INTEGER*4 MOVE ; JMOV:: CLR R0 ;INITIALIZE FOR NORMAL EXIT TST (R5)+ ;SKIP COUNT ARG MOV (R5)+,R4 ;ADDR OF OPERAND 1 MOV (R5)+,R1 ;ADDR OF OPERAND 2 MOV (R4)+,(R1)+ ;MOVE LOW PART MOV @R4,@R1 ;MOVE HIGH PART RTS PC .PAGE ; ; ** BLDMAP (DLIST,ALIST,OUTPUT) ** ; ; CREATE A REGISTER BITMAP FROM A DATA AND ADR REG MAP ; BLDMAP:: TST (R5)+ ;SKIP OVER ARG COUNT MOV @(R5)+,R0 ;GET DATA BITMAP BIC #177400,R0 ;MAKE SURE NO EXTRA BITS SET MOV @(R5)+,R1 ;GET ADR BITMAP BIC #177400,R1 ;MAKE SURE NO EXTRA BITS SET SWAB R1 ;MOVE ADR REG BITS UP WHERE THEY BELONG BIS R0,R1 ;OR IN THE D-REG BITS MOV R1,@(R5) ;SAVE THE RESULT IN THE DESTINATION RTS PC ;AND RETURN .PAGE ; ; ** JICVT (I*2,I*4 RESULT) ** ; ; I*2 TO I*4 CONVERSION (SIGNED) ; JICVT:: TST (R5)+ ;SKIP COUNT ARG CLR R2 ;INIT SIGN EXTEND WORD MOV @(R5)+,R0 ;GET INTEGER VALUE BPL 1$ ;BRANCH IF POSITIVE DEC R2 ;SET SIGN EXTEND WORD 1$: MOV @R5,R1 ;ADDR OF RESULT MOV R0,(R1)+ ;STORE LOW ORDER MOV R2,@R1 ;STORE HIGH ORDER CLR R0 ;INITIALIZE FOR NORMAL EXIT RTS PC .END