;
; Project UnReality: The First Nintendo 64 Emulator
; Copyright (C) 1997-1998, Cold Fusion Entertainment
; All rights reserved
;
; This source code is unpublished propietary information of Cold Fusion Entertainment.  No portion of this software
; may be disclosed to any third party or copied or duplicated in any form, in whole or in part, without the prior
; written consent of Cold Fusion Entertainment.
;

;
; $Log: r4300str.inc $
; Revision 1.9  1998/05/25 04:39:35  BREAKPOINT
; Added 'Call Stack' to debugger which shows the history of JAL[R]/JR RA instructions.
; Revision 1.8  1998/05/24 20:49:41  BREAKPOINT
; Beginning of TLB implementation... fixed c0reg.Context to be 32 bit, changed exception handler to support TLB and modified
; assembly core to be re-entrant.
; Revision 1.7  1998/05/23 15:40:43  BREAKPOINT
; Added COP0 IE status bit.
; Revision 1.6  1998/04/03 00:04:57  BREAKPOINT
; Added COP1 FCSR compare flag.
; Revision 1.5  1998/04/02 21:18:56  BREAKPOINT
; Implemented new memory mapping routines and changed ROM loading code.
; Revision 1.4  1998/03/08 19:13:30  BREAKPOINT
; Version 0.3b.3 checkin... I need to really check this stuff in more often..
; Revision 1.3  1998/01/31 20:02:40  BREAKPOINT
; Lots of new changes to work with new assembly core...
; Revision 1.2  1998/01/20 00:34:22  BREAKPOINT
; *Whole* new structure definition file... includes complete specs on
; all of the N64's MMIO register maps.
; Revision 1.1  1998/01/10 21:58:13  BREAKPOINT
; Initial revision
;

;---------------------------------------------------------------------------------------------------------------------

;
; -------------------------------------------[ N64EventArray structure ]------------------------------------------------------
;

N64EventStruct STRUC
    Time        dq  ?
    Action      dd  ?
ENDS

N64EVENTARRAY_OFFSET_TO_ACTION      EQU     8       ; offset from Time to Action

;
; ----------------------------------------------[ R4300i structure ]------------------------------------------------------
;

R4RegSet STRUC
	GPR			dd	?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?		; Integer registers
				dd	?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?

	GPR64		dq	?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?		; 64-bit Integer registers
				dq  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?

	FGR			dd	?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?		; Floating point registers (of type 'float' in C)
				dd  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?

	PC			dd	?													; Program counter
	MultHI		dd	?													; Multiply / divide registers
	MultLO		dd	?
	MultHI64	dq	?													; Multiply / divide registers in 64-bit mode
	MultLO64	dq	?
	LLBit		db	?													; Load / link bit
ENDS

DMA_TRANSFER_BYTES  EQU		41984

;
; ------------------------------------------------[ TLB structures ]------------------------------------------------------
;

tlb_entry STRUC
	tlb_PageMask	dd	?
	tlb_EntryHi		dd	?
	tlb_EntryLo1	dd	?
	tlb_EntryLo0	dd	?
ENDS

TLB_ENTRY_SIZE		EQU	16
TLB_ENTRY_SHIFT		EQU	4
TLB_INDEX_MASK      EQU 3Fh
TLBENTRIES			EQU	48

TLB STRUC
	tlb0		tlb_entry ?					; 48 entries in TLB, defined in: R4400 User's Manual, pg 80
	tlb1		tlb_entry ?
	tlb2		tlb_entry ?
	tlb3		tlb_entry ?
	tlb4		tlb_entry ?
	tlb5		tlb_entry ?
	tlb6		tlb_entry ?
	tlb7		tlb_entry ?
	tlb8		tlb_entry ?
	tlb9		tlb_entry ?
	tlb10		tlb_entry ?
	tlb11		tlb_entry ?
	tlb12		tlb_entry ?
	tlb13		tlb_entry ?
	tlb14		tlb_entry ?
	tlb15		tlb_entry ?

	tlb16		tlb_entry ?
	tlb17		tlb_entry ?
	tlb18		tlb_entry ?
	tlb19		tlb_entry ?
	tlb20		tlb_entry ?
	tlb21		tlb_entry ?
	tlb22		tlb_entry ?
	tlb23		tlb_entry ?
	tlb24		tlb_entry ?
	tlb25		tlb_entry ?
	tlb26		tlb_entry ?
	tlb27		tlb_entry ?
	tlb28		tlb_entry ?
	tlb29		tlb_entry ?
	tlb30		tlb_entry ?
	tlb31		tlb_entry ?

	tlb32		tlb_entry ?
	tlb33		tlb_entry ?
	tlb34		tlb_entry ?
	tlb35		tlb_entry ?
	tlb36		tlb_entry ?
	tlb37		tlb_entry ?
	tlb38		tlb_entry ?
	tlb39		tlb_entry ?
	tlb40		tlb_entry ?
	tlb41		tlb_entry ?
	tlb42		tlb_entry ?
	tlb43		tlb_entry ?
	tlb44		tlb_entry ?
	tlb45		tlb_entry ?
	tlb46		tlb_entry ?
	tlb47		tlb_entry ?
ENDS

;
; -----------------------------------------[ COP0 register structure ]---------------------------------------------------
;

C0RegSet STRUC
	Index		dd	?					; Programmable pointer into TLB array
	Random		dd	?					; Random pointer into TLB array
	EntryLo0	dd	?					; Low half of the TLB entry for even VPN
	EntryLo1	dd	?					; Low half of the TLB entry for odd VPN
	Context		dd	?					; Pointer to kernel PTE table
	PageMask	dd	?					; TLB page mask
	Wired		dd	?					; Number of wired TLB entries
	c0unused7	dd	?					; - UNUSED -
	BadVAddr	dq	?					; Bad virtual address
	Count		dq	?					; Timer count  [YES, dq!]
	EntryHi		dd	?					; High half of TLB entry
	Compare		dd	?					; Timer compare
	Status		dd	?					; Status register
	Cause		dd	?					; Cause register
	ExceptionPC	dd	?					; Exception program counter
	PRevID		dd	?					; Processor revision identifier
	Config		dd	?					; Configuration register
	LLAddr		dd	?					; Load linked address
	WatchLo		dd	?					; Memory reference trap address lower bits
	WatchHi		dd	?					; Memory reference trap address upper bits
	XContext	dq	?					; Context register for MIPS III addressing
	c0unused21  dd  ?					; - UNUSED -
	c0unused22  dd  ?					; - UNUSED -
	c0unused23  dd  ?					; - UNUSED -
	c0unused24  dd  ?					; - UNUSED -
	c0unused25  dd  ?					; - UNUSED -
	PErr		dd	?					; - UNUSED -
	CacheErr	dd	?					; - UNUSED -
	TagLo		dd	?					; Cache tag register
	TagHi		dd	?					; Cache tag register (Reserved)
	ErrorEPC	dd	?					; Error exception program counter
