📄 emulate.s
字号:
jbr L220L219: # else put fill character putfillL220: sobgtr r1,L214 jbr Ledit_caseLe_float: # move with floating sign character tstl r1 jeql Ledit_caseL221: jlbc r2,L222 extzv $4,$4,(r10),r11 jbr L223L222: extzv $0,$4,(r10),r11 incl r10L223: decl r2 # source length CAN go negative here... tstl r11 jeql L225 jbs SIGNIFBIT,r4,L226 putsignL226: setsignifL225: jbc SIGNIFBIT,r4,L227 addb3 $48,r11,(r5)+ jbr L228L227: putfillL228: sobgtr r1,L221 jbr Ledit_case .align 1 .globl _EMashp_EMashp: argb(1,r11) # (1) scale (number to shift) == r11 arguw(2,r10) # (2) source length == r10 argl(3,r1) # (3) source address == r1 argub(4,r2) # (4) rounding factor == r2 arguw(5,r3) # (5) destination length == r3 toarg(r6,3) # arg3 holds register 6 from caller argl(6,r6) # (6) destination address == r6 # we need arg6 for later # arg1 is used for temporary storage # arg2 holds "even or odd" destination length # arg4 is used as general storage # arg5 is used as general storage ashl $-1,r3,r0 # destination length is number of bytes addl2 r0,r6 # destination address == least sig nibble toarg(r6,1) # save in arg1 spot for later ashl $-1,r10,r0 addl2 r0,r1 # source address == least sig nibble extzv $0,$4,(r1),r0 # determine sign of source cmpl r0,NEGATIVEalt jeql Lashp_neg cmpl r0,NEGATIVE jeql Lashp_neg movb POSITIVE,(r6) jbr L245Lashp_neg: movb NEGATIVE,(r6)L245: clrl arg2 # arg2 is 1 if dstlen is even, 0 if odd blbs r3,L246 incl arg2 bisl2 $1,r3 # r3<0> counts digits going into destinationL246: # and is flip-flop for which nibble to tstl r11 # write in destination (1 = high, 0 = low) jgeq Lashp_left # (it must start out odd) addl2 r11,r10 # scale is negative (right shift) jgeq Lashp_right clrl r10 # test for shifting whole number out jbr Lashp_setroundLashp_right: divl3 $2,r11,r0 addl2 r0,r1 # source address == MSNibble to be shifted off jlbc r11,L249 extzv $4,$4,(r1),r0 addl2 r0,r2 # round = last nibble to be shifted off + round jbr Lashp_setroundL249: extzv $0,$4,(r1),r0 addl2 r0,r2 # round = last nibble to be shifted off + roundLashp_setround: # r11<0> now is flip-flop for which nibble to incl r11 # read from source (1 == high, 0 == low) cmpl r2,$9 # set rounding factor to one if nibble shifted jleq Lashp_noround # off + round argument was 10 or greater movl $1,r2 jbr Lashp_shiftLashp_zloop: jlbs r3,L257 # don't need to clear high nibble twice clrb -(r6) # clear low (and high) nib of next byte in destL257: sobgtr r3,L258 # move to next nibble in destination, but incl r3 # don't go beyond the end.L258: decl r11Lashp_left: # while scale is positive jneq Lashp_zloop incl r11 # r11<0> is flip-plop ... (incl sets it to one)Lashp_noround: clrl r2 # no more roundingLashp_shift: clrl arg4 # arg4 will be used for result condition codes tstl r10 jeql Lashp_roundLashp_shloop: jlbc r11,L260 extzv $4,$4,(r1),r0 jbr L261L260: decl r1 extzv $0,$4,(r1),r0L261: incl r11 # flip the source nibble flip/flop addl2 r0,r2 # round += next nibble cmpl r2,$10 # if round == 10 jneq L262 clrl arg5 # then result = 0 and round = 1 movl $1,r2 jbr L263L262: # else movl r2,arg5 # store result and round = 0 clrl r2L263: bisl2 arg5,arg4 # remember if result was nonzero in arg4 decl r3 # move to next nibble early to check cmpl r3,arg2 # if we've moved passed destination limits jgeq Lashp_noovfl # test the result for possible overflow movl arg2,r3 # ignore zero nibbles tstl arg5 # if the nibble was non-zero, overflow jeql L265 jbr Lashp_overflLashp_noovfl: # else jlbs r3,L264 insv arg5,$4,$4,(r6) # put the result into destination (high or low) jbr L265L264: movb arg5,-(r6)L265: sobgtr r10,Lashp_shloop # loop for length of sourceLashp_round: tstl r2 # take care of round out of high nibble jeql Lashp_zeroround decl r3 cmpl r3,arg2 # if we've moved passed destination limits jlss Lashp_overfl # then overflow jlbs r3,L266 insv arg5,$4,$4,(r6) # put the round into destination (high or low) jbr Lashp_zeroroundL266: movb arg5,-(r6)Lashp_zeroround: argl(1,r10) # r10 = address of destination LSNibble argl(6,r3) # r3 = address of destination MSNibble movl arg4,r11 # r11 = non-zero if destination == non-zero savepsl jbr L267Lashp_zerofill: clrb -(r6) # fill up MSNs of destination with zerosL267: cmpl r3,r6 jneq Lashp_zerofill extzv $0,$4,(r10),r0 # test for negative result cmpl r0,NEGATIVE jneq Lashp_out mnegl r11,r11 savepsl jneq Lashp_out # turn -0 into 0 insv POSITIVE,$0,$4,(r10)Lashp_out: clrl r0 argl(3,r6) # restore r6 from stack returnLashp_overfl: # do overflow clrl r2 overflowpsl jbr Lashp_out .align 1 .globl _EMcvtlp_EMcvtlp: arguw(2,r10) # (2) destination length == r10 argl(3,r3) # (3) destination address == r3 ashl $-1,r10,r10 addl2 r10,r3 # destination address points to Least Sig byte incl r10 # length is # of bytes, not nibbles argl(1,r11) # (1) source == r11 savepsl jgeq Lcvtlp_pos movb NEGATIVE,(r3) # source is negative divl3 $10,r11,r0 mull3 $10,r0,r1 subl3 r11,r1,r2 # r2 = source mod 10 mnegl r0,r11 # source = -(source / 10) jbr Lcvtlp_cvtLcvtlp_pos: movb POSITIVE,(r3) # source is non-negative divl3 $10,r11,r0 mull3 $10,r0,r1 subl3 r1,r11,r2 # r2 = source mod 10 movl r0,r11 # source = source / 10Lcvtlp_cvt: insv r2,$4,$4,(r3) # store least significant digit tstl r11 jeql Lcvtlp_zloopLcvtlp_loop: # while source is non-zero decl r10 # and for length of destination ... jeql Lcvtlp_over divl3 $10,r11,r1 # r1 = source / 10 mull3 $10,r1,r0 subl2 r0,r11 # source = source mod 10 movb r11,-(r3) # store low "nibble" in next significant byte divl3 $10,r1,r11 # source = r1 / 10 mull3 $10,r11,r0 subl2 r0,r1 # r1 = source mod 10 insv r1,$4,$4,(r3) # store high nibble tstl r11 jneq Lcvtlp_loop # quit if source becomes zeroLcvtlp_zloop: # fill any remaining bytes with zeros decl r10 jeql Lcvtlp_out clrb -(r3) jbr Lcvtlp_zloopLcvtlp_over: overflowpslLcvtlp_out: clrl r1 # r0 is already zero clrl r2 return .align 1 .globl _EMcvtpl_EMcvtpl: arguw(1,r11) # (1) source length == r11 argl(2,r10) # (2) source address == r10 clrl r3 # r3 == destination movl r10,r1 # r1 set up now for return ashl $-1,r11,r11 # source length is number of bytes jeql Lcvtpl_zeroLcvtpl_loop: # for source length mull2 $10,r3 # destination *= 10 extzv $4,$4,(r10),r0 addl2 r0,r3 # destination += high nibble mull2 $10,r3 # destination *= 10 extzv $0,$4,(r10),r0 addl2 r0,r3 # destination += low nibble incl r10 sobgtr r11,Lcvtpl_loopLcvtpl_zero: # least significant byte mull2 $10,r3 extzv $4,$4,(r10),r0 addl2 r0,r3 # dest = 10 * dest + high nibble savepsl extzv $0,$4,(r10),r2 # test sign nibble cmpl r2,NEGATIVE jeql Lcvtpl_neg cmpl r2,NEGATIVEalt jneq Lcvtpl_outLcvtpl_neg: # source was negative - negate destination mnegl r3,r3 savepslLcvtpl_out: toarg(r3,3) clrl r0 clrl r2 clrl r3 return .align 1 .globl _EMcvtps_EMcvtps: return .align 1 .globl _EMcvtsp_EMcvtsp: return .align 1 .globl _EMaddp6_EMaddp6: return .align 1 .globl _EMsubp4_EMsubp4: return .align 1 .globl _EMsubp6_EMsubp6: return .align 1 .globl _EMcvtpt_EMcvtpt: return .align 1 .globl _EMmulp_EMmulp: return .align 1 .globl _EMcvttp_EMcvttp: return .align 1 .globl _EMdivp_EMdivp: return .align 1 .globl _EMcmpp3_EMcmpp3: return .align 1 .globl _EMcmpp4_EMcmpp4: return#endif UVAXII#ifdef notdef/* * Emulation OpCode jump table: * ONLY GOES FROM 0xf8 (-8) TO 0x3B (59) */#define EMUTABLE 0x43#define NOEMULATE .long noemulate#define EMULATE(a) .long _EM/**/a .globl _emJUMPtable_emJUMPtable:/* f8 */ EMULATE(ashp); EMULATE(cvtlp); NOEMULATE; NOEMULATE/* fc */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 00 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 04 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 08 */ EMULATE(cvtps); EMULATE(cvtsp); NOEMULATE; EMULATE(crc)/* 0c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 10 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 14 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 18 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 1c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 20 */ EMULATE(addp4); EMULATE(addp6); EMULATE(subp4); EMULATE(subp6)/* 24 */ EMULATE(cvtpt); EMULATE(mulp); EMULATE(cvttp); EMULATE(divp)/* 28 */ NOEMULATE; EMULATE(cmpc3); EMULATE(scanc); EMULATE(spanc)/* 2c */ NOEMULATE; EMULATE(cmpc5); EMULATE(movtc); EMULATE(movtuc)/* 30 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE/* 34 */ EMULATE(movp); EMULATE(cmpp3); EMULATE(cvtpl); EMULATE(cmpp4)/* 38 */ EMULATE(editpc); EMULATE(matchc); EMULATE(locc); EMULATE(skpc)/* * The following is called with the stack set up as follows: * * (sp): Opcode * 4(sp): Instruction PC * 8(sp): Operand 1 * 12(sp): Operand 2 * 16(sp): Operand 3 * 20(sp): Operand 4 * 24(sp): Operand 5 * 28(sp): Operand 6 * 32(sp): Operand 7 (unused) * 36(sp): Operand 8 (unused) * 40(sp): Return PC * 44(sp): Return PSL * 48(sp): TOS before instruction * * Each individual routine is called with the stack set up as follows: * * (sp): Return address of trap handler * 4(sp): Opcode (will get return PSL) * 8(sp): Instruction PC * 12(sp): Operand 1 * 16(sp): Operand 2 * 20(sp): Operand 3 * 24(sp): Operand 4 * 28(sp): Operand 5 * 32(sp): Operand 6 * 36(sp): saved register 11 * 40(sp): saved register 10 * 44(sp): Return PC * 48(sp): Return PSL * 52(sp): TOS before instruction */SCBVEC(emulate): movl r11,32(sp) # save register r11 in unused operand movl r10,36(sp) # save register r10 in unused operand cvtbl (sp),r10 # get opcode addl2 $8,r10 # shift negative opcodes subl3 r10,$EMUTABLE,r11 # forget it if opcode is out of range bcs noemulate movl _emJUMPtable[r10],r10 # call appropriate emulation routine jsb (r10) # routines put return values into regs 0-5 movl 32(sp),r11 # restore register r11 movl 36(sp),r10 # restore register r10 insv (sp),$0,$4,44(sp) # and condition codes in Opcode spot addl2 $40,sp # adjust stack for return reinoemulate: addl2 $48,sp # adjust stack for .word 0xffff # "reserved instruction fault"SCBVEC(emulateFPD): .word 0xffff # "reserved instruction fault"#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -