.TITLE EQSM ; .MACRO .EQSM A,B,N ;A=ADDRESS OF NxN MATRIX ;B=ADDRESS OF B-MATRIX OF DIMENSION N ;SOLVES MATRIX EQ. A*X = B A0=R0 ;ANSWER IS PUT INTO B; A-MATRIX IS DESTROYED A1=R1 ;SEE EQST.MAC, EQSM.PAS, EQST.PAS, EQST.FOR .MCALL .TLQ,.MOVM,.MOVF,.EQSM,.OFSET .GLOBL .EQSM,.CALL,EQSM,EQSMF EQSM: .EQSM 2(R5),4(R5),@6(R5) ;EQSM(A,B,N) FOR PASCAL RETURN ;CALL EQSMF(A,B,N) FOR FORTRAN ;TRANSPOSE A-MATRIX BECAUSE ARRAY ADDRESSING IS BACKWARDS EQSMF: MOV R0,-(SP) ;I MOV R1,-(SP) ;ADDR A[I,J] MOV R2,-(SP) ;J MOV R3,-(SP) ;ADDR A[J,I] STF A0,-(SP) STF A1,-(SP) CLR R0 ;I LL1: MOV R0,R2 LL2: INC R2 CMP R2,@6(R5) BGE NEX .OFSET R1,R0,@6(R5),R2,@6(R5) ADD 2(R5),R1 ;ADDR A[I,J] .OFSET R3,R2,@6(R5),R0,@6(R5) ADD 2(R5),R3 ;ADDR A[J,I] LDF (R1),A0 ;SWITCH OFF-DIAGONAL ELEMENTS LDF (R3),A1 STF A0,(R3) STF A1,(R1) BR LL2 NEX: INC R0 CMP R0,@6(R5) BLT LL1 LDF (SP)+,A1 LDF (SP)+,A0 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 .EQSM 2(R5),4(R5),@6(R5) RETURN N: .BLKW 1 B: .BLKW 1 A: .BLKW 1 .EQSM: TST N BLE ERR CMP N,#128. BLE OKAY ERR: .TLQ <.EQSM DIMENSION ERROR> JMP .CALL OKAY: MOV R0,-(SP) ;R0=I MOV R1,-(SP) ;ADDRESS CALCULATION MOV R2,-(SP) ;J MOV R3,-(SP) ;ROWMAX MOV R4,-(SP) ;K MOV R5,-(SP) ;ADDRESS CALCULATION STF A0,-(SP) ;Q STF A1,-(SP) STFPS -(SP) ;ENABLE FLOATING-PT ERROR REPORTING MOV 244,-(SP) ;SAVE OLD INTERRUPT VECTOR MOV #INTRPT,244 LDFPS #0 ;ENABLE FP INTERRUPT MOV N,R0 ;FOR I=1 TO N DO MOV #USED,R1 L1: CLRB (R1)+ ;USED[I]= FALSE HAS THIS ROW BEEN USED YET? SOB R0,L1 ;----------------------- CLR R0 ;FOR I=1 TO N DO I=R0=COLUMN TO BE CLEARED LI: CLRF A0 ;MAX=0 CLR R2 ;DO J=1 TO N TO FIND MAX ELEMENT A[J,I] LJ: TSTB USED(R2) ;IF (NOT USED[J]) AND (ABS(A[J,I])>=MAX) BGT NEXTJ ;THIS ROW ALREADY USED? ; .OFSET R1,R2,N,R0,N ;A1=ABS(A[J,I]) MOV R2,R1 MUL N,R1 ADD R0,R1 ASH #2,R1 ADD A,R1 LDF (R1),A1 ABSF A1 CMPF A1,A0 CFCC BLT NEXTJ LDF A1,A0 ;MAX=A1 MOV R2,R3 ;R3=ROWMAX=J NEXTJ: INC R2 CMP R2,N BLT LJ MOVB R3,ROW(R0) ;ROW[I]=ROWMAX INCB USED(R3) ;USED[ROWMAX]=TRUE ;NORMALIZE ROWMAXth ROW SO THAT ITS Ith COLUMN ELEMENT=1 ; .OFSET R1,R3,N,R0,N ;Q=A[ROWMAX,I] MOV R3,R1 MUL N,R1 ADD R0,R1 ASH #2,R1 ADD A,R1 LDF (R1),A0 ;Q ; .OFSET R1,R3,N,#0,N MOV R3,R1 MUL N,R1 ASH #2,R1 ADD A,R1 ;ADDRESS OF A[ROWMAX,1] MOV N,R4 ;K; FOR K=1 TO N DO LK: LDF (R1),A1 ;A[ROWMAX,K]= A[ROWMAX,K]/Q DIVF A0,A1 STF A1,(R1)+ SOB R4,LK ; .OFSET R1,R3,N ;B[ROWMAX]=B[ROWMAX]/Q DO SAME THING TO B MOV R3,R1 ASH #2,R1 ADD B,R1 LDF (R1),A1 DIVF A0,A1 STF A1,(R1) ;PUT ZEROS IN Ith COLUMN CLR R2 ;FOR J=1 TO N DO DO Jth ROW LJJ: CMP R2,R3 ;IF J=ROWMAX, SKIP ROWMAX BEQ NEXTJJ ; .OFSET R1,R2,N,R0,N ;A0=Q=A[J,I] MOV R2,R1 MUL N,R1 ADD R0,R1 ASH #2,R1 ADD A,R1 LDF (R1),A0 ;Q ; .OFSET R1,R2,N,#0,N MOV R2,R1 MUL N,R1 ASH #2,R1 ADD A,R1 ;ADDR OF A[J,1] ; .OFSET R5,R3,N,#0,N MOV R3,R5 MUL N,R5 ASH #2,R5 ADD A,R5 ;ADDR OF A[ROWMAX,1] MOV N,R4 ;K LKK: LDF (R5)+,A1 ;FOR K=1 TO N DO DO ALL COLUMNS OF Jth ROW MULF A0,A1 ;A[J,K]=A[J,K]-Q*A[ROWMAX,K] NEGF A1 ADDF (R1),A1 STF A1,(R1)+ SOB R4,LKK ;DO SAME THING TO B ; .OFSET R5,R3,N ;B[J]=B[J]-Q*B[ROWMAX] MOV R3,R5 ASH #2,R5 ADD B,R5 LDF (R5),A1 MULF A0,A1 NEGF A1 ; .OFSET R1,R2,N MOV R2,R1 ASH #2,R1 ADD B,R1 ADDF (R1),A1 STF A1,(R1) NEXTJJ: INC R2 CMP R2,N BLT LJJ INC R0 CMP R0,N BGE COPY JMP LI ;-------------------------COPY B-MATRIX INTO B-MATRIX IN CORRECT ORDER COPY: .MOVM B,A,N ;USE A-MATRIX TEMPORARILY CLR R0 ;FOR I=1 TO N DO B[I]=A[ROW[I]] MOV B,R1 LII: MOVB ROW(R0),R2 ASH #2,R2 ADD A,R2 .MOVF (R2),(R1)+ INC R0 CMP R0,N BLT LII MOV (SP)+,244 ;RESTORE PREVIOUS FLOATING PT INTERRUPTS LDFPS (SP)+ LDF (SP)+,A1 LDF (SP)+,A0 MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 RETURN INTRPT: .TLQ <.EQSM FLOATING POINT OVERFLOW OR DIVF 0> JMP .CALL ROW: .BLKB 50. USED: .BLKB 50. .END