Up

Here is the complete map of the HP35 ROM 1 (256 instructions of 10 bits each).

ROM 1 contains the code for:
- Cordic routines for trigo and inverse trigo (tan, sin, cos, arc tan, arc sin, arc cos)
- root square routine,
- part of addition, multiplication and division routines.

 

01000:   go to tan13 Control comes from “tan14”  01377 (Cordic rotations)
01001: tan15: a exchange b[w] End of Cordic rotations, A=X C=Y (vectors)
01002:   jsb tnm11 Goto normalize both vector numbers
01003:   stack -> a    
01004:   jsb tnm11 Get the other from the stack
01005:   stack -> a    
01006:   if s9 = 0 If cos case, we need cot(θ) then we exchange X and Y
01007:        then go to tan16 to compute cot(θ) in place of tan(θ)
01010:   a exchange c[w]    
01011: tan16: if s5 = 0 If tan(θ) the exit door is “asn12”
01012:        then go to asn12 Else if  sin or cos :  
01013:   0 -> c[s] we compute tan calling “div11” X/Y
01014:   jsb div11    
01015: l01015: c -> stack Code for arc sin  
01016:   jsb mpy11 compute tan2 to use in formula sin= tan / SQR (1 + tan2 )
01017:   jsb add10 “add10” makes 1 +  tan2     
01020:   jsb sqt11 get other vector from the stack before calling “div11” 
01021:   stack -> a    
01022: asn12: jsb div11 “asn12” : normal path for  tan(θ) computing A/C or tan/SQR(1 + tan2 )
01023:   if s10 = 0 if direct trigo returns via “rtn12” to dsp loop 0333
01024:        then go to rtn12 or execute a return if came from a jsb in Cordic rotations
01025: atn11: 0 -> a[w] arc tan main entry point  
01026:   a + 1 -> a[p] arc tan(Z) angle Z in C  
01027:   a -> b[m] B=1  
01030:   a exchange c[m] The “atn12” loop aligns A and B according exp of C
01031: atn12: c - 1 -> c[x]    
01032:   shift right b[wp]    
01033:   if c[xs] = 0    
01034:        then go to atn12 “atn13”:  A= Z /10  B= X/100  C= exp
01035: atn13: shift right a[wp]    
01036:   c + 1 -> c[x]    
01037:   if no carry go to atn13    
01040:   shift right a[w] A = Z  
01041:   shift right b[w] B = qj  
01042:   c -> stack C = X  
01043: atn14: b exchange c[w]    
01044:   go to atn18 Goto Cordic rotations (pseudo division)
01045: sqt11: b exchange c[w] SQR(X) Entry point  
01046:   4 -> p A=X B=X C=0  
01047:   go to sqt14 p=4  
01050: tnm11: c -> stack Called in tan15 (means “to normalization”: relay to nrm21, via add15)
01051:   a exchange c[w] A is popped from stack  
01052:   if c[p] = 0 C is pushed, p=12  
01053:        then go to tnm12    
01054:   0 - c -> c[w]    
01055: tnm12: c -> a[w] absolute value of C is copied to A
01056:   b -> c[x] format registers to normalize C with std routine “nrm21”
01057:   go to add15    
01060:   c -> a[w] The BIG SWITCH  
01061:   if s1 = 0                                     S1      S5    S9    S10         (S1 = 0 : SQR)
01062:        then go to sqt11 TAN                             1                                       (S10=0 : direct trigo)
01063:   if s10 = 0 ARC TAN                    1                          1
01064:        then go to l01155 SIN                               1        1
01065:   if s5 = 0 ARC SIN                      1        1                1
01066:        then go to atn11 COS                              1       1       1
01067:   0 - c - 1 -> c[s] ARC COS                     1       1       1        1
01070:   a exchange c[s]    
01071:   go to l01015    
01072: atn15: shift right b[wp] ARC TAN  
01073: atn16: a - 1 -> a[s] 1) Cordic rotations to compute the qj – pseudo quotients)
01074:   if no carry go to atn15 To reduce component Y to zero (pseudo division)
01075:   c + 1 -> c[s]    
01076:   a exchange b[wp]    
01077:   a + c -> c[wp] 01077 is the rotation  
01100:   a exchange b[w]    
01101: atn18: a -> b[w] pseudo division entry point is “atn18”
01102:   a - c -> a[wp]    
01103:   if no carry go to atn16    
01104:   stack -> a 2) Pseudo multiplication (starting at 01104)
01105:   shift right a[w] ∑ qj tan-1 10 –j    
01106:   a exchange c[wp] use stack to store intermediate results (top of stack lost)
01107:   a exchange b[w]    
01110:   shift left a[wp]    
01111:   c -> stack    
01112:   a + 1 -> a[s] 01114 Test for more rotations (max = 5)
01113:   a + 1 -> a[s]    
01114:   if no carry go to atn14    
01115:   0 -> c[w] No more rotations  
01116:   0 -> b[x] Clear context  
01117:   shift right a[ms] And compute Y/X  
01120:   jsb div14 If direct trigo S1=1 then after “div” : rtn12 and return at 01121
01121:   c - 1 -> c[p] Control gets back here via “rtn11”, “rtn12” and “return”
01122:   stack -> a    
01123:   a exchange c[w] Prepare context  
01124:   4 -> p    
01125:   jsb pqo13 Call pseudo multiplication PM ( note in pqo13, select rom 2, use the log routines)
01126:   6 -> p load constant arc (0.0001) = 0.000099999999666
01127:   jsb pmu11 and do the PM  
01130:   8 -> p load arc ( 0.001) = 0.000999999666
01131:   jsb pmu11 and do the PM  
01132:   2 -> p load arc ( 0.01) = 0.0099996666866
01133:   load constant 8    
01134:   10 -> p    
01135:   jsb pmu11 and do the PM  
01136:   jsb atcd1 load arc ( 0.1) = 0.099668652496
01137:   jsb pmu11 and do the PM  
01140:   jsb atc1 load arc ( 1) = π / 4  
01141:   shift left a[w] and do the PM  
01142:   jsb pmu11 Angle in A in radians  
01143:   b -> c[w]    
01144:   jsb add15 goto normalize  
01145:   jsb atc1 convert to degree (load π / 4)
01146:   c + c -> c[w] double it  
01147:   jsb div11 divide A by π / 2 so a multiplication by 90 will do the job
01150:   if s9 = 0 If S9 = 0 arc tan, arc sin  
01151:        then go to l01154    
01152:   0 - c - 1 -> c[s] Else it’s “arc cos” : negate previous result : - arc sin
01153:   jsb add10 add it to π / 2 ( arc cos = π / 2 – arc sin)
01154: l01154: 0 -> s1 To return via “rtn2” at 01160 and in “rtn11” (after “mpy11”:nrm21,rtn11, rtn12, 0333.
01155: l01155: 0 -> c[w] Direct Trigo (tan, cos, sin)  
01156:   c - 1 -> c[p] Build number 90 in C  
01157:   c + 1 -> c[x]    
01160:   if s1 = 0 Multiplication in “mpy11” will convert  to degree
01161:        then go to mpy11    
01162:   jsb div11 θ/90 in (θ/90 x π / 2 = π / 180)
01163:   jsb atc1    
01164:   c + c -> c[w]    
01165:   jsb mpy11    
01166:   jsb atc1 load π / 4  
01167:   c + c -> c[w] double  
01170:   c + c -> c[w] double = π  
01171:   jsb rtn11 exit door when S1=0 (SQR)
01172:   c + c -> c[w] double again = 2π  
01173:   jsb pre11 angle prescaling : 0 <= θ < 2π
01174:   jsb atc1 load π / 4, arc tan(1)  
01175:   10 -> p    
01176:   jsb pqo11 pseudo division  
01177:   jsb atcd1 load arc tan(0.1)  
01200:   8 -> p    
01201:   jsb pqo12 2nd pdiv  
01202:   2 -> p load arc tan(0.01)  
01203:   load constant 8    
01204:   6 -> p 3th pdiv  
01205:   jsb pqo11 load arc tan(0.001)  
01206:   4 -> p 4th pdiv  
01207:   jsb pqo11 load arc tan(0.0001)  
01210:   jsb pqo11 5th pdiv  
01211:   a exchange b[w]    
01212:   shift right c[w]    
01213:   13 -> p    
01214:   load constant 5 remainder in A, pq in B  
01215:   go to tan14 goto cordic PM 5 times  
01216: atcd1: 6 -> p Forge constant constant arc tan(0.1)  with pattern “865249”
01217:   load constant 8 See note on Cst forging  
01220:   load constant 6    
01221:   load constant 5    
01222:   load constant 2    
01223:   load constant 4    
01224:   load constant 9    
01225: rtn11: if s1 = 0 Locally S1 is used to switch return from “asn12”  
01226:        then go to rtn12 via rtn12 and finally to 0333 -> dsp loop
01227:   return if S1=1 = trigo, if S1=0 ) ln and e^x ; s1 is set ot zero at 01154
01230: add10: 0 -> a[w] Arc cos  
01231:   a + 1 -> a[p]  = π / 2 – arc sin  
01232:   select rom 0   ; -> l00233
01233: pmu11: select rom 2   WARNING destructured code : read it dynamically
01234: pqo11: shift left a[w] Pseudo division entry point in direct trigo
01235: pqo12: shift right b[ms]    
01236:   b exchange c[w] Prepare registers  
01237:   go to pqo16    
01240: pqo15: c + 1 -> c[s]    
01241: pqo16: a - b -> a[w] (01241) the pseudo division, by repeated subtractions
01242:   if no carry go to pqo15    
01243:   a + b -> a[w] Restore previous  
01244: pqo13: select rom 2 goto 02245 (rom 2) “pqo23” to load constant and do the pm
01245: mpy11: select rom 2 Computes tan2   and cot2 in sin and cos formulas
01246: div11: a - c -> c[x] A/C in direct trio (vectors dividing)
01247:   select rom 2    
01250: sqt15: c + 1 -> c[p]    
01251: sqt16: a - c -> a[w] 12 bit mantissa longhand routine
01252:   if no carry go to sqt15 using a 5delta remainder  
01253:   a + c -> a[w]    
01254:   shift left a[w]    
01255:   p - 1 -> p    
01256: sqt17: shift right c[wp]    
01257:   if p # 0    
01260:        then go to sqt16    
01261:   go to tnm12 goto normalization  
01262: div14: c + 1 -> c[p] p = 12 Core dividing loop
01263: div15: a - b -> a[ms] C holds subtractions count  
01264:   if no carry go to div14 performs division by repeated subtractions
01265:   a + b -> a[ms] here we reverse gear : on step too far
01266:   shift left a[ms]    
01267:   p - 1 -> p sweeps C from 12 to 0  
01270:   if p # 0    
01271:        then go to div15 Routine Entry point = 01271 !!
01272:   go to tnm12 goto normalization  
01273: sqt12: p - 1 -> p    
01274:   a + b -> a[ms]    
01275:   if no carry go to sqt18 SQR(negative) -> error or loop to build delta remainder
01276:   select rom 0 go to blinking display 0277  
01277: add12: c - 1 -> c[xs] came from 00276  
01300:   c - 1 -> c[xs] Restore exp C  
01301:   0 -> a[x] zero exp A  
01302:   a - c -> a[s] exp comparison  
01303:   if a[s] >= 1 if exp C < exp A  
01304:        then go to add13    
01305:   select rom 2 goto core adder 02306  
01306: add13: if a >= b[m] else compare fraction part  
01307:        then go to add14 if FP A < FP B then change sign before subtraction
01310:   0 - c - 1 -> c[s]    
01311:   a exchange b[w]    
01312: add14: a - b -> a[w] simply perform subtraction in the other case
01313: add15: select rom 2 goto normalize at "nrm21"  
01314: atc1: 0 -> c[w] load π / 4  
01315:   11 -> p    
01316:   load constant 7    
01317:   load constant 8    
01320:   load constant 5    
01321:   load constant 3    
01322:   load constant 9    
01323:   load constant 8    
01324:   load constant 1    
01325:   load constant 6    
01326:   load constant 3    
01327:   load constant 5    
01330:   12 -> p    
01331:   return    
01332: rtn12: select rom 0 back to the LOOP 0333  
01333: sqt18: a + b -> a[x] mantissa multimplied by 5  
01334:   if no carry go to sqt14 p point 5 to 0  
01335:   c - 1 -> c[p]    
01336: sqt14: c + 1 -> c[s] delta remainder is built  
01337:   if p # 0    
01340:        then go to sqt12    
01341:   a exchange c[x] prepare registers for core routine
01342:   0 -> a[x]    
01343:   if c[p] >= 1 A and C are aligned  
01344:        then go to sqt13    
01345:   shift right a[w]    
01346: sqt13: shift right c[w]    
01347:   b exchange c[x]    
01350:   0 -> c[x]    
01351:   12 -> p    
01352:   go to sqt17 go to core routine  
01353: pre11: select rom 2 go to prescaling in rom 2 ("pre21")
01354: tan18: shift right b[wp] do the SR twice  
01355:   shift right b[wp]    
01356: tan19: c - 1 -> c[s] again  
01357:   if no carry go to tan18    
01360:   a + c -> c[wp] no more SR  
01361:   a - b -> a[wp] X + Z -> Z  
01362:   b exchange c[wp] A – B -> A  
01363: tan13: b -> c[w] Continuation if Cordic rotation
01364:   a - 1 -> a[s] update “ of times this rotation was made (pqj)
01365:   if no carry go to tan19 check if over  
01366:   a exchange c[wp]    
01367:   stack -> a    
01370:   if b[s] = 0 if no more rotation for a pqj goto “tan15” (01001)
01371:        then go to tan15 next pqj  
01372:   shift left a[w]    
01373: tan14: a exchange c[wp] entry point in tan cordic rotations
01374:   c -> stack Result saved in the stack  
01375:   shift right b[wp] Prepare for rotation, A = X  B = Y (angle)
01376:   c - 1 -> c[s] update #of rotations c[s]  
01377:   b exchange c[s] continuation at 01000 “tan13”

J. LAPORTE
November 2006.