gdrom_jvm_boot: jump to _start
This commit is contained in:
parent
0c70ce02ec
commit
540dec3299
@ -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
73
crc_main.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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,14 +231,14 @@ 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;
|
||||||
|
|
||||||
// Without this read from system_boot_rom, the read value of
|
// Without this read from system_boot_rom, the read value of
|
||||||
// gdrom_if.status is always 0xff
|
// gdrom_if.status is always 0xff
|
||||||
for(uint32_t i = 0; i < 0x200000 / 4; i++) {
|
for (uint32_t i = 0; i < 0x200000 / 4; i++) {
|
||||||
(void)system_boot_rom[i];
|
(void)system_boot_rom[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
6
ip.mk
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user