jvm/example/GdromTest.java

130 lines
3.8 KiB
Java

package example;
import sega.dreamcast.gdrom.GdromProtocol;
import sega.dreamcast.gdrom.G1IF;
import java.misc.Memory;
import filesystem.iso9660.VolumeParser;
import filesystem.iso9660.ExtentReader;
import filesystem.iso9660.DirectoryRecordHandler;
import filesystem.iso9660.DirectoryRecord;
import jvm.internal.Loader;
class GdromExtentReader implements ExtentReader {
public void readInto(byte[] buf, int extent) {
int starting_address = extent + 150;
System.out.print("starting_address: ");
System.out.println(starting_address);
GdromProtocol.cdReadPIO(buf, starting_address, 1);
}
}
class GdromDirectoryRecordHandler implements DirectoryRecordHandler {
int address;
int[] addresses;
public int addresses_ix;
static byte[] class_ext;
static {
class_ext = new byte[] { 'C', 'L', 'A', ';', '1' }; // CLA;1
}
public GdromDirectoryRecordHandler(int address, int[] addresses) {
this.address = address;
this.addresses = addresses;
this.addresses_ix = 0;
}
// transfer_length is in bytes
public static void startG1DMA(int start_address, int transfer_length) {
int gdstar = start_address & ~(0b111 << 29);
Memory.putU4(G1IF.GDAPRO, 0x8843407F);
Memory.putU4(G1IF.G1GDRC, 0x00001001);
Memory.putU4(G1IF.GDSTAR, gdstar);
Memory.putU4(G1IF.GDLEN, transfer_length);
Memory.putU4(G1IF.GDDIR, 1);
Memory.putU4(G1IF.GDEN, 1);
Memory.putU4(G1IF.GDST, 1);
}
public boolean drIsClass(DirectoryRecord dr) {
int length = dr.lengthOfFileIdentifier();
if (length < 6)
return false;
byte[] buf = dr.array;
int offset = dr.offset + DirectoryRecord.FILE_IDENTIFIER_START;
int ix = 0;
for (int i = length - 5; i < length; i++) {
System.out.print(ix);
System.out.print(" ");
if (buf[offset + i] != class_ext[ix]) {
return false;
}
ix += 1;
}
System.out.println();
return true;
}
public void handle(DirectoryRecord dr) {
int extent = dr.locationOfExtent(); // sector number
int length = dr.dataLength(); // bytes
if (drIsClass(dr)) {
System.out.println("class found");
} else {
System.out.println("is not class");
return;
}
// round up to nearest multiple of 2048
length = (length + 2047) & ~(2047);
System.out.print("start G1 DMA: address:");
System.out.print(address);
System.out.print(" length: ");
System.out.println(length);
System.out.println("read dma");
Memory.putU4(G1IF.GDEN, 0);
int sectors = length >> 11; // division by 2048
GdromProtocol.cdReadDMA(extent + 150, sectors);
System.out.println("start dma");
startG1DMA(address, length);
System.out.println("wait gdst");
while ((Memory.getU4(G1IF.GDST) & 1) != 0);
System.out.println("transfer complete");
addresses[addresses_ix] = 0xa0000000 | address;
addresses_ix += 1;
address += length;
}
}
class GdromTest {
public static void main() {
// assume gdrom is already unlocked
int data_track_fad = GdromProtocol.tocGetDataTrackFad();
int[] buffer_addresses = new int[0x3000]; // maximum 12,288 class files
int loader_buffer_address = Loader.getBuffer();
GdromDirectoryRecordHandler handler = new GdromDirectoryRecordHandler(loader_buffer_address, buffer_addresses);
GdromExtentReader reader = new GdromExtentReader();
VolumeParser parser = new VolumeParser(data_track_fad - 150, reader, handler);
System.out.println("::parser parse::");
parser.parse();
Loader.load(buffer_addresses, handler.addresses_ix);
}
}