📄 emulate.s
字号:
movl r1,r9 # r9 == carry (must be -1) movl $9,r1 # r1 == result = 9 jbr L128L127: # else clrl r9 # r9 == carry = 0L128: insv r1,$0,$4,(r3) # store result bisl2 r1,r2 extzv $4,$4,(r3),r0 addl2 r0,r9 # r9 == carry += next (high) nibble jgeq L129 # if less than zero movl r9,r1 # r1 == carry (must be -1) movl $9,r9 # r9 == result = 9 jbr L130L129: clrl r1L130: insv r9,$4,$4,(r3) # store result bisl2 r9,r2Laddp4_diff_carry: cmpl r3,r10 jneq Laddp4_diff_carlop tstl r1 # if carry out of MSN then fix up result jeql Laddp4_add_done argl(5,r3) # r3 == address of LSN of destination extzv $0,$4,(r3),r0 cmpl r0,NEGATIVE # switch sign of result jneq L132 insv POSITIVE,$0,$4,(r3) jbr L133L132: insv NEGATIVE,$0,$4,(r3)L133: extzv $4,$4,(r3),r0 # normalize result (carry out of MSN into LSN) subl3 r0,$10,r9 # r9 = 10 - destination LSNibble jbr L134L137: movl $9,r1Laddp4_diff_norm: insv r9,$4,$4,(r3) cmpl r3,r10 # while (not at MSNibble) jeql Laddp4_add_done decl r3 extzv $0,$4,(r3),r0 # low nibble = (9 + carry) - low nibble subl2 r0,r1 cmpl r1,$9 jleq L135 clrl r1 movl $10,r9 jbr L136L135: movl $9,r9L136: insv r1,$0,$4,(r3) extzv $4,$4,(r3),r0 # high nibble = (9 + carry) - high nibble subl2 r0,r9L134: cmpl r9,$9 jleq L137 clrl r9 movl $10,r1 jbr Laddp4_diff_normLaddp4_same: # operands are of the same sign clrl r2 addl2 r1,r9 jbr L139Laddp4_same_loop: decl r3 extzv $0,$4,(r3),r0 addl2 r0,r1 # r1 == carry += next (low) nibble of dest decl r10 extzv $0,$4,(r10),r0 addl2 r0,r1 # r1 += next (low) nibble of source cmpl r1,$9 # if result > 9 jleq L141 movl $1,r9 # r9 == carry = 1 subl2 $10,r1 # r1 == result -= 10 jbr L142L141: # else clrl r9 # r9 == carry = 0L142: insv r1,$0,$4,(r3) # store result bisl2 r1,r2 extzv $4,$4,(r10),r0 addl2 r0,r9 # ditto for high nibble extzv $4,$4,(r3),r0 addl2 r0,r9L139: cmpl r9,$9 jleq L143 movl $1,r1 subl2 $10,r9 jbr L144L143: clrl r1L144: insv r9,$4,$4,(r3) bisl2 r9,r2 sobgtr r11,Laddp4_same_loop # while (--source length) argl(4,r10) # r10 = destination address of MSNibble jbr Laddp4_same_carryLaddp4_same_cloop: decl r3 extzv $0,$4,(r3),r0 # propagate carry up to MSNibble of destination addl2 r0,r1 cmpl r1,$10 jneq L147 movl $1,r9 clrl r1 jbr L148L147: clrl r9L148: insv r1,$0,$4,(r3) bisl2 r1,r2 extzv $4,$4,(r3),r0 addl2 r0,r9 cmpl r9,$10 jneq L149 movl $1,r1 clrl r9 jbr L150L149: clrl r1L150: insv r9,$4,$4,(r3) bisl2 r9,r2Laddp4_same_carry: cmpl r3,r10 jneq Laddp4_same_cloopLaddp4_add_done: argl(5,r3) # r3 = destination address of LSNibble tstl r2 # if zero result jneq L151 savepsl # remember that for condition codes insv POSITIVE,$0,$4,(r3) # make sure sign of result is positive jbr Laddp4_outL151: # else extzv $0,$4,(r3),r0 cmpl r0,NEGATIVE # if result is negative jneq Laddp4_out mnegl r2,r2 # remember THAT in Cond Codes savepslLaddp4_out: argl(4,r3) argl(2,r1) clrl r0 clrl r2 argl(6,r9) # restore r9 from stack return .align 1 .globl _EMmovp_EMmovp: arguw(1,r11) # (1) string length == r11 argl(2,r10) # (1) source address == r10 argl(3,r3) # (1) destination address == r3 # we will need arg2 and arg3 later clrl r2 # r2 == non-zero if source is non-zero ashl $-1,r11,r11 # length is number of bytes, not nibbles jeql Lmovp_zlenLmovp_copy: bisb2 (r10),r2 # keep track of non-zero source movb (r10)+,(r3)+ # move two nibbles sobgtr r11,Lmovp_copy # loop for length of sourceLmovp_zlen: extzv $4,$4,(r10),r0 # look at least significant nibble bisl2 r0,r2 extzv $0,$4,(r10),r0 # check sign nibble cmpl r0,NEGATIVEalt jeql Lmovp_neg cmpl r0,NEGATIVE jneq Lmovp_posLmovp_neg: # source was negative mnegl r2,r2Lmovp_pos: tstl r2 # set condition codes savepsl jeql Lmovp_zero movb (r10),(r3) # move last byte if non-zero result jbr Lmovp_outLmovp_zero: movb POSITIVE,(r3) # otherwise, make result zero and positiveLmovp_out: clrl r0 argl(2,r1) clrl r2 argl(3,r3) return/* * Definitions for Editpc instruction * * Here are the commands and their corresponding hex values: * * EPend 0x00 * EPend_float 0x01 * EPclear_signif 0x02 * EPset_signif 0x03 * EPstore_sign 0x04 * EPload_fill 0x40 * EPload_sign 0x41 * EPload_plus 0x42 * EPload_minus 0x43 * EPinsert 0x44 * EPblank_zero 0x45 * EPreplace_sign 0x46 * EPadjust_input 0x47 * EPfill 0x80 * EPmove 0x90 * EPfloat 0xa0 * * * r4 is carved up as follows: * * ------------------------------------------- * | N Z V C | * ------------------------------------------- * * fill character is stuffed into arg5 space * sign character is stuffed into arg6 space */#define SIGNIFBIT $0#define setsignif bisl2 $1,r4#define clsignif bicl2 $1,r4#define OVERFLOWBIT $1#define setoverflow bisl2 $2,r4#define cloverflow bicl2 $2,r4#define ZEROBIT $2#define setzero bisl2 $4,r4#define clzero bicl2 $4,r4#define NEGATIVEBIT $3#define setnegative bisl2 $8,r4#define clnegative bicl2 $8,r4#define putfill movb arg5,(r5)+#define setfill(reg) movb reg,arg5#define putsign movb arg6,(r5)+#define setsign(reg) movb reg,arg6 .align 1 .globl _EMeditpc_EMeditpc: arguw(1,r11) # (1) source length == r11 argl(2,r10) # (2) source address == r10 argl(3,r3) # (3) pattern address == r3 argl(4,r5) # (4) destination address == r5 # we will need arg1 and arg2 later # arg5 and arg6 are used for fill and sign - r0 is free setfill($32) # fill character is ' ' setsign($32) # sign character is ' ' clrl r4 # clear flags ashl $-1,r11,r11 # source length / 2 addl3 r11,r10,r2 extzv $4,$4,(r2),r1 # r1 == least significant nibble of sourceL169: cmpl r2,r10 jeql L170 tstb -(r2) # loop over source packed decimal number jeql L169 incl r1 # r1 is non-zero if source is non-zeroL170: addl3 r11,r10,r2 tstl r1 jeql L172 # source is zero - set flags extzv $0,$4,(r2),r11 cmpl r11,NEGATIVEalt jeql L9998 # source is negative - set sign and flags cmpl r11,NEGATIVE jneq L175L9998: setnegative setsign($45) # sign character is '-' jbr L175L172: setzeroL175: arguw(1,r2) # (1) source length == r2Ledit_case: movzbl (r3)+,r11 # get next edit command (pattern) cmpl r11,$128 jlss L180 extzv $0,$4,r11,r1 # command has a "count" arg - into r1 ashl $-4,r11,r11 # and shift overL180: jbc $6,r11,L181 # "shift" those commands > 64 to 16 and up subl2 $48,r11L181: caseb r11,$0,$0x18 # "do" the command # r11 is available for use, r1 has "count" in itLcaseb_label: .word Le_end - Lcaseb_label # 00 .word Le_end_float - Lcaseb_label # 01 .word Le_clear_signif - Lcaseb_label # 02 .word Le_set_signif - Lcaseb_label # 03 .word Le_store_sign - Lcaseb_label # 04 .word Le_end - Lcaseb_label # 05 .word Le_end - Lcaseb_label # 06 .word Le_end - Lcaseb_label # 07 .word Le_fill - Lcaseb_label # 80 .word Le_move - Lcaseb_label # 90 .word Le_float - Lcaseb_label # a0 .word Le_end - Lcaseb_label # b0 .word Le_end - Lcaseb_label # c0 .word Le_end - Lcaseb_label # d0 .word Le_end - Lcaseb_label # e0 .word Le_end - Lcaseb_label # f0 .word Le_load_fill - Lcaseb_label # 40 .word Le_load_sign - Lcaseb_label # 41 .word Le_load_plus - Lcaseb_label # 42 .word Le_load_minus - Lcaseb_label # 43 .word Le_insert - Lcaseb_label # 44 .word Le_blank_zero - Lcaseb_label # 45 .word Le_replace_sign - Lcaseb_label # 46 .word Le_adjust_input - Lcaseb_label # 47Le_end: arguw(1,r0) argl(2,r1) clrl r2 decl r3 setpsl(r4) clrl r4 returnLe_end_float: jbs SIGNIFBIT,r4,Ledit_case # if significance not set putsign # drop in the sign # fall into...Le_set_signif: setsignif jbr Ledit_caseLe_clear_signif: clsignif jbr Ledit_caseLe_store_sign: putsign jbr Ledit_caseLe_load_fill: setfill((r3)+) jbr Ledit_caseLe_load_plus: jbs NEGATIVEBIT,r4,Lpattern_inc # if non-negative # fall into...Le_load_sign: setsign((r3)+) jbr Ledit_caseLe_load_minus: jbs NEGATIVEBIT,r4,Le_load_sign # if negative load the sign incl r3 # else increment pattern jbr Ledit_caseLe_insert: jbc SIGNIFBIT,r4,L196 # if significance set, put next byte movb (r3)+,(r5)+ jbr Ledit_caseL196: # else put in fill character putfill # and throw away character in patternLe_replace_sign: # we don't do anything withLpattern_inc: # replace sign `cause we don't incl r3 # get negative zero jbr Ledit_caseLe_blank_zero: jbc ZEROBIT,r4,Lpattern_inc # if zero movzbl (r3)+,r11 # next byte is a count jeql Ledit_case subl2 r11,r5 # to back up over output and replaceL200: putfill # with fill character sobgtr r11,L200 jbr Ledit_caseLe_adjust_input: movzbl (r3)+,r0 # get count of nibbles from pattern subl3 r2,r0,r11 jgeq Ledit_case # if length of source is > this numberL204: # discard digits in source jlbc r2,L206 # use low bit of length to choose nibble bitb $0xf0,(r10) # high nibble jeql L208 setsignif # set significance and overflow if setoverflow # wasted digit is non-zero jbr L208L206: bitb $0xf,(r10) # low nibble jeql L209 setsignif setoverflowL209: incl r10 # increment to next byteL208: decl r2 # decrement source length incl r11 # continue `till we're out of excess jlss L204 jbr Ledit_caseLe_fill: tstl r1 # put (count in r1) fill characters jeql Ledit_caseLe_fill_loop: putfill sobgtr r1,Le_fill_loop jbr Ledit_caseLe_move: tstl r1 # move (count in r1) characters jeql Ledit_case # from source to destinationL214: jlbc r2,L215 # read a nibble extzv $4,$4,(r10),r11 jbr L216L215: extzv $0,$4,(r10),r11 incl r10L216: decl r2 # source length CAN go negative here... tstl r11 jeql L218 # if non-zero setsignif # set significanceL218: jbc SIGNIFBIT,r4,L219 # if significance set addb3 $48,r11,(r5)+ # put '0' + digit into destination
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -