|
Nugget
Bare-metal libraries and examples for the original PlayStation
|
#include <stdint.h>#include "common/hardware/counters.h"#include "common/hardware/gpu.h"#include "common/hardware/hwregs.h"#include "common/syscalls/syscalls.h"#include "exotic/cester.h"
Macros | |
| #define | CESTER_NO_SIGNAL |
| #define | CESTER_NO_TIME |
| #define | EXIT_SUCCESS 0 |
| #define | EXIT_FAILURE 1 |
| #define | ROWS 480 |
Functions | |
| CESTER_BODY (#define ROWS static uint8_t s_rect1[ROWS];static uint8_t s_rect0[ROWS];static uint8_t s_slow0[ROWS];static uint8_t s_fill0[ROWS];static uint32_t s_col[ROWS];static unsigned s_frame, s_lastLong;static uint16_t s_vbl;static int s_interruptsWereEnabled;static void waitIdle(void) { while((GPU_STATUS &0x14000000) !=0x14000000);} static void poll(void) { if(IREG &1) { IREG=~1u;s_frame++;s_vbl=COUNTERS[1].value;} if(GPU_STATUS &0x80000000) s_lastLong=s_frame;} static uint16_t line(void) { return COUNTERS[1].value - s_vbl;} static void setup(void) { GPU_STATUS=0x00000000;GPU_STATUS=0x06000000|0x260|(0xc60<< 12);GPU_STATUS=0x07000000|0x010|(0x100<< 10);GPU_STATUS=0x05000000;GPU_STATUS=0x08000027;GPU_DATA=0xe3000000;GPU_DATA=0xe4000000|639|(479<< 10);GPU_DATA=0xe5000000;GPU_STATUS=0x03000000;COUNTERS[1].mode=0x0100;} static void fill(uint32_t color) { GPU_DATA=0x02000000|color;GPU_DATA=0x00000000;GPU_DATA=(ROWS<< 16)|640;} static void readColumn(uint8_t *out, int black) { waitIdle();GPU_DATA=0x01000000;GPU_DATA=0xc0000000;GPU_DATA=0x00000000;GPU_DATA=(ROWS<< 16)|2;while(!(GPU_STATUS &0x08000000));for(int i=0;i< ROWS;i++) s_col[i]=GPU_DATA;for(int i=0;i< ROWS;i++) out[i]=((s_col[i] &0x7fff7fff)==0)==black;} static void syncLong(uint16_t at) { IREG=~1u;s_frame=0;s_lastLong=0xffff;while(s_frame< 3) poll();while(s_frame - s_lastLong !=1) poll();unsigned f=s_frame;while(s_frame==f) poll();while(line()< at) poll();} static void rects(uint8_t *out, int dfe, int slow) { setup();GPU_DATA=0xe1000400;fill(0);waitIdle();GPU_DATA=0xe1000000|(dfe ? 0x400 :0);syncLong(slow ? 0 :30);for(int y=0;y< ROWS;y++) { if(slow) { uint16_t l=COUNTERS[1].value;while(COUNTERS[1].value==l) poll();} GPU_DATA=0x60ffffff;GPU_DATA=y<< 16;GPU_DATA=(1<< 16)|640;while((GPU_STATUS &0x14000000) !=0x14000000) poll();} readColumn(out, 0);} static void fillArm(uint8_t *out) { setup();GPU_DATA=0xe1000400;fill(0xffffff);waitIdle();GPU_DATA=0xe1000000;syncLong(30);fill(0);readColumn(out, 1);} static void print(const char *tag, const uint8_t *rows) { char buf[61];for(int base=0;base< ROWS;base+=60) { for(int i=0;i< 60;i++) buf[i]=rows[base+i] ? '#' :'.';buf[60]=0;ramsyscall_printf("%s %03d %s\n", tag, base, buf);} } static unsigned countRange(const uint8_t *rows, int from, int to, int parity) { unsigned n=0;for(int y=from;y<=to;y++) if(((y &1)==parity) &&rows[y]) n++;return n;}) CESTER_BEFORE_ALL(gpudfe480i | |
| rects (s_rect1, 1, 0) | |
| rects (s_rect0, 0, 0) | |
| rects (s_slow0, 0, 1) | |
| fillArm (s_fill0) | |
| print ("rect1", s_rect1) | |
| print ("rect0", s_rect0) | |
| print ("slow0", s_slow0) | |
| print ("fill0", s_fill0) | |
Variables | |
| s_interruptsWereEnabled = enterCriticalSection() | |
| IMASK = 0 | |
| #define CESTER_NO_SIGNAL |
| #define CESTER_NO_TIME |
| #define EXIT_FAILURE 1 |
| #define EXIT_SUCCESS 0 |
| #define ROWS 480 |
| CESTER_BODY | ( | #define ROWS static uint8_t s_rect1;static uint8_t s_rect0;static uint8_t s_slow0;static uint8_t s_fill0;static uint32_t s_col;static unsigned | s_frame[ROWS][ROWS][ROWS][ROWS][ROWS], |
| s_lastLong;static uint16_t s_vbl;static int s_interruptsWereEnabled;static void waitIdle(void) { while((GPU_STATUS &0x14000000) !=0x14000000);} static void poll(void) { if(IREG &1) { IREG=~1u;s_frame++;s_vbl=COUNTERS[1].value;} if(GPU_STATUS &0x80000000) s_lastLong=s_frame;} static uint16_t line(void) { return COUNTERS[1].value - s_vbl;} static void setup(void) { GPU_STATUS=0x00000000;GPU_STATUS=0x06000000|0x260|(0xc60<< 12);GPU_STATUS=0x07000000|0x010|(0x100<< 10);GPU_STATUS=0x05000000;GPU_STATUS=0x08000027;GPU_DATA=0xe3000000;GPU_DATA=0xe4000000|639|(479<< 10);GPU_DATA=0xe5000000;GPU_STATUS=0x03000000;COUNTERS[1].mode=0x0100;} static void fill(uint32_t color) { GPU_DATA=0x02000000|color;GPU_DATA=0x00000000;GPU_DATA=(ROWS<< 16)|640;} static void readColumn(uint8_t *out, int black) { waitIdle();GPU_DATA=0x01000000;GPU_DATA=0xc0000000;GPU_DATA=0x00000000;GPU_DATA=(ROWS<< 16)|2;while(!(GPU_STATUS &0x08000000));for(int i=0;i< ROWS;i++) s_col[i]=GPU_DATA;for(int i=0;i< ROWS;i++) out[i]=((s_col[i] &0x7fff7fff)==0)==black;} static void syncLong(uint16_t at) { IREG=~1u;s_frame=0;s_lastLong=0xffff;while(s_frame< 3) poll();while(s_frame - s_lastLong !=1) poll();unsigned f=s_frame;while(s_frame==f) poll();while(line()< at) poll();} static void rects(uint8_t *out, int dfe, int slow) { setup();GPU_DATA=0xe1000400;fill(0);waitIdle();GPU_DATA=0xe1000000|(dfe ? 0x400 :0);syncLong(slow ? 0 :30);for(int y=0;y< ROWS;y++) { if(slow) { uint16_t l=COUNTERS[1].value;while(COUNTERS[1].value==l) poll();} GPU_DATA=0x60ffffff;GPU_DATA=y<< 16;GPU_DATA=(1<< 16)|640;while((GPU_STATUS &0x14000000) !=0x14000000) poll();} readColumn(out, 0);} static void fillArm(uint8_t *out) { setup();GPU_DATA=0xe1000400;fill(0xffffff);waitIdle();GPU_DATA=0xe1000000;syncLong(30);fill(0);readColumn(out, 1);} static void print(const char *tag, const uint8_t *rows) { char buf[61];for(int base=0;base< ROWS;base+=60) { for(int i=0;i< 60;i++) buf[i]=rows[base+i] ? '#' :'.';buf[60]=0;ramsyscall_printf("%s %03d %s\n", tag, base, buf);} } static unsigned countRange(const uint8_t *rows, int from, int to, int parity) { unsigned n=0;for(int y=from;y<=to;y++) if(((y &1)==parity) &&rows[y]) n++;return n;} | |||
| ) |
| fillArm | ( | s_fill0 | ) |
| ( | "fill0" | , | |
| s_fill0 | |||
| ) |
| ( | "rect0" | , | |
| s_rect0 | |||
| ) |
| ( | "rect1" | , | |
| s_rect1 | |||
| ) |
| ( | "slow0" | , | |
| s_slow0 | |||
| ) |
| rects | ( | s_rect0 | , |
| 0 | , | ||
| 0 | |||
| ) |
| rects | ( | s_rect1 | , |
| 1 | , | ||
| 0 | |||
| ) |
| rects | ( | s_slow0 | , |
| 0 | , | ||
| 1 | |||
| ) |
| IMASK = 0 |
| s_interruptsWereEnabled = enterCriticalSection() |