Setting up hello_gte (should have done this earlier)

This commit is contained in:
2026-05-31 20:47:55 -04:00
parent 66981351ee
commit 1848a6b48e
5 changed files with 731 additions and 1 deletions
+24
View File
@@ -51,6 +51,30 @@
"tbreak main",
"continue"
]
},
{
"name": "Debug: Hello GTE Psy-Q!",
"type": "gdb",
"request": "attach",
"target": "localhost:3333",
"remote": true,
"cwd": "${workspaceRoot}/build",
"valuesFormatting": "parseText",
"stopAtConnect": true,
"gdbpath": "gdb-multiarch",
"windows": {
"gdbpath": "gdb-multiarch.exe"
},
"osx": {
"gdbpath": "gdb"
},
"executable": "${workspaceRoot}/build/hello_gte.elf",
"autorun": [
"monitor reset shellhalt",
"load hello_gte.elf",
"tbreak main",
"continue"
]
}
]
}
+287
View File
@@ -0,0 +1,287 @@
#include "stdio.h"
#include <stdlib.h>
#include "assert.h"
// #include "libgpu.h"
// #include "libetc.h"
// #include "libgte.h"
#include "duffle/dsl.h"
#include "duffle/memory.h"
#include "duffle/math.h"
#include "duffle/gp.h"
#include "hello_gte.h"
enum {
PrimitiveBuff_Len = 4096,
OrderingTbl_Len = 2048
};
typedef U4 OrderingTable_Buffer[OrderingTbl_Len];
typedef def_farray(OrderingTable_Buffer, 2);
typedef B1 PrimitiveBuffer[PrimitiveBuff_Len];
typedef def_farray(PrimitiveBuffer, 2);
typedef def_struct(PrimitiveArena) {
A2_PrimitiveBuffer buf;
U4 used;
};
#define Cube_num_verts 8
typedef def_farray(V3_S2, Cube_num_verts);
#define Cube_num_faces 6
typedef def_farray(V4_S2, Cube_num_faces);
void ent_cube128_init(A8_V3_S2* verts, A6_V4_S2* faces) {
memory_copy(verts, & (A8_V3_S2) {
{ -128, -128, -128 },
{ 128, -128, -128 },
{ 128, -128, 128 },
{ -128, -128, 128 },
{ -128, 128, -128 },
{ 128, 128, -128 },
{ 128, 128, 128 },
{ -128, 128, 128 }
}, size_of(A8_V3_S2) );
memory_copy(faces, & (A6_V4_S2) {
{ 3, 2, 0, 1 },
{ 0, 1, 4, 5 },
{ 4, 5, 7, 6 },
{ 1, 2, 5, 6 },
{ 2, 3, 6, 7 },
{ 3, 0, 7, 4 },
}, size_of(A6_V4_S2) );
return;
}
typedef def_struct(Ent_Cube) {
V3_S4 accel;
V3_S4 vel;
V3_S4 pos;
V3_S4 scale;
V3_S2 rot;
A8_V3_S2 verts;
A6_V4_S2 faces;
};
#define Floor_num_verts 4
typedef def_farray(V3_S2, Floor_num_verts);
#define Floor_num_faces 2
typedef def_farray(V3_S2, Floor_num_faces);
void ent_floor_init(A4_V3_S2* verts, A2_V3_S2* faces) {
memory_copy(verts, &(A4_V3_S2) {
{ -900, 0, -900 },
{ -900, 0, 900 },
{ 900, 0, -900 },
{ 900, 0, 900 },
}, size_of(A8_V3_S2));
memory_copy(faces, & (A2_V3_S2) {
{ 0, 1, 2 },
{ 1, 3, 2 },
}, size_of(A2_V3_S2));
};
typedef def_struct(Ent_Floor) {
V3_S4 accel;
V3_S4 pos;
V3_S4 scale;
V3_S2 rot;
A4_V3_S2 verts;
A2_V3_S2 faces;
};
typedef def_struct(SMemory) {
DoubleBuffer screen_buf;
A2_OrderingTable_Buffer ordering_tbl;
PrimitiveArena primitives;
S2 active_buf_id;
M3_S2 tform_world;
Ent_Cube cube;
Ent_Floor floor;
};
global SMemory static_mem;
extern SMemory static_mem;
B1* prim__alloc(U4 type_width, Str8 type_name) {
gknown PrimitiveArena* pa = & static_mem.primitives;
gknown B1* buf = (B1*) r_(static_mem.primitives.buf)[static_mem.active_buf_id];
assert(pa->used + type_width < PrimitiveBuff_Len);
B1* next = buf + pa->used;
pa->used += type_width;
return next;
}
#define prim_alloc(type) (type*)prim__alloc(size_of(type), txt( stringify(type)))
void gp_screen_init_c11(DoubleBuffer* screen_buf, S2* active_buf_id)
{
reset_graph(0);
// Set the current initial buffer
active_buf_id[0] = 0;
// Just setting env data, not interacting with console hw.
// First buffer area
displayenv_init(& r_(screen_buf->display)[0], 0, 0, ScreenRes_X, ScreenRes_Y);
drawenv_init (& r_(screen_buf->draw )[0], 0, ScreenRes_Y, ScreenRes_X, ScreenRes_Y);
// Second buffer area
displayenv_init(& r_(screen_buf->display)[1], 0, ScreenRes_Y, ScreenRes_X, ScreenRes_Y);
drawenv_init (& r_(screen_buf->draw )[1], 0, 0, ScreenRes_X, ScreenRes_Y);
// Set the back/drawing buffer
screen_buf->draw[0].enable_auto_clear = true;
screen_buf->draw[1].enable_auto_clear = true;
// Set the background clear color
screen_buf->draw[0].initial_bg_color = rgb8( .r = 7, .g = 7, .b = 7 );
screen_buf->draw[1].initial_bg_color = rgb8( .r = 7, .g = 7, .b = 7 );
// screen_buf->draw[1].initial_bg_color = rgb8( .r = 47, .g = 13, .b = 0 );
displayenv_put(& r_(screen_buf->display)[ active_buf_id[0] ]);
drawenv_put (& r_(screen_buf->draw )[ active_buf_id[0] ]);
// Initialize and setup the GTE geometry offsets
geom_init();
geom_set_offset(ScreenRes_CenterX, ScreenRes_CenterY);
geom_set_screen(ScreenZ);
set_display_enabled(1); // gp_DisplayEnabled
}
void gp_display_frame(DoubleBuffer* screen_buf, S2* active_buf_id, U4* ordering_buf, PrimitiveArena* pa) {
draw_sync(0);
vsync(0);
displayenv_put(& r_(screen_buf->display)[active_buf_id[0] ]);
drawenv_put (& r_(screen_buf->draw) [active_buf_id[0] ]);
{
draw_orderingtbl(ordering_buf + OrderingTbl_Len - 1);
pa->used = 0;
}
active_buf_id[0] = ! active_buf_id[0]; // Swap current buffer
}
void render(void) {
}
void update(PrimitiveArena* pa, U4* ordering_buf)
{
orderingtbl_clear_reverse(ordering_buf, OrderingTbl_Len);
// Update the position based on acceleration and velocity
gknown V3_S4_R pos = & static_mem.cube.pos;
gknown V3_S4_R vel = & static_mem.cube.vel;
gknown V3_S4_R acc = & static_mem.cube.accel;
add_v3s4(vel, acc[0]);
add_v3s4_fp(pos, vel[0]);
// vel->x += acc->x;
// vel->y += acc->y;
// vel->z += acc->z;
// pos->x += vel->x;
// pos->y += vel->y;
// pos->z += vel->z;
if (pos->y + 150 > static_mem.floor.pos.y) vel->y *= -1;
// Prep
S4 nclip = 0;
S4 orderingtbl_z = 0;
A2_S2 p; //???
S4 flag; //????
// Draw Cube
{
m3s2_rotation (& static_mem.cube.rot, & static_mem.tform_world);
m3s2_translation(& static_mem.tform_world, & static_mem.cube.pos);
m3s2_scale (& static_mem.tform_world, & static_mem.cube.scale);
gte_matrix_set_rotation (& static_mem.tform_world);
gte_matrix_set_translation(& static_mem.tform_world);
for (U4 face_id = 0; face_id < Cube_num_faces; face_id += 1)
{
Poly_G4* quad = prim_alloc(Poly_G4); set_poly_g4(quad);
quad->c0 = rgb8(255, 0, 255);
quad->c1 = rgb8(255, 255, 0);
quad->c2 = rgb8( 0, 255, 255);
quad->c3 = rgb8( 0, 255, 0);
V4_S2* face = & static_mem.cube.faces[face_id];
V3_S2* p0 = & static_mem.cube.verts[face->x];
V3_S2* p1 = & static_mem.cube.verts[face->y];
V3_S2* p2 = & static_mem.cube.verts[face->z];
V3_S2* p3 = & static_mem.cube.verts[face->w];
nclip = rtp_avg_nclip_a4_v3s2(
p0, p1, p2, p3,
& quad->p0, & quad->p1, & quad->p2, & quad->p3,
& p, & orderingtbl_z, & flag
);
if (nclip <= 0) {
continue;
}
if ((orderingtbl_z > 0) && (orderingtbl_z < OrderingTbl_Len)) {
orderingtbl_add_primitive(ordering_buf[orderingtbl_z], quad);
}
}
// static_mem.cube.rot.x += 6;
// static_mem.cube.rot.y += 8;
// static_mem.cube.rot.z += 12;
static_mem.cube.rot.y += 20;
}
// Draw Floor
{
m3s2_rotation (& static_mem.floor.rot, & static_mem.tform_world);
m3s2_translation(& static_mem.tform_world, & static_mem.floor.pos);
m3s2_scale (& static_mem.tform_world, & static_mem.floor.scale);
gte_matrix_set_rotation (& static_mem.tform_world);
gte_matrix_set_translation(& static_mem.tform_world);
for (U4 face_id = 0; face_id < Floor_num_faces; face_id += 1)
{
Poly_F3* tri = prim_alloc(Poly_F3); set_poly_f3(tri);
tri->color = rgb8(255, 255, 255);
V3_S2* face = & static_mem.floor.faces[face_id];
V3_S2* p0 = & static_mem.floor.verts[face->x];
V3_S2* p1 = & static_mem.floor.verts[face->y];
V3_S2* p2 = & static_mem.floor.verts[face->z];
nclip = rtp_avg_nclip_a3_v3s2(p0, p1, p2
, & tri->p0, & tri->p1, & tri->p2
, & p, & orderingtbl_z, & flag
);
if (nclip <= 0) {
continue;
}
if ((orderingtbl_z > 0) && (orderingtbl_z < OrderingTbl_Len)) {
orderingtbl_add_primitive(ordering_buf[orderingtbl_z], tri);
}
}
static_mem.floor.rot.y += 5;
}
}
int main(void)
{
static_mem = (SMemory){0};
static_mem.primitives.used = 0;
ent_cube128_init(& static_mem.cube.verts, & static_mem.cube.faces); {
Ent_Cube* cube = & static_mem.cube;
cube->rot = v3s2(0, 0, 0);
// cube->pos = v3s4(0, 0, 900);
cube->scale = v3s4_fp_one();
cube->accel = v3s4(0, 1, 0);
cube->pos = v3s4(0, -400, 1800);
}
ent_floor_init(& static_mem.floor.verts, & static_mem.floor.faces); {
Ent_Floor* floor = & static_mem.floor;
floor->rot = v3s2(0, 0, 0);
floor->pos = v3s4(0, 450, 1800);
floor->scale = v3s4_fp_one();
}
// gknown gp_screen_init();
gp_screen_init_c11(& static_mem.screen_buf, & static_mem.active_buf_id);
while (1)
{
gknown S2* active_buf_id = & static_mem.active_buf_id;
gknown U4* ordering_buf = r_(static_mem.ordering_tbl)[active_buf_id[0]];
gknown PrimitiveArena* pa = & static_mem.primitives;
update(pa, ordering_buf);
render();
gp_display_frame(& static_mem.screen_buf, active_buf_id, ordering_buf, pa);
};
return 0;
}
+207
View File
@@ -0,0 +1,207 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "duffle/dsl.h"
# include "duffle/math.h"
# include "duffle/gp.h"
#endif
typedef def_struct(DrawEnv_Packed) { U4 tag; U4 code[15]; };
typedef def_struct(DrawEnv) {
Rect_S2 clip_area;
A2_S2 drawing_offset;
Rect_S2 texture_window;
S2 texture_page;
B1 flag_dither;
B1 flag_draw_on_display;
B1 enable_auto_clear;
RGB8 initial_bg_color;
DrawEnv_Packed dr_env; // reserved
};
typedef def_struct(DisplayEnv) {
Rect_S2 display_area;
Rect_S2 screen;
B1 vinterlace;
B1 color24;
B1 pad0;
B1 pad1;
};
typedef def_farray(DrawEnv, 2);
typedef def_farray(DisplayEnv, 2);
typedef def_struct(DoubleBuffer) {
A2_DrawEnv draw;
A2_DisplayEnv display;
};
#define ScreenRes_X 320
#define ScreenRes_Y 240
#define ScreenZ 320
#define ScreenRes_CenterX (ScreenRes_X >> 1)
#define ScreenRes_CenterY (ScreenRes_Y >> 1)
DisplayEnv* displayenv_init(DisplayEnv* env, S4 x, S4 y, S4 w, S4 h) __asm__("SetDefDispEnv");
DrawEnv* drawenv_init (DrawEnv* env, S4 x, S4 y, S4 w, S4 h) __asm__("SetDefDrawEnv");
DisplayEnv* displayenv_put(DisplayEnv* env) __asm__("PutDispEnv");
DrawEnv* drawenv_put (DrawEnv* env) __asm__("PutDrawEnv");
U4 geom_init(void) __asm__("InitGeom");
void geom_set_offset(U4 x, U4 y) __asm__("SetGeomOffset");
void geom_set_screen(U4 h) __asm__("SetGeomScreen");
U4* orderingtbl_clear_reverse(U4* ot, U4 len) __asm__("ClearOTagR");
U4 reset_graph(U4 mode) __asm__("ResetGraph");
void set_display_enabled(U4 mask) __asm__("SetDispMask");
U4 draw_sync(U4 mode) __asm__("DrawSync");
U4 vsync(U4 mode) __asm__("VSync");
void draw_orderingtbl(U4* buf) __asm__("DrawOTag");
typedef def_struct(PolyTag) {
U4 addr: 24;
U4 len: 8;
RGB8 color;
B1 code;
};
/*
* Primitive Handling Macros
*/
#define set_len( p, _len) (((PolyTag*R_)(p))->len = (B1)(_len))
#define set_addr(p, _addr) (((PolyTag*R_)(p))->addr = (U4)(_addr))
#define set_code(p, _code) (((PolyTag*R_)(p))->code = (B1)(_code))
#define get_len(p) (B1)(((PolyTag*R_)(p))->len)
#define get_code(p) (B1)(((PolyTag*R_)(p))->code)
#define get_addr(p) (U4)(((PolyTag*R_)(p))->addr)
#define orderingtbl_add_primitive(ot, p) set_addr(p, get_addr(ot)), set_addr(ot, p)
#define orderingtbl_add_primitives(ot, p0, p1) set_addr(p1, get_addr(ot)), set_addr(ot, p0)
/* Primitive Length Code */
#define set_poly_f3(p) set_len(p, 4), set_code(p, 0x20)
#define set_poly_ft3(p) set_len(p, 7), set_code(p, 0x24)
#define set_poly_g3(p) set_len(p, 6), set_code(p, 0x30)
#define set_poly_gt3(p) set_len(p, 9), set_code(p, 0x34)
#define set_poly_f4(p) set_len(p, 5), set_code(p, 0x28)
#define set_poly_ft4(p) set_len(p, 9), set_code(p, 0x2c)
#define set_poly_g4(p) set_len(p, 8), set_code(p, 0x38)
#define set_poly_gt4(p) set_len(p, 12), set_code(p, 0x3c)
// #define setSprt8(p) setlen(p, 3), setcode(p, 0x74)
// #define setSprt16(p) setlen(p, 3), setcode(p, 0x7c)
// #define setSprt(p) setlen(p, 4), setcode(p, 0x64)
// #define setTile1(p) set_len(p, 2), set_code(p, 0x68)
// #define setTile8(p) set_len(p, 2), set_code(p, 0x70)
// #define setTile16(p) set_len(p, 2), set_code(p, 0x78)
#define set_tile(p) set_len(p, 3), set_code(p, 0x60)
// #define setLineF2(p) set_len(p, 3), set_code(p, 0x40)
// #define setLineG2(p) set_len(p, 4), set_code(p, 0x50)
// #define setLineF3(p) set_len(p, 5), set_code(p, 0x48),(p)->pad = 0x55555555
// #define setLineG3(p) set_len(p, 7), set_code(p, 0x58),(p)->pad = 0x55555555, (p)->p2 = 0
// #define setLineF4(p) set_len(p, 6), set_code(p, 0x4c),(p)->pad = 0x55555555
// #define setLineG4(p) set_len(p, 9), set_code(p, 0x5c),(p)->pad = 0x55555555, (p)->p2 = 0, (p)->p3 = 0
typedef def_struct(Poly_F3) {
U4 tag;
RGB8 color;
B1 code;
union {
struct {
V2_S2 p0;
V2_S2 p1;
V2_S2 p2;
};
A3_V2_S2 points;
};
};
typedef def_struct(Poly_G3) {
U4 tag; RGB8 c0; B1 code;
V2_S2 p0; RGB8 c1; B1 pad1;
V2_S2 p1; RGB8 c2; B1 pad2;
V2_S2 p2;
};
typedef def_struct(Poly_F4) {
U4 tag;
RGB8 color;
B1 code;
union {
struct {
V2_S2 p0;
V2_S2 p1;
V2_S2 p2;
V2_S2 p3;
};
A4_V2_S2 points;
};
};
typedef def_struct(Poly_G4) {
U4 tag; RGB8 c0; B1 code;
V2_S2 p0; RGB8 c1; B1 pad1;
V2_S2 p1; RGB8 c2; B1 pad2;
V2_S2 p2; RGB8 c3; B1 pad3;
V2_S2 p3;
};
typedef def_struct(Tile) {
U4 tag;
RGB8 color;
B1 code;
Rect_S2 rect;
};
/*
Linear Algebra
*/
M3_S2* m3s2_rotation (V3_S2* vec, M3_S2* mat) __asm__("RotMatrix");
M3_S2* m3s2_translation(M3_S2* mat, V3_S4* vec) __asm__("TransMatrix");
M3_S2* m3s2_scale (M3_S2* mat, V3_S4* vec) __asm__("ScaleMatrix");
// Rotation, Translation, Perspective
S4 rtp_v3s2_raw(V3_S2* vec, S4* xy, S4* pp, S4* flag) __asm__("RotTransPers");
FI_ S4 rtp_v3s2(V3_S2* vec, V2_S2* xy, A2_S2* pp, S4* flag) { return rtp_v3s2_raw(vec, cast(S4*R_, & xy->x), cast(S4*R_, pp), r_(flag)); }
S4 rtp_avg_nclip_a3_v3s2_raw(V3_S2* v0, V3_S2* v1, V3_S2* v2, S4* xy1, S4* xy2, S4* xy3, S4* pp, S4* otz, S4* flag) __asm__("RotAverageNclip3");
FI_ S4 rtp_avg_nclip_a3_v3s2(
V3_S2* v0, V3_S2* v1, V3_S2* v2,
V2_S2* xy0, V2_S2* xy1, V2_S2* xy2,
A2_S2* pp, S4* otz, S4* flag
){
return rtp_avg_nclip_a3_v3s2_raw(
v0, v1, v2,
cast(S4*R_, xy0), cast(S4*R_, xy1), cast(S4*R_, xy2),
cast(S4*R_, pp), cast(S4*R_, otz), cast(S4*R_, flag)
);
}
S4 rtp_avg_nclip_a4_v3s2_raw(V3_S2* v0, V3_S2* v1, V3_S2* v2, V3_S2* v3, S4* xy1, S4* xy2, S4* xy3, S4* xy4, S4* pp, S4* otz, S4* flag) __asm__("RotAverageNclip4");
FI_ S4 rtp_avg_nclip_a4_v3s2(
V3_S2* v0, V3_S2* v1, V3_S2* v2, V3_S2* v3,
V2_S2* xy0, V2_S2* xy1, V2_S2* xy2, V2_S2* xy3,
A2_S2* pp, S4* otz, S4* flag
){
return rtp_avg_nclip_a4_v3s2_raw(
v0, v1, v2, v3,
cast(S4*R_, xy0), cast(S4*R_, xy1), cast(S4*R_, xy2), cast(S4*R_, xy3),
cast(S4*R_, pp), cast(S4*R_, otz), cast(S4*R_, flag)
);
}
void gte_matrix_set_rotation (M3_S2* mat) __asm__("SetRotMatrix");
void gte_matrix_set_translation(M3_S2* mat) __asm__("SetTransMatrix");
enum {
fp_one = (1 << 12),
};
#define v3s4_fp_one() v3s4(fp_one, fp_one, fp_one)
+170
View File
@@ -0,0 +1,170 @@
// .include "./toolchain/pcsx-redux/src/mips/common/crt0/crt0.s"
.include "./asmdd/dsl.s"
.include "./asmdd/math.s"
.include "./asmdd/io.s"
.include "./asmdd/gp.s"
# DrawEnv_Packed { U4 tag; U4 code[15]; }
.equ DrawEnv_Packed_tag, 0
.equ DrawEnv_Packed_code, DrawEnv_Packed_tag + U4
.equ DrawEnv_Packed, 64
# DrawEnv { Rect_S2 clip; V2_S2 ofs; Rect_S2 tw; U2 tpage; U8 dtd; U8 dfe; U8 tme; U8 r0,g0,b0; DR_ENV dr_env; }
.equ DrawEnv_clip_area, /* 0 */ Rect_S2 * 0
.equ DrawEnv_drawing_offset, /* 8 */ V2_S2 * 0 + Rect_S2
.equ DrawEnv_texture_window, /* 12 */ Rect_S2 * 0 + A2_S2 + DrawEnv_drawing_offset
.equ DrawEnv_texture_page, /* 20 */ S1 * 0 + Rect_S2 + DrawEnv_texture_window
.equ DrawEnv_flag_dither, /* 22 */ B1 * 0 + S2 + DrawEnv_texture_page
.equ DrawEnv_flag_draw_on_display, /* 23 */ B1 * 0 + B1 + DrawEnv_flag_dither
.equ DrawEnv_enable_auto_clear, /* 24 */ B1 * 0 + B1 + DrawEnv_flag_draw_on_display
.equ DrawEnv_initial_bg_color, /* 25 */ RGB8 * 0 + B1 + DrawEnv_enable_auto_clear
.equ DrawEnv_dr_env, /* 28 */ DrawEnv_Packed * 0 + RGB8 + DrawEnv_initial_bg_color
.equ DrawEnv, /* 92 */ DrawEnv_dr_env + DrawEnv_Packed
# DisplayEnv { Rect_S16 disp; Rect_S16 screen; U8 isinter; U8 isrgb24; U8 pad[2]; }
.equ DisplayEnv_display_area, Rect_S2 * 0
.equ DisplayEnv_screen, Rect_S2 * 0 + Rect_S2 + DisplayEnv_display_area
.equ DisplayEnv_vinterlace, B1 * 0 + Rect_S2 + DisplayEnv_screen
.equ DisplayEnv_color24, B1 * 0 + B1 + DisplayEnv_vinterlace
.equ DisplayEnv_pad0, B1 * 0 + B1 + DisplayEnv_color24
.equ DisplayEnv_pad1, B1 * 0 + B1 + DisplayEnv_pad0
.equ DisplayEnv, DisplayEnv_pad1 + B1
# DoubleBuffer { DrawEnv draw[2]; DisplayEnv display[2]; }
.equ DoubleBuffer_draw, 0
.equ DoubleBuffer_draw_0, (DrawEnv * 0)
.equ DoubleBuffer_draw_1, (DrawEnv * 1)
.equ DoubleBuffer_display, (DrawEnv * 2)
.equ DoubleBuffer_display_0, (DisplayEnv * 0) + DoubleBuffer_display
.equ DoubleBuffer_display_1, (DisplayEnv * 1) + DoubleBuffer_display
.equ DoubleBuffer, (DisplayEnv * 2) + DoubleBuffer_display
# Screen Constants
.equ ScreenRes_X, 320
.equ ScreenRes_Y, 240
.equ ScreenRes_CenterX, (ScreenRes_X >> 1)
.equ ScreenRes_CenterY, (ScreenRes_Y >> 1)
.equ SMemory_screen_buf, DoubleBuffer * 0
.equ SMemory_active_screen_buf, S2 * 0 + DoubleBuffer
.equ CF_Shadow, 16
.extern ResetGraph
.equ ResetGraph_mode, rarg_0
.extern SetDispMask
.equ SetDispMask_mask, rarg_0
.extern PutDispEnv
.extern PutDrawEnv
.equ PutDispEnv_env, rarg_0
.equ PutDrawEnv_env, rarg_0
.extern SetDefDispEnv
.equ SetDefDispEnv_env, rarg_0
.equ SetDefDispEnv_x, rarg_1
.equ SetDefDispEnv_y, rarg_2
.equ SetDefDispEnv_w, rarg_3
.equ SetDefDispEnv_h, CF_Shadow
.set SetDefDispEnv_sp_size, CF_Shadow + S4
.extern SetDefDrawEnv
.equ SetDefDrawEnv_env, rarg_0
.equ SetDefDrawEnv_x, rarg_1
.equ SetDefDrawEnv_y, rarg_2
.equ SetDefDrawEnv_w, rarg_3
.equ SetDefDrawEnv_h, CF_Shadow
.set SetDefDrawEnv_sp_size, CF_Shadow + S4
.extern SetGeomOffset
.equ SetGeomOffset_x, rarg_0
.equ SetGeomOffset_y, rarg_1
.extern SetGeomScreen
.equ SetGeomScreen_h, rarg_0
.global gp_screen_init_asm
.type gp_screen_init_asm, @function
gp_screen_init_asm:
.equiv rio_offset, rtmp_0
load_imm rtmp_0, IO_BASE_ADDR
#define gp0 gpio_port0(rio_offset)
#define gp1 gpio_port1(rio_offset)
def_cf_sp_size 0x18; // Should be enough for all calls within this proc, for some reason SetDefDispEnv needs the offset to be CF_Shadow..
stack_alloc cf_ssize
store_word rret_addr, 0($sp)
// Note(Ed): Cannot be used psyq manages things related to vblank and other things so the api must be called instead
// gcmd_push gp1, rtmp_1, gp_Reset // ResetGraph(0)
// gcmd_push gp1, rtmp_1, gp_DisplayEnabled // SetDispMask(1)
load_imm ResetGraph_mode, gp_Reset; jump_nlink ResetGraph
load_imm SetDispMask_mask, 1; jump_nlink SetDispMask
// First buffer area
load_addr rtmp_0, static_mem; add_ui SetDefDispEnv_env, rtmp_0, SMemory_screen_buf + DoubleBuffer_display_0
move SetDefDispEnv_x, $zero
move SetDefDispEnv_y, $zero
load_imm SetDefDispEnv_w, ScreenRes_X
load_imm rtmp_0, ScreenRes_Y; store_word rtmp_0, SetDefDispEnv_h($sp)
jump_nlink SetDefDispEnv
load_addr rtmp_0, static_mem; add_ui SetDefDrawEnv_env, rtmp_0, SMemory_screen_buf + DoubleBuffer_draw_0
move SetDefDrawEnv_x, $zero
load_imm SetDefDrawEnv_y, ScreenRes_Y
load_imm SetDefDrawEnv_w, ScreenRes_X
load_imm rtmp_0, ScreenRes_Y; store_word rtmp_0, SetDefDrawEnv_h($sp)
jump_nlink SetDefDrawEnv
// Second buffer area
load_addr rtmp_0, static_mem; add_ui SetDefDispEnv_env, rtmp_0, SMemory_screen_buf + DoubleBuffer_display_1
move SetDefDispEnv_x, $zero
load_imm SetDefDispEnv_y, ScreenRes_Y
load_imm SetDefDispEnv_w, ScreenRes_X
load_imm rtmp_0, ScreenRes_Y; store_word rtmp_0, SetDefDispEnv_h($sp)
jump_nlink SetDefDispEnv
load_addr rtmp_0, static_mem; add_ui SetDefDrawEnv_env, rtmp_0, SMemory_screen_buf + DoubleBuffer_draw_1
move SetDefDrawEnv_x, $zero
move SetDefDrawEnv_y, $zero
load_imm SetDefDrawEnv_w, ScreenRes_X
load_imm rtmp_0, ScreenRes_Y; store_word rtmp_0, SetDefDrawEnv_h($sp)
jump_nlink SetDefDrawEnv
// Set the back/drawing buffer
load_imm rtmp_1, true
load_addr rtmp_0, static_mem; // At SMemory_screen_buf
store_word rtmp_1, DoubleBuffer_draw_0 + DrawEnv_enable_auto_clear(rtmp_0)
store_word rtmp_1, DoubleBuffer_draw_1 + DrawEnv_enable_auto_clear(rtmp_0)
// Set background clear color
load_imm rtmp_1, 28; load_imm rtmp_2, 22; load_imm rtmp_3, 25
// 63, 0, 127
store_byte rtmp_2, DoubleBuffer_draw_0 + DrawEnv_initial_bg_color + RGB8_r(rtmp_0)
store_byte rtmp_1, DoubleBuffer_draw_0 + DrawEnv_initial_bg_color + RGB8_g(rtmp_0)
store_byte rtmp_3, DoubleBuffer_draw_0 + DrawEnv_initial_bg_color + RGB8_b(rtmp_0)
// 127, 63, 0
store_byte rtmp_3, DoubleBuffer_draw_1 + DrawEnv_initial_bg_color + RGB8_r(rtmp_0)
store_byte rtmp_2, DoubleBuffer_draw_1 + DrawEnv_initial_bg_color + RGB8_g(rtmp_0)
store_byte rtmp_1, DoubleBuffer_draw_1 + DrawEnv_initial_bg_color + RGB8_b(rtmp_0)
load_addr rtmp_0, static_mem; store_word rtmp_1, SMemory_active_screen_buf(rtmp_0)
load_addr rtmp_1, static_mem; load_half rtmp_1, SMemory_active_screen_buf(rtmp_1); // rtmp_1 = active_screen_buffer
load_imm rtmp_2, DisplayEnv; mult_u rtmp_1, rtmp_2; mov_from_low rtmp_2 // rtmp_2 = DisplayEnv.type_size * active_screen_Buffer (rtmp_1)
add_ui rtmp_2, rtmp_2, DoubleBuffer_display // rtmp_2 += DoubleBuffer.display
load_addr rtmp_0, static_mem; add_u PutDispEnv_env, rtmp_0, rtmp_2 // rarg_0 = rtmp_0 (screen_buffer) + rtmp_2 (.display[active_screen-buffer])
jump_nlink PutDispEnv
load_addr rtmp_1, static_mem; load_half rtmp_1, SMemory_active_screen_buf(rtmp_1);
load_imm rtmp_2, DrawEnv; mult_u rtmp_1, rtmp_2; mov_from_low rtmp_2;
add_ui rtmp_2, rtmp_2, DoubleBuffer_draw
load_addr rtmp_0, static_mem; add_u PutDrawEnv_env, rtmp_0, rtmp_2
jump_nlink PutDrawEnv
// Initialize and setup the GTE geometry offsets
jump_nlink InitGeom
load_imm SetGeomOffset_x, ScreenRes_CenterX
load_imm SetGeomOffset_y, ScreenRes_CenterY
jump_nlink SetGeomOffset
load_imm SetGeomScreen_h, ScreenRes_CenterX
jump_nlink SetGeomScreen
load_word rret_addr, 0($sp)
stack_release cf_ssize
jump_reg rret_addr;
.Lgp_screen_init_end:
.size gp_screen_init_asm, . - gp_screen_init_asm
+43 -1
View File
@@ -307,4 +307,46 @@ function build-graphis_hello {
link-modules @($module_asm_crt, $module_asm, $module_c) $elf $link_args
make-binary $elf $exe
}
build-graphis_hello
# build-graphis_hello
function build-gte_hello {
$includes += @()
$path_module = join-path $path_code 'gte_hello'
$assemble_args = @()
$assemble_args += $f_debug
$assemble_args += $f_optimize_none
$assemble_args += ($f_include + $path_code)
$src_asm_crt = join-path $path_nugget_common 'crt0/crt0.s'
$module_asm_crt = join-path $path_build 'crt0.o'
# assemble-unit $src_asm_crt $module_asm_crt $includes $assemble_args
$src_asm = join-path $path_module 'hello_gte.s'
$module_asm = join-path $path_build 'hello_gte.o'
assemble-unit $src_asm $module_asm $includes $assemble_args
$src_c = join-path $path_module 'hello_gte.c'
$module_c = join-path $path_build 'hello_gte_c.o'
$compile_args = @()
$compile_args += $f_debug
# $compile_args += $f_optimize_none
# $compile_args += $f_optimize_intrinsics
$compile_args += $f_optimize_size
# $compile_args += $f_optimize_debug
$compile_args += ($f_include + $path_code)
compile-unit $src_c $module_c $includes $compile_args
$elf = join-path $path_build 'hello_gte.elf'
$exe = join-path $path_build 'hello_gte.ps-exe'
$link_args = @()
$link_args += $f_debug
# $link_args += $f_optimize_size
link-modules @($module_asm_crt, $module_asm, $module_c) $elf $link_args
make-binary $elf $exe
}
build-gte_hello