Writing N64 homebrew hangs after 2 seconds on hardware
Page 1 of 1

Author:  orbitaldecay [ Fri Jan 15, 2016 7:14 pm ]
Post subject:  Writing N64 homebrew hangs after 2 seconds on hardware

Hello all,

For perverse reasons, I'm interested in squeezing small graphical effects into the boot code of an N64 rom. The code I have so far sets up the frame buffer and writes some garbage to it producing a pink screen. It works perfectly on Project64 2.2, but when I attempt to run it on real hardware, I see the pink screen for about 2 seconds and then it goes black. I have used extensively code from Peter Lemon's N64 github repo. I am assembling with bass. Here is my source code:

arch n64.cpu
endian msb
output "@party2016.n64", create
fill 1052672
include "N64.INC"
include "N64_GFX.INC"

origin  $00000000
base    $A4000000

// N64 Header (64 bytes)
db $80                      // Initial PI_BSB_DOM1_LAT_REG Value
db $37                      // Initial PI_BSB_DOM1_PGS_REG Value
db $12                      // Initial PI_BSB_DOM1_PWD_REG Value
db $40                      // Initial PI_BSB_DOM1_PGS_REG Value
dd $0000000F                // Initial clock rate
dd BootcodeStart            // Boot address (normally this is in RDRAM)
dd $00001444                // Release offset
db "CRC1"                   // CRC1
db "CRC2"                   // CRC2
dd $00000000                // Unknown
dd $00000000                // Unknown
db "@PARTY2016          "   // Program title (20 bytes)
dd $00000000                // Unknown
db $00                      // Unknown
db $00                      // Unknown
db $00                      // Unknown
db $00                      // Developer ID code "N" = Nintendo
dw $0000                    // Cartridge ID code
db $00                      // Country code
db $00                      // Unused

// Write 8 to $BFC007FC. This is supposed to stop the N64 from freezing after a
// couple of seconds. Don't ask me why, I just read it on the internet.
    li      r1, 8
    lui     r2, $BFC0
    sw      r1, $07FC (r2)

// Initialize the screen buffer
    ScreenNTSC(320, 240, BPP32, $A0100000)
    lui     r1, $A010
    lui     r2, $0004
    ori     r2, r2, $B000

    sw      r1, $0000 (r1)
    bne     r1, r2, DrawLoop
    addiu   r1, r1, 4

    j       PaintScreen

ScreenNTSC just initializes the screen buffer. It is a macro that is defined in the following way:

macro ScreenNTSC(width,height, status, origin) {
  lui a0,VI_BASE // A0 = VI Base Register ($A4400000)
  li t0,{status}      // T0 = Status/Control
  sw t0,VI_STATUS(a0) // Store Status/Control To VI Status Register ($A4400000)
  la t0,{origin}      // T0 = Origin (Frame Buffer Origin In Bytes)
  sw t0,VI_ORIGIN(a0) // Store Origin To VI Origin Register ($A4400004)
  lli t0,{width}      // T0 = Width (Frame Buffer Line Width In Pixels)
  sw t0,VI_WIDTH(a0)  // Store Width To VI Width Register ($A4400008)
  lli t0,$200         // T0 = Vertical Interrupt (Interrupt When Current Half-Line $200)
  sw t0,VI_V_INTR(a0) // Store Vertical Interrupt To VI Interrupt Register ($A440000C)
  lli t0,0                    // T0 = Current Vertical Line (Current Half-Line, Sampled Once Per Line = 0)
  sw t0,VI_V_CURRENT_LINE(a0) // Store Current Vertical Line To VI Current Register ($A4400010)
  li t0,$3E52239      // T0 = Video Timing (Start Of Color Burst In Pixels from H-Sync = 3, Vertical Sync Width In Half Lines = 229, Color Burst Width In Pixels = 34, Horizontal Sync Width In Pixels = 57)
  sw t0,VI_TIMING(a0) // Store Video Timing To VI Burst Register ($A4400014)
  lli t0,$20D         // T0 = Vertical Sync (Number Of Half-Lines Per Field = 525)
  sw t0,VI_V_SYNC(a0) // Store Vertical Sync To VI V Sync Register ($A4400018)
  lli t0,$C15         // T0 = Horizontal Sync (5-bit Leap Pattern Used For PAL only = 0, Total Duration Of A Line In 1/4 Pixel = 3093)
  sw t0,VI_H_SYNC(a0) // Store Horizontal Sync To VI H Sync Register ($A440001C)
  li t0,$C150C15           // T0 = Horizontal Sync Leap (Identical To H Sync = 3093, Identical To H Sync = 3093)
  sw t0,VI_H_SYNC_LEAP(a0) // Store Horizontal Sync Leap To VI Leap Register ($A4400020)
  li t0,$6C02EC        // T0 = Horizontal Video (Start Of Active Video In Screen Pixels = 108, End Of Active Video In Screen Pixels = 748)
  sw t0,VI_H_VIDEO(a0) // Store Horizontal Video To VI H Start Register ($A4400024)
  li t0,$2501FF        // T0 = Vertical Video (Start Of Active Video In Screen Half-Lines = 37, End Of Active Video In Screen Half-Lines = 511)
  sw t0,VI_V_VIDEO(a0) // Store Vertical Video To VI V Start Register ($A4400028)
  li t0,$E0204         // T0 = Vertical Burst (Start Of Color Burst Enable In Half-Lines = 14, End Of Color Burst Enable In Half-Lines = 516)
  sw t0,VI_V_BURST(a0) // Store Vertical Burst To VI V Burst Register ($A440002C)
  lli t0,($100*({width}/160)) // T0 = X-Scale (Horizontal Subpixel Offset In 2.10 Format = 0, 1/Horizontal Scale Up Factor In 2.10 Format)
  sw t0,VI_X_SCALE(a0)        // Store X-Scale To VI X Scale Register ($A4400030)
  lli t0,($100*({height}/60)) // T0 = Y-Scale (Vertical Subpixel Offset In 2.10 Format = 0, 1/Vertical Scale Up Factor In 2.10 Format)
  sw t0,VI_Y_SCALE(a0)        // Store Y-Scale To VI Y Scale Register ($A4400034)

Are there any N64 hardware gurus who know why this might be freezing after a couple of seconds? I'm sure there is something that the bootcode does which prevents this from happening, but if anyone knows what it is before I spend the rest of the week picking apart the bootcode disassembly I have, it would be immensely helpful.

Author:  Parasyte [ Sat Sep 30, 2017 11:26 pm ]
Post subject:  Re: Writing N64 homebrew hangs after 2 seconds on hardware

Woah, old post is old! But this is a really interesting question. I have no idea if you ever found a solution, but I do have a little information that I can share.

Address BFC007FC is in PIF RAM (which is 64 bytes total). There's really no reason that the console should crash if you don't write the magic number 8 to the end of PIF RAM. (This is definitely some cargo-cult programming here.)

Anyway, I have disassembled all of the various CIC boot codes in the past, and they do a lot of arcane stuff with the various hardware registers, like the MIPS interface and RDRAM interface. AFAIK, this is the only code that ever touches that stuff, so it's hard to find documentation on any of it. I wouldn't be surprised if what you're missing is something along the lines of setting up the RDRAM refresh rates or something.

Page 1 of 1 All times are UTC - 8 hours [ DST ]
Powered by phpBB® Forum Software © phpBB Group