gdrom_jvm_boot: jump to _start

This commit is contained in:
Zack Buhman 2025-01-01 11:58:20 -06:00
parent 0c70ce02ec
commit 540dec3299
5 changed files with 180 additions and 8 deletions

View File

@ -60,7 +60,8 @@ sine.pcm: common.mk
/=./pcm/PRELUDE.PCM \ /=./pcm/PRELUDE.PCM \
/=./pcm/CLOCKTOW.PCM \ /=./pcm/CLOCKTOW.PCM \
/=./pcm/ELEC.PCM \ /=./pcm/ELEC.PCM \
/=./pcm/ECCLESIA.PCM /=./pcm/ECCLESIA.PCM \
/=jvm.bin
clean: clean:
find -P \ find -P \

73
crc_main.c Normal file
View File

@ -0,0 +1,73 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <inttypes.h>
#include "crc32.c"
int read_file(const char * filename, uint8_t ** buf, uint32_t * size_out)
{
FILE * file = fopen(filename, "rb");
if (file == NULL) {
fprintf(stderr, "fopen(\"%s\", \"rb\"): %s\n", filename, strerror(errno));
return -1;
}
int ret;
ret = fseek(file, 0L, SEEK_END);
if (ret < 0) {
fprintf(stderr, "fseek(SEEK_END)");
return -1;
}
long offset = ftell(file);
if (offset < 0) {
fprintf(stderr, "ftell");
return -1;
}
size_t size = offset;
ret = fseek(file, 0L, SEEK_SET);
if (ret < 0) {
fprintf(stderr, "fseek(SEEK_SET)");
return -1;
}
fprintf(stderr, "read_file: %s size %ld\n", filename, size);
*buf = (uint8_t *)malloc(size);
size_t fread_size = fread(*buf, 1, size, file);
if (fread_size != size) {
fprintf(stderr, "fread `%s` short read: %" PRIu64 " ; expected: %" PRIu64 "\n", filename, fread_size, size);
return -1;
}
ret = fclose(file);
if (ret < 0) {
fprintf(stderr, "fclose");
return -1;
}
*size_out = size;
return 0;
}
int main(int argc, char * argv[])
{
assert(argc == 2);
uint8_t * buf;
uint32_t size;
int ret = read_file(argv[1], &buf, &size);
assert(ret == 0);
printf("size: %08x\n", size);
int chunks = size / 2048;
printf("crc:\n");
for (int i = 0; i < chunks; i++) {
uint32_t crc = crc32(&buf[i * 2048], 2048);
printf("0x%08x\n", crc);
}
}

View File

