;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; This file is part of 'M', a MIPS system emulator. ;; ;; ;; ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;; ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;; ;; ;; ;; You do not have, nor can you ever acquire the right to use, copy or ;; ;; distribute this software ; Should you use this software for any purpose, ;; ;; or copy and distribute it to anyone or in any manner, you are breaking ;; ;; the laws of whatever soi-disant jurisdiction, and you promise to ;; ;; continue doing so for the indefinite future. In any case, please ;; ;; always : read and understand any software ; verify any PGP signatures ;; ;; that you use - for any purpose. ;; ;; ;; ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;----------------------------------------------------------------------------- ; MIPS Processor State. ; Note: PC, nPC, CP0_Status, CP0_Cause, CP0_Compare, are housed in x86 regs. struc MCPU .Regs resd 32 ; The standard MIPS Register Set .LO resd 1 ; Multiplication/division results - Low Half .HI resd 1 ; Multiplication/division results - High Half .CP0_Index resd 1 ; Index into the TLB array .CP0_EntryHi resd 1 ; High-order portion of the TLB entry .CP0_EntryLo0 resd 1 ; Low portion of TLB entry for even-#'d pages .CP0_EntryLo1 resd 1 ; Low portion of TLB entry for odd-#'d pages .CP0_Context resd 1 .CP0_Wired resd 1 ; The number of fixed ('wired') TLB entries .CP0_Epc resd 1 ; Exception program counter return address .CP0_BadVAddr resd 1 ; Addr. of most recent addr.-caused exception .CP0_ErrorEpc resd 1 ; Program counter at last exception .CP0_PageMask resd 1 ; Control variable page sizes in TLB entries ;; The TLB: .TLB_Entries resd TLB_ENTRIES_COUNT ; TLB entries (without PFN) .TLB_PFN_Even resd TLB_ENTRIES_COUNT ; TLB PFN0 .TLB_PFN_Odd resd TLB_ENTRIES_COUNT ; TLB PFN1 endstruc ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Refer to the N-th TLB Entry: ;----------------------------------------------------------------------------- %define TLB_E(N) dword [M_Base_32 + MCPU.TLB_Entries + 4 * (N)] ; N-th PFN : %define TLB_PFN_E(N) dword [M_Base_32 + MCPU.TLB_PFN_Even + 4 * (N)] %define TLB_PFN_O(N) dword [M_Base_32 + MCPU.TLB_PFN_Odd + 4 * (N)] ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- section .bss align GRAIN ; MIPS CPU State MIPS_State resb MCPU_size section .text ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Global 'fast' MIPS State: ; TODO: is it possible to use the upper halves of the 64bit regs for anything? ; ... or entirely worthless from intel's idiocy of 'auto-zero on mov' ? ;----------------------------------------------------------------------------- %define Flag_Reg edi ; Delay, Exception, etc flags %define RAM_Floor rsi ; Physical (x86) address of 1st RAM word %define RAM_Ceiling r8 ; Physical (x86) address of last RAM word %define PC r9d ; Current Program Counter %define nPC r10d ; 'Next' Program Counter %define CP0_Status r11d ; Processor status and control %define CP0_Cause r12d ; Cause of last general exception %define CP0_Count r13d ; Processor cycle count %define CP0_Compare r14d ; Timer interrupt control %define AUX r15d ; Additional TMP for certain ops ; TODO: 'Suspend to RAM' routine for all of the above. ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Access to MIPS Registers that live in MCPU (Emulator State) : ;----------------------------------------------------------------------------- ; Refer to given MIPS special Reg: ;----------------------------------------------------------------------------- %define Sr(N) dword [M_Base_32 + MCPU. %+ N] ;----------------------------------------------------------------------------- ; Refer to Nth Reg: ;----------------------------------------------------------------------------- %define R(N) Sr(Regs + 4 * (N)) ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Update given MIPS Reg # with new value, but always avoid overwriting R(0) ;----------------------------------------------------------------------------- ; TODO: measure if this is actually faster than simply R(31) := 0 every time %macro Wr_Reg 2 ; params: %1: Reg # %2: PC reg with new value xor AUX, AUX ; Clear AUX test %1, %1 ; Set Z if destination reg # is R(0) cmovz %2, AUX ; If Z: Replace written value with zero mov R(%1), %2 ; Regs[rD] := new value ;;;; alt variant: ; mov R(%1), %2 ; Regs[rD] := new value ; mov R(0), 0 ;;;; TODO: which is actually faster ? %endmacro ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Init MIPS CPU: ;----------------------------------------------------------------------------- _cpu_reset: xor eax, eax ; eax := 0 mov AUX, eax ; Clear AUX register mov M_Base_64, MIPS_State ; Set RBP to point to MIPS CPU State ;; Init 'fast' MIPS Regs: mov PC, INIT_PC mov nPC, eax mov CP0_Status, eax mov CP0_Cause, eax mov CP0_Count, eax mov CP0_Compare, eax ;; Init 'slow' MIPS Regs: mov ecx, 0 _init_reg: mov R(ecx), eax inc ecx cmp ecx, 32 jb _init_reg xor ecx, ecx mov Sr(HI), eax mov Sr(LO), eax mov Sr(CP0_Index), eax mov Sr(CP0_EntryHi), eax mov Sr(CP0_EntryLo0), eax mov Sr(CP0_EntryLo1), eax mov Sr(CP0_Context), eax mov Sr(CP0_Wired), eax mov Sr(CP0_Epc), eax mov Sr(CP0_BadVAddr), eax mov Sr(CP0_ErrorEpc), eax Flg_Clear_All ; Reset all misc Flags to 0 bts CP0_Status, CP0St_ERL ; Start in kernel mode w/ unmapped useg ret ;-----------------------------------------------------------------------------