-
+ FD686B4ADBDB138A08F6B8F95620FD0533B2BD68C5B5056D24100F28B552CB6E7AF74B32BFD739F029E065D257F456024D223073DA3F0F8168E6D98F75BE053D
m/mips_exc.asm
(0 . 0)(1 . 92)
2030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2031 ;; ;;
2032 ;; This file is part of 'M', a MIPS system emulator. ;;
2033 ;; ;;
2034 ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;;
2035 ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;;
2036 ;; ;;
2037 ;; You do not have, nor can you ever acquire the right to use, copy or ;;
2038 ;; distribute this software ; Should you use this software for any purpose, ;;
2039 ;; or copy and distribute it to anyone or in any manner, you are breaking ;;
2040 ;; the laws of whatever soi-disant jurisdiction, and you promise to ;;
2041 ;; continue doing so for the indefinite future. In any case, please ;;
2042 ;; always : read and understand any software ; verify any PGP signatures ;;
2043 ;; that you use - for any purpose. ;;
2044 ;; ;;
2045 ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;;
2046 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2047
2048 section .text
2049
2050 ;-----------------------------------------------------------------------------
2051 ; Get the current Exception Code, write to the specified destination
2052 ;-----------------------------------------------------------------------------
2053 %macro GetEXC 1 ; param is destination to write the exception code
2054 mov %1, CP0_Cause ; Dest := CP0_Cause
2055 shr %1, 2 ; Dest := Dest >> 2
2056 and %1, 0x1F ; Dest := Dest & 0x1F
2057 %endmacro
2058 ;-----------------------------------------------------------------------------
2059
2060 ;-----------------------------------------------------------------------------
2061 ; Set the current Exception Code from the given constant
2062 ;-----------------------------------------------------------------------------
2063 %macro SetEXC 1 ; param is the exception code to set
2064 and CP0_Cause, ~(0x1F << 2) ; Clear the current Exception Code
2065 or CP0_Cause, (%1 & 0x1F) << 2 ; set the new one
2066 %endmacro
2067 ;-----------------------------------------------------------------------------
2068
2069 ;------------------------------
2070 ; Exception (and IRQ) Handler |
2071 ;-----------------------------------------------------------------------------
2072 _Handle_Exception:
2073 Flg_Off InDelaySlot ; Clear the InDelaySlot Flag
2074 bt CP0_Status, CP0St_EXL ; CF := EXL
2075 jc _H_Exc_Off_Is_180 ; If EXL is 1, Offset := 0x180; else:
2076 ;; EXL is 0:
2077 mov Sr(CP0_Epc), PC ; CP0_Epc := PC
2078 Flg_Get RunningDelaySlot ; Are we running the delay slot?
2079 jnc _H_Exc_Not_R_Delay ; If yes, then skip, else:
2080 _H_Exc_R_Delay: ; We ARE running the delay slot:
2081 sub Sr(CP0_Epc), 0x4 ; CP0_Epc := CP0_Epc - 0x4
2082 bts CP0_Cause, CP0Cau_BD ; Set BD Flag in CP0_Cause
2083 jmp _H_Exc_Test_TLB ; Proceed to test for TLBism
2084 _H_Exc_Not_R_Delay: ; We are NOT running the delay slot:
2085 btr CP0_Cause, CP0Cau_BD ; Clear BD Flag in CP0_Cause
2086 _H_Exc_Test_TLB:
2087 ;; Test whether this was a TLB Exception:
2088 GetEXC eax ; EAX := the current exception code
2089 cmp eax, EXC_TLBL ; was it EXC_TLBL ?
2090 je __H_Exc_Was_TLB ; ... if yes, go to H_Exc_Was_TLB
2091 cmp eax, EXC_TLBS ; was it EXC_TLBS ?
2092 je __H_Exc_Was_TLB ; ... if yes, go to H_Exc_Was_TLB
2093 ;; This was NOT a TLB Exception:
2094 cmp eax, EXC_Int ; was code EXC_Int ?
2095 jne _H_Exc_Off_Is_180 ; if not, Offset := 0x180
2096 bt CP0_Cause, CP0Cau_IV ; Was CP0_Cause bit 23 (IV) zero?
2097 jnc _H_Exc_Off_Is_180 ; if was zero, Offset := 0x180
2098 ;; If CP0_Cause bit 23 != 0: Offset := 0x200
2099 mov eax, 0x200 ; Offset := 0x200
2100 jmp _H_Exc_Have_Offset ; Go to H_Exc_Have_Offset
2101 __H_Exc_Was_TLB: ; This WAS a TLB Exception:
2102 Flg_Get ExcWasTLBNoMatch ; CF := 'TLB No Match'
2103 ;; TODO: in 'cmips', this case was reversed? why?
2104 ;; For now, we'll do likewise:
2105 jnc _H_Exc_Off_Is_180 ; ... if 0, Offset := 0x180
2106 ;; Else: Offset := 0x0
2107 xor eax, eax ; Clear EAX (Offset := 0)
2108 jmp _H_Exc_Have_Offset ; Finish up
2109 _H_Exc_Off_Is_180: ; Offset := 0x180
2110 mov eax, 0x180 ; Set the Offset
2111 _H_Exc_Have_Offset: ; We finished calculating the Offset:
2112 bts CP0_Status, CP0St_EXL ; Set the EXL Flag
2113 mov PC, eax ; PC := Offset (eax)
2114 mov eax, 0x80000000 ; Base that will be used if BEV=0
2115 mov ebx, 0xBFC00200 ; Base that will be used if BEV=1
2116 bt CP0_Status, CP0St_BEV ; CF := the BEV Flag
2117 cmovc eax, ebx ; If CF = 1, use the BEV=1 Base
2118 add PC, eax ; PC := PC + Base
2119 ;; Done handling exception
2120 jmp _cycle ; Start next cycle.
2121 ;-----------------------------------------------------------------------------