m_genesis.kv 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
m_genesis.kv 2 ;; ;;
m_genesis.kv 3 ;; This file is part of 'M', a MIPS system emulator. ;;
m_genesis.kv 4 ;; ;;
m_genesis.kv 5 ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;;
m_genesis.kv 6 ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;;
m_genesis.kv 7 ;; ;;
m_genesis.kv 8 ;; You do not have, nor can you ever acquire the right to use, copy or ;;
m_genesis.kv 9 ;; distribute this software ; Should you use this software for any purpose, ;;
m_genesis.kv 10 ;; or copy and distribute it to anyone or in any manner, you are breaking ;;
m_genesis.kv 11 ;; the laws of whatever soi-disant jurisdiction, and you promise to ;;
m_genesis.kv 12 ;; continue doing so for the indefinite future. In any case, please ;;
m_genesis.kv 13 ;; always : read and understand any software ; verify any PGP signatures ;;
m_genesis.kv 14 ;; that you use - for any purpose. ;;
m_genesis.kv 15 ;; ;;
m_genesis.kv 16 ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;;
m_genesis.kv 17 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
m_genesis.kv 18
m_genesis.kv 19 ;-----------------------------------------------------------------------------
m_genesis.kv 20 ; Helper macros for MIPS instruction operands.
m_genesis.kv 21 ; All presume that current MIPS instruction is found in r_I.
m_genesis.kv 22 ; Note that variable shifts on x86 require slide amount to reside in CL.
m_genesis.kv 23 ;-----------------------------------------------------------------------------
m_genesis.kv 24
m_genesis.kv 25 ;-----------------------------------------------------------------------------
m_genesis.kv 26 ; These constants are fixed for the MIPS32 architecture and will NEVER change:
m_genesis.kv 27 ;-----------------------------------------------------------------------------
m_genesis.kv 28 ; Masks for Instruction Fields:
m_genesis.kv 29 %define rD_Mask 0xF800 ; Mask for rD Field
m_genesis.kv 30 %define rS_Mask 0x3E00000 ; Mask for rS Field
m_genesis.kv 31 %define rT_Mask 0x1F0000 ; Mask for rT Field
m_genesis.kv 32 %define Imm_Mask 0xFFFF ; Mask for Imm Field
m_genesis.kv 33 %define Shamt_Mask 0x7C0 ; Mask for Shamt Field
m_genesis.kv 34 %define J_Mask 0x3FFFFFF ; Mask for J Field
m_genesis.kv 35 %define Q_Mask 0x7 ; Mask for Q Field (MFC0/MTC0 instructions)
m_genesis.kv 36 ;-----------------------------------------------------------------------------
m_genesis.kv 37 ; Shifts for Instruction Fields (Imm doesn't need one) :
m_genesis.kv 38 %define rD_Shr 11 ; Right Shift for rD Field
m_genesis.kv 39 %define rS_Shr 21 ; Right Shift for rS Field
m_genesis.kv 40 %define rT_Shr 16 ; Right Shift for rT Field
m_genesis.kv 41 %define Shamt_Shr 6 ; Right Shift for Shamt Field
m_genesis.kv 42 %define J_Shl 2 ; Left Shift for J Field
m_genesis.kv 43 ;-----------------------------------------------------------------------------
m_genesis.kv 44
m_genesis.kv 45 ;-----------------------------------------------------------------------------
m_genesis.kv 46 ; Register Placements
m_genesis.kv 47 ;-----------------------------------------------------------------------------
m_genesis.kv 48
m_genesis.kv 49 ; To point to MIPS state:
m_genesis.kv 50 %define M_Base_64 rbp ; Pointer to base of MIPS data structure
m_genesis.kv 51 %define M_Base_32 ebp ; 32-bit component of above
m_genesis.kv 52
m_genesis.kv 53 ;-----------------------------------------------------------------------------
m_genesis.kv 54 ; Scratch Registers used inside Opcodes:
m_genesis.kv 55 ;-----------------------------------------------------------------------------
m_genesis.kv 56 %define rD eax ; Where to extract rD Field
m_genesis.kv 57 %define Imm rD ; Where IType's Imm goes (they have no rD)
m_genesis.kv 58 %define JTarg rD ; Where JType's J field goes
m_genesis.kv 59
m_genesis.kv 60 ; x86 is braindamaged and DEMANDS variable shift slides in CL. So rS is ECX.
m_genesis.kv 61 %define rS ecx ; Where to extract rS Field
m_genesis.kv 62 %define rS_LowByte cl ; Low byte of rS, for some 'flag' ops
m_genesis.kv 63 %define r_Shamt rS ; must be also this (see above)
m_genesis.kv 64 %define r_Q rS ; Q field in the coprocessor instructions
m_genesis.kv 65
m_genesis.kv 66 %define rT ebx ; Where to extract rT Field
m_genesis.kv 67
m_genesis.kv 68 ; Scratch Register for intermediates:
m_genesis.kv 69 %define TMP edx ; Scratch register used in all ops
m_genesis.kv 70 %define TMP_LowByte dl ; Low byte of TMP, for some 'flag' ops
m_genesis.kv 71
m_genesis.kv 72 ; After we decode all fields, we no longer need the original instruction :
m_genesis.kv 73 %define r_I TMP ; Copy of currently-executing instruction
m_genesis.kv 74 ;-----------------------------------------------------------------------------
m_genesis.kv 75
m_genesis.kv 76 ;-----------------------------------------------------------------------------
m_genesis.kv 77 ; Instruction Field Manipulations. Arranged so as to satisfy the x86 pipeline.
m_genesis.kv 78 ;-----------------------------------------------------------------------------
m_genesis.kv 79
m_genesis.kv 80 ;-----------------------------------------------------------------------------
m_genesis.kv 81 ; Extract rD, rS, rT fields from the currently-executing MIPS instruction
m_genesis.kv 82 ; For instructions encoded as ???? ??ss ssst tttt dddd d??? ???? ????
m_genesis.kv 83 ;-----------------------------------------------------------------------------
m_genesis.kv 84 %macro RType 0 ; no params
m_genesis.kv 85 mov rD, rD_Mask ; Mask for rD Field
m_genesis.kv 86 mov rS, rS_Mask ; Mask for rS Field
m_genesis.kv 87 mov rT, rT_Mask ; Mask for rT Field
m_genesis.kv 88 and rD, r_I ; Mask orig. inst. to get rD Field
m_genesis.kv 89 and rS, r_I ; Mask orig. inst. to get rS Field
m_genesis.kv 90 and rT, r_I ; Mask orig. inst. to get rT Field
m_genesis.kv 91 shr rD, rD_Shr ; rD is now rD Index
m_genesis.kv 92 shr rS, rS_Shr ; rS is now rS Index
m_genesis.kv 93 shr rT, rT_Shr ; rT is now rT Index
m_genesis.kv 94 %endmacro
m_genesis.kv 95 ;-----------------------------------------------------------------------------
m_genesis.kv 96
m_genesis.kv 97 ;-----------------------------------------------------------------------------
m_genesis.kv 98 ; Extract only rS field from the currently-executing MIPS instruction
m_genesis.kv 99 ; For instructions encoded as ???? ??ss sss? ???? ???? ???? ???? ????
m_genesis.kv 100 ;-----------------------------------------------------------------------------
m_genesis.kv 101 %macro RType_S_Only 0 ; no params
m_genesis.kv 102 mov rS, rS_Mask ; Mask for rS Field
m_genesis.kv 103 and rS, r_I ; Mask orig. inst. to get rS Field
m_genesis.kv 104 shr rS, rS_Shr ; rS is now rS Index
m_genesis.kv 105 %endmacro
m_genesis.kv 106 ;-----------------------------------------------------------------------------
m_genesis.kv 107
m_genesis.kv 108 ; Works same
m_genesis.kv 109 %define IType_S_Only RType_S_Only
m_genesis.kv 110
m_genesis.kv 111 ;-----------------------------------------------------------------------------
m_genesis.kv 112 ; Extract only rS and rT fields from the currently-executing MIPS instruction
m_genesis.kv 113 ; For instructions encoded as ???? ??ss ssst tttt ???? ???? ???? ????
m_genesis.kv 114 ;-----------------------------------------------------------------------------
m_genesis.kv 115 %macro RType_S_T_Only 0 ; no params
m_genesis.kv 116 mov rS, rS_Mask ; Mask for rS Field
m_genesis.kv 117 mov rT, rT_Mask ; Mask for rT Field
m_genesis.kv 118 and rS, r_I ; Mask orig. inst. to get rS Field
m_genesis.kv 119 and rT, r_I ; Mask orig. inst. to get rT Field
m_genesis.kv 120 shr rS, rS_Shr ; rS is now rS Index
m_genesis.kv 121 shr rT, rT_Shr ; rT is now rT Index
m_genesis.kv 122 %endmacro
m_genesis.kv 123 ;-----------------------------------------------------------------------------
m_genesis.kv 124
m_genesis.kv 125 ; Works same
m_genesis.kv 126 %define IType_S_T_Only RType_S_T_Only
m_genesis.kv 127
m_genesis.kv 128 ;-----------------------------------------------------------------------------
m_genesis.kv 129 ; Extract only rS and rD fields from the currently-executing MIPS instruction
m_genesis.kv 130 ; For instructions encoded as ???? ??ss sss? ???? dddd d??? ???? ????
m_genesis.kv 131 ;-----------------------------------------------------------------------------
m_genesis.kv 132 %macro RType_S_D_Only 0 ; no params
m_genesis.kv 133 mov rD, rD_Mask ; Mask for rD Field
m_genesis.kv 134 mov rS, rS_Mask ; Mask for rS Field
m_genesis.kv 135 and rD, r_I ; Mask orig. inst. to get rD Field
m_genesis.kv 136 and rS, r_I ; Mask orig. inst. to get rS Field
m_genesis.kv 137 shr rD, rD_Shr ; rD is now rD Index
m_genesis.kv 138 shr rS, rS_Shr ; rS is now rS Index
m_genesis.kv 139 %endmacro
m_genesis.kv 140 ;-----------------------------------------------------------------------------
m_genesis.kv 141
m_genesis.kv 142 ;-----------------------------------------------------------------------------
m_genesis.kv 143 ; Extract only rD field from the currently-executing MIPS instruction
m_genesis.kv 144 ; For instructions encoded as ???? ???? ???? ???? dddd d??? ???? ????
m_genesis.kv 145 ;-----------------------------------------------------------------------------
m_genesis.kv 146 %macro RType_D_Only 0 ; no params
m_genesis.kv 147 mov rD, rD_Mask ; Mask for rD Field
m_genesis.kv 148 and rD, r_I ; Mask orig. inst. to get rD Field
m_genesis.kv 149 shr rD, rD_Shr ; rD is now rD Index
m_genesis.kv 150 %endmacro
m_genesis.kv 151 ;-----------------------------------------------------------------------------
m_genesis.kv 152
m_genesis.kv 153 ;-----------------------------------------------------------------------------
m_genesis.kv 154 ; Extract rD, rT, Shamt fields from the currently-executing MIPS instruction
m_genesis.kv 155 ; For instructions encoded as ???? ???? ???t tttt dddd dhhh hh?? ????
m_genesis.kv 156 ;-----------------------------------------------------------------------------
m_genesis.kv 157 %macro RType_D_T_Shamt 0 ; no params
m_genesis.kv 158 mov rD, rD_Mask ; Mask for rD Field
m_genesis.kv 159 mov r_Shamt, Shamt_Mask ; Mask for Shamt Field
m_genesis.kv 160 mov rT, rT_Mask ; Mask for rT Field
m_genesis.kv 161 and rD, r_I ; Mask orig. inst. to get rD Field
m_genesis.kv 162 and r_Shamt, r_I ; Mask orig. inst. to get Shamt Field
m_genesis.kv 163 and rT, r_I ; Mask orig. inst. to get rT Field
m_genesis.kv 164 shr rD, rD_Shr ; rD is now rD Index
m_genesis.kv 165 shr r_Shamt, Shamt_Shr ; r_Shamt is now Shamt value
m_genesis.kv 166 shr rT, rT_Shr ; rT is now rT Index
m_genesis.kv 167 %endmacro
m_genesis.kv 168 ;-----------------------------------------------------------------------------
m_genesis.kv 169
m_genesis.kv 170 ;-----------------------------------------------------------------------------
m_genesis.kv 171 ; Extract rD, rT, Q fields from the currently-executing MIPS instruction
m_genesis.kv 172 ; For MFC/MTC instructions encoded as 0100 0000 ?00t tttt dddd d000 0000 0qqq
m_genesis.kv 173 ;-----------------------------------------------------------------------------
m_genesis.kv 174 %macro CPType 0 ; no params
m_genesis.kv 175 mov rD, rD_Mask ; Mask for rD Field
m_genesis.kv 176 mov r_Q, Q_Mask ; Mask for Q Field
m_genesis.kv 177 mov rT, rT_Mask ; Mask for rT Field
m_genesis.kv 178 and rD, r_I ; Mask orig. inst. to get rD Field
m_genesis.kv 179 and r_Q, r_I ; Mask orig. inst. to get Q Field
m_genesis.kv 180 and rT, r_I ; Mask orig. inst. to get rT Field
m_genesis.kv 181 shr rD, rD_Shr ; rD is now rD Index
m_genesis.kv 182 shr rT, rT_Shr ; rT is now rT Index
m_genesis.kv 183 %endmacro
m_genesis.kv 184 ;-----------------------------------------------------------------------------
m_genesis.kv 185
m_genesis.kv 186 ;-----------------------------------------------------------------------------
m_genesis.kv 187 ; Extract Imm, rS, rT fields from the currently-executing MIPS instruction
m_genesis.kv 188 ;-----------------------------------------------------------------------------
m_genesis.kv 189 %macro IType 0 ; no params
m_genesis.kv 190 mov Imm, Imm_Mask ; Mask for Imm Field; needs no shift
m_genesis.kv 191 mov rS, rS_Mask ; Mask for rS Field
m_genesis.kv 192 mov rT, rT_Mask ; Mask for rT Field
m_genesis.kv 193 and Imm, r_I ; Mask orig. inst. to get Imm Field
m_genesis.kv 194 and rS, r_I ; Mask orig. inst. to get rS Field
m_genesis.kv 195 and rT, r_I ; Mask orig. inst. to get rT Field
m_genesis.kv 196 shr rS, rS_Shr ; rS is now rS Index
m_genesis.kv 197 shr rT, rT_Shr ; rT is now rT Index
m_genesis.kv 198 %endmacro
m_genesis.kv 199 ;-----------------------------------------------------------------------------
m_genesis.kv 200
m_genesis.kv 201 ;-----------------------------------------------------------------------------
m_genesis.kv 202 ; Extract only Imm, rS fields from the currently-executing MIPS instruction
m_genesis.kv 203 ;-----------------------------------------------------------------------------
m_genesis.kv 204 %macro IType_I_S_Only 0 ; no params
m_genesis.kv 205 mov Imm, Imm_Mask ; Mask for Imm Field; needs no shift
m_genesis.kv 206 mov rS, rS_Mask ; Mask for rS Field
m_genesis.kv 207 and Imm, r_I ; Mask orig. inst. to get Imm Field
m_genesis.kv 208 and rS, r_I ; Mask orig. inst. to get rS Field
m_genesis.kv 209 shr rS, rS_Shr ; rS is now rS Index
m_genesis.kv 210 %endmacro
m_genesis.kv 211 ;-----------------------------------------------------------------------------
m_genesis.kv 212
m_genesis.kv 213 ;-----------------------------------------------------------------------------
m_genesis.kv 214 ; Extract only Imm field from the currently-executing MIPS instruction
m_genesis.kv 215 ;-----------------------------------------------------------------------------
m_genesis.kv 216 %macro IType_I_Only 0 ; no params
m_genesis.kv 217 mov Imm, Imm_Mask ; Mask for Imm Field; needs no shift
m_genesis.kv 218 and Imm, r_I ; Mask orig. inst. to get Imm Field
m_genesis.kv 219 %endmacro
m_genesis.kv 220 ;-----------------------------------------------------------------------------
m_genesis.kv 221
m_genesis.kv 222 ;-----------------------------------------------------------------------------
m_genesis.kv 223 ; Extract Imm, rT fields from the currently-executing MIPS instruction
m_genesis.kv 224 ;-----------------------------------------------------------------------------
m_genesis.kv 225 %macro IType_I_T_Only 0 ; no params
m_genesis.kv 226 mov Imm, Imm_Mask ; Mask for Imm Field; needs no shift
m_genesis.kv 227 mov rT, rT_Mask ; Mask for rT Field
m_genesis.kv 228 and Imm, r_I ; Mask orig. inst. to get Imm Field
m_genesis.kv 229 and rT, r_I ; Mask orig. inst. to get rT Field
m_genesis.kv 230 shr rT, rT_Shr ; rT is now rT Index
m_genesis.kv 231 %endmacro
m_genesis.kv 232 ;-----------------------------------------------------------------------------
m_genesis.kv 233
m_genesis.kv 234 ;-----------------------------------------------------------------------------
m_genesis.kv 235 ; Extract J field from the currently-executing MIPS instruction
m_genesis.kv 236 ; Encoding: ???? 11ii iiii iiii iiii iiii iiii iiii
m_genesis.kv 237 ;-----------------------------------------------------------------------------
m_genesis.kv 238 %macro JType 0 ; no params
m_genesis.kv 239 mov JTarg, J_Mask ; Mask for J Field; needs no shift
m_genesis.kv 240 and JTarg, r_I ; Mask orig. inst. to get J Field
m_genesis.kv 241 shl JTarg, J_Shl ; Shift the J Field to get Target Address
m_genesis.kv 242 %endmacro
m_genesis.kv 243 ;-----------------------------------------------------------------------------
m_genesis.kv 244
m_genesis.kv 245 ;-----------------------------------------------------------------------------
m_genesis.kv 246 ; Sign-Extend((16bit Address) * 4) (where 18th bit is considered 'sign')
m_genesis.kv 247 ;-----------------------------------------------------------------------------
m_genesis.kv 248 %macro SX18_4N 1 ; param is A, the address to extend
m_genesis.kv 249 shl %1, 16 ; upper 16 bits are now equal to A
m_genesis.kv 250 sar %1, 14 ; Shift back to A*4, extending sign bit.
m_genesis.kv 251 %endmacro
m_genesis.kv 252 ;-----------------------------------------------------------------------------
m_genesis.kv 253
m_genesis.kv 254 ;-----------------------------------------------------------------------------
m_genesis.kv 255 ; Sign-Extend(16bit Address) (where 16th bit is considered 'sign')
m_genesis.kv 256 ;-----------------------------------------------------------------------------
m_genesis.kv 257 %macro SX16 1 ; param is A, the address to extend
m_genesis.kv 258 shl %1, 16 ; upper 16 bits are now equal to A
m_genesis.kv 259 sar %1, 16 ; Shift back to A, extending sign bit.
m_genesis.kv 260 %endmacro
m_genesis.kv 261 ;-----------------------------------------------------------------------------
m_genesis.kv 262
m_genesis.kv 263 ;-----------------------------------------------------------------------------
m_genesis.kv 264 ; Denote privileged (permitted in Kernel-Mode strictly) instructions.
m_genesis.kv 265 ;-----------------------------------------------------------------------------
m_genesis.kv 266 %macro PRIVILEGED 0
m_genesis.kv 267 bt CP0_Status, CP0St_UM ; CF := CP0St_UM Flag
m_genesis.kv 268 jnc %%proceed ; If UM = 0: Kernel Mode, proceed.
m_genesis.kv 269 test CP0_Status, (1 << CP0St_EXL) | (1 << CP0St_ERL) ; EXL or ERL
m_genesis.kv 270 jnz %%proceed ; If EXL && ERL: Kernel Mode, proceed.
m_genesis.kv 271 ;; We are NOT in kernel mode, but trying to execute a privileged inst:
m_genesis.kv 272 SetEXC EXC_RI ; Set the 'Reserved Instr.' Exception.
m_genesis.kv 273 jmp _Handle_Exception ; Go straight to exception handler.
m_genesis.kv 274 %%proceed ; We're in Kernel Mode, so proceed with the privileged instruction.
m_genesis.kv 275 %endmacro
m_genesis.kv 276 ;-----------------------------------------------------------------------------
m_genesis.kv 277
m_genesis.kv 278 ;-----------------------------------------------------------------------------
m_genesis.kv 279 ; Store the significant 32 bits of locative
m_genesis.kv 280 ;-----------------------------------------------------------------------------
m_genesis.kv 281 %macro A32 1 ; %1: locative
m_genesis.kv 282 dd %1
m_genesis.kv 283 %endmacro
m_genesis.kv 284 ;-----------------------------------------------------------------------------