raw
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 section .text
m_genesis.kv 20
m_genesis.kv 21 ;-----------------------------------------------------------------------------
m_genesis.kv 22 ; Dispatch via rax, given index Register, and given Table (of 32-bit offsets)
m_genesis.kv 23 ;-----------------------------------------------------------------------------
m_genesis.kv 24 %macro JTABLE 2 ; %1 : index register, %2 : table offset
m_genesis.kv 25 mov eax, dword [%2 + 4 * %1]
m_genesis.kv 26 jmp rax
m_genesis.kv 27 %endmacro
m_genesis.kv 28 ;-----------------------------------------------------------------------------
m_genesis.kv 29
m_genesis.kv 30 ;----------------------------
m_genesis.kv 31 ; Start of MIPS CPU Cycle : |
m_genesis.kv 32 ;-----------------------------------------------------------------------------
m_genesis.kv 33 _wait_cycle:
m_genesis.kv 34 _cycle:
m_genesis.kv 35 inc CP0_Count ; Timer: CP0_Count := CP0_Count + 1
m_genesis.kv 36
m_genesis.kv 37 ;; Timer Interrupt
m_genesis.kv 38 cmp CP0_Count, CP0_Compare ; Has timer reached limit?
m_genesis.kv 39 jne _cycle_no_mips_timer ; If not, do not invoke interrupt
m_genesis.kv 40 SetIRQ TIMER_IRQ ; Timer reached limit, invoke timer IRQ
m_genesis.kv 41
m_genesis.kv 42 _cycle_no_mips_timer:
m_genesis.kv 43
m_genesis.kv 44 ;; Test if Interrupts are Disabled:
m_genesis.kv 45 bt CP0_Status, CP0St_IE ; CF := CP0St_IE
m_genesis.kv 46 jnc _cycle_no_irq ; If 0, IRQs are disabled, go to no_irq
m_genesis.kv 47 test CP0_Status, (1 << CP0St_ERL) | (1 << CP0St_EXL) ; If ERL/EXL:
m_genesis.kv 48 jnz _cycle_no_irq ; ... then also interrupts are disabled
m_genesis.kv 49
m_genesis.kv 50 GetSlaveIRQ ; See if slave threw interrupt
m_genesis.kv 51
m_genesis.kv 52 ;; Interrupts are Enabled; handle any pending Interrupt:
m_genesis.kv 53 mov eax, 0xFC00 ; ( 0xFC00 &
m_genesis.kv 54 and eax, CP0_Cause ; CP0_Cause &
m_genesis.kv 55 and eax, CP0_Status ; CP0_Status )
m_genesis.kv 56 jz _cycle_no_irq ; == 0 ? Then no pending IRQ, go to no_irq.
m_genesis.kv 57
m_genesis.kv 58 ;; If here, there is a pending interrupt, service it:
m_genesis.kv 59 _cycle_irq_handler:
m_genesis.kv 60
m_genesis.kv 61 Flg_Off Waiting ; Clear Waiting Flag
m_genesis.kv 62 SetEXC EXC_Int ; Set the EXC_Int Exception Code
m_genesis.kv 63
m_genesis.kv 64 ;; Copy InDelaySlot Flag to RunningDelaySlot Flag:
m_genesis.kv 65 Flg_Cpy RunningDelaySlot, InDelaySlot
m_genesis.kv 66
m_genesis.kv 67 jmp _Handle_Exception ; Handle exception and end cycle.
m_genesis.kv 68
m_genesis.kv 69 _cycle_no_irq: ; If ints disabled or none pending
m_genesis.kv 70
m_genesis.kv 71 Flg_Get Waiting ; CF := Waiting Flag
m_genesis.kv 72 jc _wait_cycle ; If Waiting, start next cycle, else:
m_genesis.kv 73
m_genesis.kv 74 ;; Copy InDelaySlot Flag to RunningDelaySlot Flag:
m_genesis.kv 75 Flg_Cpy RunningDelaySlot, InDelaySlot
m_genesis.kv 76
m_genesis.kv 77 ;; Fetch the instruction to execute:
m_genesis.kv 78 mov eax, PC ; vAddr := PC
m_genesis.kv 79 call _Virt_Read_Word ; EAX := MEM[Virt2Phys(PC)]
m_genesis.kv 80 mov r_I, eax ; Store fetched instruction
m_genesis.kv 81
m_genesis.kv 82 ;; Dispatch the current instruction:
m_genesis.kv 83 mov eax, r_I ; Get the original instruction :
m_genesis.kv 84
m_genesis.kv 85 ;; 'Accelerated NOPs'
m_genesis.kv 86 test eax, eax ; Is the current instruction null?
m_genesis.kv 87 jnz _not_nop ; ... if so, skip dispatch entirely!
m_genesis.kv 88 jmp _end_cycle ; go to tail of this cycle
m_genesis.kv 89 _not_nop: ; If not a NOP:
m_genesis.kv 90
m_genesis.kv 91 shr eax, 26 ; Get I-field (upper 6 bits of instr) ;
m_genesis.kv 92 JTABLE eax, _I_Table ; Dispatch on I-field via I-Table.
m_genesis.kv 93 ;;; Instruction executes, after which goes to _end_cycle
m_genesis.kv 94 ;-----------------------------------------------------------------------------
m_genesis.kv 95
m_genesis.kv 96 ;---------------------------------
m_genesis.kv 97 ; Tail End of a MIPS CPU Cycle : |
m_genesis.kv 98 ;-----------------------------------------------------------------------------
m_genesis.kv 99 _end_cycle:
m_genesis.kv 100 Flg_GOF RunningDelaySlot ; Were we running the delay slot?
m_genesis.kv 101 jnc _end_cycle_was_not_in_delay_slot ; if not, skip, else:
m_genesis.kv 102 ;; We WERE running in the delay slot:
m_genesis.kv 103 _end_cycle_was_in_delay_slot: ; If we were running the delay slot:
m_genesis.kv 104 mov PC, nPC ; PC := nPC
m_genesis.kv 105 Flg_Off InDelaySlot ; Clear the InDelaySlot Flag
m_genesis.kv 106 jmp _cycle ; Go to next cycle without advancing PC
m_genesis.kv 107 _end_cycle_was_not_in_delay_slot: ; If we were NOT running the delay slot:
m_genesis.kv 108 add PC, 0x4 ; PC := PC + 4
m_genesis.kv 109 ;; Test for Shutdown Condition:
m_genesis.kv 110 Flg_Get Shutdown ; CF := Shutdown Flag
m_genesis.kv 111 jc _shutdown ; ... if CF, then shut down.
m_genesis.kv 112 jmp _cycle ; ... otherwise, go to next cycle.
m_genesis.kv 113 ;-----------------------------------------------------------------------------