; bfsml.a ; Last modified April 5, 1980 5:54 PM by Taft ; miscellaneous machine code ; frame callersFrame=0 savedPC=1 temp=2 extraArguments=3 ; machine code for messing with frames .srel FrameSize: pFrameSize MyFrame: pMyFrame CallersFrame: pCallersFrame .bext FrameSize,MyFrame,CallersFrame .nrel pFrameSize: mov 3 1 mov 0 3 lda 0 2,3 mov 1 3 jmp 1,3 pMyFrame: mov 2 0 jmp 1,3 pCallersFrame: lda 0 callersFrame,2 jmp 1,3 ; machine code for getting at block store and transfer ; instructions .srel MoveBlock: pMoveBlock SetBlock: pSetBlock Zero: pZero .bext MoveBlock,SetBlock,Zero .nrel pMoveBlock: sta 3 savedPC,2 mkone 3 3 sub 3 1 sub 0 3 mov 1 0 neg 3 1 lda 3 extraArguments,2 add 3 1 neg 3 3 blt lda 3 savedPC,2 jmp 1,3 pZero: sta 1 extraArguments,2 mkzero 1 1 ; fall through pSetBlock: sta 3 savedPC,2 mkone 3 3 sub 0 3 mov 1 0 neg 3 1 lda 3 extraArguments,2 add 3 1 neg 3 3 blks lda 3 savedPC,2 jmp 1,3 ; machine code for unsigned compare. Returns -1 is ac0 ls ac1, ; 0 if ac0 eq ac1, and 1 if ac2 gr ac1, taken as 16 bit positive ; numbers .srel Usc: pUsc .bext Usc .nrel pUsc: adcz# 0 1 szc jmp Uscr1 subz 1 0 szr mkone 0 0 jmp 1,3 Uscr1: mknil 0 0 jmp 1,3 ; Min(a, b); Max(a, b) -- signed compares (a and b must differ by < 2^15) ; Umin(a, b); Umax(a, b) -- unsigned compares .srel Min: .Min Max: .Max Umin: .Umin Umax: .Umax .ent Min, Max, Umin, Umax .nrel .Min: sle 0 1 mov 1 0 jmp 1 3 .Max: sge 0 1 mov 1 0 jmp 1 3 .Umin: sleu 0 1 mov 1 0 jmp 1 3 .Umax: sgeu 0 1 mov 1 0 jmp 1 3 ;DoubleAdd(a,b) a_a+b (a and b are pointers to double precision #'s) .srel DoubleAdd: .DoubleAdd .ent DoubleAdd .nrel .DoubleAdd: sta 3 savedPC,2 sta 1 temp,2 ;=> first word of arg 2 mov 1,3 lda 1,1,3 ;word 2 of arg 2 mov 0 3 lda 0,1,3 ;word 2 of arg 1 addz 1,0 ;Sets carry if overflow sta 0,1,3 ;Save word 2 of result lda 0,0,3 ;word 1 of arg 1 lda 1 @temp,2 ;word 1 of arg 2 mov 0,0,szc inc 1,1 add 1,0 sta 0,0,3 ;Save word 1 of result lda 3 savedPC,2 jmp 1,3 ; StartIO(ac0) - access to the SIO instruction .srel StartIO: .StartIO .ent StartIO .nrel .StartIO: sio jmp 1 3 ; table to convert from bit number to bit position .srel oneBits: .oneBits .bext oneBits .nrel .oneBits: 100000 40000 20000 10000 4000 2000 1000 400 200 100 40 20 10 4 2 1 ; free page fileId .srel freePageId: .freePageId .bext freePageId .nrel .freePageId: -1 -1 -1 ; machine code for simple coroutine linkages .srel CallFrame: .CallFrame GotoFrame: .GotoFrame CoCall: .CoCall CoReturn: .CoReturn ReturnTo: .ReturnTo GotoLabel: .GotoLabel .bext CoCall,CallFrame,GotoFrame,CoReturn,ReturnTo,GotoLabel .nrel ; CallFrame(dest frame[, arg 1[, arg 2]]) sends control to ; the specified frame and links it back to this one .CallFrame: sta 3 savedPC,2 mov 0 3 sta 2 callersFrame,3 callf1: mov 1 0 lda 1 extraArguments,2 callf2: mov 3 2 lda 3 savedPC,2 jmp 1,2 ; just like CallFrame, but doesn't plant the return link. This ; is like Mesa's transfer .GotoFrame: sta 3 savedPC,2 mov 0 3 jmp callf1 ; CoCall(a, b)=CallFrame(MyFrame()>>F.callersFrame, a, b) .CoCall: sta 3 savedPC,2 lda 3 callersFrame,2 sta 2 callersFrame,3 jmp callf2 ; just like CoCall, but doesn't plant the return link .CoReturn: sta 3 savedPC,2 lda 2 callersFrame,2 lda 3 savedPC,2 jmp 1,3 ; ReturnTo(label) does a return to the specified label .ReturnTo: lda 2 callersFrame,2 mov 0 3 jmp 0,3 ; GotoLabel(frame, label, v) sends control to the specified label in the ; specified frame, and passes v in AC0 .GotoLabel: mov 0 3 lda 0 extraArguments,2 mov 3 2 mov 1 3 jmp 0,3 .end