mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-14 11:38:14 +00:00
79 lines
3.3 KiB
C
79 lines
3.3 KiB
C
#ifdef INTELLISENSE_DIRECTIVES
|
|
# include "dsl.h"
|
|
# include "gcc_asm.h"
|
|
# include "mips.h"
|
|
# include "bios.h"
|
|
# include "pad.h"
|
|
#endif
|
|
|
|
/* Uses ONE 8-byte frame allocated via the compiler's standard prologue.
|
|
* 4 wasted-arg words for B(12h) InitPAD2 are at [SP+0..15] but are not explicitly allocated.
|
|
* Compiler handles the MIPS O32 "wasted stack" convention for us by treating the B-call as a 4-arg call.
|
|
*
|
|
* The buffer pointers are passed as arguments so the compiler keeps them in callee-saved registers;
|
|
* The B(12h) asm volatile block does NOT clobber those registers (it clobbers only the volatile GPRs + B-table arg registers explicitly).
|
|
* The C-level writes after the call re-load the pointers from their callee-saved homes.
|
|
*
|
|
* The clobber list for both B-calls names the full BIOS destroy set documented in kernelbios.md:167-174 (R1..R15, R24..R25, R31, HI/LO).
|
|
* The kernel-ABI "volatile GPRs" subset is clb_mem_drain; the rest of the destroy set is enumerated explicitly here. */
|
|
NI_ void pad_bios_init_start(PadBiosRaw* raw0, PadBiosRaw* raw1)
|
|
{
|
|
/* Pin raw0 + raw1 to $a0 + $a1 via rgcc; the B(12h) call uses these directly.
|
|
* The `(void)` casts mark them as unread after the call so the compiler doesn't need to move them back. */
|
|
register PadBiosRaw* p0 rgcc(R_A0) = raw0;
|
|
register PadBiosRaw* p1 rgcc(R_A1) = raw1;
|
|
(void)p0; (void)p1;
|
|
|
|
// TODO(Ed): Properly annotate the raw values in the inline asm instructions.
|
|
// Use enums.
|
|
|
|
/* B(12h) InitPAD2(raw0, 0x22, raw1, 0x22)
|
|
* $a0 = raw0 (rgcc-bound; survives the sequence below)
|
|
* $a1 = raw1 (preserved into $a2 before $a1 is overwritten)
|
|
* $a2 = raw1 (moved from $a1; survives $a1's overwrite)
|
|
* $a3 = 0x22 (immediate)
|
|
* $t1 = 0x12 (function number)
|
|
* $t2 = 0xB0 (BIOS B-table address) */
|
|
asm volatile(
|
|
asm_words(
|
|
or_u( R_A2, R_A0, R_0), /* $a2 = $a1 = raw1 */
|
|
add_ui( R_A1, R_0, bios_pad_buffer_size), /* $a1 = 0x22 */
|
|
add_ui( R_A3, R_0, bios_pad_buffer_size), /* $a3 = 0x22 */
|
|
add_ui( R_T1, R_0, bios_init_pad_2), /* $t1 = 0x12 */
|
|
add_ui( R_T2, R_0, bios_btable_addr), /* $t2 = 0xB0 */
|
|
call_reg(R_T2), /* jalr $t2, $ra */
|
|
nop /* BD slot */
|
|
)
|
|
asm_rpins, r_use(p0), r_use(p1)
|
|
asm_clobber:
|
|
rlit(R_AT),
|
|
rlit(R_V0), rlit(R_V1),
|
|
rlit(R_T0), rlit(R_T1), rlit(R_T2), rlit(R_T3), rlit(R_T4),
|
|
rlit(R_T5), rlit(R_T6), rlit(R_T7), rlit(R_T8), rlit(R_T9),
|
|
rlit(R_RA),
|
|
clb_mem_drain
|
|
);
|
|
|
|
/* The C-level writes re-load the pointers via the parameter names and write 0xFF to each
|
|
* buffer's status byte to mark the initial-state hazard documented in kernelbios.md:1621-1624. */
|
|
u1_v(raw0)[0] = 0xFF;
|
|
u1_v(raw1)[0] = 0xFF;
|
|
|
|
/* B(13h) StartPAD2() — no args. The BIOS preserves $sp. */
|
|
asm volatile(
|
|
asm_words(
|
|
add_ui( R_T1, R_0, bios_start_pad_2), /* $t1 = 0x13 */
|
|
add_ui( R_T2, R_0, bios_btable_addr), /* $t2 = 0xB0 (re-load) */
|
|
call_reg(R_T2), /* jalr $t2, $ra */
|
|
nop /* BD slot */
|
|
)
|
|
asm_clobber:
|
|
rlit(R_AT),
|
|
rlit(R_V0), rlit(R_V1),
|
|
rlit(R_T0), rlit(R_T1), rlit(R_T2), rlit(R_T3), rlit(R_T4),
|
|
rlit(R_T5), rlit(R_T6), rlit(R_T7), rlit(R_T8), rlit(R_T9),
|
|
rlit(R_RA),
|
|
clb_mem_drain
|
|
);
|
|
}
|