diff --git a/.gitignore b/.gitignore index a3453c6..af65465 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ build -psxdev_sample toolchain/armips toolchain/pcsx-redux toolchain/psyq_iwyu +toolchain/PSn00bSDK *.exe *.elf diff --git a/.vscode/settings.json b/.vscode/settings.json index 9f1bb12..c05d14e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,6 +24,12 @@ "string_view": "c", "functional": "c", "tuple": "c", - "hello_gpu.h": "c" + "hello_gpu.h": "c", + "compare": "c", + "ratio": "c", + "scoped_allocator": "c", + "variant": "c", + "math.h": "c", + "cstdint": "c" } } \ No newline at end of file diff --git a/code/asmdd/dsl.s b/code/asmdd/dsl.s index b2f2b04..2e7cb82 100644 --- a/code/asmdd/dsl.s +++ b/code/asmdd/dsl.s @@ -11,10 +11,19 @@ .macro load_uimm p1, p2 lui \p1, \p2 .endm +.macro load_half p1, p2 + lh \p1, \p2 +.endm .macro load_word p1, p2 lw \p1, \p2 .endm # Store +.macro store_byte p1, p2 + sb \p1, \p2 +.endm +.macro store_half p1, p2 + sh \p1, \p2 +.endm .macro store_word p1, p2 sw \p1, \p2 .endm @@ -33,14 +42,14 @@ add \p1, \p2, \p3 .endm .macro add_u p1, p2, p3 - add \p1, \p2, \p3 + addu \p1, \p2, \p3 .endm .macro add_si p1, p2, p3 addi \p1, \p2, \p3 .endm -.macro add_ui p1, p2, p3 - addiu \p1, \p2, \p3 -.endm + .macro add_ui p1, p2, p3 + addiu \p1, \p2, \p3 + .endm # Subtraction .macro sub_s p1, p2, p3 sub \p1, \p2, \p3 @@ -49,7 +58,18 @@ subu \p1, \p2, \p3 .endm # Multiplication - +.macro mult_s p1, p2 + mult \p1, \p2 +.endm +.macro mult_u p1, p2 + multu \p1, \p2 +.endm +.macro mult_si p1, p2 + multi \p1, \p2 +.endm +.macro mult_ui p1, p2 + multui \p1, \p2 +.endm # Division .macro div_s p1, p2 div \p1, \p2 @@ -122,14 +142,38 @@ # Subroutine return address when doing a sub .set rret_addr, $ra +.macro align8 size + (\size + 7) & ~7 +.endm + +.macro def_cf_sp_size size +.set cf_ssize, (\size + 7) & ~7 +.endm + +.macro stack_alloc amount + add_ui $sp, $sp, - \amount +.endm + +.macro stack_release amount + add_ui $sp, $sp, \amount +.endm + # Data Widths .set byte, 1 .set word, 4 -.macro stack_alloc amount - add_ui $sp, - \amount -.endm +.equ U8, 1 +.equ S8, 1 +.equ U16, 2 +.equ S16, 2 +.equ U32, 4 +.equ S32, 4 +.equ SSIZE, 4 +.equ USIZE, 4 +.equ B8, S8 +.equ B16, S16 +.equ B32, S32 -.macro stack_release amount - add_ui $sp, \amount -.endm +.equ false, 0 +.equ true, 1 +.equ true_overflow, 3 diff --git a/code/asmdd/gp.s b/code/asmdd/gp.s index 4d5fc4d..f3fc896 100644 --- a/code/asmdd/gp.s +++ b/code/asmdd/gp.s @@ -177,10 +177,10 @@ .equiv gp_b16_X, 0 .equiv gp_b16_Y, 16 -.equiv RGB8_r, 0 -.equiv RGB8_g, 1 -.equiv RGB8_b, 2 -.equiv sizeof_RGB8, 3 +.equiv RGB8_r, 0 +.equiv RGB8_g, 1 +.equiv RGB8_b, 2 +.equiv RGB8, 3 .equiv gp_pixel16, (2 * byte) .equiv gp_pixel24, (3 * byte) diff --git a/code/asmdd/math.s b/code/asmdd/math.s index 75220d7..2bd6ec5 100644 --- a/code/asmdd/math.s +++ b/code/asmdd/math.s @@ -1,44 +1,46 @@ +.equ A2_S16, (S16 * 2) +.equ A2_S32, (S32 * 2) # Extent_2S16 { S16 width; S16 height; } -.equ Extent_2S16_width, 0 -.equ Extent_2S16_height, 2 -.equ sizeof_Extent_2S16, 4 +.equ Extent_2S16_width, (S16 * 0) +.equ Extent_2S16_height, (S16 * 1) +.equ Extent_2S16, (S16 * 2) # Extent_2S32 { S32 width; S32 height; } -.equ Extent_2S32_width, 0 -.equ Extent_2S32_height, 4 -.equ sizeof_Extent_2S32, 8 +.equ Extent_2S32_width, (S32 * 0) +.equ Extent_2S32_height, (S32 * 1) +.equ Extent_2S32, (S32 * 2) # Vec_2S16 { S16 x; S16 y; } -.equ Vec_2S16_x, 0 -.equ Vec_2S16_y, 2 -.equ sizeof_Vec_2S16, 4 +.equ Vec_2S16_x, (S16 * 0) +.equ Vec_2S16_y, (S16 * 1) +.equ Vec_2S16, (S16 * 2) # Vec_2S32 { S32 x; S32 y; } -.equ Vec_2S32_x, 0 -.equ Vec_2S32_y, 4 -.equ sizeof_Vec_2S32, 8 +.equ Vec_2S32_x, (S32 * 0) +.equ Vec_2S32_y, (S32 * 1) +.equ Vec_2S32, (S32 * 2) # Range_2S16 { Vec_2S16 p0; Vec_2S16 p1; } -.equ Range_2S16_p0, 0 -.equ Range_2S16_p0_x, 0 -.equ Range_2S16_p0_y, 2 -.equ Range_2S16_p1, 4 -.equ Range_2S16_p1_x, 4 -.equ Range_2S16_p1_y, 6 -.equ sizeof_Range_2S16, 8 +.equ Range_2S16_p0, (Vec_2S16 * 0) +.equ Range_2S16_p1, (Vec_2S16 * 1) +.equ Range_2S16_p0_x, (S16 * 0) +.equ Range_2S16_p0_y, (S16 * 1) +.equ Range_2S16_p1_x, (S16 * 2) +.equ Range_2S16_p1_y, (S16 * 3) +.equ Range_2S16, (S16 * 4) # Range_2S32 { Vec_2S32 p0; Vec_2S32 p1; } -.equ Range_2S32_p0, 0 -.equ Range_2S32_p0_x, 0 -.equ Range_2S32_p0_y, 4 -.equ Range_2S32_p1, 8 -.equ Range_2S32_p1_x, 8 -.equ Range_2S32_p1_y, 12 -.equ sizeof_Range_2S32, 16 +.equ Range_2S32_p0, (Vec_2S32 * 0) +.equ Range_2S32_p1, (Vec_2S32 * 1) +.equ Range_2S32_p0_x, (S32 * 0) +.equ Range_2S32_p0_y, (S32 * 1) +.equ Range_2S32_p1_x, (S32 * 2) +.equ Range_2S32_p1_y, (S32 * 3) +.equ Range_2S32, (S32 * 4) # Rect_S16 { S16 x; S16 y; S16 width; S16 height; } -.equ Rect_S16_x, 0 -.equ Rect_S16_y, 2 -.equ Rect_S16_width, 4 -.equ Rect_S16_height, 6 -.equ sizeof_Rect_S16, 8 +.equ Rect_S16_x, (S16 * 0) +.equ Rect_S16_y, (S16 * 1) +.equ Rect_S16_width, (S16 * 2) +.equ Rect_S16_height, (S16 * 3) +.equ Rect_S16, (S16 * 4) # Rect_S32 { S32 x; S32 y; S32 width; S32 height; } -.equ Rect_S32_x, 0 -.equ Rect_S32_y, 4 -.equ Rect_S32_width, 8 -.equ Rect_S32_height, 12 -.equ sizeof_Rect_S32, 16 +.equ Rect_S32_x, (S32 * 0) +.equ Rect_S32_y, (S32 * 1) +.equ Rect_S32_width, (S32 * 2) +.equ Rect_S32_height, (S32 * 3) +.equ Rect_S32, (S32 * 4) diff --git a/code/duffle/gp.h b/code/duffle/gp.h index 8a733f5..a509311 100644 --- a/code/duffle/gp.h +++ b/code/duffle/gp.h @@ -85,4 +85,8 @@ typedef BYTE gp_Pixel24[3]; typedef def_struct(gp_Vec2) { U16 y; U16 x; }; -void gp_screen_init(void) __asm__("gp_screen_init"); +#if 1 +void gp_screen_init(void) __asm__("gp_screen_init_asm"); +#else +#define gp_screen_init() gp_screen_init_c11() +#endif diff --git a/code/graphics_hello_psyq/hello_gpu.c b/code/graphics_hello_psyq/hello_gpu.c index a83f5a0..32409c6 100644 --- a/code/graphics_hello_psyq/hello_gpu.c +++ b/code/graphics_hello_psyq/hello_gpu.c @@ -13,10 +13,13 @@ S16 active_screen_buffer; void gp_screen_init_c11(void) { ResetGraph(0); + SetDispMask(1); // gp_DisplayEnabled + + // Just setting env data, not interacting with console hw. // First buffer area SetDefDispEnv((DISPENV*)& screen_buffer.display[0], 0, 0, ScreenRes_X, ScreenRes_Y); SetDefDrawEnv((DRAWENV*)& screen_buffer.draw [0], 0, ScreenRes_Y, ScreenRes_X, ScreenRes_Y); - // Second buffer rea + // Second buffer area SetDefDispEnv((DISPENV*)& screen_buffer.display[1], 0, ScreenRes_Y, ScreenRes_X, ScreenRes_Y); SetDefDrawEnv((DRAWENV*)& screen_buffer.draw [1], 0, 0, ScreenRes_X, ScreenRes_Y); // Set the back/drawing buffer @@ -27,17 +30,20 @@ void gp_screen_init_c11(void) screen_buffer.draw[1].initial_bg_color = (RGB8){ .r = 127, .g = 63, .b = 0 }; // Set the current initial buffer active_screen_buffer = 0; + PutDispEnv((DISPENV*)& screen_buffer.display[active_screen_buffer]); - PutDrawEnv((DRAWENV*)& screen_buffer.draw [active_screen_buffer]); + + DRAWENV* wtf = (DRAWENV*)& screen_buffer.draw [active_screen_buffer]; + PutDrawEnv(wtf); + // Initialize and setup the GTE geometry offsets InitGeom(); + SetGeomOffset(ScreenRes_CenterX, ScreenRes_CenterY); SetGeomScreen(ScreenRes_CenterX); - // Enable display - SetDispMask(1); } -void gp_display_frame_c11(void) { +void gp_display_frame(void) { DrawSync(0); VSync(0); PutDispEnv((DISPENV*)& screen_buffer.display[active_screen_buffer]); @@ -48,19 +54,16 @@ void gp_display_frame_c11(void) { active_screen_buffer = !active_screen_buffer; // Swap current buffer } -void render_c11(void) { +void render(void) { } int main(void) { - // gp_screen_init(); - gp_screen_init_c11(); - + gp_screen_init(); while (1) { - render_c11(); - gp_display_frame_c11(); + render(); + gp_display_frame(); }; - return 0; } diff --git a/code/graphics_hello_psyq/hello_gpu.h b/code/graphics_hello_psyq/hello_gpu.h index 1a28576..49b4b29 100644 --- a/code/graphics_hello_psyq/hello_gpu.h +++ b/code/graphics_hello_psyq/hello_gpu.h @@ -11,7 +11,7 @@ typedef def_struct(DrawEnv) { A2_S16 drawing_offset; Rect_S16 texture_window; S16 texture_page; - BYTE flag_dither; + BYTE flag_dither; BYTE flag_draw_on_display; BYTE enable_auto_clear; RGB8 initial_bg_color; diff --git a/code/graphics_hello_psyq/hello_gpu.s b/code/graphics_hello_psyq/hello_gpu.s index 337d690..0adb147 100644 --- a/code/graphics_hello_psyq/hello_gpu.s +++ b/code/graphics_hello_psyq/hello_gpu.s @@ -5,69 +5,163 @@ .include "./asmdd/io.s" .include "./asmdd/gp.s" -# DrawEnv_Packed -.equ DrawEnv_Packed_tag, 0 -.equ DrawEnv_Packed_code, 4 -.equ sizeof_DrawEnv_Packed, 64 -# DrawEnv -.equ DrawEnv_clip_area, 0 -.equ DrawEnv_drawing_offset, 8 -.equ DrawEnv_texture_window, 12 -.equ DrawEnv_texture_page, 20 -.equ DrawEnv_flag_dither, 22 -.equ DrawEnv_flag_draw_on_display, 23 -.equ DrawEnv_enable_auto_clear, 24 -.equ DrawEnv_initial_bg_color, 25 -.equ DrawEnv_dr_env, 28 -.equ sizeof_DrawEnv, 92 -# DisplayEnv -.equ DisplayEnv_display_area, 0 -.equ DisplayEnv_screen, 8 -.equ DisplayEnv_vinterlace, 16 -.equ DisplayEnv_color24, 17 -.equ DisplayEnv_pad0, 18 -.equ DisplayEnv_pad1, 19 -.equ sizeof_DisplayEnv, 20 -# DoubleBuffer +# DrawEnv_Packed { U32 tag; U32 code[15]; } +.equ DrawEnv_Packed_tag, 0 +.equ DrawEnv_Packed_code, DrawEnv_Packed_tag + U32 +.equ DrawEnv_Packed, 64 +# DrawEnv { Rect_S16 clip; Vec_2S16 ofs; Rect_S16 tw; U16 tpage; U8 dtd; U8 dfe; U8 tme; U8 r0,g0,b0; DR_ENV dr_env; } +.equ DrawEnv_clip_area, /* 0 */ Rect_S16 * 0 +.equ DrawEnv_drawing_offset, /* 8 */ A2_S16 * 0 + Rect_S16 +.equ DrawEnv_texture_window, /* 12 */ Rect_S16 * 0 + A2_S16 + DrawEnv_drawing_offset +.equ DrawEnv_texture_page, /* 20 */ S16 * 0 + Rect_S16 + DrawEnv_texture_window +.equ DrawEnv_flag_dither, /* 22 */ byte * 0 + S16 + DrawEnv_texture_page +.equ DrawEnv_flag_draw_on_display, /* 23 */ byte * 0 + byte + DrawEnv_flag_dither +.equ DrawEnv_enable_auto_clear, /* 24 */ byte * 0 + byte + DrawEnv_flag_draw_on_display +.equ DrawEnv_initial_bg_color, /* 25 */ RGB8 * 0 + byte + 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_S16 * 0 +.equ DisplayEnv_screen, Rect_S16 * 0 + Rect_S16 + DisplayEnv_display_area +.equ DisplayEnv_vinterlace, byte * 0 + Rect_S16 + DisplayEnv_screen +.equ DisplayEnv_color24, byte * 0 + byte + DisplayEnv_vinterlace +.equ DisplayEnv_pad0, byte * 0 + byte + DisplayEnv_color24 +.equ DisplayEnv_pad1, byte * 0 + byte + DisplayEnv_pad0 +.equ DisplayEnv, DisplayEnv_pad1 + byte +# DoubleBuffer { DrawEnv draw[2]; DisplayEnv display[2]; } .equ DoubleBuffer_draw, 0 -.equ DoubleBuffer_draw_0, 0 -.equ DoubleBuffer_draw_1, 92 # 0 + sizeof_DrawEnv -.equ DoubleBuffer_display, 184 # 92 * 2 -.equ DoubleBuffer_display_0, 184 -.equ DoubleBuffer_display_1, 204 # 184 + sizeof_DisplayEnv -.equ sizeof_DoubleBuffer, 224 +.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 CF_Shadow, 16 +.extern ResetGraph +.equ ResetGraph_mode, rarg_0 -.global gp_screen_init -.type gp_screen_init, @function -gp_screen_init: +.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 + S32 + +.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 + S32 + +.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) - gcmd_push gp1, rtmp_1, gp_Reset - gcmd_push gp1, rtmp_1, gp_DisplayEnabled - gcmd_push gp1, rtmp_1, gp_DisplayMode_320x240_15bit_NTSC - gcmd_push gp1, rtmp_1, gp_HorizontalDisplayRange_3168_608 - gcmd_push gp1, rtmp_1, gp_VerticalDisplayRange_264_24 + def_cf_sp_size 0x80; + stack_alloc cf_ssize + store_word rret_addr, 0($sp) - jump_reg rret_addr; nop + // 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, screen_buffer; add_ui SetDefDispEnv_env, rtmp_0, 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, screen_buffer; add_ui SetDefDrawEnv_env, rtmp_0, 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, screen_buffer; add_ui SetDefDispEnv_env, rtmp_0, 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, screen_buffer; add_ui SetDefDrawEnv_env, rtmp_0, 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, screen_buffer; + 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 + move rtmp_1, $zero; load_imm rtmp_2, 63; load_imm rtmp_3, 127 + // 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, active_screen_buffer; store_word rtmp_1, 0(rtmp_0) + + load_addr rtmp_1, active_screen_buffer; load_half rtmp_1, 0(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, screen_buffer; 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, active_screen_buffer; load_half rtmp_1, 0(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, screen_buffer; 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, . - gp_screen_init - -.global gp_display_frame -.type gp_display_frame, @function -gp_display_frame: - // TODO(Ed): Time to read docs - -.Lgp_display_frame_end: -.size gp_display_frame, . - gp_display_frame - +.size gp_screen_init_asm, . - gp_screen_init_asm