ENDS

c0reg_offsets	dd	Index,      Random,     EntryLo0, EntryLo1, Context,  PageMask,   Wired,       c0unused7
				dd	BadVAddr,   Count,      EntryHi,  Compare,  Status,   Cause,      ExceptionPC, PRevID
				dd  Config,     LLAddr,     WatchLo,  WatchHi,  XContext, c0unused21, c0unused22,  c0unused23
				dd	c0unused24, c0unused25, PErr,     CacheErr, TagLo,    TagHi,      ErrorEPC

C0REG_INDEX			EQU	0
C0REG_RANDOM		EQU	1
C0REG_ENTRYLO0		EQU 2
C0REG_ENTRYLO1		EQU 3
C0REG_CONTEXT		EQU	4
C0REG_PAGEMASK		EQU	5
C0REG_WIRED			EQU	6
C0REG_BADVADDR		EQU	8
C0REG_COUNT			EQU	9
C0REG_ENTRYHI		EQU	10
C0REG_COMPARE		EQU	11
C0REG_STATUS		EQU	12
C0REG_CAUSE			EQU	13
C0REG_EXCEPTIONPC	EQU	14
C0REG_PREVID		EQU	15
C0REG_CONFIG		EQU	16
C0REG_LLADDR		EQU	17
C0REG_WATCHLO		EQU	18
C0REG_WATCHHI		EQU	19
C0REG_XCONTEXT		EQU	20
C0REG_PERR			EQU	26
C0REG_CACHEERR		EQU	27
C0REG_TAGLO			EQU	28
C0REG_TAGHI			EQU	29
C0REG_ERROREPC		EQU	30

C0STATUS_IE		EQU 00000001h
C0STATUS_EXL	EQU	00000002h
C0STATUS_ERL	EQU 00000004h
C0STATUS_SR		EQU	00100000h

;
; -----------------------------------------[ COP1 register structure ]---------------------------------------------------
;

C1RegSet STRUC
	Impl_Rev	dd	?					; Implementation / revision
	c1unused1	dd	?					; - UNUSED -
	c1unused2	dd	?					; - UNUSED -
	c1unused3	dd	?					; - UNUSED -
	c1unused4	dd	?					; - UNUSED -
	c1unused5	dd	?					; - UNUSED -
	c1unused6	dd	?					; - UNUSED -
	c1unused7	dd	?					; - UNUSED -
	c1unused8	dd	?					; - UNUSED -
	c1unused9	dd	?					; - UNUSED -
	c1unused10	dd	?					; - UNUSED -
	c1unused11	dd	?					; - UNUSED -
	c1unused12	dd	?					; - UNUSED -
	c1unused13	dd	?					; - UNUSED -
	c1unused14	dd	?					; - UNUSED -
	c1unused15	dd	?					; - UNUSED -
	c1unused16	dd	?					; - UNUSED -
	c1unused17	dd	?					; - UNUSED -
	c1unused18	dd	?					; - UNUSED -
	c1unused19	dd	?					; - UNUSED -
	c1unused20	dd	?					; - UNUSED -
	c1unused21	dd	?					; - UNUSED -
	c1unused22	dd	?					; - UNUSED -
	c1unused23	dd	?					; - UNUSED -
	c1unused24	dd	?					; - UNUSED -
	c1unused25	dd	?					; - UNUSED -
	c1unused26	dd	?					; - UNUSED -
	c1unused27	dd	?					; - UNUSED -
	c1unused28	dd	?					; - UNUSED -
	c1unused29	dd	?					; - UNUSED -
	c1unused30	dd	?					; - UNUSED -
	FCSR		dd	?					; Control / status
ENDS

c1reg_offsets	dd	Impl_Rev,   c1unused1,  c1unused2,  c1unused3,  c1unused4,  c1unused5,  c1unused6,  c1unused7
				dd	c1unused8,  c1unused9,  c1unused10, c1unused11, c1unused12, c1unused13, c1unused14, c1unused15
				dd	c1unused16, c1unused17, c1unused18, c1unused19, c1unused20, c1unused21, c1unused22, c1unused23
				dd	c1unused24, c1unused25, c1unused26, c1unused27, c1unused28, c1unused29, c1unused30, FCSR

C1REG_IMPL_REV      EQU 0
C1REG_FCSR          EQU 31

C1FCSR_COMP         EQU 00800000h

;
; -----------------------------------------[ RDRAM register structure ]---------------------------------------------------
;

RDRAM_BASE_REG		EQU		03F00000h
RDRAM_BASE_SIZE     EQU     00000028h
RDRAM_BASE_END      EQU		(RDRAM_BASE_REG + (RDRAM_BASE_SIZE - 1))

RDRAM_CONFIG_REG            EQU		00h
RDRAM_DEVICE_TYPE_REG       EQU		00h
RDRAM_DEVICE_ID_REG         EQU		04h
RDRAM_DELAY_REG             EQU		08h
RDRAM_MODE_REG              EQU		0Ch
RDRAM_REF_INTERVAL_REG      EQU		10h
RDRAM_REF_ROW_REG           EQU		14h
RDRAM_RAS_INTERVAL_REG      EQU		18h
RDRAM_MIN_INTERVAL_REG      EQU		1Ch
RDRAM_ADDR_SELECT_REG       EQU		20h
RDRAM_DEVICE_MANUF_REG      EQU		24h

RDRAM_0_DEVICE_ID           EQU		0
RDRAM_1_DEVICE_ID           EQU		1

RDRAM_RESET_MODE            EQU		0
RDRAM_ACTIVE_MODE           EQU		1
RDRAM_STANDBY_MODE          EQU		2

RDRAM_BASE_ADDR             EQU		00000000h
RDRAM_COUNT                 EQU		2                               ; 2 chips in N64
RDRAM_LENGTH                EQU		(2 * 512 * 2048)
RDRAM_TOTAL_LENGTH          EQU		(RDRAM_COUNT * RDRAM_LENGTH)

RDRAM_0_BASE_ADDRESS        EQU		(RDRAM_0_DEVICE_ID * RDRAM_LENGTH)
RDRAM_1_BASE_ADDRESS        EQU		(RDRAM_1_DEVICE_ID * RDRAM_LENGTH)

RDRAM_0_CONFIG              EQU		00000h
RDRAM_1_CONFIG              EQU		00400h
RDRAM_GLOBAL_CONFIG         EQU		80000h

RDRAM_RegSet STRUC
	rdram_config_devty		dd	?
    rdram_device_id			dd	?
    rdram_delay				dd	?
    rdram_mode				dd	?
    rdram_ref_interval		dd	?
    rdram_ref_row			dd	?
    rdram_ras_interval		dd	?
    rdram_min_interval		dd	?
    rdram_addr_select		dd	?
    rdram_device_manuf		dd	?
ENDS                                ; 03F0_0000 -> 03F0_0027 (?)


;
; --------------------------------------[ Sound Processor register structure ]---------------------------------------------
;

SP_DMEM_SIZE                EQU		1000			; 4096 bytes
SP_IMEM_SIZE                EQU		1000			; 4096 bytes

SP_DMEM_BASE                EQU		04000000h
SP_IMEM_BASE                EQU		04001000h

SP_BASE_REG                 EQU		04040000h
SP_BASE_SIZE                EQU		00000020h
SP_BASE_END                 EQU		(SP_BASE_REG + (SP_BASE_SIZE - 1))

SP_MEM_ADDR_REG             EQU		00h				; Master
SP_DRAM_ADDR_REG            EQU		04h				; Slave
SP_RD_LEN_REG               EQU		08h				; R/W: read len
SP_WR_LEN_REG               EQU		0Ch				; R/W: write len
SP_STATUS_REG               EQU		10h
SP_DMA_FULL_REG             EQU		14h
SP_DMA_BUSY_REG             EQU		18h
SP_SEMAPHORE_REG            EQU		1Ch

; SP MEM address: bit 12 specifies if address is IMEM or DMEM
SP_DMA_DMEM                 EQU		0000h			; Bit 12: 0=DMEM, 1=IMEM
SP_DMA_IMEM                 EQU		1000h			; Bit 12: 0=DMEM, 1=IMEM

; Values to clear/set bit in status reg (SP_STATUS_REG - write)
SP_CLR_HALT                 EQU		0000001h		; Bit  0: clear halt
SP_SET_HALT                 EQU		0000002h		; Bit  1: set halt
SP_CLR_BROKE                EQU		0000004h		; Bit  2: clear broke
SP_CLR_INTR                 EQU		0000008h		; Bit  3: clear intr
SP_SET_INTR                 EQU		0000010h		; Bit  4: set intr
SP_CLR_SSTEP                EQU		0000020h		; Bit  5: clear sstep
SP_SET_SSTEP                EQU		0000040h		; Bit  6: set sstep
SP_CLR_INTR_BREAK           EQU		0000080h		; Bit  7: clear intr on break
SP_SET_INTR_BREAK           EQU		0000100h		; Bit  8: set intr on break
SP_CLR_SIG0                 EQU		0000200h		; Bit  9: clear signal 0
SP_SET_SIG0                 EQU		0000400h		; Bit 10: set signal 0
SP_CLR_SIG1                 EQU		0000800h		; Bit 11: clear signal 1
SP_SET_SIG1                 EQU		0001000h		; Bit 12: set signal 1
SP_CLR_SIG2                 EQU		0002000h		; Bit 13: clear signal 2
SP_SET_SIG2                 EQU		0004000h		; Bit 14: set signal 2
SP_CLR_SIG3                 EQU		0008000h		; Bit 15: clear signal 3
SP_SET_SIG3                 EQU		0010000h		; Bit 16: set signal 3
SP_CLR_SIG4                 EQU		0020000h		; Bit 17: clear signal 4
SP_SET_SIG4                 EQU		0040000h		; Bit 18: set signal 4
SP_CLR_SIG5                 EQU		0080000h		; Bit 19: clear signal 5
SP_SET_SIG5                 EQU		0100000h		; Bit 20: set signal 5
SP_CLR_SIG6                 EQU		0200000h		; Bit 21: clear signal 6
SP_SET_SIG6                 EQU		0400000h		; Bit 22: set signal 6
SP_CLR_SIG7                 EQU		0800000h		; Bit 23: clear signal 7
SP_SET_SIG7                 EQU		1000000h		; Bit 24: set signal 7

; Patterns to interpret status reg (SP_STATUS_REG - read)
SP_STATUS_HALT              EQU		0001h			; Bit  0: halt
SP_STATUS_BROKE             EQU		0002h			; Bit  1: broke
SP_STATUS_DMA_BUSY          EQU		0004h			; Bit  2: dma busy
SP_STATUS_DMA_FULL          EQU		0008h			; Bit  3: dma full
SP_STATUS_IO_FULL           EQU		0010h			; Bit  4: io full
SP_STATUS_SSTEP             EQU		0020h			; Bit  5: single step
SP_STATUS_INTR_BREAK        EQU		0040h			; Bit  6: interrupt on break
SP_STATUS_SIG0              EQU		0080h			; Bit  7: signal 0 set
SP_STATUS_SIG1              EQU		0100h			; Bit  8: signal 1 set
SP_STATUS_SIG2              EQU		0200h			; Bit  9: signal 2 set
SP_STATUS_SIG3              EQU		0400h			; Bit 10: signal 3 set
SP_STATUS_SIG4              EQU		0800h			; Bit 11: signal 4 set
SP_STATUS_SIG5              EQU		1000h			; Bit 12: signal 5 set
SP_STATUS_SIG6              EQU		2000h			; Bit 13: signal 6 set
SP_STATUS_SIG7              EQU		4000h			;Bit 14: signal 7 set

; Use of SIG bits
SP_CLR_YIELD                EQU		SP_CLR_SIG0
SP_SET_YIELD                EQU		SP_SET_SIG0
SP_STATUS_YIELD             EQU		SP_STATUS_SIG0
SP_CLR_YIELDED              EQU		SP_CLR_SIG1
SP_SET_YIELDED              EQU		SP_SET_SIG1
SP_STATUS_YIELDED           EQU		SP_STATUS_SIG1
SP_CLR_TASKDONE             EQU		SP_CLR_SIG2
SP_SET_TASKDONE             EQU		SP_SET_SIG2
SP_STATUS_TASKDONE          EQU		SP_STATUS_SIG2

SP_RegSet STRUC
    sp_mem_addr		dd	?			; SP memory address   (R/W): [11:0] DMEM/IMEM address; [12] 0=DMEM,1=IMEM
    sp_dram_addr	dd	?			; SP DRAM DMA address (R/W): [23:0] RDRAM address
    sp_read_len		dd	?			; SP read DMA length  (R/W): [11:0] length, [19:12] count, [31:20] skip | direction: I/DMEM <- RDRAM
    sp_write_len	dd	?			; SP write DMA length (R/W): [11:0] length, [19:12] count, [31:20] skip | direction: I/DMEM -> RDRAM
    sp_status		dd	?			; SP status           (R/W): [14:0] valid bits
    sp_dma_full		dd	?			; SP DMA full           (R): [0] valid bit; dma full
    sp_dma_busy		dd	?			; SP DMA busy           (R): [0] valid bit; dma busy
    sp_semaphore	dd	?			; SP semaphore        (R/W): Read:  [0] semaphore flag (set on read)  Write: [] clear semaphore flag
ENDS								; 0404_0000 -> 0404_001F

SP_PC_REG                   EQU		04080000h
SP_PC_SIZE                  EQU		00000004h
SP_PC_END                   EQU		(SP_PC_REG + (SP_PC_SIZE - 1))

SP_PC_RegSet STRUC
    SPPC			dd	?			; SP PC               (R/W): [11:0] program counter
ENDS                                ; 0408_0000 -> 0408_0003

SP_IBIST_REG                EQU		04080004h
SP_IBIST_SIZE               EQU		00000004h
SP_IBIST_END                EQU		(SP_IBIST_REG + (SP_IBIST_SIZE - 1))

; Patterns to interpret status reg (SP_BIST_REG - write)
SP_IBIST_CHECK              EQU		01h			; Bit 0: BIST check
SP_IBIST_GO                 EQU		02h			; Bit 1: BIST go
SP_IBIST_CLEAR              EQU		04h			; Bit 2: BIST clear

; Patterns to interpret status reg (SP_BIST_REG - read).
; First 2 bits are same as in write mode: Bit 0: BIST check; Bit 1: BIST go
SP_IBIST_DONE               EQU		04h			; Bit 2: BIST done
SP_IBIST_FAILED             EQU		78h			; Bit [6:3]: BIST fail

SP_IMEM_BIST_RegSet STRUC
    ibist			dd	?			; SP IMEM BIST REG (R/W): [6:0] BIST status bits
ENDS                                ; 0408_0004 -> 0408_0007

;
; -------------------------------[ Display Processor Command register structure ]-------------------------------------------
;

DPC_BASE_REG                EQU		04100000h
DPC_BASE_SIZE               EQU		00000020h
DPC_BASE_END                EQU		(DPC_BASE_REG + (DPC_BASE_SIZE - 1))

DPC_START_REG               EQU		00h
DPC_END_REG                 EQU		04h
DPC_CURRENT_REG             EQU		08h
DPC_STATUS_REG              EQU		0Ch
DPC_CLOCK_REG               EQU		10h
DPC_BUFBUSY_REG             EQU		14h
DPC_PIPEBUSY_REG            EQU		18h
DPC_TMEM_REG                EQU		1Ch

; Values to clear/set bit in status reg (DPC_STATUS_REG - write)
DPC_CLR_XBUS_DMEM_DMA       EQU		0001h       ; Bit 0: clear xbus_dmem_dma
DPC_SET_XBUS_DMEM_DMA       EQU		0002h       ; Bit 1: set xbus_dmem_dma
DPC_CLR_FREEZE              EQU		0004h       ; Bit 2: clear freeze
DPC_SET_FREEZE              EQU		0008h       ; Bit 3: set freeze
DPC_CLR_FLUSH				EQU		0010h       ; Bit 4: clear flush
DPC_SET_FLUSH               EQU		0020h       ; Bit 5: set flush
DPC_CLR_TMEM_CTR            EQU		0040h       ; Bit 6: clear tmem ctr
DPC_CLR_PIPE_CTR            EQU		0080h		; Bit 7: clear pipe ctr
DPC_CLR_CMD_CTR             EQU		0100h		; Bit 8: clear cmd ctr
DPC_CLR_CLOCK_CTR           EQU		0200h		; Bit 9: clear clock ctr

; Patterns to interpret status reg (DPC_STATUS_REG - read)
DPC_STATUS_XBUS_DMEM_DMA    EQU		001h		; Bit  0: xbus_dmem_dma
DPC_STATUS_FREEZE           EQU		002h		; Bit  1: freeze
DPC_STATUS_FLUSH            EQU		004h		; Bit  2: flush
;DPC_STATUS_FROZEN           EQU		008h		; Bit  3: frozen
DPC_STATUS_START_GCLK       EQU		008h		; Bit  3: start gclk
DPC_STATUS_TMEM_BUSY        EQU		010h		; Bit  4: tmem busy
DPC_STATUS_PIPE_BUSY        EQU		020h		; Bit  5: pipe busy
DPC_STATUS_CMD_BUSY         EQU		040h		; Bit  6: cmd busy
DPC_STATUS_CBUF_READY       EQU		080h		; Bit  7: cbuf ready
DPC_STATUS_DMA_BUSY         EQU		100h		; Bit  8: dma busy
DPC_STATUS_END_VALID        EQU		200h		; Bit  9: end valid
DPC_STATUS_START_VALID      EQU		400h		; Bit 10: start valid

DPC_RegSet STRUC
    dpc_start		dd	?			; DP CMD DMA start     (R/W): [23:0] DMEM/RDRAM start address
    dpc_end			dd	?			; DP CMD DMA end       (R/W): [23:0] DMEM/RDRAM end address
    dpc_current		dd	?			; DP CMD DMA end         (R): [23:0] DMEM/RDRAM current address
    dpc_status		dd	?			; DP CMD status        (R/W):  [9:0] valid bits
    dpc_clock		dd	?			; DP clock counter       (R): [23:0] clock counter 
    dpc_bufbusy		dd	?			; DP buffer busy counter (R): [23:0] clock counter
    dpc_pipebusy	dd	?			; DP pipe busy counter   (R): [23:0] clock counter
    dpc_tmem		dd	?			; DP TMEM load counter   (R): [23:0] clock counter
ENDS                                ; 0410_0000 -> 0410_001F

;
; ---------------------------------[ Display Processor Span register structure ]-------------------------------------------
;

DPS_BASE_REG                EQU		04200000h
DPS_BASE_SIZE               EQU		00000010h
DPS_BASE_END                EQU		(DPS_BASE_REG + (DPS_BASE_SIZE - 1))

DPS_TBIST_REG               EQU		00h
DPS_TEST_MODE_REG           EQU		04h
DPS_BUFTEST_ADDR_REG		EQU		08h
DPS_BUFTEST_DATA_REG        EQU		0Ch

; Patterns to interpret status reg (DPS_TMEM_BIST_REG - write)
DPS_TBIST_CHECK             EQU		01h			; Bit 0: BIST check
DPS_TBIST_GO                EQU		02h			; Bit 1: BIST go
DPS_TBIST_CLEAR             EQU		04h			; Bit 2: BIST clear

; Patterns to interpret status reg (DPS_TMEM_BIST_REG - read)
; First 2 bits are same as in write mode: Bit 0: BIST check; Bit 1: BIST go
DPS_TBIST_DONE              EQU		004h		; Bit 2: BIST done
DPS_TBIST_FAILED            EQU		7F8h		; Bit [10:3]: BIST fail

DPS_RegSet STRUC
    dps_tbist			dd	?		; DP tmem bist                (R/W): [10:0] BIST status bits
    dps_test_mode		dd	?		; DP span test mode           (R/W): [0] Span buffer test access enable
    dps_buftest_addr	dd	?		; DP span buffer test address (R/W): [6:0] bits
    dps_buftest_data	dd	?		; DP span buffer test data    (R/W): [31:0] span buffer data
ENDS								; 0420_0000 -> 0420_000F

;
; --------------------------------------[ MIPS Interface register structure ]-------------------------------------------
;

MI_BASE_REG                 EQU		04300000h
MI_BASE_SIZE                EQU		00000010h
MI_BASE_END					EQU		(MI_BASE_REG + (MI_BASE_SIZE - 1))

MI_INIT_MODE_REG            EQU		00h
MI_MODE_REG                 EQU		MI_INIT_MODE_REG
MI_VERSION_REG              EQU		04h
MI_NOOP_REG                 EQU		MI_VERSION_REG
MI_INTR_REG                 EQU		08h
MI_INTR_MASK_REG            EQU		0Ch

; Values to clear/set bit in mode reg (MI_MODE_REG - write)
MI_CLR_INIT                 EQU		0080h		; Bit  7: clear init mode
MI_SET_INIT                 EQU		0100h		; Bit  8: set init mode
MI_CLR_EBUS                 EQU		0200h		; Bit  9: clear ebus test
MI_SET_EBUS                 EQU		0400h		; Bit 10: set ebus test mode
MI_CLR_DP_INTR              EQU		0800h		; Bit 11: clear dp interrupt
MI_CLR_RDRAM                EQU		1000h		; Bit 12: clear RDRAM reg
MI_SET_RDRAM                EQU		2000h		; Bit 13: set RDRAM reg mode

; Patterns to interpret mode reg (MI_MODE_REG - read)
MI_MODE_INIT                EQU		0080h		; Bit  7: init mode
MI_MODE_EBUS                EQU		0100h		; Bit  8: ebus test mode
MI_MODE_RDRAM               EQU		0200h		; Bit  9: RDRAM reg mode

; The following are values to check for interrupt setting (MI_INTR_REG)
MI_INTR_SP                  EQU		01h			; Bit 0: SP intr
MI_INTR_SI                  EQU		02h			; Bit 1: SI intr
MI_INTR_AI                  EQU		04h			; Bit 2: AI intr
MI_INTR_VI                  EQU		08h			; Bit 3: VI intr
MI_INTR_PI                  EQU		10h			; Bit 4: PI intr
MI_INTR_DP                  EQU		20h			; Bit 5: DP intr

; The following are values to clear/set various interrupt bit mask (MI_INTR_MASK_REG - write)
MI_INTR_MASK_CLR_SP         EQU		0001h		; Bit  0: clear SP mask
MI_INTR_MASK_SET_SP         EQU		0002h		; Bit  1: set SP mask
MI_INTR_MASK_CLR_SI         EQU		0004h		; Bit  2: clear SI mask
MI_INTR_MASK_SET_SI         EQU		0008h		; Bit  3: set SI mask
MI_INTR_MASK_CLR_AI         EQU		0010h		; Bit  4: clear AI mask
MI_INTR_MASK_SET_AI         EQU		0020h		; Bit  5: set AI mask
MI_INTR_MASK_CLR_VI         EQU		0040h		; Bit  6: clear VI mask
MI_INTR_MASK_SET_VI         EQU		0080h		; Bit  7: set VI mask
MI_INTR_MASK_CLR_PI         EQU		0100h		; Bit  8: clear PI mask
MI_INTR_MASK_SET_PI         EQU		0200h		; Bit  9: set PI mask
MI_INTR_MASK_CLR_DP         EQU		0400h		; Bit 10: clear DP mask
MI_INTR_MASK_SET_DP         EQU		0800h		; Bit 11: set DP mask

; The following are values to check for interrupt mask setting (MI_INTR_MASK_REG - read)
MI_INTR_MASK_SP             EQU		01h			; Bit 0: SP intr mask
MI_INTR_MASK_SI             EQU		02h			; Bit 1: SI intr mask
MI_INTR_MASK_AI             EQU		04h			; Bit 2: AI intr mask
MI_INTR_MASK_VI             EQU		08h			; Bit 3: VI intr mask
MI_INTR_MASK_PI             EQU		10h			; Bit 4: PI intr mask
MI_INTR_MASK_DP             EQU		20h			; Bit 5: DP intr mask

MIPS_Intf_RegSet STRUC
    mi_mode			dd	?			; MI init mode      (W): [6:0] init length, [7] clear init mode, [8] set init mode
									;		                [9:10] clear/set ebus test mode, [11] clear DP interrupt
									;                   (R): [6:0] init length, [7] init mode, [8] ebus test mode

    mi_version		dd	?			; MI version        (R): [7:0] io, [15:8] rac, [23:16] rdp, [31:24] rsp
    mi_intr			dd	?			; MI interrupt      (R): [5:0] valid bits
    mi_intr_mask	dd	?			; MI interrupt mask (W): [11:0] valid bits | (R): [5:0] valid bits
ENDS                                ; 0430_0000 -> 0430_000F

;
; --------------------------------------[ Video Interface register structure ]-------------------------------------------
;

VI_BASE_REG                 EQU		04400000h
VI_BASE_SIZE                EQU		00000038h
VI_BASE_END                 EQU		(VI_BASE_REG + (VI_BASE_SIZE - 1))

VI_STATUS_REG               EQU		00h
VI_CONTROL_REG              EQU		VI_STATUS_REG
VI_ORIGIN_REG               EQU		04h
VI_DRAM_ADDR_REG            EQU		VI_ORIGIN_REG
VI_WIDTH_REG                EQU		08h
VI_H_WIDTH_REG              EQU		VI_WIDTH_REG
VI_INTR_REG                 EQU		0Ch
VI_V_INTR_REG               EQU		VI_INTR_REG
VI_CURRENT_REG              EQU		10h
VI_V_CURRENT_LINE_REG       EQU		VI_CURRENT_REG
VI_BURST_REG                EQU		14h
VI_TIMING_REG               EQU		VI_BURST_REG
VI_V_SYNC_REG               EQU		18h
VI_H_SYNC_REG               EQU		1Ch
VI_LEAP_REG                 EQU		20h
VI_H_SYNC_LEAP_REG          EQU		VI_LEAP_REG
VI_H_START_REG              EQU		24h
VI_H_VIDEO_REG              EQU		VI_H_START_REG
VI_V_START_REG              EQU		28h
VI_V_VIDEO_REG              EQU		VI_V_START_REG
VI_V_BURST_REG              EQU		2Ch
VI_X_SCALE_REG              EQU		30h
VI_Y_SCALE_REG              EQU		34h

; Patterns to interpret VI_CONTROL_REG
VI_CTRL_TYPE_16             EQU		00002h		; Bit [1:0] pixel size: 16 bit
VI_CTRL_TYPE_32             EQU		00003h		; Bit [1:0] pixel size: 32 bit
VI_CTRL_GAMMA_DITHER_ON     EQU		00004h		; Bit 2: default = on
VI_CTRL_GAMMA_ON            EQU		00008h		; Bit 3: default = on
VI_CTRL_DIVOT_ON            EQU		00010h		; Bit 4: default = on
VI_CTRL_SERRATE_ON          EQU		00040h		; Bit 6: on if interlaced
VI_CTRL_ANTIALIAS_MASK      EQU		00300h		; Bit [9:8] anti-alias mode
VI_CTRL_DITHER_FILTER_ON    EQU		10000h		; Bit 16: dither-filter mode

; Possible video clocks (NTSC or PAL)
VI_NTSC_CLOCK               EQU		48681812	; Hz = 48.681812 MHz
VI_PAL_CLOCK                EQU		49656530	; Hz = 49.656530 MHz
VI_MPAL_CLOCK               EQU		48628316	; Hz = 48.628316 MHz

; VI status/control (R/W): [15-0] valid bits:
;  [1:0]   = type[1:0] (pixel size)
;          0: blank (no data, no sync)
;                      1: reserved
;                      2: 5/5/5/3 ("16" bit)
;                      3: 8/8/8/8 (32 bit)
;  [2]     = gamma_dither_enable (normally on, unless "special effect")
;  [3]     = gamma_enable (normally on, unless MPEG/JPEG)
;  [4]     = divot_enable (normally on if antialiased, unless decal lines)
;  [5]     = reserved - always off
;  [6]     = serrate (always on if interlaced, off if not)
;  [7]     = reserved - diagnostics only
;  [9:8]   = anti-alias (aa) mode[1:0]
;          0: aa & resamp (always fetch extra lines)
;                      1: aa & resamp (fetch extra lines if needed)
;                      2: resamp only (treat as all fully covered)
;                      3: neither (replicate pixels, no interpolate)
;  [11]    = reserved - diagnostics only
;  [15:12] = reserved

VI_RegSet STRUC
    vi_stat_ctrl	dd	?
    vi_origin		dd	?			; VI origin        (R/W): [23:0] frame buffer origin in bytes
    vi_width		dd	?			; VI width         (R/W): [11:0] frame buffer line width in pixels
    vi_intr			dd	?			; VI vertical intr (R/W):  [9:0] interrupt when current half-line = V_INTR

    vi_curr_vline	dd	?			; VI current vertical line (R/W): [9:0] current half line, sampled once per line (the lsb of 
									; V_CURRENT is constant within a field, and in interlaced modes gives the field number - which
									; is constant for non-interlaced modes) - Any write to this register will clear interrupt line

	vi_vid_timing	dd	?			; VI video timing  (R/W): [ 7: 0] horizontal sync width in pixels,
									;                         [15: 8] color burst width in pixels,
									;                         [19:16] vertical sync width in half lines,
									;                         [29:20] start of color burst in pixels from h-sync

    vi_vsync		dd	?			; VI vertical sync   (R/W): [ 9: 0] number of half-lines per field
    vi_hsync		dd	?			; VI horizontal sync (R/W): [11: 0] total duration of a line in 1/4 pixel
									;	                        [20:16] a 5-bit leap pattern used for PAL only (h_sync_period)

    vi_hsync_leap	dd	?			; VI horizontal sync leap (R/W): [11: 0] identical to h_sync_period
									;                                [27:16] identical to h_sync_period

    vi_horiz_vid	dd	?			; VI horizontal video (R/W): [ 9: 0] end of active video in screen pixels
									;                          : [25:16] start of active video in screen pixels

    vi_vert_vid		dd	?			; VI vertical video (R/W): [ 9: 0] end of active video in screen half-lines
									;	                     : [25:16] start of active video in screen half-lines

    vi_vert_burst	dd	?			; VI vertical burst (R/W): [ 9: 0] end of color burst enable in half-lines
									;	                     : [25:16] start of color burst enable in half-lines

    vi_x_scale		dd	?			; VI x-scale (R/W): [11: 0] 1/horizontal scale up factor (2.10 format)
									;	                [27:16] horizontal subpixel offset (2.10 format)
    vi_y_scale		dd	?			; VI y-scale (R/W): [11: 0] 1/vertical scale up factor (2.10 format)
									;                   [27:16] vertical subpixel offset (2.10 format)
ENDS                                ; 0440_0000 -> 0440_0037


;
; --------------------------------------[ Audio Interface register structure ]-------------------------------------------
;

; The address and length registers are double buffered; that is, they can be written twice before becoming full.
; The address must be written before the length.

AI_BASE_REG                 EQU     04500000h
AI_BASE_SIZE                EQU     00000018h
AI_BASE_END                 EQU     (AI_BASE_REG + (AI_BASE_SIZE - 1))

AI_DRAM_ADDR_REG            EQU     00h         ; R0: DRAM address
AI_LEN_REG                  EQU     04h         ; R1: Length
AI_CONTROL_REG              EQU     08h         ; R2: DMA Control
AI_STATUS_REG               EQU     0Ch         ; R3: Status
AI_DACRATE_REG              EQU     10h         ; R4: DAC rate 14-lsb
AI_BITRATE_REG              EQU     14h         ; R5: Bit rate 4-lsb

; Value for control register
AI_CONTROL_DMA_ON           EQU     01h         ; LSB = 1: DMA enable
AI_CONTROL_DMA_OFF          EQU     00h         ; LSB = 1: DMA enable

; Value for status register
AI_STATUS_FIFO_FULL         EQU     80000000h   ; Bit 31: full
AI_STATUS_DMA_BUSY          EQU     40000000h   ; Bit 30: busy

; DAC rate = video clock / audio frequency - DAC rate >= (66 * Bit rate) must be true
AI_MAX_DAC_RATE             EQU     16384       ; 14-bit+1
AI_MIN_DAC_RATE             EQU     132

; Bit rate <= (DAC rate / 66)
AI_MAX_BIT_RATE             EQU     16          ; 4-bit+1
AI_MIN_BIT_RATE             EQU     2

; Maximum and minimum values for audio frequency based on video clocks
;   max frequency = (video clock / min dac rate)
;   min frequency = (video clock / max dac rate)
AI_NTSC_MAX_FREQ            EQU     368000      ; 368 KHz
AI_NTSC_MIN_FREQ            EQU     3000        ;   3 KHz ~ 2971 Hz

AI_PAL_MAX_FREQ             EQU     376000      ; 376 KHz
AI_PAL_MIN_FREQ             EQU     3050        ;   3 KHz ~ 3031 Hz

AI_MPAL_MAX_FREQ            EQU     368000      ; 368 KHz
AI_MPAL_MIN_FREQ            EQU     3000        ;   3 KHz ~ 2968 Hz

AI_RegSet STRUC
    ai_dram_addr    dd  ?           ; AI DRAM address (W): [23:0] starting RDRAM address (8B-aligned)    

    ai_len          dd  ?           ; AI length     (R/W): [14:0] transfer length (v1.0) - Bottom 3 bits are ignored
                                    ;                      [17:0] transfer length (v2.0) - Bottom 3 bits are ignored

    ai_control      dd  ?           ; AI control      (W): [0] DMA enable - if LSB == 1, DMA is enabled

    ai_status       dd  ?           ; AI status       (R): [31]/[0] ai_full (addr & len buffer full), [30] ai_busy
                                    ;                      Note that a 1->0 transition in ai_full will set interrupt
                                    ;                 (W): clear audio interrupt

    ai_dacrate      dd  ?           ; AI DAC sample period register (W): [13:0] dac rate
                                    ;   - vid_clock/(dperiod + 1) is the DAC sample rate
                                    ;   - (dperiod + 1) >= 66 * (aclockhp + 1) must be true

    ai_bitrate      dd  ?           ; AI bit rate (W): [3:0] bit rate (abus clock half period register - aclockhp)
                                    ;   - vid_clock/(2 * (aclockhp + 1)) is the DAC clock rate
                                    ;   - The abus clock stops if aclockhp is zero
ENDS                                ; 0450_0000 -> 0450_0017


;
; ------------------------------------[ Peripheral Interface register structure ]-------------------------------------------
;

PI_BASE_REG                 EQU     04600000h
PI_BASE_SIZE                EQU     00000034h
PI_BASE_END                 EQU     (PI_BASE_REG + (PI_BASE_SIZE - 1))

PI_DRAM_ADDR_REG            EQU     00h     ; DRAM address
PI_CART_ADDR_REG            EQU     04h
PI_RD_LEN_REG               EQU     08h
PI_WR_LEN_REG               EQU     0Ch
PI_STATUS_REG               EQU     10h
PI_BSD_DOM1_LAT_REG         EQU     14h
PI_BSD_DOM1_PWD_REG         EQU     18h
PI_BSD_DOM1_PGS_REG         EQU     1Ch     ;   page size
PI_BSD_DOM1_RLS_REG         EQU     20h
PI_BSD_DOM2_LAT_REG         EQU     24h     ; Domain 2 latency
PI_BSD_DOM2_PWD_REG         EQU     28h     ;   pulse width
PI_BSD_DOM2_PGS_REG         EQU     2Ch     ;   page size
PI_BSD_DOM2_RLS_REG         EQU     30h     ;   release duration

PI_DOMAIN1_REG              EQU     PI_BSD_DOM1_LAT_REG
PI_DOMAIN2_REG              EQU     PI_BSD_DOM2_LAT_REG

PI_DOM_LAT_OFS              EQU     00h
PI_DOM_PWD_OFS              EQU     04h
PI_DOM_PGS_OFS              EQU     08h
PI_DOM_RLS_OFS              EQU     0Ch

; PI status register has 3 bits active when read from (PI_STATUS_REG - read)
;  Bit 0: DMA busy - set when DMA is in progress
;  Bit 1: IO busy  - set when IO is in progress
;  Bit 2: Error    - set when CPU issues IO request while DMA is busy
PI_STATUS_ERROR             EQU     04h
PI_STATUS_IO_BUSY           EQU     02h
PI_STATUS_DMA_BUSY          EQU     01h

; PI status register has 2 bits active when written to:
; Bit 0: When set, reset PIC
; Bit 1: When set, clear interrupt flag
; The values of the two bits can be ORed together to both reset PIC and
; clear interrupt at the same time.
;
; Note:
;  - The PIC does generate an interrupt at the end of each DMA. CPU
;  needs to clear the interrupt flag explicitly (from an interrupt
;  handler) by writing into the STATUS register with bit 1 set.
;
;  - When a DMA completes, the interrupt flag is set.  CPU can issue
;  another request even while the interrupt flag is set (as long as
;  PIC is idle).  However, it is the CPU's responsibility for
;  maintaining accurate correspondence between DMA completions and
;  interrupts.
;
;  - When PIC is reset, if PIC happens to be busy, an interrupt will
;  be generated as PIC returns to idle.  Otherwise, no interrupt will
;  be generated and PIC remains idle.

; Values to clear interrupt/reset PIC (PI_STATUS_REG - write)
PI_STATUS_RESET             EQU     01h
PI_SET_RESET                EQU     PI_STATUS_RESET
PI_STATUS_CLR_INTR          EQU     02h
PI_CLR_INTR                 EQU     PI_STATUS_CLR_INTR

PI_DMA_BUFFER_SIZE          EQU     128

PI_DOM1_ADDR1               EQU     06000000h   ; to 07FFFFFFh
PI_DOM1_ADDR2               EQU     10000000h   ; to 1FBFFFFFh
PI_DOM1_ADDR3               EQU     1FD00000h   ; to 7FFFFFFFh
PI_DOM2_ADDR1               EQU     05000000h   ; to 05FFFFFFh
PI_DOM2_ADDR2               EQU     08000000h   ; to 0FFFFFFFh

PI_RegSet STRUC
    pi_dram_addr        dd  ?       ; PI DRAM address        (R/W): [23:0] starting RDRAM address
    pi_cart_addr        dd  ?       ; PI pbus (cart) address (R/W): [31:0] starting AD16 address
    pi_rd_len           dd  ?       ; PI read length         (R/W): [23:0] read data length
    pi_wr_len           dd  ?       ; PI write length        (R/W): [23:0] write data length

    pi_status           dd  ?       ; PI status             (R): [0] DMA busy, [1] IO busy, [2], error
                                    ;                       (W): [0] reset controller (and abort current op), [1] clear intr

    pi_dom1_lat         dd  ?       ; PI dom1 latency     (R/W): [7:0] domain 1 device latency
    pi_dom1_pulse_width dd  ?       ; PI dom1 pulse width (R/W): [7:0] domain 1 device R/W strobe pulse width
    pi_dom1_page_size   dd  ?       ; PI dom1 page size   (R/W): [3:0] domain 1 device page size
    pi_dom1_release     dd  ?       ; PI dom1 release     (R/W): [1:0] domain 1 device R/W release duration

    pi_dom2_lat         dd  ?       ; PI dom2 latency     (R/W): [7:0] domain 2 device latency
    pi_dom2_pulse_width dd  ?       ; PI dom2 pulse width (R/W): [7:0] domain 2 device R/W strobe pulse width
    pi_dom2_page_size   dd  ?       ; PI dom2 page size   (R/W): [3:0] domain 2 device page size
    pi_dom2_release     dd  ?       ; PI dom2 release     (R/W): [1:0] domain 2 device R/W release duration
ENDS                                ; 0460_0000 -> 0460_0033


;
; --------------------------------------[ RDRAM Interface register structure ]---------------------------------------------
;

RI_BASE_REG                 EQU     04700000h
RI_BASE_SIZE                EQU     00000020h
RI_BASE_END                 EQU     (RI_BASE_REG + (RI_BASE_SIZE - 1))

RI_MODE_REG                 EQU     00h
RI_CONFIG_REG               EQU     04h
RI_CURRENT_LOAD_REG         EQU     08h
RI_SELECT_REG               EQU     0Ch
RI_REFRESH_REG              EQU     10h
RI_COUNT_REG                EQU     RI_REFRESH_REG
RI_LATENCY_REG              EQU     14h
RI_RERROR_REG               EQU     18h
RI_WERROR_REG               EQU     1Ch

RI_RegSet STRUC
    ri_mode         dd  ?           ; RI mode       (R/W): [1:0] operating mode, [2] stop T active, [3] stop R active
    ri_config       dd  ?           ; RI config     (R/W): [5:0] current control input, [6] current control enable
    ri_current_load dd  ?           ; RI current load (W): [] any write updates current control register
    ri_select       dd  ?           ; RI select     (R/W): [2:0] receive select, [2:0] transmit select

    ri_refresh      dd  ?           ; RI refresh    (R/W): [7:0] clean refresh delay, [15:8] dirty refresh delay,
                                    ;                      [16] refresh bank, [17] refresh enable [18] refresh optimize

    ri_latency      dd  ?           ; RI latency    (R/W): [3:0] DMA latency/overlap
    ri_rerror       dd  ?           ; RI error        (R): [0] nack error, [1] ack error
    ri_werror       dd  ?           ; RI error        (W): [] any write clears all error bits
ENDS                                ; 0470_0000 -> 0470_001F


;
; --------------------------------------[ Serial Interface register structure ]---------------------------------------------
;

SI_BASE_REG                 EQU		04800000h
SI_BASE_SIZE                EQU		0000001Ch
SI_BASE_END                 EQU		(SI_BASE_REG + (SI_BASE_SIZE - 1))

SI_DRAM_ADDR_REG            EQU		00h			; R0: DRAM address
SI_PIF_ADDR_RD64B_REG       EQU		04h			; R1: 64B PIF->DRAM
SI_PIF_ADDR_WR64B_REG       EQU		10h			; R4: 64B DRAM->PIF
SI_STATUS_REG               EQU		18h			; R6: Status

; SI status register has the following bits active:
;  0:   DMA busy       - set when DMA is in progress
;  1:   IO busy        - set when IO access is in progress
;  3:   DMA error      - set when there are overlapping DMA requests
; 12:   Interrupt      - Interrupt set
SI_STATUS_DMA_BUSY          EQU		0001h
SI_STATUS_RD_BUSY           EQU		0002h
SI_STATUS_DMA_ERROR         EQU		0008h
SI_STATUS_INTERRUPT         EQU		1000h

SI_RegSet STRUC
    si_dram_addr		dd	?		; SI DRAM address    (R/W): [23:0] starting RDRAM address   
    si_pif_addr_rd64b	dd	?		; SI address read 64B  (W): [] any write causes a 64B DMA write
    si_reserved1		dd	?
    si_reserved2		dd	?
    si_pif_addr_wr64b	dd	?		; SI address write 64B (W): [] any write causes a 64B DMA read
    si_reserved3		dd	?
    si_status			dd	?		; SI status (W): [] any write clears interrupt
									;           (R): [0] DMA busy, [1] IO read busy, [2] reserved, [3] DMA error, [12] interrupt
ENDS                                ; 0480_0000 -> 0480_001B


;
; -------------------------------------------------[ PIF ROM structure ]---------------------------------------------------
;

PIF_ROM_BASE_REG            EQU		1FC00000h
PIF_ROM_BASE_END			EQU		1FC007BFh
PIF_ROM_BASE_SIZE           EQU		((PIF_ROM_BASE_END - PIF_ROM_BASE_REG) + 1)

;
; -------------------------------------------------[ PIF RAM structure ]---------------------------------------------------
;

PIF_RAM_BASE_REG            EQU		1FC007C0h
PIF_RAM_BASE_END            EQU		1FC007FFh
PIF_RAM_BASE_SIZE           EQU		((PIF_RAM_BASE_END - PIF_RAM_BASE_REG) + 1)

;
; ------------------------------------------------[ LEO (DD64) structure ]--------------------------------------------------
;

LEO_BASE_REG                EQU		05000508h
LEO_BASE_END                EQU		0500050Bh
LEO_BASE_SIZE               EQU		((LEO_BASE_END - LEO_BASE_REG) + 1)

LEO_NOTEXIST_REG            EQU		00h

LEO_RegSet STRUC
    leo_not_exist		dd	?		; Leo exists == 0, Leo doesn't exist != 0
ENDS								; 0500_0508 -> 0500_050B

; ==========================================================================================================================

; Lowest and highest addresses that are considered MMIO related.
MMIO_LOWEST_ADDR			EQU     RDRAM_BASE_REG
MMIO_HIGHEST_ADDR			EQU     SI_BASE_END

NUM_MEMMAPS				EQU		24

MemMapDef STRUC
    ptr					dd	?		; Pointer in Windows memory where this block is stored.
    start_addr			dd	?		; Starting address in N64 where this block exists.
    end_addr			dd	?		; Ending address in N64 where this block exists.

    ; Read function to call with offset when memory is read at an address in this block.
    read_func			dd	?

    ; Write function to call with offset when memory is written to at an address in this block.
    write_func			dd	?
ENDS

SIZEOF_MEMMAPDEF		EQU		20

MemMap STRUC
	mm0			MemMapDef ?					; 24 entries in memory map...
	mm1			MemMapDef ?
	mm2			MemMapDef ?
	mm3			MemMapDef ?
	mm4			MemMapDef ?
	mm5			MemMapDef ?
	mm6			MemMapDef ?
	mm7			MemMapDef ?

	mm8			MemMapDef ?
	mm9			MemMapDef ?
	mm10		MemMapDef ?
	mm11		MemMapDef ?
	mm12		MemMapDef ?
	mm13		MemMapDef ?
	mm14		MemMapDef ?
	mm15		MemMapDef ?

	mm16		MemMapDef ?
	mm17		MemMapDef ?
	mm18		MemMapDef ?
	mm19		MemMapDef ?
	mm20		MemMapDef ?
	mm21		MemMapDef ?
	mm22		MemMapDef ?
	mm23		MemMapDef ?
ENDS

; ==========================================================================================================================

CallStackDef STRUC
    cs_PC                   dd  ?
    cs_call                 dd  ?
ENDS
