|
|
1.1 ! root 1: # 3B1 Assembler - primitives for multi-precision math on the MC68010 ! 2: # ! 3: # Written by Rob Stampfli 19-Oct-92 for 3B1 ! 4: # Assembler: 3B1 native assembler ! 5: # ! 6: # Note that the function P_SETP of the Intel primitives is not used. ! 7: # `set_precision' has to be defined just like in `PORTABLE' mode. ! 8: ! 9: global global_precision ! 10: global P_ADDC ! 11: global P_SUBB ! 12: global P_ROTL ! 13: global P_SETP ! 14: global P_SMUL ! 15: ! 16: text ! 17: ! 18: #boolean P_ADDC(unitptr r1, unitptr r2, boolean carry); ! 19: # /* multiprecision add with carry r2 to r1, result in r1 */ ! 20: #Parameters: A0.l: r1, A1.l: r2, D0.b: carry ! 21: #Result: D0.b: new carry ! 22: #Modifies: D0-D2/A0-A1 ! 23: ! 24: P_ADDC: mov.l 4(%sp),%a0 # fetch first argument: r1 ! 25: mov.l 8(%sp),%a1 # fetch second argument: r2 ! 26: mov.l 12(%sp),%d1 # fetch third argument: carry ! 27: mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg ! 28: mov.w global_precision,%d2 # fetch # of 16 bit units ! 29: mov.w %d2,%d0 # copy units ! 30: lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes) ! 31: add.w %d0,%a0 # point r1 to 1 past least significant unit ! 32: add.w %d0,%a1 # point r2 to 1 past least significant unit ! 33: lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1 ! 34: and.w &15,%d2 # = (units%16); # times thru loop2 ! 35: lsr.b &1,%d1 # set X-bit as specified by carry arg ! 36: bra adbf1 ! 37: aloop1: #REPT 8 # 16 units per loop ! 38: addx.l -(%a1),-(%a0) ! 39: addx.l -(%a1),-(%a0) ! 40: addx.l -(%a1),-(%a0) ! 41: addx.l -(%a1),-(%a0) ! 42: addx.l -(%a1),-(%a0) ! 43: addx.l -(%a1),-(%a0) ! 44: addx.l -(%a1),-(%a0) ! 45: addx.l -(%a1),-(%a0) ! 46: adbf1: dbf %d0,aloop1 ! 47: bra adbf2 ! 48: aloop2: addx.w -(%a1),-(%a0) ! 49: adbf2: dbf %d2,aloop2 ! 50: scs %d0 #set returned carry ! 51: mov.l (%sp)+,%d2 # restore d2 ! 52: rts ! 53: ! 54: #boolean P_SUBB(unitptr r1, unitptr r2, boolean borrow); ! 55: # /* multiprecision subtract with borrow, r2 from r1, result in r1 */ ! 56: #Parameters: A0.l: r1, A1.l: r2, D0.b: borrow ! 57: #Result: D0.b: new borrow ! 58: #Modifies: D0-D2/A0/A1 ! 59: ! 60: P_SUBB: mov.l 4(%sp),%a0 # fetch first argument: r1 ! 61: mov.l 8(%sp),%a1 # fetch second argument: r2 ! 62: mov.l 12(%sp),%d1 # fetch third argument: carry ! 63: mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg ! 64: mov.w global_precision,%d2 # fetch # of 16 bit units ! 65: mov.w %d2,%d0 # copy units ! 66: lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes) ! 67: add.w %d0,%a0 # point r1 to 1 past least significant unit ! 68: add.w %d0,%a1 # point r2 to 1 past least significant unit ! 69: lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1 ! 70: and.w &15,%d2 # = (units%16); # times thru loop2 ! 71: lsr.b &1,%d1 # set X-bit as specified by carry arg ! 72: bra bdbf1 ! 73: bloop1: #REPT 8 # 16 units per loop ! 74: subx.l -(%a1),-(%a0) ! 75: subx.l -(%a1),-(%a0) ! 76: subx.l -(%a1),-(%a0) ! 77: subx.l -(%a1),-(%a0) ! 78: subx.l -(%a1),-(%a0) ! 79: subx.l -(%a1),-(%a0) ! 80: subx.l -(%a1),-(%a0) ! 81: subx.l -(%a1),-(%a0) ! 82: bdbf1: dbf %d0,bloop1 ! 83: bra bdbf2 ! 84: bloop2: subx.w -(%a1),-(%a0) ! 85: bdbf2: dbf %d2,bloop2 ! 86: scs %d0 # set returned carry ! 87: mov.l (%sp)+,%d2 # restore d2 ! 88: rts ! 89: ! 90: #boolean P_ROTL(unitptr r1, boolean carry); ! 91: # /* multiprecision rotate left 1 bit with carry, result in r1. */ ! 92: #Parameters: A0.l: r1, D0.b: carry ! 93: #Result: D0.b: new carry ! 94: #Modifies: D0-D2/A0 ! 95: ! 96: P_ROTL: mov.l 4(%sp),%a0 # fetch first argument: r1 ! 97: mov.l 8(%sp),%d1 # fetch second argument: carry ! 98: mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg ! 99: mov.w global_precision,%d2 # fetch # of 16 bit units ! 100: mov.w %d2,%d0 # copy units ! 101: lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes) ! 102: add.w %d0,%a0 # point r1 to 1 past least significant unit ! 103: lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1 ! 104: and.w &15,%d2 # = (units%16); # times thru loop2 ! 105: lsr.b &1,%d1 # set X-bit as specified by carry arg ! 106: bra cdbf1 ! 107: cloop1: #REPT 16 # note roxl.l not valid on 68010 ! 108: roxl.w &1,-(%a0) ! 109: roxl.w &1,-(%a0) ! 110: roxl.w &1,-(%a0) ! 111: roxl.w &1,-(%a0) ! 112: roxl.w &1,-(%a0) ! 113: roxl.w &1,-(%a0) ! 114: roxl.w &1,-(%a0) ! 115: roxl.w &1,-(%a0) ! 116: roxl.w &1,-(%a0) ! 117: roxl.w &1,-(%a0) ! 118: roxl.w &1,-(%a0) ! 119: roxl.w &1,-(%a0) ! 120: roxl.w &1,-(%a0) ! 121: roxl.w &1,-(%a0) ! 122: roxl.w &1,-(%a0) ! 123: roxl.w &1,-(%a0) ! 124: cdbf1: dbf %d0,cloop1 ! 125: bra cdbf2 ! 126: cloop2: roxl.w &1,-(%a0) ! 127: cdbf2: dbf %d2,cloop2 ! 128: scs %d0 # set returned carry ! 129: mov.l (%sp)+,%d2 # restore d2 ! 130: rts ! 131: ! 132: #void P_SETP(short nbits); ! 133: # /* sets working precision to specified number of bits. */ ! 134: # /* only to minimize portation differences */ ! 135: #Parameters: -- ! 136: #Result: -- ! 137: ! 138: P_SETP: rts ! 139: ! 140: #void P_SMUL(MULTUNIT *prod, MULTUNIT *multiplicand, MULTUNIT multiplier) ! 141: # /* multiprecision multiply */ ! 142: #Parameters: A0.l: prod, A1.l: multiplicand, D0.w: multiplier ! 143: #Modifies: D0-D4/A0-A1 ! 144: #Result: -- ! 145: #Note: prod and multiplicand have already been adjusted to point to LSB ! 146: # prior to making the call. ! 147: ! 148: P_SMUL: mov.l 4(%sp),%a0 # fetch first argument: prod ! 149: mov.l 8(%sp),%a1 # fetch second argument: multiplicand ! 150: mov.l 12(%sp),%d0 # fetch third argument: multiplier ! 151: mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg ! 152: mov.l %d3,-(%sp) # save d3 -- not a Unix-PC scratch reg ! 153: mov.l %d4,-(%sp) # save d4 -- not a Unix-PC scratch reg ! 154: clr.l %d2 # clear the carry register ! 155: clr.l %d4 # clear upper half of temp reg for prod ! 156: add.w &2,%a0 # position prod to 1 beyond LSB ! 157: add.w &2,%a1 # position multiplicand to 1 beyond LSB ! 158: mov.w global_precision,%d3 # fetch size of multiplicand ! 159: bra ddbf1 ! 160: ! 161: dloop: mov.w -(%a1),%d1 # fetch multiplicand ! 162: mulu.w %d0,%d1 # multiply by multiplier ! 163: mov.w -(%a0),%d4 # fetch prod ! 164: add.l %d4,%d1 # add in prod ! 165: add.l %d2,%d1 # add in carry ! 166: mov.w %d1,(%a0) # store result back to prod ! 167: swap.w %d1 # fetch carry info (upper 16 bits of mult) ! 168: mov.w %d1,%d2 # and move it into carry ! 169: ddbf1: dbf %d3,dloop ! 170: ! 171: mov.w %d2,-(%a0) # store carry ! 172: mov.l (%sp)+,%d4 ! 173: mov.l (%sp)+,%d3 ! 174: mov.l (%sp)+,%d2 ! 175: rts
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.