📄 isp.s
字号:
# cas.w 0000 1100 11 |<ea>| 0000 000* **00 0*** ## cas.l 0000 1110 11 |<ea>| 0000 000* **00 0*** ## ## cas2.w 0000 1100 11 111100 **** 000* **00 0*** ## **** 000* **00 0*** ## cas2.l 0000 1110 11 111100 **** 000* **00 0*** ## **** 000* **00 0*** ## ## chk2.b 0000 0000 11 |<ea>| **** 1000 0000 0000 ## chk2.w 0000 0010 11 |<ea>| **** 1000 0000 0000 ## chk2.l 0000 0100 11 |<ea>| **** 1000 0000 0000 ## ## cmp2.b 0000 0000 11 |<ea>| **** 0000 0000 0000 ## cmp2.w 0000 0010 11 |<ea>| **** 0000 0000 0000 ## cmp2.l 0000 0100 11 |<ea>| **** 0000 0000 0000 ############################################################################ using bit 14 of the operation word, separate into 2 groups:# (group1) mul64, div64# (group2) movep, chk2, cmp2, cas2, cas# btst &0x1e,%d0 # group1 or group2 beq.b uieh_group2 # go handle group2## now, w/ group1, make mul64's decode the fastest since it will# most likely be used the most.#uieh_group1: btst &0x16,%d0 # test for div64 bne.b uieh_div64 # go handle div64uieh_mul64:# mul64() may use ()+ addressing and may, therefore, alter a7 bsr.l _mul64 # _mul64() btst &0x5,EXC_ISR(%a6) # supervisor mode? beq.w uieh_done btst &mia7_bit,SPCOND_FLG(%a6) # was a7 changed? beq.w uieh_done # no btst &0x7,EXC_ISR(%a6) # is trace enabled? bne.w uieh_trace_a7 # yes bra.w uieh_a7 # nouieh_div64:# div64() may use ()+ addressing and may, therefore, alter a7.# div64() may take a divide by zero exception. bsr.l _div64 # _div64()# here, we sort out all of the special cases that may have happened. btst &mia7_bit,SPCOND_FLG(%a6) # was a7 changed? bne.b uieh_div64_a7 # yesuieh_div64_dbyz: btst &idbyz_bit,SPCOND_FLG(%a6) # did divide-by-zero occur? bne.w uieh_divbyzero # yes bra.w uieh_done # nouieh_div64_a7: btst &0x5,EXC_ISR(%a6) # supervisor mode? beq.b uieh_div64_dbyz # no# here, a7 has been incremented by 4 bytes in supervisor mode. we still# may have the following 3 cases:# (i) (a7)+# (ii) (a7)+; trace# (iii) (a7)+; divide-by-zero# btst &idbyz_bit,SPCOND_FLG(%a6) # did divide-by-zero occur? bne.w uieh_divbyzero_a7 # yes tst.b EXC_ISR(%a6) # no; is trace enabled? bmi.w uieh_trace_a7 # yes bra.w uieh_a7 # no## now, w/ group2, make movep's decode the fastest since it will# most likely be used the most.#uieh_group2: btst &0x18,%d0 # test for not movep beq.b uieh_not_movep bsr.l _moveperipheral # _movep() bra.w uieh_doneuieh_not_movep: btst &0x1b,%d0 # test for chk2,cmp2 beq.b uieh_chk2cmp2 # go handle chk2,cmp2 swap %d0 # put opword in lo word cmpi.b %d0,&0xfc # test for cas2 beq.b uieh_cas2 # go handle cas2uieh_cas: bsr.l _compandset # _cas()# the cases of "cas Dc,Du,(a7)+" and "cas Dc,Du,-(a7)" used from supervisor# mode are simply not considered valid and therefore are not handled. bra.w uieh_doneuieh_cas2: mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr bsr.l _imem_read_word # read extension word tst.l %d1 # ifetch error? bne.w isp_iacc # yes bsr.l _compandset2 # _cas2() bra.w uieh_doneuieh_chk2cmp2:# chk2 may take a chk exception bsr.l _chk2_cmp2 # _chk2_cmp2()# here we check to see if a chk trap should be taken cmpi.b SPCOND_FLG(%a6),&ichk_flg bne.w uieh_done bra.b uieh_chk_trap############################################################################# the required emulation has been completed. now, clean up the necessary stack# info and prepare for rte#uieh_done: mov.b EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes# if exception occurred in user mode, then we have to restore a7 in case it# changed. we don't have to update a7 for supervisor mose because that case# doesn't flow through here btst &0x5,EXC_ISR(%a6) # user or supervisor? bne.b uieh_finish # supervisor mov.l EXC_A7(%a6),%a0 # fetch user stack pointer mov.l %a0,%usp # restore ituieh_finish: movm.l EXC_DREGS(%a6),&0x3fff # restore d0-d7/a0-a5 btst &0x7,EXC_ISR(%a6) # is trace mode on? bne.b uieh_trace # yes;go handle trace mode mov.l EXC_EXTWPTR(%a6),EXC_IPC(%a6) # new pc on stack frame mov.l EXC_A6(%a6),(%a6) # prepare new a6 for unlink unlk %a6 # unlink stack frame bra.l _isp_done## The instruction that was just emulated was also being traced. The trace# trap for this instruction will be lost unless we jump to the trace handler.# So, here we create a Trace Exception format number two exception stack# frame from the Unimplemented Integer Intruction Exception stack frame# format number zero and jump to the user supplied hook "_real_trace()".## UIEH FRAME TRACE FRAME# ***************** *****************# * 0x0 * 0x0f4 * * Current *# ***************** * PC *# * Current * *****************# * PC * * 0x2 * 0x024 *# ***************** *****************# * SR * * Next *# ***************** * PC *# ->* Old * *****************# from link -->* A6 * * SR *# ***************** *****************# /* A7 * * New * <-- for final unlink# / * * * A6 *# link frame < ***************** *****************# \ ~ ~ ~ ~# \***************** *****************#uieh_trace: mov.l EXC_A6(%a6),-0x4(%a6) mov.w EXC_ISR(%a6),0x0(%a6) mov.l EXC_IPC(%a6),0x8(%a6) mov.l EXC_EXTWPTR(%a6),0x2(%a6) mov.w &0x2024,0x6(%a6) sub.l &0x4,%a6 unlk %a6 bra.l _real_trace## UIEH FRAME CHK FRAME# ***************** *****************# * 0x0 * 0x0f4 * * Current *# ***************** * PC *# * Current * *****************# * PC * * 0x2 * 0x018 *# ***************** *****************# * SR * * Next *# ***************** * PC *# (4 words) *****************# * SR *# *****************# (6 words)## the chk2 instruction should take a chk trap. so, here we must create a# chk stack frame from an unimplemented integer instruction exception frame# and jump to the user supplied entry point "_real_chk()".#uieh_chk_trap: mov.b EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes movm.l EXC_DREGS(%a6),&0x3fff # restore d0-d7/a0-a5 mov.w EXC_ISR(%a6),(%a6) # put new SR on stack mov.l EXC_IPC(%a6),0x8(%a6) # put "Current PC" on stack mov.l EXC_EXTWPTR(%a6),0x2(%a6) # put "Next PC" on stack mov.w &0x2018,0x6(%a6) # put Vector Offset on stack mov.l EXC_A6(%a6),%a6 # restore a6 add.l &LOCAL_SIZE,%sp # clear stack frame bra.l _real_chk## UIEH FRAME DIVBYZERO FRAME# ***************** *****************# * 0x0 * 0x0f4 * * Current *# ***************** * PC *# * Current * *****************# * PC * * 0x2 * 0x014 *# ***************** *****************# * SR * * Next *# ***************** * PC *# (4 words) *****************# * SR *# *****************# (6 words)## the divide instruction should take an integer divide by zero trap. so, here# we must create a divbyzero stack frame from an unimplemented integer# instruction exception frame and jump to the user supplied entry point# "_real_divbyzero()".#uieh_divbyzero: mov.b EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes movm.l EXC_DREGS(%a6),&0x3fff # restore d0-d7/a0-a5 mov.w EXC_ISR(%a6),(%a6) # put new SR on stack mov.l EXC_IPC(%a6),0x8(%a6) # put "Current PC" on stack mov.l EXC_EXTWPTR(%a6),0x2(%a6) # put "Next PC" on stack mov.w &0x2014,0x6(%a6) # put Vector Offset on stack mov.l EXC_A6(%a6),%a6 # restore a6 add.l &LOCAL_SIZE,%sp # clear stack frame bra.l _real_divbyzero## DIVBYZERO FRAME# *****************# * Current *# UIEH FRAME * PC *# ***************** *****************# * 0x0 * 0x0f4 * * 0x2 * 0x014 *# ***************** *****************# * Current * * Next *# * PC * * PC *# ***************** *****************# * SR * * SR *# ***************** *****************# (4 words) (6 words)## the divide instruction should take an integer divide by zero trap. so, here# we must create a divbyzero stack frame from an unimplemented integer# instruction exception frame and jump to the user supplied entry point# "_real_divbyzero()".## However, we must also deal with the fact that (a7)+ was used from supervisor# mode, thereby shifting the stack frame up 4 bytes.#uieh_divbyzero_a7: mov.b EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes movm.l EXC_DREGS(%a6),&0x3fff # restore d0-d7/a0-a5 mov.l EXC_IPC(%a6),0xc(%a6) # put "Current PC" on stack mov.w &0x2014,0xa(%a6) # put Vector Offset on stack mov.l EXC_EXTWPTR(%a6),0x6(%a6) # put "Next PC" on stack mov.l EXC_A6(%a6),%a6 # restore a6 add.l &4+LOCAL_SIZE,%sp # clear stack frame bra.l _real_divbyzero## TRACE FRAME# *****************# * Current *# UIEH FRAME * PC *# ***************** *****************# * 0x0 * 0x0f4 * * 0x2 * 0x024 *# ***************** *****************# * Current * * Next *# * PC * * PC *# ***************** *****************# * SR * * SR *# ***************** *****************# (4 words) (6 words)### The instruction that was just emulated was also being traced. The trace# trap for this instruction will be lost unless we jump to the trace handler.# So, here we create a Trace Exception format number two exception stack# frame from the Unimplemented Integer Intruction Exception stack frame# format number zero and jump to the user supplied hook "_real_trace()".## However, we must also deal with the fact that (a7)+ was used from supervisor# mode, thereby shifting the stack frame up 4 bytes.#uieh_trace_a7: mov.b EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes movm.l EXC_DREGS(%a6),&0x3fff # restore d0-d7/a0-a5 mov.l EXC_IPC(%a6),0xc(%a6) # put "Current PC" on stack mov.w &0x2024,0xa(%a6) # put Vector Offset on stack mov.l EXC_EXTWPTR(%a6),0x6(%a6) # put "Next PC" on stack mov.l EXC_A6(%a6),%a6 # restore a6 add.l &4+LOCAL_SIZE,%sp # clear stack frame bra.l _real_trace## UIEH FRAME# *****************# * 0x0 * 0x0f4 *# UIEH FRAME *****************# ***************** * Next *# * 0x0 * 0x0f4 * * PC *# ***************** *****************# * Current * * SR *# * PC * *****************# ***************** (4 words)# * SR *# *****************# (4 words)uieh_a7: mov.b EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes movm.l EXC_DREGS(%a6),&0x3fff # restore d0-d7/a0-a5 mov.w &0x00f4,0xe(%a6) # put Vector Offset on stack mov.l EXC_EXTWPTR(%a6),0xa(%a6) # put "Next PC" on stack mov.w EXC_ISR(%a6),0x8(%a6) # put SR on stack mov.l EXC_A6(%a6),%a6 # restore a6 add.l &8+LOCAL_SIZE,%sp # clear stack frame bra.l _isp_done########### this is the exit point if a data read or write fails.# a0 = failing address# d0 = fslwisp_dacc: mov.l %a0,(%a6) # save address mov.l %d0,-0x4(%a6) # save partial fslw lea -64(%a6),%sp movm.l (%sp)+,&0x7fff # restore d0-d7/a0-a6 mov.l 0xc(%sp),-(%sp) # move voff,hi(pc) mov.l 0x4(%sp),0x10(%sp) # store fslw mov.l 0xc(%sp),0x4(%sp) # store sr,lo(pc) mov.l 0x8(%sp),0xc(%sp) # store address mov.l (%sp)+,0x4(%sp) # store voff,hi(pc) mov.w &0x4008,0x6(%sp) # store new voff bra.b isp_acc_exit# this is the exit point if an instruction word read fails.# FSLW:# misaligned = true# read = true# size = word# instruction = true# software emulation error = trueisp_iacc: movm.l EXC_DREGS(%a6),&0x3fff # restore d0-d7/a0-a5 unlk %a6 # unlink frame sub.w &0x8,%sp # make room for acc frame mov.l 0x8(%sp),(%sp) # store sr,lo(pc) mov.w 0xc(%sp),0x4(%sp) # store hi(pc) mov.w &0x4008,0x6(%sp) # store new voff mov.l 0x2(%sp),0x8(%sp) # store address (=pc) mov.l &0x09428001,0xc(%sp) # store fslwisp_acc_exit: btst &0x5,(%sp) # user or supervisor? beq.b isp_acc_exit2 # user bset &0x2,0xd(%sp) # set supervisor TM bitisp_acc_exit2: bra.l _real_access# if the addressing mode was (an)+ or -(an), the address register must# be restored to its pre-exception value before entering _real_access.isp_restore: cmpi.b SPCOND_FLG(%a6),&restore_flg # do we need a restore? bne.b isp_restore_done # no clr.l %d0 mov.b EXC_SAVREG(%a6),%d0 # regno to restore mov.l EXC_SAVVAL(%a6),(EXC_AREGS,%a6,%d0.l*4) # restore valueisp_restore_done: rts########################################################################## XDEF **************************************************************** ## _calc_ea(): routine to calculate effective address ## ## XREF **************************************************************** ## _imem_read_word() - read instruction word ## _imem_read_long() - read instruction longword ## _dmem_read_long() - read data longword (for memory indirect) ## isp_iacc() - handle instruction access error exception ## isp_dacc() - handle data access error exception ## ## INPUT *************************************************************** ## d0 = number of bytes related to effective address (w,l) ## ## OUTPUT ************************************************************** ## If exiting through isp_dacc... ## a0 = failing address ## d0 = FSLW ## elsif exiting though isp_iacc... ## none ## else ## a0 = effective address ## ## ALGORITHM *********************************************************** ## The effective address type is decoded from the opword residing ## on the stack. A jump table is used to vector to a routine for the ## appropriate mode. Since none of the emulated integer instructions ## uses byte-sized operands, only handle word and long operations. ## ## Dn,An - shouldn't enter here ## (An) - fetch An value from stack #
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -