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/CLOCKTOW.PCM \
|
||||
/=./pcm/ELEC.PCM \
|
||||
/=./pcm/ECCLESIA.PCM
|
||||
/=./pcm/ECCLESIA.PCM \
|
||||
/=jvm.bin
|
||||
|
||||
clean:
|
||||
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/command_packet_format.hpp"
|
||||
#include "gdrom/toc.hpp"
|
||||
#include "holly/video_output.hpp"
|
||||
|
||||
#include "iso9660/primary_volume_descriptor.hpp"
|
||||
#include "iso9660/directory_record.hpp"
|
||||
|
||||
#include "crc32.h"
|
||||
|
||||
typedef void (*main_ptr_t)(void);
|
||||
|
||||
void pio_data(const uint8_t * data)
|
||||
{
|
||||
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)
|
||||
{
|
||||
serial::string("read_data drq interrupt_reason: ");
|
||||
serial::integer<uint8_t>(gdrom::status::drq(gdrom_if.status), ' ');
|
||||
serial::integer<uint8_t>(gdrom_if.interrupt_reason);
|
||||
//serial::string("read_data drq interrupt_reason: ");
|
||||
//serial::integer<uint8_t>(gdrom::status::drq(gdrom_if.status), ' ');
|
||||
//serial::integer<uint8_t>(gdrom_if.interrupt_reason);
|
||||
for (uint32_t i = 0; i < (length / 2); i++) {
|
||||
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
|
||||
|
||||
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)
|
||||
{
|
||||
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(dr->file_identifier, dr->length_of_file_identifier);
|
||||
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)
|
||||
@ -154,7 +231,7 @@ void walk_directory(uint16_t * buf, int extent, int num_extents)
|
||||
|
||||
void main()
|
||||
{
|
||||
//serial::init(0);
|
||||
serial::init(0);
|
||||
|
||||
// gdrom unlock undocumented register
|
||||
g1_if.GDUNLOCK = 0x1fffff;
|
||||
@ -195,7 +272,24 @@ void main()
|
||||
const int data_length = root_dr->data_length.get();
|
||||
const int num_extents = data_length >> 11; // division by 2048
|
||||
|
||||
jvm_load_complete = false;
|
||||
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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
holly.SPG_LOAD = mode.spg_load;
|
||||
|
6
ip.mk
6
ip.mk
@ -22,7 +22,8 @@ SERIAL_LOAD_OBJ = \
|
||||
|
||||
GDROM_JVM_BOOT_OBJ = \
|
||||
example/gdrom_jvm_boot.o \
|
||||
sh7091/serial.o
|
||||
sh7091/serial.o \
|
||||
crc32.o
|
||||
|
||||
%.o: %.obj
|
||||
$(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)
|
||||
$(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