* MATRIX - AFFINE TRANSFORM SUPPORT PACKAGE * * * AUTHOR: * * PHILIPP HACHTMANN * * VERSIONS: * 0.1 - INITIAL REVISION (22.12.2007 * * * PURPOSE: * * THIS LIBRARY PROVIDES AFFINE TRANSFORMATION ROUTINES TO * PLOTTING ROUTINES AND OTHER SOFTWARE. * * * DATA REPRESENTATION: * * * MATRIX FORMAT: | A11 A12 | * M= | | * | A21 A22 | * * A11-A22 ARE SINGLE PRECISION FLOAT VALUES COMPLIANT TO THE * HONEYWELL MATHEMATICAL LIBARAY. EVERY VALUE USES TWO * 16 BIT MACHINE WORDS. * IF A MATRIX IS USED AS A DAC ARGUMENT, A POINTER TO THE FIRST * ELEMENT, A11, HAS TO BE USED. * * * VECTOR FORMAT: | A1 | * V= | | * | A2 | * * A1 AND A2 ARE SIGNED INTEGER VALUES. EVERY VALUE USES ONE * 16 BIT MACHINE WORD. * IF A VECTOR IS USED AS A DAC ARGUMENT, A POINTER TO THE FIRST * ELEMENT, A1, HAS TO BE USED. * * * AFFINE TRANSFORM FORMAT: * * AN AFFINE TRANSFORM CONSISTS OF A MATRIX FOR ROTATING AND SCALING * AND A VECTOR VOR RELOCATION OF THE RESULT. * A VECTOR IS TRANSFORMED BY FIRST MULTIPLYING THE MATRIX WITH IT * AND THEN ADDING THE RELOCATION VECTOR: * * | A11 A12 | | VI1 | | VT1 | * VO = MT * VI + VT = | | * | | + | | * | A21 A22 | | VI2 | | VT2 | * * | VI1*A11 + VI2*A12 + VT1 | * = | | * | VI1*A21 + VI2*A22 + VT2 | * * MT AND VT ARE THE TRANSFORMATION MATRIX AND VECTOR, VI THE INPUT * VECTOR, VO THE RESULT VECTOR. * * AN AFFINE TRANSFORM IS STORED AS A CONCATENATION OF A MATRIX AND * A VECTOR. HERE IS THE MEMORY LAYOUT: * * '000 : MT11 UPPER * '001 : MT11 LOWER * '002 : MT12 UPPER * '003 : MT12 LOWER * '004 : MT21 UPPER * '005 : MT21 LOWER * '006 : MT22 UPPER * '007 : MT22 LOWER * '010 : VT1 * '011 : VT2 * * FOR EVERY TRANSFORMATION, '12 WORDS HAVE TO BE RESERVED. * IN AN APPLICATION, A TRANFORMATION VARIABLE COULD BE * DECLARED WITH: * * TRANS BSS '12 * * * ********************************************************************************* * * * * M$INIT: INITIALISE MATRIX TO IDENTITY * * THE MATRIX ARGUMENT IS SET TO * * | 1.0 0.0 | * M= | | * | 0.0 1.0 | * * WICH RESULTS TO THE IDENTITY TRANSFORMATION. * * JST M$INIT * DAC MATRIX POINTER TO A MATRIX * * * * M$MUL: MATRIX MULTIPLICATION * * JST M$MUL * DAC TARGET POINTER TO TARGET MATRIX * DAC MATRIX1 POINTER TO LEFT MATRIX * DAC MATRIX2 POINTER TO RIGHT MATRIX * DAC 0 FOR FORTRAN IV COMPATIBILITY * * * * M$APLI: APPLY MATRIX TO VECTOR * * THIS ROUTINE CONVERTS THE VECTOR ELEMENTS TO FLOATING POINT VALUES, * APPLIES THE TRANSFORMATION TO THEM AND ROUNDS THE RESULTS BACK TO * INTEGER VALUES. THEN IT SAVES THE NEW VECTOR IN THE PLACE OF THE * OLD VECTOR. * * JST M$APLI * DAC MATRIX MATRIX TO APPLY * DAC VECTOR VECTOR TO TRANSFORM * DAC 0 FOR FORTRAN IV COMPATIBILITY * * * M$APII: APPLY MATRIX TO PAIR OF INTEGERS AS VECTOR * * THIS ROUTINE USES TWO DISTINCT INTEGER POINTERS INSTEAD OF ONE VECTOR * POINTER. THE REST OF THE BEHAVIOR IS EXACTLY LIKE M$APL. * * JST M$APLI * DAC MATRIX MATRIX TO APPLY * DAC X X COORDINATE OF ARGUMENT VECTOR * DAC Y Y COORDINATE OF ARGUMENT VECTOR * * * M$ROT: ROTATE MATRIX * * THIS ROUTINE TAKES A MATRIX AND ADDS A ROTATION TO IT. * INTERNALLY, THE ROUTINE CREATES A ROTATION MATRIX AND THEN * MULTIPLIES IT WITH THE ARGUMENT MATRIX. THE ROTATION IS SPECIFIED * COUNTERCLOCKWISE FORWARD, ANGLE IN RADIANT. * THE ANGLE ARGUMENT IS A SINGLE PRECISION FLOATING POINT NUMER * TAKING TWO WORDS TO STORE. * * JST M$ROT * DAC MATRIX MATRIX TO MODIFY * DAC ANGLE RADIANT ANGLE * * * M$SCLE: SCALE MATRIX * * THIS ROUTINE WORKS SIMILAR TO M$ROT BUT SCALES THE ARGUMENT MATRIX. * THE SCALE FACTOR IS A FLOATING POINT NUMBER. LIKE THE ROTATION ANGLE. * * JST M$SCLE * DAC MATRIX MATRIX TO MODIFY * DAC SCALE SCALE FACTOR * * ******************************************************************************** * **** EXPORTED SYMBOLS * SUBR MATRIX,INIT JUST A FANCY LABEL SUBR M$INIT,INIT INITIALISE MATRIX SUBR M$MUL,MUL MATRIX MULTIPLICATION SUBR M$APLI,APLI APPLY MATRIX TO INTEGER VECTOR SUBR M$APII,APII APPLY MATRIX TO PAIR OF INTEGERS SUBR M$ROT,ROT ADD ROTATION TO MATRIX SUBR M$SCLE,SCLE SCALE MATRIX * SUBR A$INIT,AFIN INITIALISE AFFINE TRANSFORMATION * * ******************************************************************************** * * REL RELOCATEABLE MODE * * ******************************************************************************** * * **** INITIALIZE AFFINE TRANSFORMATION * AFIN DAC ** LDA* AFIN STA AFI1 STORE ARGUMENT POINTER LDX AFIN LOAD INTO INDEX REGISTER, TOO IRS AFIN TALLY RETURN ADDRESS * JST INIT MATRIX INIT AFI1 DAC ** * CRA STA 8,1 CLEAR FIRST VECTOR ELEMENT STA 9,1 CLEAR SECOND VECTOR ELEMENT * JMP* AFIN RETURN TO CALLER * * ******************************************************************************** * * **** INITIALIZE MATRIX * * THIS ROUTINE SHOULD BE IMPROVED BY SUPPLYING * A FLOATING POINT 1.0 CONSTANT! * **************************************** * INIT DAC ** LDX* INIT LOAD INDEX REGISTER WITH ADDRESS OF MATRIX LDA* INIT LOAD MATRIX ADDRESS STA IM11 STORE POINTER TO FIRST ELEMENT (A11) ADD =6 IM12,IM21 ARE NOT TO BE INITIALISED WITH FP DATA STA IM22 STORE POINTER TO FOURTH ELEMENT (A22) IRS INIT CORRECT RETURN ADDRESS * CRA INITIALISE STA 2,1 A12 STA 3,1 STA 4,1 A21 STA 5,1 CALL FLOAT GENERATE FLOATING POINT 1.0 DAC ONE CONSTANT INTEGER 1 CALL H$22 STORE FLOATING POINT IM11 DEC 0 CALL H$22 IM22 DEC 0 * JMP* INIT RETURN. * * ******************************************************************************** * * **** MATRIX MULTIPLICATION * * C = A * B * * | a11 a12 | | b11 b12 | * = | | * | | * | a21 a22 | | b21 b22 | * * | (a11*b11) (a21*b12) | * = | | * | (a12*b21) (a22*b22) | * * CALL: * JST MUL * DAC MC * DAC MA * DAC MB * **************************************** * MUL DAC ** LDX* MUL * LDA* MUL STA PC11 ADD =2 STA PC12 ADD =2 STA PC21 ADD =2 STA PC22 IRS MUL * LDA* MUL STA PA11 ADD =2 STA PA12 ADD =2 STA PA21 ADD =2 STA PA22 ADD =2 * IRS MUL * LDA* MUL STA PB11 ADD =2 STA PB12 ADD =2 STA PB21 ADD =2 STA PB22 ADD =2 * IRS MUL IRS MUL * * a11 a12 b11 b12 a11*b11 a21*b12 * a21 a22 b21 b22 a12*b21 a22*b22 * CALL L$22 LOAD REAL PA11 DAC 0 CALL M$22 MULTIPLY PB11 DAC 0 CALL H$22 STORE PC11 DEC 0 * CALL L$22 PA21 DEC 0 CALL M$22 PB12 DEC 0 CALL H$22 PC12 DEC 0 * CALL L$22 PA12 DEC 0 CALL M$22 PB21 DEC 0 CALL H$22 PC21 DEC 0 * CALL L$22 PA22 DEC 0 CALL M$22 PB22 DEC 0 CALL H$22 PC22 DEC 0 * * JMP* MUL RETURN. * * ******************************************************************************** * * **** SCALE MATRIX * SCLE DAC ** SCALE MATRIX LDX* SCLE * LDA* SCLE GET MATRIX BASE ADDRESS STA SM11 STA TM11 ADD =6 STA SM22 STA TM22 IRS SCLE LDA* SCLE STA SX STA SY IRS SCLE TALLY RETURN ADDRESS * CALL L$22 SM11 DAC 0 CALL M$22 SX DAC 0 CALL H$22 TM11 DAC 0 * CALL L$22 SM22 DAC 0 CALL M$22 SY DAC 0 CALL H$22 TM22 DAC 0 * JMP* SCLE * * ******************************************************************************** * * **** ADD ROTATION TO MATRIX * * * M = M * MROT * * | M11 M12 | | COS(X) -SIN(X)| * = | | * | | * | M21 M22 | | SIN( X) COS(X)| * * | M11*COS(X)+M12*SIN(X) M12*COS(X)-M11*SIN(X) | * = | | * | M21*COS(X)+M22*SIN(X) M22*COS(X)-M21*SIN(X) | * * CALL: * JST ROT * DAC MATRIX * DAC ANGLE * DAC 0 DON'T FORGET! * **************************************** * ROT DAC ** ENTRY * LDA* ROT GET MATRIX POINTER STA R111 M11, FIRST COPY STA R211 M11, SECOND COPY ADD =2 STA R112 STA R212 ADD =2 STA R121 STA R221 ADD =2 STA R122 STA R222 IRS ROT STA RA1 STA RA2 IRS ROT IRS ROT * * CALL SINX1 FLOATING POINT SINE RA1 DAC ** POINTER TO ANGLE LDA ='77 HLT CALL H$22 SAVE TO TMP1 DAC TMP1 CALL M$22 MULTIPLY R112 DAC ** M12 CALL H$22 STORE TO TMP3 DAC TMP3 CALL COSX1 FLOATING POINT COSINE RA2 DAC ** POINTER TO ANGLE CALL H$22 SAVE TO TMP2 DAC TMP2 CALL M$22 MULTIPLY R111 DAC ** M11 CALL A$22 ADD TMP3 DAC TMP3 CALL H$22 SAVE NEW M11 TO TMP3 DAC TMP3 * CALL L$22 LOAD SINE DAC TMP1 CALL M$22 MULTIPLY R212 DAC ** M12 CALL H$22 STORE TO TMP4 DAC TMP4 CALL L$22 LOAD COSINE CALL M$22 MULTIPLY R211 DAC ** CALL S$22 SUBSTRACT DAC TMP4 CALL H$22 SAVE TO NEW M12 R312 DAC ** CALL L$22 LOAD NEW M11 FROM TMP3 CALL H$22 AND SAVE TO NEW M11 R311 DAC ** * * CALL L$22 LOAD SINE CALL M$22 MULTIPLY R122 DAC ** M12 CALL H$22 STORE TO TMP3 DAC TMP3 CALL H$22 LOAD COSINE DAC TMP2 CALL M$22 MULTIPLY R121 DAC ** M11 CALL A$22 ADD TMP3 DAC TMP3 CALL H$22 SAVE NEW M11 TO TMP3 DAC TMP3 * CALL L$22 LOAD SINE DAC TMP1 CALL M$22 MULTIPLY R222 DAC ** M12 CALL H$22 STORE TO TMP4 DAC TMP4 CALL L$22 LOAD COSINE CALL M$22 MULTIPLY R221 DAC ** CALL S$22 SUBSTRACT DAC TMP4 CALL H$22 SAVE TO NEW M12 R322 DAC ** CALL L$22 LOAD NEW M11 FROM TMP3 CALL H$22 AND SAVE TO NEW M11 R321 DAC ** * * JMP* ROT RETURN. * * ******************************************************************************** * * **** APPLY MATRIX TO PAIR OF INTEGERS * * SETS UP MATRIX POINTERS AND VECTOR POINTERS. * THEN IT CALLS APL, THE REAL WORKING ROUTINE. * * CALL: * JST M$APII * DAC MATRIX * DAC X * DAC Y * DAC 0 DON'T FORGET! * **************************************** * APII DAC ** * LDA* APII STA MP11 ADD =2 STA MP12 ADD =2 STA MP21 ADD =2 STA MP22 IRS APII * LDA* APII STA XP1 STA XP2 IRS APII LDA* APII STA YP1 STA YP2 IRS APII IRS APII JST APL CALL REAL ROUTINE JMP* APII * ******************************************************************************** * * **** APPLY MATRIX TO VECTOR * * SETS UP MATRIX POINTERS AND VECTOR POINTERS. THEN IT CALLS APL, * THE REAL WORKING ROUTINE. * * CALL: * JST M$APLI * DAC MATRIX * DAC VECTOR * DAC 0 DON'T FORGET! * **************************************** * APLI DAC ** * LDA* APLI STA MP11 ADD =2 STA MP12 ADD =2 STA MP21 ADD =2 STA MP22 IRS APLI * LDA* APLI STA XP1 STA XP2 AOA STA YP1 STA YP2 IRS APLI IRS APLI JST APL CALL INTERNAL ROUTINE JMP* APLI RETURN. * * ******************************************************************************** * * **** INTERNAL ROUTINE OF M$APL AND M$APII. * * ALL DATA IS SET UP BY THE BOTH USER ROUTINES ABOVE. * **************************************** * APL DAC ** * CALL FLOAT LOAD SINGLE PRECISION FLOAT FROM 1-WORD INTEGER XP1 DAC 0 CALL M$22 MULTIPLY FLOAT*FLOAT MP11 DAC 0 CALL H$22 STORE FLOAT DAC TMP1 CALL FLOAT YP1 DAC 0 CALL M$22 MP12 DAC 0 CALL A$22 DAC TMP1 JST RND ROUND AND CONVERT TO INTEGER STA PA21 STORE NEW X VALUE INTO TEMPORARY LOCATION **** CALL FLOAT XP2 DAC 0 CALL M$22 MP21 DAC 0 CALL H$22 DAC TMP1 * CALL FLOAT YP2 DAC 0 CALL M$22 MP22 DAC 0 CALL A$22 DAC TMP1 JST RND NOW INTEGER IN AC STA* YP1 STORE NEW Y VALUE * LDA PA21 STA* XP1 JMP* APL RETURN TO CALLER. * * ******************************************************************************** * * **** ROUND FLOAT TO INTEGER ROUTINE * * THERE IS NO CORRECTLY WORKING ROUNDING ROUTINE IN THE LIBRARY. * SO THIS IS A WORKAROUND. ADDS 0.5 TO THE VALUE AND USES ONE * ONE OF THE TRUNCATE AND CONVERT ROUTINES. * THE ARGUMENT IS IN REGISTERS A/B, THE RESULT IS PUT INTO A. * **************************************** * RND DAC ** CALL A$22 ADD DAC HLF 0.5 CALL C$21 TRUNCATE TO INTEGER NOP JMP* RND * * ******************************************************************************** * * **** CONSTANTS * ONE DEC 1 HLF OCT '040100 CONSTANT 0.5 OCT '000000 * * ******************************************************************************** * **** VARIABLES * TMP1 BSS '2 TEMPORARY 2-WORD VARIABLE TMP2 BSS '2 " " " TMP3 BSS '2 " " " TMP4 BSS '2 " " " * * ******************************************************************************** * * **** END OF THE LINE * END * * ********************************************************************************