rewrite the way VI is handled
warning: only 240p is tested, and i think 480i is broken.
This commit is contained in:
parent
850108b157
commit
c8e5d24975
4 changed files with 216 additions and 30 deletions
|
@ -13,6 +13,10 @@ constant K_ERRORPC(0x0614)
|
|||
constant K_BADVADDR(0x0618)
|
||||
constant K_HISTORY(0x061C)
|
||||
|
||||
constant KV_RES(0x0620)
|
||||
constant KV_MODE(0x0624)
|
||||
constant KV_ORIGIN(0x0628)
|
||||
|
||||
constant K_64DRIVE_MAGIC(0x0700)
|
||||
constant K_CI_BASE(0x0704)
|
||||
constant K_CONSOLE_AVAILABLE(0x0708)
|
||||
|
|
149
inc/n64_vi.inc
149
inc/n64_vi.inc
|
@ -55,6 +55,155 @@ constant VI_NTSC_CLOCK(48681812) // NTSC: Hz = 48.681812 MHz
|
|||
constant VI_PAL_CLOCK(49656530) // PAL: Hz = 49.656530 MHz
|
||||
constant VI_MPAL_CLOCK(48628316) // MPAL: Hz = 48.628316 MHz
|
||||
|
||||
// enum for video resolutions; values are arbitrary.
|
||||
// interlaced:
|
||||
constant RES_640_480(480) // no padding.
|
||||
constant RES_576_432(432) // 640x480 after VI padding.
|
||||
constant RES_512_448(448) // stretched to 640x448, 640x480 after VI padding.
|
||||
// not interlaced:
|
||||
constant RES_320_240(240) // upscaled 2x.
|
||||
constant RES_288_216(216) // upscaled 2x. 640x480 after VI padding.
|
||||
constant RES_256_224(224) // upscaled 2x, stretched to 640x448, etc.
|
||||
|
||||
macro MakeSetScreenNTSC() {
|
||||
// note that you can only call this macro once.
|
||||
|
||||
SetScreenNTSC:
|
||||
// this version expects to be called every frame.
|
||||
// a0: resolution to use (enum).
|
||||
// a1: desired VI settings (status/control). mutable.
|
||||
// a2: image color buffer origin address. mutable.
|
||||
// v0: zero on success, non-zero on failure (bad enum or VI settings).
|
||||
|
||||
lui v1, VI_BASE
|
||||
lw t0, VI_V_CURRENT_LINE(v1)
|
||||
andi t0, 1
|
||||
|
||||
andi t1, a1, 3 // extract BPP
|
||||
subiu t1, 2 // now 16 BPP is 0 and 32 BPP is 1
|
||||
bltz t1, SetScreenNTSC_Fail // fail if it's not set to 16 or 32 BPP
|
||||
|
||||
lli t8, RES_640_480 // delay slot
|
||||
beq a0, t8, SetScreenNTSC_480
|
||||
|
||||
lli t9, RES_576_432 // delay slot
|
||||
beq a0, t9, SetScreenNTSC_432
|
||||
|
||||
lli t8, RES_512_448 // delay slot
|
||||
beq a0, t8, SetScreenNTSC_448
|
||||
|
||||
lli t9, RES_320_240 // delay slot
|
||||
beq a0, t9, SetScreenNTSC_240
|
||||
|
||||
lli t8, RES_288_216 // delay slot
|
||||
beq a0, t8, SetScreenNTSC_216
|
||||
|
||||
lli t9, RES_256_224 // delay slot
|
||||
beq a0, t9, SetScreenNTSC_224
|
||||
|
||||
SetScreenNTSC_Fail:
|
||||
lli v0, 1 // delay slot
|
||||
jr ra
|
||||
sw r0, VI_V_CURRENT_LINE(v1) // clear interrupt
|
||||
|
||||
SetScreenNTSC_SetInterlaced:
|
||||
beqz t0, SetScreenNTSC_Set // nothing more to do on even fields.
|
||||
ori a1, INTERLACE
|
||||
|
||||
// handle odd fields.
|
||||
addu a2, t2 // add width to origin
|
||||
addu a2, t2 // and again for a full row (when 16 BPP)
|
||||
beqz t1, SetScreenNTSC_Set // branch when 16 BPP
|
||||
subiu t7, 2 // prevents bottom line from displaying out-of-bounds garbage
|
||||
addu a2, t2
|
||||
addu a2, t2 // full row (when 32 BPP)
|
||||
|
||||
SetScreenNTSC_Set:
|
||||
lw t1, VI_V_CURRENT_LINE(v1)
|
||||
|
||||
// variable stuff:
|
||||
sw t1, VI_V_CURRENT_LINE(v1)
|
||||
sw t2, VI_WIDTH(v1) // VI_H_WIDTH
|
||||
sw t3, VI_V_SYNC(v1)
|
||||
sw t4, VI_X_SCALE(v1)
|
||||
sw t5, VI_Y_SCALE(v1)
|
||||
sw t6, VI_H_VIDEO(v1) // VI_H_START
|
||||
sw t7, VI_V_VIDEO(v1) // VI_V_START
|
||||
|
||||
// constant stuff:
|
||||
lli t1, 2
|
||||
li t2, 57 | (34 << 8) | (5 << 16) | (62 << 20)
|
||||
lli t3, 3093
|
||||
li t4, 3093 | (3093 << 16)
|
||||
li t5, (0x0E << 16) | 0x204
|
||||
sw t1, VI_V_INTR(v1) // VI_INTR
|
||||
sw t2, VI_TIMING(v1) // VI_BURST
|
||||
sw t3, VI_H_SYNC(v1)
|
||||
sw t4, VI_H_SYNC_LEAP(v1) // VI_LEAP
|
||||
sw t5, VI_V_BURST(v1)
|
||||
|
||||
// final variable stuff:
|
||||
sw a1, VI_STATUS(v1) // VI_CONTROL
|
||||
sw a2, VI_ORIGIN(v1) // VI_DRAM_ADDR
|
||||
|
||||
jr ra
|
||||
lli v0, 0
|
||||
|
||||
SetScreenNTSC_480:
|
||||
lli t2, 640
|
||||
li t4, 0x400
|
||||
li t5, 0x800 | (0x200 << 16)
|
||||
li t6, (0x6C << 16) | (0x6C + 640)
|
||||
li t7, (0x23 << 16) | (0x23 + 480)
|
||||
b SetScreenNTSC_SetInterlaced
|
||||
lli t3, 525 - 1
|
||||
|
||||
SetScreenNTSC_432:
|
||||
lli t2, 576
|
||||
li t4, 0x400
|
||||
li t5, 0x800 | (0x200 << 16)
|
||||
li t6, (0x8C << 16) | (0x8C + 576)
|
||||
li t7, (0x3B << 16) | (0x3B + 432)
|
||||
b SetScreenNTSC_SetInterlaced
|
||||
lli t3, 525 - 1
|
||||
|
||||
SetScreenNTSC_448:
|
||||
lli t2, 512
|
||||
li t4, (512 * 256 + 128) / 160
|
||||
li t5, 0x800 | (0x200 << 16)
|
||||
li t6, (0x6C << 16) | (0x6C + 640)
|
||||
li t7, (0x33 << 16) | (0x33 + 448)
|
||||
b SetScreenNTSC_SetInterlaced
|
||||
lli t3, 525 - 1
|
||||
|
||||
SetScreenNTSC_240:
|
||||
lli t2, 320
|
||||
li t4, 0x200
|
||||
li t5, 0x400
|
||||
li t6, (0x6C << 16) | (0x6C + 640)
|
||||
li t7, (0x23 << 16) | (0x23 + 480)
|
||||
b SetScreenNTSC_Set
|
||||
lli t3, 525
|
||||
|
||||
SetScreenNTSC_216:
|
||||
lli t2, 288
|
||||
li t4, 0x200
|
||||
li t5, 0x400
|
||||
li t6, (0x8C << 16) | (0x8C + 576)
|
||||
li t7, (0x3B << 16) | (0x3B + 432)
|
||||
b SetScreenNTSC_Set
|
||||
lli t3, 525
|
||||
|
||||
SetScreenNTSC_224:
|
||||
lli t2, 256
|
||||
li t4, (256 * 256 + 128) / 160
|
||||
li t5, 0x400
|
||||
li t6, (0x6C << 16) | (0x6C + 640)
|
||||
li t7, (0x33 << 16) | (0x33 + 448)
|
||||
b SetScreenNTSC_Set
|
||||
lli t3, 525
|
||||
}
|
||||
|
||||
macro ScreenNTSC(width,height, status, origin) {
|
||||
lui a0,VI_BASE // A0 = VI Base Register ($A4400000)
|
||||
la t0,{origin} // T0 = Origin (Frame Buffer Origin In Bytes)
|
||||
|
|
41
kernel.asm
41
kernel.asm
|
@ -24,6 +24,9 @@ include "init.asm"
|
|||
sw r0, K_UNUSED(gp)
|
||||
sw r0, K_CONSOLE_AVAILABLE(gp)
|
||||
sw r0, K_HISTORY(gp)
|
||||
sw r0, KV_RES(gp)
|
||||
sw r0, KV_MODE(gp)
|
||||
sw r0, KV_ORIGIN(gp)
|
||||
|
||||
Drive64Init:
|
||||
lui t9, CI_BASE
|
||||
|
@ -368,12 +371,12 @@ K_MI_Loop:
|
|||
nop
|
||||
|
||||
K_MI_SP:
|
||||
KWriteString(KS_MI_SP)
|
||||
|
||||
lli t0, SP_INT_CLR
|
||||
lui a1, SP_BASE
|
||||
sw t0, SP_STATUS(a1)
|
||||
|
||||
KWriteString(KS_MI_SP)
|
||||
|
||||
lw t0, K_HISTORY(k0)
|
||||
ori t0, MI_INTR_SP
|
||||
sw t0, K_HISTORY(k0)
|
||||
|
@ -381,11 +384,11 @@ K_MI_SP:
|
|||
andi s0, ~MI_INTR_SP
|
||||
|
||||
K_MI_SI:
|
||||
KWriteString(KS_MI_SI)
|
||||
|
||||
lui a1, SI_BASE
|
||||
sw r0, SI_STATUS(a1)
|
||||
|
||||
KWriteString(KS_MI_SI)
|
||||
|
||||
lw t0, K_HISTORY(k0)
|
||||
ori t0, MI_INTR_SI
|
||||
sw t0, K_HISTORY(k0)
|
||||
|
@ -393,11 +396,11 @@ K_MI_SI:
|
|||
andi s0, ~MI_INTR_SI
|
||||
|
||||
K_MI_AI:
|
||||
KWriteString(KS_MI_AI)
|
||||
|
||||
lui a1, AI_BASE
|
||||
sw r0, AI_STATUS(a1)
|
||||
|
||||
KWriteString(KS_MI_AI)
|
||||
|
||||
lw t0, K_HISTORY(k0)
|
||||
ori t0, MI_INTR_AI
|
||||
sw t0, K_HISTORY(k0)
|
||||
|
@ -405,11 +408,13 @@ K_MI_AI:
|
|||
andi s0, ~MI_INTR_AI
|
||||
|
||||
K_MI_VI:
|
||||
KWriteString(KS_MI_VI)
|
||||
|
||||
lui a1, VI_BASE
|
||||
lw t0, VI_V_CURRENT_LINE(a1)
|
||||
sw t0, VI_V_CURRENT_LINE(a1)
|
||||
lw a0, KV_RES(k0)
|
||||
lw a1, KV_MODE(k0)
|
||||
jal SetScreenNTSC
|
||||
lw a2, KV_ORIGIN(k0)
|
||||
|
||||
KWriteString(KS_MI_VI)
|
||||
|
||||
lw t0, K_HISTORY(k0)
|
||||
ori t0, MI_INTR_VI
|
||||
|
@ -418,12 +423,12 @@ K_MI_VI:
|
|||
andi s0, ~MI_INTR_VI
|
||||
|
||||
K_MI_PI:
|
||||
KWriteString(KS_MI_PI)
|
||||
|
||||
lli t0, 0x02
|
||||
lui a1, PI_BASE
|
||||
sw t0, PI_STATUS(a1)
|
||||
|
||||
KWriteString(KS_MI_PI)
|
||||
|
||||
lw t0, K_HISTORY(k0)
|
||||
ori t0, MI_INTR_PI
|
||||
sw t0, K_HISTORY(k0)
|
||||
|
@ -431,12 +436,12 @@ K_MI_PI:
|
|||
andi s0, ~MI_INTR_PI
|
||||
|
||||
K_MI_DP:
|
||||
KWriteString(KS_MI_DP)
|
||||
|
||||
lli t0, 0x0800
|
||||
lui a1, MI_BASE
|
||||
sw t0, MI_INIT_MODE(a1)
|
||||
|
||||
KWriteString(KS_MI_DP)
|
||||
|
||||
lw t0, K_HISTORY(k0)
|
||||
ori t0, MI_INTR_DP
|
||||
sw t0, K_HISTORY(k0)
|
||||
|
@ -485,6 +490,14 @@ dw KCode20, KCode21, KCode22, KCode23
|
|||
dw KCode24, KCode25, KCode26, KCode27
|
||||
dw KCode28, KCode29, KCode30, KCode31
|
||||
|
||||
K_SetScreenNTSC:
|
||||
lui a3, K_BASE
|
||||
sw a0, KV_RES(a3)
|
||||
sw a1, KV_MODE(a3)
|
||||
sw a2, KV_ORIGIN(a3)
|
||||
// fall-thru
|
||||
MakeSetScreenNTSC()
|
||||
|
||||
include "debug.asm"
|
||||
|
||||
if K_DEBUG {
|
||||
|
|
52
main.asm
52
main.asm
|
@ -117,8 +117,23 @@ MainLoop:
|
|||
beqz t0,-
|
||||
nop
|
||||
|
||||
WriteString(S_VI_Wait)
|
||||
// queue buffers to swap
|
||||
lui a0, K_BASE
|
||||
beqz s1, SwapToMain
|
||||
nop
|
||||
SwapToAlt:
|
||||
la t0, VIDEO_C_IMAGE_ALT | UNCACHED
|
||||
sw t0, KV_ORIGIN(a0)
|
||||
b +
|
||||
lli s1, 0
|
||||
SwapToMain:
|
||||
la t0, VIDEO_C_IMAGE | UNCACHED
|
||||
sw t0, KV_ORIGIN(a0)
|
||||
lli s1, 1
|
||||
+
|
||||
|
||||
// wait on VI too
|
||||
WriteString(S_VI_Wait)
|
||||
lui a0, VI_BASE
|
||||
-
|
||||
lw t0, VI_V_CURRENT_LINE(a0)
|
||||
|
@ -129,24 +144,27 @@ MainLoop:
|
|||
|
||||
WriteString(SNewFrame)
|
||||
|
||||
// swap buffers
|
||||
lui a0, VI_BASE
|
||||
beqz s1, SwitchToAlt
|
||||
j Start3D
|
||||
nop
|
||||
SwitchToMain:
|
||||
la t0, VIDEO_C_IMAGE_ALT | UNCACHED
|
||||
sw t0, VI_ORIGIN(a0)
|
||||
j Start3D
|
||||
lli s1, 0
|
||||
SwitchToAlt:
|
||||
la t0, VIDEO_C_IMAGE | UNCACHED
|
||||
sw t0, VI_ORIGIN(a0)
|
||||
j Start3D
|
||||
lli s1, 1
|
||||
|
||||
SetupScreen:
|
||||
ScreenNTSC(WIDTH, HEIGHT, VIDEO_MODE, VIDEO_C_IMAGE | UNCACHED)
|
||||
jr ra
|
||||
if WIDTH == 640 {
|
||||
lli a0, RES_640_480
|
||||
} else if WIDTH == 576 {
|
||||
lli a0, RES_576_432
|
||||
} else if WIDTH == 512 {
|
||||
lli a0, RES_512_448
|
||||
} else if WIDTH == 320 {
|
||||
lli a0, RES_320_240
|
||||
} else if WIDTH == 288 {
|
||||
lli a0, RES_288_216
|
||||
} else if WIDTH == 256 {
|
||||
lli a0, RES_256_224
|
||||
}
|
||||
|
||||
li a1, VIDEO_MODE
|
||||
la a2, VIDEO_C_IMAGE | UNCACHED
|
||||
j K_SetScreenNTSC // tail-call
|
||||
nop
|
||||
|
||||
MainDumpWrite:
|
||||
|
@ -164,6 +182,8 @@ MainDumpWrite:
|
|||
addiu sp, 0x18
|
||||
|
||||
Die:
|
||||
mfc0 t0, CP0_Status
|
||||
mtc0 t0, CP0_Status
|
||||
j Die
|
||||
nop
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue