main: initial vga mode setting

This feels very hacky, and I'd like to make this better.
This commit is contained in:
Zack Buhman 2023-10-13 05:30:21 -07:00
parent 2bcf1aedef
commit 99701f0b57
4 changed files with 333 additions and 116 deletions

176
holly.h
View File

@ -1,93 +1,95 @@
#include <stdint.h>
#include <stddef.h>
#include "type.h"
struct holly_reg {
uint32_t ID; /* Device ID */
uint32_t REVISION; /* Revision Number */
uint32_t SOFTRESET; /* CORE & TA software reset */
uint8_t _pad0[8];
uint32_t STARTRENDER; /* Drawing start */
uint32_t TEST_SELECT; /* Test (writing this register is prohibited) */
uint8_t _pad1[4];
uint32_t PARAM_BASE; /* Base address for ISP parameters */
uint8_t _pad2[8];
uint32_t REGION_BASE; /* Base address for Region Array */
uint32_t SPAN_SORT_CFG; /* Span Sorter control */
uint8_t _pad3[12];
uint32_t VO_BORDER_COL; /* Border area color */
uint32_t FB_R_CTRL; /* Frame buffer read control */
uint32_t FB_W_CTRL; /* Frame buffer write control */
uint32_t FB_W_LINESTRIDE;/* Frame buffer line stride */
uint32_t FB_R_SOF1; /* Read start address for field - 1/strip - 1 */
uint32_t FB_R_SOF2; /* Read start address for field - 2/strip - 2 */
uint8_t _pad4[4];
uint32_t FB_R_SIZE; /* Frame buffer XY size */
uint32_t FB_W_SOF1; /* Write start address for field - 1/strip - 1 */
uint32_t FB_W_SOF2; /* Write start address for field - 2/strip - 2 */
uint32_t FB_X_CLIP; /* Pixel clip X coordinate */
uint32_t FB_Y_CLIP; /* Pixel clip Y coordinate */
uint8_t _pad5[4];
uint32_t FPU_SHAD_SCALE; /* Intensity Volume mode */
uint32_t FPU_CULL_VAL; /* Comparison value for culling */
uint32_t FPU_PARAM_CFG; /* Parameter read control */
uint32_t HALF_OFFSET; /* Pixel sampling control */
uint32_t FPU_PERP_VAL; /* Comparison value for perpendicular polygons */
uint32_t ISP_BACKGND_D; /* Background surface depth */
uint32_t ISP_BACKGND_T; /* Background surface tag */
uint8_t _pad6[8];
uint32_t ISP_FEED_CFG; /* Translucent polygon sort mode */
uint8_t _pad7[4];
uint32_t SDRAM_REFRESH; /* Texture memory refresh counter */
uint32_t SDRAM_ARB_CFG; /* Texture memory arbiter control */
uint32_t SDRAM_CFG; /* Texture memory control */
uint8_t _pad8[4];
uint32_t FOG_COL_RAM; /* Color for Look Up table Fog */
uint32_t FOG_COL_VERT; /* Color for vertex Fog */
uint32_t FOG_DENSITY; /* Fog scale value */
uint32_t FOG_CLAMP_MAX; /* Color clamping maximum value */
uint32_t FOG_CLAMP_MIN; /* Color clamping minimum value */
uint32_t SPG_TRIGGER_POS;/* External trigger signal HV counter value */
uint32_t SPG_HBLANK_INT; /* H-blank interrupt control */
uint32_t SPG_VBLANK_INT; /* V-blank interrupt control */
uint32_t SPG_CONTROL; /* Sync pulse generator control */
uint32_t SPG_HBLANK; /* H-blank control */
uint32_t SPG_LOAD; /* HV counter load value */
uint32_t SPG_VBLANK; /* V-blank control */
uint32_t SPG_WIDTH; /* Sync width control */
uint32_t TEXT_CONTROL; /* Texturing control */
uint32_t VO_CONTROL; /* Video output control */
uint32_t VO_STARTX; /* Video output start X position */
uint32_t VO_STARTY; /* Video output start Y position */
uint32_t SCALER_CTL; /* X & Y scaler control */
uint8_t _pad9[16];
uint32_t PAL_RAM_CTRL; /* Palette RAM control */
uint32_t SPG_STATUS; /* Sync pulse generator status */
uint32_t FB_BURSTCTRL; /* Frame buffer burst control */
uint32_t FB_C_SOF; /* Current frame buffer start address */
uint32_t Y_COEFF; /* Y scaling coefficent */
uint32_t PT_ALPHA_REF; /* Alpha value for Punch Through polygon comparison */
uint8_t _pad10[4];
uint32_t TA_OL_BASE; /* Object List write start address */
uint32_t TA_ISP_BASE; /* ISP/TSP Parameter write start address */
uint32_t TA_OL_LIMIT; /* Object List write limit address */
uint32_t TA_ISP_LIMIT; /* ISP/TSP Parameter limit address */
uint32_t TA_NEXT_OPB; /* Start address for the Object Pointer Block */
uint32_t TA_ITP_CURRENT; /* Starting address where the next ISP/TSP Parameters are stored */
uint32_t TA_GLOB_TILE_CLIP;/* Global Tile Clip control */
uint32_t TA_ALLOC_CTRL; /* Object list control */
uint32_t TA_LIST_INIT; /* TA initialization */
uint32_t TA_YUV_TEX_BASE;/* YUV422 texture write start address */
uint32_t TA_YUV_TEX_CTRL;/* YUV converter control */
uint32_t TA_YUV_TEX_CNT; /* YUV converter macro block counter value */
uint8_t _pad11[12];
uint32_t TA_LIST_CONT; /* TA continuation processing */
uint32_t TA_NEXT_OPB_INIT;/* Additional OPB starting address */
uint8_t _pad12[152];
uint8_t FOG_TABLE[512]; /* Look-up table fog data */
uint8_t _pad13[512];
uint8_t TA_OL_POINTERS[2400];/* TA Object List Pointer data */
uint8_t _pad14[160];
uint8_t PALETTE_RAM[4096];/* Palette RAM */
reg32 ID; /* Device ID */
reg32 REVISION; /* Revision Number */
reg32 SOFTRESET; /* CORE & TA software reset */
reg8 _pad0[8];
reg32 STARTRENDER; /* Drawing start */
reg32 TEST_SELECT; /* Test (writing this register is prohibited) */
reg8 _pad1[4];
reg32 PARAM_BASE; /* Base address for ISP parameters */
reg8 _pad2[8];
reg32 REGION_BASE; /* Base address for Region Array */
reg32 SPAN_SORT_CFG; /* Span Sorter control */
reg8 _pad3[12];
reg32 VO_BORDER_COL; /* Border area color */
reg32 FB_R_CTRL; /* Frame buffer read control */
reg32 FB_W_CTRL; /* Frame buffer write control */
reg32 FB_W_LINESTRIDE; /* Frame buffer line stride */
reg32 FB_R_SOF1; /* Read start address for field - 1/strip - 1 */
reg32 FB_R_SOF2; /* Read start address for field - 2/strip - 2 */
reg8 _pad4[4];
reg32 FB_R_SIZE; /* Frame buffer XY size */
reg32 FB_W_SOF1; /* Write start address for field - 1/strip - 1 */
reg32 FB_W_SOF2; /* Write start address for field - 2/strip - 2 */
reg32 FB_X_CLIP; /* Pixel clip X coordinate */
reg32 FB_Y_CLIP; /* Pixel clip Y coordinate */
reg8 _pad5[4];
reg32 FPU_SHAD_SCALE; /* Intensity Volume mode */
reg32 FPU_CULL_VAL; /* Comparison value for culling */
reg32 FPU_PARAM_CFG; /* Parameter read control */
reg32 HALF_OFFSET; /* Pixel sampling control */
reg32 FPU_PERP_VAL; /* Comparison value for perpendicular polygons */
reg32 ISP_BACKGND_D; /* Background surface depth */
reg32 ISP_BACKGND_T; /* Background surface tag */
reg8 _pad6[8];
reg32 ISP_FEED_CFG; /* Translucent polygon sort mode */
reg8 _pad7[4];
reg32 SDRAM_REFRESH; /* Texture memory refresh counter */
reg32 SDRAM_ARB_CFG; /* Texture memory arbiter control */
reg32 SDRAM_CFG; /* Texture memory control */
reg8 _pad8[4];
reg32 FOG_COL_RAM; /* Color for Look Up table Fog */
reg32 FOG_COL_VERT; /* Color for vertex Fog */
reg32 FOG_DENSITY; /* Fog scale value */
reg32 FOG_CLAMP_MAX; /* Color clamping maximum value */
reg32 FOG_CLAMP_MIN; /* Color clamping minimum value */
reg32 SPG_TRIGGER_POS; /* External trigger signal HV counter value */
reg32 SPG_HBLANK_INT; /* H-blank interrupt control */
reg32 SPG_VBLANK_INT; /* V-blank interrupt control */
reg32 SPG_CONTROL; /* Sync pulse generator control */
reg32 SPG_HBLANK; /* H-blank control */
reg32 SPG_LOAD; /* HV counter load value */
reg32 SPG_VBLANK; /* V-blank control */
reg32 SPG_WIDTH; /* Sync width control */
reg32 TEXT_CONTROL; /* Texturing control */
reg32 VO_CONTROL; /* Video output control */
reg32 VO_STARTX; /* Video output start X position */
reg32 VO_STARTY; /* Video output start Y position */
reg32 SCALER_CTL; /* X & Y scaler control */
reg8 _pad9[16];
reg32 PAL_RAM_CTRL; /* Palette RAM control */
reg32 SPG_STATUS; /* Sync pulse generator status */
reg32 FB_BURSTCTRL; /* Frame buffer burst control */
reg32 FB_C_SOF; /* Current frame buffer start address */
reg32 Y_COEFF; /* Y scaling coefficent */
reg32 PT_ALPHA_REF; /* Alpha value for Punch Through polygon comparison */
reg8 _pad10[4];
reg32 TA_OL_BASE; /* Object List write start address */
reg32 TA_ISP_BASE; /* ISP/TSP Parameter write start address */
reg32 TA_OL_LIMIT; /* Object List write limit address */
reg32 TA_ISP_LIMIT; /* ISP/TSP Parameter limit address */
reg32 TA_NEXT_OPB; /* Start address for the Object Pointer Block */
reg32 TA_ITP_CURRENT; /* Starting address where the next ISP/TSP Parameters are stored */
reg32 TA_GLOB_TILE_CLIP; /* Global Tile Clip control */
reg32 TA_ALLOC_CTRL; /* Object list control */
reg32 TA_LIST_INIT; /* TA initialization */
reg32 TA_YUV_TEX_BASE; /* YUV422 texture write start address */
reg32 TA_YUV_TEX_CTRL; /* YUV converter control */
reg32 TA_YUV_TEX_CNT; /* YUV converter macro block counter value */
reg8 _pad11[12];
reg32 TA_LIST_CONT; /* TA continuation processing */
reg32 TA_NEXT_OPB_INIT; /* Additional OPB starting address */
reg8 _pad12[152];
reg8 FOG_TABLE[512]; /* Look-up table fog data */
reg8 _pad13[512];
reg8 TA_OL_POINTERS[2400];/* TA Object List Pointer data */
reg8 _pad14[160];
reg8 PALETTE_RAM[4096]; /* Palette RAM */
};
static_assert((offsetof (struct holly_reg, ID)) == 0x0);
@ -162,5 +164,5 @@ static_assert((offsetof (struct holly_reg, FOG_TABLE)) == 0x200);
static_assert((offsetof (struct holly_reg, TA_OL_POINTERS)) == 0x600);
static_assert((offsetof (struct holly_reg, PALETTE_RAM)) == 0x1000);
extern holly_reg HOLLY;
extern struct holly_reg HOLLY __asm("HOLLY");

265
main.c
View File

@ -3,51 +3,260 @@
#include "cache.h"
#include "sh7091.h"
#include "sh7091_bits.h"
#include "holly.h"
volatile uint32_t * RAM = (volatile uint32_t *)0xa5000000;
volatile uint32_t * SPG_STATUS = (volatile uint32_t *)0xa05f810;
uint32_t get_cable_type()
{
/* set all pins to input */
SH7091.BSC.PCTRA = 0;
/* get cable type from pins 9 + 8 */
return SH7091.BSC.PDTRA & PDTRA__MASK;
}
void vga1()
{
uint16_t pclk_delay = 0x0016;
uint32_t fb_r_ctrl = HOLLY.FB_R_CTRL;
HOLLY.FB_R_CTRL = fb_r_ctrl & ~(1 << 0); // fb_enable = 0
HOLLY.VO_CONTROL = pclk_delay << 16 | (1 << 3); // blank_video
HOLLY.FB_R_CTRL = fb_r_ctrl & (1<<23); // vclk_div, for VGA
HOLLY.FB_R_SIZE = 0;
uint16_t vblank_in = 0x0208;
uint16_t vblank_out = 0x0015;
HOLLY.SPG_VBLANK_INT = (vblank_out << 16) | (vblank_in << 0);
HOLLY.SPG_CONTROL = (1 << 8); // sync_direction__output ; non-default
uint16_t hbstart = 0x0345; // default
uint16_t hbend = 0x007e; // default
HOLLY.SPG_HBLANK = (hbend << 16) | (hbstart << 0);
uint16_t hcount = 0x0359; // default
uint16_t vcount = 0x020c; // non-default
HOLLY.SPG_LOAD = (vcount << 16) | (hcount << 0);
uint16_t vbstart = 0x0208; // non-default
uint16_t vbend = 0x0028; // non-default
HOLLY.SPG_VBLANK = (vbend << 16) | (vbstart << 0);
uint16_t hswidth = 0x003f;
uint16_t vswidth = 0x0003;
uint16_t bpwidth = 0x0319;
uint16_t eqwidth = 0x000f;
HOLLY.SPG_WIDTH =
(hswidth << 0)
| (vswidth << 8)
| (bpwidth << 12)
| (eqwidth << 22);
uint16_t startx = 0x0a8;
uint16_t starty = 0x028;
HOLLY.VO_STARTX = startx;
HOLLY.VO_STARTY = (starty << 16) | (starty << 0);
HOLLY.SPG_HBLANK_INT = hbstart << 16;
}
void vga2()
{
uint16_t xsize = 640;
uint16_t ysize = 480;
uint16_t fb_xclip_min = 0;
uint16_t fb_xclip_max = xsize-1;
HOLLY.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0);
uint16_t fb_yclip_min = 0;
uint16_t fb_yclip_max = ysize-1;
HOLLY.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0);
uint16_t fb_latency = 0x09;
uint16_t fb_burstctrl = 15 - fb_latency;
uint16_t wr_burst = 0x08;
HOLLY.FB_BURSTCTRL = 0
| (fb_burstctrl << 0)
| (fb_latency << 4)
| (wr_burst << 9)
;
uint32_t fb_xsize = (xsize * 16)/(32) - 1;
uint32_t fb_ysize = ysize - 3;
uint32_t fb_mod = 1;
HOLLY.FB_R_SIZE = 0
| (fb_xsize << 0)
| (fb_ysize << 10)
| (fb_mod << 20);
uint16_t coeff0 = 0x40;
uint16_t coeff1 = 0x80;
HOLLY.Y_COEFF = (coeff1 << 8) | (coeff0 << 0);
uint16_t vscale_factor = 0x0400;
HOLLY.SCALER_CTL = (vscale_factor << 0);
uint32_t fb_linestride = (xsize * 16) / 64;
HOLLY.FB_W_LINESTRIDE = fb_linestride;
HOLLY.FB_W_CTRL = 0
| 0b001 << 0 // fb_packmode: RGB 565
;
HOLLY.FB_W_SOF1 = 0;
HOLLY.FB_W_SOF2 = 0;
HOLLY.FB_R_SOF1 = 0;
HOLLY.FB_R_SOF2 = 0;
HOLLY.FB_R_CTRL = 0
| 1 << 23 // vclk_div
| 0 << 22 // fb_strip_buf_en
| 0 << 16 // fb_strip_size
| 0 << 8 // fb_chroma_threshold
| 0 << 4 // fb_concat
| 1 << 2 // fb_depth
| 0 << 1 // fb_line_double
| 1 << 0 // fb_enable
;
*((reg32 *)0xa0702c00) = 0;
}
void v_sync_in()
{
#define V_SYNC (1<<13)
while (!(V_SYNC & HOLLY.SPG_STATUS)) {
asm volatile ("nop");
}
while ((V_SYNC & HOLLY.SPG_STATUS)) {
asm volatile ("nop");
}
#undef V_SYNC
}
void vga()
{
get_cable_type();
HOLLY.SOFTRESET = 0;
HOLLY.TEXT_CONTROL = 3;
HOLLY.FB_W_CTRL = 9;
SH7091.SCIF.SCFTDR2 = 'g';
/*
*/
SH7091.SCIF.SCFTDR2 = 'v';
vga1();
vga2();
v_sync_in();
HOLLY.VO_BORDER_COL = 31;
HOLLY.VO_CONTROL = 0x0016;
}
extern uint32_t __bss_link_start __asm("__bss_link_start");
extern uint32_t __bss_link_end __asm("__bss_link_end");
struct rgb
{
unsigned char r;
unsigned char g;
unsigned char b;
};
struct hsv
{
unsigned char h;
unsigned char s;
unsigned char v;
};
struct rgb hsv_to_rgb(struct hsv hsv)
{
struct rgb rgb;
unsigned char region, remainder, p, q, t;
if (hsv.s == 0) {
rgb.r = hsv.v;
rgb.g = hsv.v;
rgb.b = hsv.v;
return rgb;
}
region = hsv.h / 43;
remainder = (hsv.h - (region * 43)) * 6;
p = (hsv.v * (255 - hsv.s)) >> 8;
q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;
switch (region) {
case 0: rgb.r = hsv.v; rgb.g = t; rgb.b = p; break;
case 1: rgb.r = q; rgb.g = hsv.v; rgb.b = p; break;
case 2: rgb.r = p; rgb.g = hsv.v; rgb.b = t; break;
case 3: rgb.r = p; rgb.g = q; rgb.b = hsv.v; break;
case 4: rgb.r = t; rgb.g = p; rgb.b = hsv.v; break;
default: rgb.r = hsv.v; rgb.g = p; rgb.b = q; break;
}
return rgb;
}
void main()
{
cache_init();
uint32_t * start = &__bss_link_start;
uint32_t * end = &__bss_link_end;
while (start < end) {
*start++ = 0;
}
// clear BSS
#define SCSCR2__TE (1 << 5)
#define SCSCR2__RE (1 << 4)
SH7091.SCIF.SCSCR2 = 0;
SH7091.SCIF.SCSMR2 = 0;
SH7091.SCIF.SCBRR2 = 12;
SH7091.SCIF.SCFCR2 = (1 << 2) | (1 << 1); // tfrst rfrst
SH7091.SCIF.SCFCR2 = 0;
SH7091.SCIF.SCSPTR2 = 0;
SH7091.SCIF.SCLSR2 = 0;
SH7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE;
SH7091.SCIF.SCFTDR2 = 'H';
SH7091.SCIF.SCFTDR2 = 'e';
SH7091.SCIF.SCFTDR2 = 'l';
SH7091.SCIF.SCFTDR2 = 'o';
/*
*SOFT_RESET = 0b111;
*SOFT_RESET = 0b000;
*VO_CONTROL |= 1 << 3;
*VO_BORDER_COL = 31;
for (int i = 0; i < (2*1024*1024 + 1024 * 2 + 512 + 4) / 4; i++) {
RAM[i] = 0x1;
}
*/
vga();
while (1) {
v_sync_in();
SH7091.SCIF.SCFTDR2 = 'v';
SH7091.SCIF.SCFTDR2 = 'g';
SH7091.SCIF.SCFTDR2 = 'a';
reg16 * vram = (reg16 *)0xa5000000;
for (int y = 0; y < 480; y++) {
for (int x = 0; x < 640; x++) {
struct hsv hsv = {(y * 255) / 480, 255, 255};
struct rgb rgb = hsv_to_rgb(hsv);
vram[y * 640 + x] = (rgb.r >> 3) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 11);
}
}
vram[0] = 0xf000;
vram[10] = 0xf0ff;
vram[11] = 0xf0ab;
}
}
/*
{
DM_640x480,
640, 480,
VID_INTERLACE, // flags
CT_VGA, // cable type
0, // pixel mode
0x20C, 0x359, // scanlines, clocks per scanline
0xAC, 0x28, // bitmap x, bitmap y
0x15, 0x104, // first scanline interrupt, second scanline interrupt
0x7E, 0x345, // border x start, border x stop
0x24, 0x204, // border y start, border y stop
0, 1, // current framebuffer, number of framebuffers
{ 0, 0, 0, 0 } // offset to framebuffers
},
*/

View File

@ -6,7 +6,7 @@ from sh7091 import headers
from generate import renderer
def block():
yield "extern holly_reg HOLLY;"
yield 'extern struct holly_reg HOLLY __asm("HOLLY");'
input_file = sys.argv[1]
rows = read_input(input_file)

View File

@ -7,3 +7,9 @@
#define CCR__CB (1 << 2)
#define CCR__WT (1 << 1)
#define CCR__OCE (1 << 0)
#define PDTRA__MASK (0b11 << 8)
#define PDTRA__VGA (0b00 << 8)
#define PDTRA__RESERVED (0b01 << 8)
#define PDTRA__RGB (0b10 << 8)
#define PDTRA__AV (0b11 << 8)