Sei sulla pagina 1di 7

MARRAY IDNT 1,0

NOLIST
INCLUDE MACROS.INC
LIST
ADDRMASK SET $0FFFFFE
ADRMSK DC.L ADDRMASK
*
BASE DC.L 0
* XREF BASE
* ENTRY POINTS INCLUDE:
* ??AND2, ??AND4 - MEMORY TO MEMORY 2/4 BYTE AND
* ??IOR2, ??IOR4 - MEMORY TO MEMORY 2/4 BYTE INCLUSIVE OR
* ??MSK2, ??MSK4 - MEMORY TO MEMORY 2/4 BYTE MASKING - result is
* set to 0 if source is 0, unchanged else
* ?? is DD, DI, ID, II - Direct/Indirect reference
* arg list is (DESTIN/RESULT, SOURCE, LENGTH (in units not in bytes))
*
* I?FLT2(ARRAY base,OFFSET,N) - Local (ie. windowed) weighted deriv.
* -- NOTE: the returned value is proportional to deriv. in a manner which
* depends on the value of N
* ? is D, I - Direct/Indirect reference
* OFFSET in words, 2**N is window (0< N <8) to either side
*
* ?W2SLP(ARRAY base,OFFSET,N) - Local (ie. windowed) weighted deriv.
* ? is I,J,K,L: J,K - Direct/I,L - Indirect reference
* I,J - return windowed slope*2; K,L - return slope
* OFFSET in words, N is window (0< N <64) to either side
*
* MUDEV?(array BASE,OFFSET,RESULT ARRAY,N) - MUltiple DEriVative
* ? is D, I - Direct/Indirect reference
* OFFSET in words, N is window (0< N <64) to either side
*
IIAND4 EQU *
XDEF IIAND4,DDAND4,DIAND4,IDAND4
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INAND4
IDAND4 EQU *
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVE.L 8(A7),D1
BRA.S INAND4
DIAND4 EQU *
MOVE.L 12(A7),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INAND4
DDAND4 EQU *
MOVE.L 12(A7),D0
MOVE.L 8(A7),D1
INAND4 EQU *
MOVEA.L 4(A7),A1
MOVE.L (A1),D2
SUBQ.L #1,D2
LSL.L #2,D2
AND.L ADRMSK(PC),D0
BEQ.S AND4NO0DST
MOVEA.L D0,A0
ANDI.B #$FE,D1
MOVEA.L D1,A1
FOR.L D0 = #0 TO D2 BY #4
DO.S
MOVE.L 0(A1,D0.L),D1
AND.L D1,0(A0,D0.L)
ENDF
AND4NO0DST EQU *
FNRET 3
IIAND2 EQU *
XDEF IIAND2,DDAND2,DIAND2,IDAND2
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INAND2
IDAND2 EQU *
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVE.L 8(A7),D1
BRA.S INAND2
DIAND2 EQU *
MOVE.L 12(A7),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INAND2
DDAND2 EQU *
MOVE.L 12(A7),D0
MOVE.L 8(A7),D1
INAND2 EQU *
MOVEA.L 4(A7),A1
MOVE.L (A1),D2
SUBQ.L #1,D2
LSL.L #1,D2
AND.L ADRMSK(PC),D0
BEQ.S AND2NO0DST
MOVEA.L D0,A0
ANDI.B #$FE,D1
MOVEA.L D1,A1
FOR.L D0 = #0 TO D2 BY #2
DO.S
MOVE.W 0(A1,D0.L),D1
AND.W D1,0(A0,D0.L)
ENDF
AND2NO0DST EQU *
FNRET 3
*
*
IIIOR4 EQU *
XDEF IIIOR4,DDIOR4,DIIOR4,IDIOR4
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INIOR4
IDIOR4 EQU *
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVE.L 8(A7),D1
BRA.S INIOR4
DIIOR4 EQU *
MOVE.L 12(A7),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INIOR4
DDIOR4 EQU *
MOVE.L 12(A7),D0
MOVE.L 8(A7),D1
INIOR4 EQU *
MOVEA.L 4(A7),A1
MOVE.L (A1),D2
SUBQ.L #1,D2
LSL.L #2,D2
AND.L ADRMSK(PC),D0
BEQ.S IOR4NO0DST
MOVEA.L D0,A0
ANDI.B #$FE,D1
MOVEA.L D1,A1
FOR.L D0 = #0 TO D2 BY #4
DO.S
MOVE.L 0(A1,D0.L),D1
OR.L D1,0(A0,D0.L)
ENDF
IOR4NO0DST EQU *
FNRET 3
IIIOR2 EQU *
XDEF IIIOR2,DDIOR2,DIIOR2,IDIOR2
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INIOR2
IDIOR2 EQU *
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVE.L 8(A7),D1
BRA.S INIOR2
DIIOR2 EQU *
MOVE.L 12(A7),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INIOR2
DDIOR2 EQU *
MOVE.L 12(A7),D0
MOVE.L 8(A7),D1
INIOR2 EQU *
MOVEA.L 4(A7),A1
MOVE.L (A1),D2
SUBQ.L #1,D2
LSL.L #1,D2
AND.L ADRMSK(PC),D0
BEQ.S IOR2NO0DST
MOVEA.L D0,A0
ANDI.B #$FE,D1
MOVEA.L D1,A1
FOR.L D0 = #0 TO D2 BY #2
DO.S
MOVE.W 0(A1,D0.L),D1
OR.W D1,0(A0,D0.L)
ENDF
IOR2NO0DST EQU *
FNRET 3
*
IIMSK4 EQU *
XDEF IIMSK4,DDMSK4,DIMSK4,IDMSK4
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INMSK4
IDMSK4 EQU *
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVE.L 8(A7),D1
BRA.S INMSK4
DIMSK4 EQU *
MOVE.L 12(A7),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INMSK4
DDMSK4 EQU *
MOVE.L 12(A7),D0
MOVE.L 8(A7),D1
INMSK4 EQU *
MOVEA.L 4(A7),A1
MOVE.L (A1),D2
SUBQ.L #1,D2
LSL.L #2,D2
AND.L ADRMSK(PC),D0
BEQ.S MSK4NO0DST
MOVEA.L D0,A0
ANDI.B #$FE,D1
MOVEA.L D1,A1
FOR.L D0 = #0 TO D2 BY #4
DO.S
MOVE.L 0(A1,D0.L),D1
AND.L D1,D1
BNE.S MSK4OK
MOVE.L #0,0(A0,D0.L)
MSK4OK EQU *
ENDF
MSK4NO0DST EQU *
FNRET 3
IIMSK2 EQU *
XDEF IIMSK2,DDMSK2,DIMSK2,IDMSK2
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INMSK2
IDMSK2 EQU *
MOVEA.L 12(A7),A0
MOVE.L (A0),D0
MOVE.L 8(A7),D1
BRA.S INMSK2
DIMSK2 EQU *
MOVE.L 12(A7),D0
MOVEA.L 8(A7),A1
MOVE.L (A1),D1
BRA.S INMSK2
DDMSK2 EQU *
MOVE.L 12(A7),D0
MOVE.L 8(A7),D1
INMSK2 EQU *
MOVEA.L 4(A7),A1
MOVE.L (A1),D2
SUBQ.L #1,D2
LSL.L #1,D2
AND.L ADRMSK(PC),D0
BEQ.S MSK2NO0DST
MOVEA.L D0,A0
ANDI.B #$FE,D1
MOVEA.L D1,A1
FOR.L D0 = #0 TO D2 BY #2
DO.S
MOVE.W 0(A1,D0.L),D1
AND.W D1,D1
BNE.S MSK2OK
MOVE.W #0,0(A0,D0.L)
MSK2OK EQU *
ENDF
MSK2NO0DST EQU *
FNRET 3
*
*
IDFLT2 EQU *
XDEF IDFLT2,IIFLT2
MOVE.L 12(A7),D0 argument 1 is address
BRA.S INFLAT2
IIFLT2 EQU *
MOVEA.L 12(A7),A0 argument 1 is pointer to address
MOVE.L (A0),D0
INFLAT2 EQU *
SAVREG
AND.L ADRMSK(PC),D0 no address trap, if passed bad argument
MOVEA.L D0,A0
*--
MOVEA.L 4(A5),A1 get N (third argument) and check limits
MOVE.L (A1),D5 0 < N < 8,
ANDI.L #$3FFFFFF8,D5 ? N > 8 ?
BEQ.S FLAT2N1OK N < 8
MOVEQ.L #4,D5 N > 8 so set N = 4
BRA.S FLAT2NEND
FLAT2N1OK EQU *
MOVE.L (A1),D5
ANDI.L #$80000000,D5 ? N < 0 ?
BNE.S FLAT2N0 N < 0 so set N = 3
MOVE.L (A1),D5
AND.L D5,D5 ? N = 0 ?
BEQ.S FLAT2N0 N = 0 so set N = 3
BRA.S FLAT2NEND N is OK!
FLAT2N0 EQU *
MOVEQ.L #3,D5
FLAT2NEND EQU *
*--
MOVEA.L 8(A5),A1 get OFFSET
MOVE.L (A1),D1
AND.L ADRMSK(PC),D1 no address trap, if passed bad argument
MOVEA.L D1,A2
*--
MOVEA.L A0,A1 Copy Base addr for addressing forward and back
XOR.L D1,D1 Clear working registers to be accumulators
MOVE.L D1,D0 D0 = ACCUM. / D1 = PARTIAL ACCUM.
*--
MOVEQ.L #1,D4 N (in D5) is Log2 of number of points
LSL.L D5,D4 D5 = 2 ** D4
SUBQ.L #2,D4 want 2 ** N - 1, using DBRA so extra -1
*-- the main processing loop begins here
FLAT2LOOP EQU *
ADDA.L A2,A0 increment forward pointer by offset
SUBA.L A2,A1 decrement backward pointer by offset
XOR.L D2,D2 clear TEMP register
*--
MOVE.W (A0),D2 get forward value
OR.W (A1),D2 get backward value OR'd on forward
ANDI.W #$C000,D2 is either skipit flag set?
BEQ.S FLAT2LOK it's cool, neither flag set
XOR.W D2,D2 some flag set zero it out and skip
BRA.S FLAT2LSKP
*--
FLAT2LOK EQU *
XOR.L D2,D2 Clear TEMP register for forward value
MOVE.L D2,D3 Clear TEMP register for backward value
MOVE.W (A0),D2 get forward value
MOVE.W (A0),D3 get backward value
SUB.L D3,D2 form the difference (signed) as a long word
*--
FLAT2LSKP EQU *
ADD.L D2,D1 form partial accumulation of differences
ADD.L D1,D0 form total accumulation
DBRA D4,FLAT2LOOP loop until d4 = -1
*-- end of main processing loop
ASR.L D5,D0 divide by 2**N
* MOVE.L D0,TEMPD0 save computed value
RSTREG RESTORE REGISTERS
* MOVE.L TEMPD0(PC),D0 recover computed value
FNRET 3 3 ARGUMENT FUNCTION RETURN - FORTRAN CALLING CONVENTION
*TEMPD0 DC.L 0
*
*
JW2SLP EQU *
XDEF IDFLT2,IIFLT2
MOVE.L 12(A7),D0 argument 1 is address
BRA.S INW2SLP
IW2SLP EQU *
MOVEA.L 12(A7),A0 argument 1 is pointer to address
MOVE.L (A0),D0
INW2SLP EQU *
SAVREG
MOVEQ.L #0,D6
BRA.S NIW2SLP
KW2SLP EQU *
XDEF IDFLT2,IIFLT2
MOVE.L 12(A7),D0 argument 1 is address
BRA.S W2SLPIN
LW2SLP EQU *
MOVEA.L 12(A7),A0 argument 1 is pointer to address
MOVE.L (A0),D0
W2SLPIN EQU *
SAVREG
MOVEQ.L #1,D6
NIW2SLP EQU *
AND.L ADRMSK(PC),D0 no address trap, if passed bad argument
MOVEA.L D0,A0
XDEF IW2SLP,JW2SLP,KW2SLP,LW2SLP
*--
MOVEA.L 4(A5),A1 get N (fourth argument) and check limits
MOVE.L (A1),D1 0 < N < 64,
ANDI.L #$3FFFFFC0,D1 ? N > 63 ?
BEQ.S W2SLPN1OK N < 64
MOVEQ.L #32,D1 N > 63 so set N = 32
BRA.S W2SLPNEND
W2SLPN1OK EQU *
MOVE.L (A1),D1
ANDI.L #$80000000,D1 ? N < 0 ?
BNE.S W2SLPN0 N < 0 so set N = 8
MOVE.L (A1),D1
AND.L D1,D1 ? N = 0 ?
BEQ.S W2SLPN0 N = 0 so set N = 8
BRA.S W2SLPNEND N is OK!
W2SLPN0 EQU *
MOVEQ.L #8,D1
W2SLPNEND EQU *
*--
MOVEA.L 8(A5),A1 get OFFSET
MOVE.L (A1),D0
AND.L ADRMSK(PC),D0 no address trap, if passed bad argument
*--
MOVEA.L D0,A2 offset in A2
MOVEA.L A0,A1
MOVE.L D1,D0 limit in D0
XOR.L D1,D1
MOVE.L D1,D2
MOVE.L D1,D3
MOVE.L D1,D7
*-- the main processing loop begins here
W2SLPLOOP EQU *
ADDA.L D0,A0 increment forward pointer by offset
SUBA.L D0,A1 decrement backward pointer by offset
ADD.L D2,D7 D7 = K (K-1)/2
ADDQ.L #1,D2 D2 = K
ADD.L D2,D3 D3 = K (K+1)/2
*--
MOVE.W (A0),D4 get forward value
OR.W (A1),D4 get backward value OR'd on forward
ANDI.W #$C000,D4 is either skipit flag set?
BEQ.S W2SLPLOK it's cool, neither flag set
BRA.S W2SLPLOUT UNCOOL - THEN END LOOP
*--
W2SLPLOK EQU *
MOVE.W (A0),D4 get forward value
EXT.L D4 convert word to long
MOVE.W (A0),D5 get backward value
EXT.L D5 convert word to long
SUB.L D5,D4 form the difference (signed) as a long word
MOVE.L D7,D5 get K(K-1)/2
ADD.L D3,D5 add K(K+1)/2 to get K*K
DIVS D5,D4 divide by K*K
EXT.L D4 convert word to long
ADD.L D4,D1 accumulate
CMP.L D2,D0
BLO.S W2SLPLOOP
W2SLPLOUT EQU *
*--
MOVE.L D1,D0
ASR.L D6,D0
RSTREG
FNRET 3
*
*
MUDEVD EQU *
MOVE.L 16(A7),D0
BRA.S INMUDEV
MUDEVI EQU *
MOVEA.L 16(A7),A0
MOVE.L (A0),D0
INMUDEV EQU *
SAVREG
AND.L ADRMSK(PC),D0 no address trap, if passed bad argument
MOVEA.L D0,A0
*--
MOVEA.L 4(A5),A1 get N (fourth argument) and check limits
MOVE.L (A1),D1 0 < N < 64,
ANDI.L #$3FFFFFC0,D1 ? N > 63 ?
BEQ.S MUDEVN1OK N < 64
MOVEQ.L #32,D1 N > 63 so set N = 32
BRA.S MUDEVNEND
MUDEVN1OK EQU *
MOVE.L (A1),D1
ANDI.L #$80000000,D1 ? N < 0 ?
BNE.S MUDEVN0 N < 0 so set N = 8
MOVE.L (A1),D1
AND.L D1,D1 ? N = 0 ?
BEQ.S MUDEVN0 N = 0 so set N = 8
BRA.S MUDEVNEND N is OK!
MUDEVN0 EQU *
MOVEQ.L #8,D1
MUDEVNEND EQU *
*--
MOVEA.L 12(A5),A1 get OFFSET
MOVE.L (A1),D0
AND.L ADRMSK(PC),D0 no address trap, if passed bad argument
*--
MOVE.L 8(A5),D1 get RESULTS address
AND.L ADRMSK(PC),D1 no address trap, if passed bad argument
MOVEA.L D1,A2
*--
MOVEQ.L #0,D2
MOVEA.L A0,A1
*-- the main processing loop begins here
MUDEVLOOP EQU *
ADDQ.L #1,D2
ADDA.L D0,A0 increment forward pointer by offset
SUBA.L D0,A1 decrement backward pointer by offset
*--
MOVE.W (A0),D3 get forward value
OR.W (A1),D3 get backward value OR'd on forward
ANDI.W #$C000,D3 is either skipit flag set?
BEQ.S MUDEVLOK it's cool, neither flag set
XOR.W D3,D3 some flag set zero it out and skip
BRA.S MUDEVLSKP
*--
MUDEVLOK EQU *
MOVE.W (A0),D3 get forward value
EXT.L D3 convert word to long
MOVE.W (A0),D4 get backward value
EXT.L D4 convert word to long
SUB.L D4,D3 form the difference (signed) as a long word
ASR.L #1,D3 divide by 2
DIVS.W D2,D3 divide by current index
*-- result is approximation to f'(0) based on +/- index
MUDEVLSKP EQU *
MOVE.W D3,(A2)+ store as next entry in result array
*--
CMP.W D2,D1 finished yet?
BLT.S MUDEVLOOP
*--
RSTREG
FNRET 4
*
END

Potrebbero piacerti anche