example: add gdrom_test
This successfully reads the first 17 sectors of the first data track of a CD.
This commit is contained in:
parent
c851070604
commit
e4c2a047fa
28
example/dump_ram.cpp
Normal file
28
example/dump_ram.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "memorymap.hpp"
|
||||
|
||||
#include "sh7091/serial.hpp"
|
||||
|
||||
void dump_ram(const volatile uint32_t * mem, const uint32_t len)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
for (uint32_t i = 0; i < ; i++) {
|
||||
uint8_t n = mem[i];
|
||||
sum += n;
|
||||
serial::hexlify(n);
|
||||
if ((i & 0xf) == 0xf)
|
||||
serial::character('\n');
|
||||
}
|
||||
serial::character('\n');
|
||||
serial::integer<uint32_t>(sum);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// dump the first 64k of system memory
|
||||
dump_ram(system_memory, 0x10000);
|
||||
|
||||
|
||||
while (1);
|
||||
}
|
@ -326,12 +326,18 @@ DUMP_OBJECT_LIST_OBJ = \
|
||||
holly/region_array.o \
|
||||
holly/background.o \
|
||||
holly/ta_fifo_polygon_converter.o \
|
||||
sh7091/serial.o \
|
||||
libm.o
|
||||
sh7091/serial.o
|
||||
|
||||
example/dump_object_list.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
example/dump_object_list.elf: $(START_OBJ) $(DUMP_OBJECT_LIST_OBJ)
|
||||
|
||||
DUMP_RAM_OBJ = \
|
||||
example/dump_ram.o \
|
||||
sh7091/serial.o
|
||||
|
||||
example/dump_ram.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
example/dump_ram.elf: $(START_OBJ) $(DUMP_RAM_OBJ)
|
||||
|
||||
SOFTWARE_TA_OBJ = \
|
||||
example/software_ta.o \
|
||||
vga.o \
|
||||
@ -344,3 +350,10 @@ SOFTWARE_TA_OBJ = \
|
||||
|
||||
example/software_ta.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
example/software_ta.elf: $(START_OBJ) $(SOFTWARE_TA_OBJ)
|
||||
|
||||
GDROM_TEST_OBJ = \
|
||||
example/gdrom_test.o \
|
||||
sh7091/serial.o
|
||||
|
||||
example/gdrom_test.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
example/gdrom_test.elf: $(START_OBJ) $(GDROM_TEST_OBJ)
|
||||
|
253
example/gdrom_test.cpp
Normal file
253
example/gdrom_test.cpp
Normal file
@ -0,0 +1,253 @@
|
||||
#include "gdrom.hpp"
|
||||
#include "gdrom_bits.hpp"
|
||||
#include "memorymap.hpp"
|
||||
|
||||
#include "sh7091/serial.hpp"
|
||||
|
||||
union data {
|
||||
uint8_t u8[2];
|
||||
uint16_t u16;
|
||||
};
|
||||
static_assert((sizeof (data)) == 2);
|
||||
|
||||
|
||||
void test_unit()
|
||||
{
|
||||
serial::string("test_unit\n");
|
||||
// wait for BSY == 0 && DRQ == 0
|
||||
while ((gdrom_if.status & (gdrom::status::bsy | gdrom::status::drq)) != 0) {
|
||||
serial::integer<uint8_t>(gdrom_if.status);
|
||||
for (int i = 0; i < 1000000; i++) { asm volatile ("nop;"); }
|
||||
};
|
||||
serial::string("bsy | drq == 0\n");
|
||||
|
||||
gdrom_if.command = 0xa0; // packet command
|
||||
while ((gdrom_if.status & gdrom::status::drq) == 0);
|
||||
serial::string("drq != 0; CoD: ");
|
||||
serial::integer<uint8_t>(gdrom_if.interrupt_reason & 1);
|
||||
|
||||
serial::string("bsy1: ");
|
||||
serial::integer<uint8_t>(gdrom_if.status & gdrom::status::bsy);
|
||||
for (int i = 0; i < 6; i++)
|
||||
gdrom_if.data = 0;
|
||||
serial::integer<uint8_t>(gdrom_if.status & gdrom::status::bsy);
|
||||
|
||||
while ((gdrom_if.status & (gdrom::status::bsy | gdrom::status::drq)) != 0);
|
||||
serial::string("bsy2: ");
|
||||
serial::integer<uint8_t>(gdrom_if.status);
|
||||
serial::string("\n");
|
||||
}
|
||||
|
||||
void pio_data(const uint8_t * data)
|
||||
{
|
||||
while ((gdrom_if.status & (gdrom::status::bsy | gdrom::status::drq)) != 0);
|
||||
serial::string("bsy | drq == 0\n");
|
||||
|
||||
gdrom_if.features = 0; // not DMA
|
||||
gdrom_if.drive_select = 0b1010'0000; // LUN 0
|
||||
|
||||
gdrom_if.command = 0xa0; // packet command
|
||||
// CoD
|
||||
//serial::string("wait CoD\n");
|
||||
while ((gdrom_if.interrupt_reason & 0b11) != gdrom::interrupt_reason::cod);
|
||||
//serial::string("done CoD\n");
|
||||
while ((gdrom_if.status & gdrom::status::drq) == 0);
|
||||
serial::string("drq == 1\n");
|
||||
|
||||
const uint16_t * buf = reinterpret_cast<const uint16_t *>(&data[0]);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
gdrom_if.data = buf[i];
|
||||
}
|
||||
|
||||
serial::string("status1: ");
|
||||
serial::integer<uint8_t>(gdrom_if.status);
|
||||
while ((gdrom_if.status & gdrom::status::bsy) != 0) {
|
||||
serial::integer<uint8_t>(gdrom_if.status);
|
||||
for (int i = 0; i < 10000000; i++) { asm volatile ("nop;"); }
|
||||
};
|
||||
serial::string("status2: ");
|
||||
serial::integer<uint8_t>(gdrom_if.status);
|
||||
|
||||
serial::string("byte_control: ");
|
||||
serial::integer<uint8_t>(gdrom_if.byte_control_high, ' ');
|
||||
serial::integer<uint8_t>(gdrom_if.byte_control_low);
|
||||
}
|
||||
|
||||
void read_data(uint32_t length)
|
||||
{
|
||||
uint16_t read[length / 2];
|
||||
for (uint32_t i = 0; i < (length / 2); i++) {
|
||||
read[i] = gdrom_if.data;
|
||||
}
|
||||
const uint8_t * read_buf = reinterpret_cast<const uint8_t *>(&read[0]);
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
serial::hexlify(read_buf[i]);
|
||||
serial::character(' ');
|
||||
if ((i & 0xf) == 0xf)
|
||||
serial::character('\n');
|
||||
}
|
||||
serial::character('\n');
|
||||
serial::string("status: ");
|
||||
serial::integer<uint8_t>(gdrom_if.status);
|
||||
}
|
||||
|
||||
void req_stat()
|
||||
{
|
||||
const uint8_t data[12] = {
|
||||
0x10, // req_stat
|
||||
0x00,
|
||||
0x00, // starting_address
|
||||
0x00,
|
||||
0x0a, // allocation_length
|
||||
0x00,
|
||||
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
serial::string("\nreq_stat\n");
|
||||
pio_data(data);
|
||||
read_data(0xa);
|
||||
}
|
||||
|
||||
void req_mode()
|
||||
{
|
||||
const uint8_t data[12] = {
|
||||
0x11, // req_mode
|
||||
0x00,
|
||||
0x00, // starting_address
|
||||
0x00,
|
||||
0x20, // allocation_length
|
||||
0x00,
|
||||
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
serial::string("\nreq_mode\n");
|
||||
pio_data(data);
|
||||
read_data(0x20);
|
||||
}
|
||||
|
||||
void get_toc()
|
||||
{
|
||||
const uint8_t data[12] = {
|
||||
0x14, // GET_TOC
|
||||
(0 << 0), // single density
|
||||
0x0,
|
||||
0xff, // allocation length msb
|
||||
0xff, // allocation length lsb
|
||||
0x00, // 5
|
||||
0x00, // 6
|
||||
0x00, // 7
|
||||
0x00, // 8
|
||||
0x00, // 9
|
||||
0x00, // 10
|
||||
0x00, // 11
|
||||
};
|
||||
|
||||
serial::string("\nget_toc\n");
|
||||
pio_data(data);
|
||||
const uint32_t length = (gdrom_if.byte_control_high << 8) | (gdrom_if.byte_control_low << 0);
|
||||
// 102 entries ; 4 bytes per entry, 408 bytes (0x0198)
|
||||
read_data(length);
|
||||
}
|
||||
|
||||
/* TOC:
|
||||
01 00 00 96 (track 1 information)
|
||||
- audio track
|
||||
- FAD track start: 0x000096
|
||||
|
||||
41 00 2e 4c (track 2 information)
|
||||
- data track
|
||||
- FAD track start: 0x002e4c
|
||||
|
||||
01 01 00 00 (start track information)
|
||||
01: first track is audio track
|
||||
01: first track is track number 1
|
||||
|
||||
41 02 00 00 (end track information)
|
||||
41: last track is data track
|
||||
02: last track is track number 2
|
||||
|
||||
41 00 2f 7c (lead-out information)
|
||||
*/
|
||||
|
||||
void cd_read()
|
||||
{
|
||||
// CD-ROM XA mode 2 form 1
|
||||
|
||||
const uint8_t data_select = 0b0010; // data
|
||||
const uint8_t expected_data_type = 0b100; // XA mode 2 form 1
|
||||
const uint8_t parameter_type = 0b0; // FAD specified
|
||||
|
||||
|
||||
const uint8_t data[12] = {
|
||||
0x31, // CD_READ
|
||||
(data_select << 4) | (expected_data_type << 1) | (parameter_type << 0),
|
||||
|
||||
0x00, // starting address (msb)
|
||||
0x2e, //
|
||||
0x4c, // starting address (lsb)
|
||||
|
||||
0x00, // 5
|
||||
|
||||
0x00, // transfer length (msb)
|
||||
0x11, // transfer length (lsb)
|
||||
|
||||
0x00, // next address (msb)
|
||||
0x2e, // 9
|
||||
0x4c, // next address (lsb)
|
||||
0x00, // 11
|
||||
};
|
||||
|
||||
serial::string("\ncd_read\n");
|
||||
pio_data(data);
|
||||
|
||||
uint32_t read = 0;
|
||||
|
||||
while ((gdrom_if.status & 0x08) != 0) {
|
||||
serial::string("offset: ");
|
||||
serial::integer<uint32_t>(read);
|
||||
|
||||
const uint32_t length = (gdrom_if.byte_control_high << 8) | (gdrom_if.byte_control_low << 0);
|
||||
// 102 entries ; 4 bytes per entry, 408 bytes (0x0198)
|
||||
read_data(length);
|
||||
read += length;
|
||||
|
||||
serial::string("byte_control: ");
|
||||
serial::integer<uint8_t>(gdrom_if.byte_control_high, ' ');
|
||||
serial::integer<uint8_t>(gdrom_if.byte_control_low);
|
||||
}
|
||||
serial::string("read bytes: ");
|
||||
serial::integer<uint32_t>(read);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// gdrom unlock undocumented register
|
||||
*((volatile unsigned long *)0xa05f74e4) = 0x1fffff;
|
||||
|
||||
// Without this read from system_boot_rom, the read value of
|
||||
// gdrom_if.status is always 0xff
|
||||
for(uint32_t i = 0; i < 0x200000 / 4; i++) {
|
||||
(void)system_boot_rom[i];
|
||||
}
|
||||
|
||||
test_unit();
|
||||
req_stat();
|
||||
req_mode();
|
||||
get_toc();
|
||||
|
||||
cd_read();
|
||||
|
||||
while (1);
|
||||
}
|
@ -210,6 +210,7 @@ void main()
|
||||
qq.c = rotate(q.c, theta);
|
||||
qq.d = rotate(q.d, theta);
|
||||
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||
if (hardware_ta) {
|
||||
ta_polygon_converter_init(opb_size.total(),
|
||||
ta_alloc,
|
||||
@ -219,11 +220,10 @@ void main()
|
||||
ta_polygon_converter_transfer(ta_parameter_buf, ta_parameter_size);
|
||||
ta_wait_opaque_list();
|
||||
} else {
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||
|
||||
software_ta::object_pointer_blocks<8>(&mem->object_list[0], qq);
|
||||
software_ta::isp_tsp_parameters(&mem->isp_tsp_parameters[0], qq);
|
||||
software_ta::object_pointer_blocks<8>(mem->object_list, qq);
|
||||
software_ta::isp_tsp_parameters(mem->isp_tsp_parameters, qq);
|
||||
}
|
||||
software_ta::opb_checkerboard_pattern<8>(mem->object_list);
|
||||
|
||||
core_start_render(frame_ix, num_frames);
|
||||
core_wait_end_of_render_video();
|
||||
|
@ -116,6 +116,21 @@ void object_pointer_blocks(volatile uint32_t * mem, const quad& quad)
|
||||
}
|
||||
}
|
||||
|
||||
template <int N>
|
||||
void opb_checkerboard_pattern(volatile uint32_t * mem)
|
||||
{
|
||||
auto block = reinterpret_cast<volatile object_pointer_block<N> *>(mem);
|
||||
for (uint32_t y = 0; y < tile_height; y++) {
|
||||
for (uint32_t x = 0; x < tile_width; x++) {
|
||||
if (((x + (y & 1)) & 1) == 0) continue;
|
||||
|
||||
auto& opb = block[y * tile_width + x];
|
||||
opb.pointer[0] = object_list_data::pointer_type::object_pointer_block_link
|
||||
| object_list_data::object_pointer_block_link::end_of_list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct __untextured_quad_vertex {
|
||||
float x;
|
||||
float y;
|
||||
|
43
gdrom_bits.hpp
Normal file
43
gdrom_bits.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include <cstdint>
|
||||
|
||||
namespace gdrom {
|
||||
|
||||
namespace status {
|
||||
|
||||
constexpr uint8_t bsy = (1 << 7);
|
||||
constexpr uint8_t drdy = (1 << 6);
|
||||
constexpr uint8_t df = (1 << 5);
|
||||
constexpr uint8_t dsc = (1 << 4);
|
||||
constexpr uint8_t drq = (1 << 3);
|
||||
constexpr uint8_t corr = (1 << 2);
|
||||
constexpr uint8_t check = (1 << 0);
|
||||
|
||||
}
|
||||
|
||||
namespace interrupt_reason {
|
||||
|
||||
constexpr uint8_t io = (1 << 1);
|
||||
constexpr uint8_t cod = (1 << 0);
|
||||
|
||||
}
|
||||
|
||||
namespace command {
|
||||
|
||||
constexpr uint8_t test_unit = 0x00;
|
||||
constexpr uint8_t req_stat = 0x10;
|
||||
constexpr uint8_t req_mode = 0x11;
|
||||
constexpr uint8_t set_mode = 0x12;
|
||||
constexpr uint8_t req_error = 0x13;
|
||||
constexpr uint8_t get_toc = 0x14;
|
||||
constexpr uint8_t req_ses = 0x15;
|
||||
constexpr uint8_t cd_open = 0x16;
|
||||
constexpr uint8_t cd_play = 0x20;
|
||||
constexpr uint8_t cd_seek = 0x21;
|
||||
constexpr uint8_t cd_scan = 0x22;
|
||||
constexpr uint8_t cd_read = 0x30;
|
||||
constexpr uint8_t cd_read2 = 0x31;
|
||||
constexpr uint8_t get_scd = 0x40;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -47,6 +47,15 @@ void string(const char * s)
|
||||
}
|
||||
}
|
||||
|
||||
void hexlify(const uint8_t n)
|
||||
{
|
||||
constexpr uint32_t length = 2;
|
||||
char num_buf[length];
|
||||
string::hex<char>(num_buf, length, n);
|
||||
character(num_buf[0]);
|
||||
character(num_buf[1]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void integer(const T n, const char end)
|
||||
{
|
||||
|
@ -6,6 +6,8 @@ void character(const char c);
|
||||
|
||||
void string(const char * s);
|
||||
|
||||
void hexlify(const uint8_t n);
|
||||
|
||||
template <typename T>
|
||||
void integer(const T n, const char end);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user