@ -7,10 +7,15 @@
#include "gdrom/gdrom_bits.hpp" #include "gdrom/gdrom_bits.hpp"
#include "gdrom/command_packet_format.hpp" #include "gdrom/command_packet_format.hpp"
#include "gdrom/toc.hpp" #include "gdrom/toc.hpp"
#include "holly/video_output.hpp"
#include "iso9660/primary_volume_descriptor.hpp" #include "iso9660/primary_volume_descriptor.hpp"
#include "iso9660/directory_record.hpp" #include "iso9660/directory_record.hpp"
#include "crc32.h"
typedef void (*main_ptr_t)(void);
void pio_data(const uint8_t * data) void pio_data(const uint8_t * data)
{ {
while ((gdrom::status::bsy(gdrom_if.status) | gdrom::status::drq(gdrom_if.status)) != 0); while ((gdrom::status::bsy(gdrom_if.status) | gdrom::status::drq(gdrom_if.status)) != 0);
@ -32,9 +37,9 @@ void pio_data(const uint8_t * data)
void read_data(uint16_t * buf, const uint32_t length) void read_data(uint16_t * buf, const uint32_t length)
{ {
serial::string("read_data drq interrupt_reason: "); //serial::string("read_data drq interrupt_reason: ");
serial::integer<uint8_t>(gdrom::status::drq(gdrom_if.status), ' '); //serial::integer<uint8_t>(gdrom::status::drq(gdrom_if.status), ' ');
serial::integer<uint8_t>(gdrom_if.interrupt_reason); //serial::integer<uint8_t>(gdrom_if.interrupt_reason);
for (uint32_t i = 0; i < (length / 2); i++) { for (uint32_t i = 0; i < (length / 2); i++) {
buf[i] = gdrom_if.data; buf[i] = gdrom_if.data;
} }
@ -110,6 +115,72 @@ bool dr_is_self_or_parent(const iso9660::directory_record * dr)
#define FILE_FLAGS__DIRECTORY 2 #define FILE_FLAGS__DIRECTORY 2
bool is_jvm_bin(const uint8_t * file_identifier, int length_of_file_identifier)
{
static const uint8_t * jvm_bin = (const uint8_t *)"JVM.BIN;1";
int jvm_bin_length = 9;
if (length_of_file_identifier != jvm_bin_length)
return false;
for (int i = 0; i < jvm_bin_length; i++) {
if (file_identifier[i] != jvm_bin[i])
return false;
}
return true;
}
static inline int min(int a, int b)
{
return a < b ? a : b;
}
static bool jvm_load_complete;
static int __data_length;
constexpr int load_address = 0xac010000;
void load_jvm_bin(const iso9660::directory_record * dr)
{
serial::string("load jvm bin:\n");
//__attribute__((aligned(4))) static uint16_t file_buf16[16384 / 2];
//uint32_t * file_buf32 = reinterpret_cast<uint32_t *>(file_buf16);
uint16_t * load_buf = reinterpret_cast<uint16_t *>(load_address);
int offset = 0;
int extent = dr->location_of_extent.get();
int data_length = dr->data_length.get();
serial::integer<uint32_t>(extent);
int transfers = 0;
while (data_length > 0) {
int transfer_size = min(data_length, 2048);
int sectors = transfer_size >> 11; // divide by 2048
if (sectors == 0)
sectors = 1;
cd_read(&load_buf[offset],
extent + 150, // 150?
sectors // one sector
);
offset += transfer_size / (sizeof (load_buf[0]));
extent += sectors;
data_length -= sectors * 2048;
transfers += 1;
}
serial::string("\njvm load complete\n");
jvm_load_complete = true;
serial::integer<uint32_t>(extent);
serial::string("size: ");
serial::integer<uint32_t>(dr->data_length.get());
__data_length = dr->data_length.get();
serial::string("transfers: ");
serial::integer<uint32_t>(transfers);
}
void walk_directory_record(const iso9660::directory_record * dr) void walk_directory_record(const iso9660::directory_record * dr)
{ {
if (dr_is_self_or_parent(dr)) if (dr_is_self_or_parent(dr))
@ -124,6 +195,12 @@ void walk_directory_record(const iso9660::directory_record * dr)
serial::string(" file_identifier: "); serial::string(" file_identifier: ");
serial::string(dr->file_identifier, dr->length_of_file_identifier); serial::string(dr->file_identifier, dr->length_of_file_identifier);
serial::character('\n'); serial::character('\n');
if ((dr->file_flags & FILE_FLAGS__DIRECTORY) == 0) {
if (is_jvm_bin(dr->file_identifier, dr->length_of_file_identifier)) {
load_jvm_bin(dr);
}
}
} }
void walk_directory(uint16_t * buf, int extent, int num_extents) void walk_directory(uint16_t * buf, int extent, int num_extents)
@ -154,7 +231,7 @@ void walk_directory(uint16_t * buf, int extent, int num_extents)
void main() void main()
{ {
//serial::init(0); serial::init(0);
// gdrom unlock undocumented register // gdrom unlock undocumented register
g1_if.GDUNLOCK = 0x1fffff; g1_if.GDUNLOCK = 0x1fffff;
@ -195,7 +272,24 @@ void main()
const int data_length = root_dr->data_length.get(); const int data_length = root_dr->data_length.get();
const int num_extents = data_length >> 11; // division by 2048 const int num_extents = data_length >> 11; // division by 2048
jvm_load_complete = false;
walk_directory(buf, extent, num_extents); walk_directory(buf, extent, num_extents);
serial::integer<uint32_t>(jvm_load_complete);
if (jvm_load_complete) {
main_ptr_t jvm_main = reinterpret_cast<main_ptr_t>(load_address);
uint8_t * load_buf = reinterpret_cast<uint8_t *>(load_address);
serial::string("crc32: ");
int chunks = __data_length / 2048;
for (int i = 0; i < chunks; i++) {
uint32_t crc = crc32(&((uint8_t *)load_address)[i * 2048], 2048);
serial::integer<uint32_t>(crc);
}
serial::string("jvm jump\n");
jvm_main();
serial::string("jvm return\n");
}
while (1); while (1);
} }

View File

@ -38,7 +38,7 @@ void set_framebuffer_resolution(const uint32_t x_size, const uint32_t y_size)
void set_mode(const struct mode& mode) void set_mode(const struct mode& mode)
{ {
holly.FB_R_CTRL = mode.fb_r_ctrl holly.FB_R_CTRL = mode.fb_r_ctrl
| fb_r_ctrl::fb_depth::_0565_rgb_16bit | fb_r_ctrl::fb_depth::_565_rgb_16bit
| fb_r_ctrl::fb_enable; | fb_r_ctrl::fb_enable;
holly.SPG_LOAD = mode.spg_load; holly.SPG_LOAD = mode.spg_load;

6
ip.mk
View File

@ -22,7 +22,8 @@ SERIAL_LOAD_OBJ = \
GDROM_JVM_BOOT_OBJ = \ GDROM_JVM_BOOT_OBJ = \
example/gdrom_jvm_boot.o \ example/gdrom_jvm_boot.o \
sh7091/serial.o sh7091/serial.o \
crc32.o
%.o: %.obj %.o: %.obj
$(OBJCOPY) -g \ $(OBJCOPY) -g \
@ -34,3 +35,6 @@ serial_load_ip.elf: $(IP_OBJ) $(SERIAL_LOAD_OBJ)
gdrom_jvm_boot_ip.elf: $(IP_OBJ) $(GDROM_JVM_BOOT_OBJ) gdrom_jvm_boot_ip.elf: $(IP_OBJ) $(GDROM_JVM_BOOT_OBJ)
$(LD) --orphan-handling=error --print-memory-usage -T $(LIB)/ip.lds $^ -o $@ $(LD) --orphan-handling=error --print-memory-usage -T $(LIB)/ip.lds $^ -o $@
gdrom-jvm-boot-ip-bin: gdrom_jvm_boot_ip.bin
cp $< ip.bin