📄 init0.s
字号:
/*
** FILE
** init0.S
**
** DESCRIPTION
** the bootstrap ROM code for VCD/SVCD/DVD systems.
** it located in several places and serves as the
** exception-handler, also.
*/
#include "regdef.h"
#include "intdef.h"
#include "config.h"
#define RGST_BASE 0xafff0000
#define AGDC_CONFIG 120*4
#define COMBO_RESET 2*4
#define CLKGEN_V 179*4
.text
.global __romstart
.extern start /* real start point */
.text
#ifdef SUPPORT_ESP
.extern do_cd_esp
#endif
/*
** BOOT EXCEPTION ENTRY POINT: 0xbfc0_0000
*/
.ent __romstart
__romstart:
nop /* wait 1 instructions */
la t0, RGST_BASE
li t1,0x04a0 /* kevinlu 20021126 default 67.5 MHz */
sw t1,CLKGEN_V(t0)
li t1,0x00a0
sw t1,CLKGEN_V(t0)
#if (CONFIG==CONFIG_COMBO_VCD)
li t1,2
sw t1,AGDC_CONFIG(t0)
#endif
sw zero, COMBO_RESET(t0)
nop
li t0, 8 /* wait 8*4 cycles */
1: subu t0, 1
bnez t0, 1b
//Nes game init()
//IM cache 0x400 ~ 0xbff
#if 0//def SUPPORT_ESP
la t0, do_cd_esp
li t1,0x0fffff00
and t0,t0,t1
mtc0 t0, C0_IW_BASE
addi t0, t0, 0x800
mtc0 t0, C0_IW_TOP
#else
li t0, 0x400
mtc0 t0, C0_IW_BASE
li t1, 0xc00
mtc0 t1, C0_IW_TOP
#endif
/*
** invalidate cache (....)
*/
.set noreorder
mtc0 zero, C0_CCTL /* */
li t0, CCTL_DIvl|CCTL_IIvl /* 0 to 1 transition */
mtc0 t0, C0_CCTL /* -- */
mtc0 zero, C0_CCTL /* -- */
.set reorder
li t0, 8 /* wait some cycles for cache */
1: subu t0, 1
bnez t0, 1b
/*
** jump to cached region
*/
la t0, start
jr t0
.end __romstart
/*
** EXCEPTION ENTRY POINT: 8000_0080
**
** BEV = 0
*/
.org 0x0080
.global __exception_bev0
.ent __exception_bev0
__exception_bev0:
la k0, __exception_arise
jr k0
.end __exception_bev0
/*
** Interrupt Vectors
*/
.extern exception_panic
.extern intr_field_end
.extern intr_pic_end
.extern intr_timer0
.extern intr_timer1
.extern intr_uart
.extern intr_iop_unmap
.extern intr_watchdog
.extern intr_decerr
.extern intr_panic
/*
** FUNCTION
** __exception_arise
**
** DESCRIPTION
** first exception-handler
** 1. check C0_CAUSE for exception_cause [IP7-IP0]
*/
.global __exception_arise
.extern __swap
.extern monitor
.ent __exception_arise
__exception_arise:
mfc0 k0, C0_CAUSE
li k1, EXCCODE_Int<<2 /* .EEE EE.. */
andi k0, (0x001f<<2) /* CP0_CAUSE[6:2] */
.set noreorder
beq k1, k0, __exception_chk_intr
li k1, EXCCODE_Sys<<2
beq k1, k0, __exception_chk_syscall
li k1, EXCCODE_RI<<2
beq k1, k0, __exception_chk_ri
li k1, EXCCODE_Bp<<2
beq k1, k0, __exception_chk_bp
li k1, EXCCODE_CpU<<2
beq k1, k0, __exception_chk_cpu
li k1, EXCCODE_Ov<<2
beq k1, k0, __exception_chk_ov
li k1, EXCCODE_AdEL<<2
beq k1, k0, __exception_chk_adel
li k1, EXCCODE_AdES<<2
beq k1, k0, __exception_chk_ades
nop
.set reorder
__exception_chk_syscall:
__exception_chk_ri:
__exception_chk_bp:
__exception_chk_cpu:
__exception_chk_ov:
__exception_chk_adel:
__exception_chk_ades:
la k1, exception_panic
jr k1
/*
**
*/
.org 0x0100
.global __exception_mmu
__exception_mmu:
la k1, exception_panic
jr k1
/*
** checking IP7-0
** currently the external interrupt are all wired
** into IntreqN[0] (IntreqN[5:0]), and that is mapped
** into IP2. Since there are no other interrupt enabled,
** we simple jump to exception_intr
*/
__exception_chk_intr:
b __external_interrupt
#if 0
mfc0 k0, C0_CAUSE
__exception_chk_intr7:
andi k1, k0, CAUSE_IP7 /* check IP7 */
bnez k1, __exception_intr7
__exception_chk_intr6:
andi k1, k0, CAUSE_IP6 /* check IP6 */
bnez k1, __exception_intr6
__exception_chk_intr5:
andi k1, k0, CAUSE_IP5 /* check IP5 */
bnez k1, __exception_intr5
__exception_chk_intr4:
andi k1, k0, CAUSE_IP4 /* check IP4 */
bnez k1, __exception_intr4
__exception_chk_intr3:
andi k1, k0, CAUSE_IP3 /* check IP3 */
bnez k1, __exception_intr3
__exception_chk_intr2:
andi k1, k0, CAUSE_IP2 /* check IP2 */
bnez k1, __external_interrupt
__exception_chk_intr1:
andi k1, k0, CAUSE_IP1 /* check IP1 */
bnez k1, __exception_intr1
__exception_chk_intr0:
andi k1, k0, CAUSE_IP0 /* check IP0 */
bnez k1, __exception_intr0
#endif
__exception_leave:
mfc0 k0, C0_EPC
.set noreorder
jr k0
rfe
.set reorder
.end __exception_arise
/*
** EXCEPTION ENTRY POINT: bfc0_0180
**
** BEV = 1
*/
.org 0x0180
.global __exception_bev1
.ent __exception_bev1
__exception_bev1:
la k0, __exception_arise
jr k0
.end __exception_bev1
/*
** ENTRY
** __exception_intr:
**
** DESCRIPTION
** interrupt(s) handler
*/
//#define R_PAGE_NUMBER (764)
#define R_INTR_FLAG (16*4)
.extern s_gp
.sdata
.text
.ent __external_interrupt
__external_interrupt:
li k0, RGST_BASE /* load register-file-base */
lw k1, R_INTR_FLAG(k0) /* load-interrupt flag */
andi k0, k1, INTR_TIMER0 /* check timer0 interrupt */
bnez k0, __entry_timer0
andi k0, k1, INTR_TIMER1 /* check timer1 interrupt */
bnez k0, __entry_timer1
andi k0, k1, INTR_UART /* check UART interrupt */
bnez k0, __entry_uart
andi k0, k1, INTR_IOP_UNMAP /* check IOP UNMAP interrupt */
bnez k0, __entry_iop_unmap
andi k0, k1, INTR_FIELD_END /* check FIELD END interrupt */
bnez k0, __entry_field_end
andi k0, k1, INTR_WATCHDOG /* check watchdog interrupt */
bnez k0, __entry_watchdog
andi k0, k1, INTR_DECERR
bnez k0, __entry_decerr
#if 0
/*
** ?? spurious interrupt flag
*/
move k0, k1 /* PANIC PANIC PANIC */
move a0, k1
mfc0 a1, C0_EPC
la k1, intr_panic
b __interrupt_service
#endif
li k0, RGST_BASE /* load register-file-base */
sw k1, R_INTR_FLAG(k0)
b __exception_leave
__entry_field_end:
la k1, intr_field_end
b __interrupt_service
__entry_pic_end:
la k1, intr_pic_end
b __interrupt_service
__entry_device_atapi:
// la k1, intr_device_atapi
b __interrupt_service
__entry_timer0:
la k1, intr_timer0
b __interrupt_service
__entry_timer1:
la k1, intr_timer1
b __interrupt_service
__entry_uart:
la k1, intr_uart
b __interrupt_service
__entry_iop_unmap:
la k1, intr_iop_unmap
b __interrupt_service
__entry_watchdog:
la k1, intr_watchdog
b __interrupt_service
__entry_decerr:
la k1, intr_decerr
b __interrupt_service
.end __external_interrupt
#include "regloc.h"
#define SAVE_REG(a,b,c) sw a, 4*b(c)
#define LOAD_REG(a,b,c) lw a, 4*b(c)
.ent __interrupt_service
/*
** __interrupt_service:
**
** when entering this point:
** k0: interrupt_flag (to be cleared)
** k1: interrupt routine
**
** save only caller-saved registers
** AT
** v0/v1
** a0/a1/a2/a3
** t0/t1/t2/t3/t4/t5/t6/t7/t8/t9
** s6 (load with register-pointer)
** gp (load with global-pointer)
** ra
*/
__interrupt_service:
/*
** leave space in stack
*/
subu sp, +4*REGLOCi_NUM
.set noat
SAVE_REG(AT, REGLOCi_AT, sp)
.set at
SAVE_REG(v0, REGLOCi_v0, sp)
SAVE_REG(v1, REGLOCi_v1, sp)
mfc0 v0, C0_EPC
SAVE_REG(a0, REGLOCi_a0, sp)
SAVE_REG(a1, REGLOCi_a1, sp)
SAVE_REG(a2, REGLOCi_a2, sp)
SAVE_REG(a3, REGLOCi_a3, sp)
SAVE_REG(t0, REGLOCi_t0, sp)
SAVE_REG(t1, REGLOCi_t1, sp)
SAVE_REG(t2, REGLOCi_t2, sp)
SAVE_REG(t3, REGLOCi_t3, sp)
SAVE_REG(t4, REGLOCi_t4, sp)
SAVE_REG(t5, REGLOCi_t5, sp)
SAVE_REG(t6, REGLOCi_t6, sp)
SAVE_REG(t7, REGLOCi_t7, sp)
SAVE_REG(t8, REGLOCi_t8, sp)
SAVE_REG(t9, REGLOCi_t9, sp)
SAVE_REG(s6, REGLOCi_s6, sp)
SAVE_REG(gp, REGLOCi_gp, sp)
SAVE_REG(ra, REGLOCi_ra, sp)
SAVE_REG(v0, REGLOCi_EPC, sp) /* save EPC (v0) */
// reload gp will lead to an abnormal phenomonon
// lw gp, s_gp /* reload gp */
li s6, RGST_BASE /* load global pointer S6 */
jalr k1 /* call to service routine */
sw k0, R_INTR_FLAG(s6) /* clear interrupt flag */
.set noat
LOAD_REG(AT, REGLOCi_AT, sp)
.set at
LOAD_REG(v0, REGLOCi_v0, sp)
LOAD_REG(v1, REGLOCi_v1, sp)
LOAD_REG(a0, REGLOCi_a0, sp)
LOAD_REG(a1, REGLOCi_a1, sp)
LOAD_REG(a2, REGLOCi_a2, sp)
LOAD_REG(a3, REGLOCi_a3, sp)
LOAD_REG(t0, REGLOCi_t0, sp)
LOAD_REG(t1, REGLOCi_t1, sp)
LOAD_REG(t2, REGLOCi_t2, sp)
LOAD_REG(t3, REGLOCi_t3, sp)
LOAD_REG(t4, REGLOCi_t4, sp)
LOAD_REG(t5, REGLOCi_t5, sp)
LOAD_REG(t6, REGLOCi_t6, sp)
LOAD_REG(t7, REGLOCi_t7, sp)
LOAD_REG(t8, REGLOCi_t8, sp)
LOAD_REG(t9, REGLOCi_t9, sp)
LOAD_REG(s6, REGLOCi_s6, sp)
LOAD_REG(gp, REGLOCi_gp, sp)
LOAD_REG(ra, REGLOCi_ra, sp)
LOAD_REG(k1, REGLOCi_EPC, sp) /* load EPC (k1) */
addiu sp, +4*REGLOCi_NUM
.set noreorder
jr k1 /* jump to EPC (k1) */
rfe
.set reorder
.end __interrupt_service
/*
** others exception handlers
*/
__exception_intr7:
__exception_intr6:
__exception_intr5:
__exception_intr4:
__exception_intr3:
__exception_intr2:
__exception_intr1:
__exception_intr0:
b __exception_leave
//Nes game
.org 0x400
nop
nop
.org 0xc00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -