dve: initial description of DVE bits

This also implements primitive cable-detection and video output.
This commit is contained in:
Zack Buhman 2024-03-08 18:27:12 +08:00
parent eafd4e6f23
commit db323c85c5
11 changed files with 164 additions and 22 deletions

35
dve.hpp Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include <cstdint>
namespace vreg {
namespace output_mode {
constexpr uint32_t vga = 0b00 << 0;
constexpr uint32_t rgb = 0b10 << 0;
constexpr uint32_t cvbs_yc = 0b11 << 0;
constexpr uint32_t bit_mask = 0x3 << 0;
}
}
namespace pdtra {
namespace cable_type {
constexpr uint32_t vga = 0b00 << 8;
constexpr uint32_t rbg = 0b10 << 8;
constexpr uint32_t cvbs_yc = 0b11 << 8;
constexpr uint32_t bit_mask = 0x3 << 8;
}
namespace video_mode {
constexpr uint32_t ntsc = 0b000 << 2;
constexpr uint32_t pal = 0b001 << 2;
constexpr uint32_t pal_m = 0b011 << 2;
constexpr uint32_t pal_n = 0b101 << 2;
constexpr uint32_t forced_ntsc_interlacing = 0b110 << 2;
constexpr uint32_t forced_pal_interlacing = 0b111 << 2;
constexpr uint32_t bit_mask = 0x7 << 2;
}
}

View File

@ -2,8 +2,6 @@
#include <cstdint>
#include "../float_uint32.hpp"
namespace gdrom {
namespace status {
constexpr uint32_t bsy(uint32_t reg) { return (reg >> 7) & 0x1; }

View File

@ -14,6 +14,11 @@ sh7091/sh7091_bits.hpp: regs/sh7091_bits.csv regs/gen/core_bits.py
systembus_bits.hpp: regs/systembus_bits.csv regs/gen/core_bits.py
python regs/gen/core_bits.py $< > $@
# DVE
dve.hpp: regs/dve.csv regs/gen/core_bits.py
python regs/gen/core_bits.py $< > $@
# HOLLY
holly/core_bits.hpp: regs/core_bits.csv regs/gen/core_bits.py

View File

@ -2,8 +2,6 @@
#include <cstdint>
#include "../float_uint32.hpp"
namespace object_list_data {
namespace pointer_type {
constexpr uint32_t triangle_strip = 0b000 << 29;

85
holly/video_output.cpp Normal file
View File

@ -0,0 +1,85 @@
#include <cstdint>
#include "sh7091/serial.hpp"
#include "dve.hpp"
#include "holly.hpp"
#include "holly_bits.hpp"
#include "video_output.hpp"
namespace video_output {
void set_framebuffer_resolution(const uint32_t x_size, const uint32_t y_size)
{
holly.Y_COEFF = y_coeff::coefficient_1(0x80)
| y_coeff::coefficient_0_2(0x40);
// in 6.10 fixed point; 0x0400 is 1x vertical scale
holly.SCALER_CTL = scaler_ctl::vertical_scale_factor(0x0400);
holly.FB_BURSTCTRL = fb_burstctrl::wr_burst(0x09)
| fb_burstctrl::vid_lat(0x3f)
| fb_burstctrl::vid_burst(0x39);
holly.FB_X_CLIP = fb_x_clip::fb_x_clip_max(x_size - 1)
| fb_x_clip::fb_x_clip_min(0);
holly.FB_Y_CLIP = fb_y_clip::fb_y_clip_max(y_size - 1)
| fb_y_clip::fb_y_clip_min(0);
holly.FB_R_SIZE = fb_r_size::fb_modulus(1)
| fb_r_size::fb_y_size(y_size - 3)
| fb_r_size::fb_x_size((x_size * 16) / 32 - 1);
}
void set_mode(const struct mode& mode)
{
holly.FB_R_CTRL = mode.fb_r_ctrl
| fb_r_ctrl::fb_depth::_0565_rgb_16bit
| fb_r_ctrl::fb_enable;
holly.SPG_LOAD = mode.spg_load;
holly.SPG_HBLANK = mode.spg_hblank;
holly.SPG_VBLANK = mode.spg_vblank;
holly.SPG_WIDTH = mode.spg_width;
holly.SPG_CONTROL = mode.spg_control;
holly.VO_STARTX = mode.vo_startx;
holly.VO_STARTY = mode.vo_starty;
holly.VO_CONTROL = mode.vo_control;
holly.SPG_HBLANK_INT = mode.spg_hblank_int;
holly.SPG_VBLANK_INT = mode.spg_vblank_int;
}
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::cable_type::bit_mask;
}
void automatic()
{
switch (get_cable_type()) {
case pdtra::cable_type::vga:
set_mode(vga);
set_framebuffer_resolution(640, 480);
aica.common.VREG(vreg::output_mode::vga);
break;
case pdtra::cable_type::rgb:
set_mode(ntsc_ni);
set_framebuffer_resolution(320, 240);
aica.common.VREG(vreg::output_mode::rgb);
break;
case pdtra::cable_type::cvbs_yc:
set_mode(pal_ni);
set_framebuffer_resolution(320, 240);
aica.common.VREG(vreg::output_mode::cvbs_yc);
break;
}
}
}

View File

@ -1,3 +1,5 @@
#pragma once
#include <cstdint>
namespace video_output {
@ -16,4 +18,10 @@ struct mode {
const uint32_t spg_vblank_int;
};
extern const struct mode vga;
extern const struct mode ntsc_ni;
extern const struct mode ntsc_i;
extern const struct mode pal_ni;
extern const struct mode pal_i;
}

View File

@ -2,30 +2,28 @@
#include <cstdint>
#include "../float_uint32.hpp"
namespace host_instruction {
constexpr uint32_t end_flag = 1 << 31;
namespace port_select {
constexpr uint32_t a = 0 << 16;
constexpr uint32_t b = 1 << 16;
constexpr uint32_t c = 2 << 16;
constexpr uint32_t d = 3 << 16;
constexpr uint32_t bit_mask = 0x3 << 16;
}
namespace pattern {
constexpr uint32_t normal = 0b000 << 8;
constexpr uint32_t light_gun_mode = 0b010 << 8;
constexpr uint32_t reset = 0b011 << 8;
constexpr uint32_t return_from_light_gun_mode = 0b100 << 8;
constexpr uint32_t nop = 0b111 << 8;
constexpr uint32_t bit_mask = 0x7 << 8;
}
constexpr uint32_t transfer_length(uint32_t num) { return (num & 0xff) << 0; }
}
@ -39,25 +37,25 @@ namespace ap {
constexpr uint32_t b = 0b01 << 6;
constexpr uint32_t c = 0b10 << 6;
constexpr uint32_t d = 0b11 << 6;
constexpr uint32_t bit_mask = 0x3 << 6;
}
namespace de {
constexpr uint32_t device = 1 << 5;
constexpr uint32_t expansion_device = 0 << 5;
constexpr uint32_t port = 0 << 5;
constexpr uint32_t bit_mask = 0x1 << 5;
}
namespace lm_bus {
constexpr uint32_t _4 = 0b10000 << 0;
constexpr uint32_t _3 = 0b01000 << 0;
constexpr uint32_t _2 = 0b00100 << 0;
constexpr uint32_t _1 = 0b00010 << 0;
constexpr uint32_t _0 = 0b00001 << 0;
constexpr uint32_t bit_mask = 0x1f << 0;
}
}

15
regs/dve.csv Normal file
View File

@ -0,0 +1,15 @@
"register_name","enum_name","bits","bit_name","value","mask","description"
"VREG","output_mode","1-0","vga","0b00",,
"VREG","output_mode","1-0","rgb","0b10",,
"VREG","output_mode","1-0","cvbs_yc","0b11",,
,,,,,,
"PDTRA","cable_type","9-8","vga","0b00",,
"PDTRA","cable_type","9-8","rbg","0b10",,
"PDTRA","cable_type","9-8","cvbs_yc","0b11",,
,,,,,,
"PDTRA","video_mode","4-2","ntsc","0b000",,
"PDTRA","video_mode","4-2","pal","0b001",,
"PDTRA","video_mode","4-2","pal_m","0b011",,
"PDTRA","video_mode","4-2","pal_n","0b101",,
"PDTRA","video_mode","4-2","forced_ntsc_interlacing","0b110",,
"PDTRA","video_mode","4-2","forced_pal_interlacing","0b111",,
1 register_name enum_name bits bit_name value mask description
2 VREG output_mode 1-0 vga 0b00
3 VREG output_mode 1-0 rgb 0b10
4 VREG output_mode 1-0 cvbs_yc 0b11
5
6 PDTRA cable_type 9-8 vga 0b00
7 PDTRA cable_type 9-8 rbg 0b10
8 PDTRA cable_type 9-8 cvbs_yc 0b11
9
10 PDTRA video_mode 4-2 ntsc 0b000
11 PDTRA video_mode 4-2 pal 0b001
12 PDTRA video_mode 4-2 pal_m 0b011
13 PDTRA video_mode 4-2 pal_n 0b101
14 PDTRA video_mode 4-2 forced_ntsc_interlacing 0b110
15 PDTRA video_mode 4-2 forced_pal_interlacing 0b111

BIN
regs/dve.ods Normal file

Binary file not shown.

View File

@ -261,13 +261,15 @@ def render_registers(registers, file_namespace):
if file_namespace is not None:
yield '}' # end of file namespace
def header():
def header(name):
yield "#pragma once"
yield ""
yield "#include <cstdint>"
yield ""
yield '#include "../float_uint32.hpp"'
yield ""
if "core_bits" in name:
# hack
yield '#include "../float_uint32.hpp"'
yield ""
if __name__ == "__main__":
d = read_input(sys.argv[1])
@ -275,6 +277,6 @@ if __name__ == "__main__":
aggregated = aggregate_registers(d)
registers = aggregate_all_enums(aggregated)
render, out = renderer()
render(header())
render(header(sys.argv[1]))
render(render_registers(registers, file_namespace))
sys.stdout.write(out.getvalue())

View File

@ -2,8 +2,6 @@
#include <cstdint>
#include "../float_uint32.hpp"
namespace ccn {
namespace pteh {
constexpr uint32_t VPN(uint32_t reg) { return (reg >> 10) & 0x3fffff; }