add DreamcastVideo example
This commit is contained in:
parent
89cac52b14
commit
de4d8761f1
4
Makefile
4
Makefile
@ -7,7 +7,7 @@ CC ?= gcc
|
|||||||
ARCH = -m32
|
ARCH = -m32
|
||||||
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g
|
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g
|
||||||
CFLAGS += -DDEBUG
|
CFLAGS += -DDEBUG
|
||||||
CFLAGS += -DDEBUG_PRINT
|
#CFLAGS += -DDEBUG_PRINT
|
||||||
OPT ?= -O0
|
OPT ?= -O0
|
||||||
DEPFLAGS = -MMD -MP
|
DEPFLAGS = -MMD -MP
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ main: $(OBJ) $(MAIN_HOSTED_OBJ)
|
|||||||
$(CC) $(ARCH) $^ -o $@
|
$(CC) $(ARCH) $^ -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f main print_class c/*.o c/*.d
|
rm -f main print_class c/*.o c/*.d *.elf *.bin
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.INTERMEDIATE:
|
.INTERMEDIATE:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp))
|
all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp))
|
||||||
|
|
||||||
OPT = -O0
|
OPT = -O3
|
||||||
|
|
||||||
MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST)))))
|
MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST)))))
|
||||||
LIB ?= $(MAKEFILE_PATH)/dreamcast
|
LIB ?= $(MAKEFILE_PATH)/dreamcast
|
||||||
@ -9,6 +9,7 @@ CFLAGS += -DDEBUG
|
|||||||
#CFLAGS += -DDEBUG_PRINT
|
#CFLAGS += -DDEBUG_PRINT
|
||||||
CFLAGS += -I$(MAKEFILE_PATH)
|
CFLAGS += -I$(MAKEFILE_PATH)
|
||||||
CFLAGS += -I$(MAKEFILE_PATH)/dreamcast/
|
CFLAGS += -I$(MAKEFILE_PATH)/dreamcast/
|
||||||
|
CFLAGS += -Wno-error=strict-aliasing -fno-strict-aliasing
|
||||||
CARCH = -m4-single -ml
|
CARCH = -m4-single -ml
|
||||||
|
|
||||||
include dreamcast/base.mk
|
include dreamcast/base.mk
|
||||||
@ -47,11 +48,14 @@ LIBGCC_OBJ = \
|
|||||||
libgcc/_div_table.o
|
libgcc/_div_table.o
|
||||||
|
|
||||||
CLASS_FILES = \
|
CLASS_FILES = \
|
||||||
p/Native.class.o \
|
p/DreamcastVideo.class.o \
|
||||||
java/lang/String.class.o \
|
java/lang/String.class.o \
|
||||||
|
java/lang/Integer.class.o \
|
||||||
java/lang/System.class.o \
|
java/lang/System.class.o \
|
||||||
java/io/PrintStream.class.o \
|
java/io/PrintStream.class.o \
|
||||||
java/lang/Object.class.o
|
java/lang/Object.class.o \
|
||||||
|
sega/dreamcast/holly/Holly.class.o \
|
||||||
|
java/misc/Memory.class.o
|
||||||
|
|
||||||
main.elf: LDSCRIPT = $(LIB)/main.lds
|
main.elf: LDSCRIPT = $(LIB)/main.lds
|
||||||
main.elf: $(START_OBJ) $(OBJ) $(MAIN_OBJ) $(MAIN_DREAMCAST_OBJ) $(LIBGCC_OBJ) $(CLASS_FILES)
|
main.elf: $(START_OBJ) $(OBJ) $(MAIN_OBJ) $(MAIN_DREAMCAST_OBJ) $(LIBGCC_OBJ) $(CLASS_FILES)
|
||||||
|
@ -679,8 +679,8 @@ uint32_t decode_print_instruction(const uint8_t * code, uint32_t pc)
|
|||||||
case 132: // iinc
|
case 132: // iinc
|
||||||
{
|
{
|
||||||
uint32_t index = _u1(&code[pc + 1]);
|
uint32_t index = _u1(&code[pc + 1]);
|
||||||
uint32_t _const = _u1(&code[pc + 2]);
|
int32_t _const = _s1(&code[pc + 2]);
|
||||||
debugf("%4d: iinc %u, %u\n", pc, index, _const);
|
debugf("%4d: iinc %u, %d\n", pc, index, _const);
|
||||||
return pc + 3;
|
return pc + 3;
|
||||||
}
|
}
|
||||||
case 133: // i2l
|
case 133: // i2l
|
||||||
@ -1910,7 +1910,7 @@ void decode_execute_instruction(struct vm * vm, const uint8_t * code, uint32_t p
|
|||||||
case 132: // iinc
|
case 132: // iinc
|
||||||
{
|
{
|
||||||
uint32_t index = _u1(&code[pc + 1]);
|
uint32_t index = _u1(&code[pc + 1]);
|
||||||
uint32_t _const = _u1(&code[pc + 2]);
|
int32_t _const = _s1(&code[pc + 2]);
|
||||||
vm->current_frame->next_pc = pc + 3;
|
vm->current_frame->next_pc = pc + 3;
|
||||||
op_iinc(vm, index, _const);
|
op_iinc(vm, index, _const);
|
||||||
break;
|
break;
|
||||||
|
10
c/execute.c
10
c/execute.c
@ -140,6 +140,7 @@ void op_bastore(struct vm * vm)
|
|||||||
int8_t value = operand_stack_pop_u32(vm->current_frame);
|
int8_t value = operand_stack_pop_u32(vm->current_frame);
|
||||||
int32_t index = operand_stack_pop_u32(vm->current_frame);
|
int32_t index = operand_stack_pop_u32(vm->current_frame);
|
||||||
int32_t * arrayref = (int32_t *)operand_stack_pop_u32(vm->current_frame);
|
int32_t * arrayref = (int32_t *)operand_stack_pop_u32(vm->current_frame);
|
||||||
|
debugf("%d %d\n", arrayref[0], index);
|
||||||
assert(arrayref[0] > 0 && index < arrayref[0]);
|
assert(arrayref[0] > 0 && index < arrayref[0]);
|
||||||
int8_t * bytearray = (int8_t *)&arrayref[1];
|
int8_t * bytearray = (int8_t *)&arrayref[1];
|
||||||
bytearray[index] = value;
|
bytearray[index] = value;
|
||||||
@ -1027,9 +1028,9 @@ void op_ifnull(struct vm * vm, int32_t branch)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_iinc(struct vm * vm, uint32_t index, uint32_t _const)
|
void op_iinc(struct vm * vm, uint32_t index, int32_t _const)
|
||||||
{
|
{
|
||||||
uint32_t value = vm->current_frame->local_variable[index];
|
int32_t value = vm->current_frame->local_variable[index];
|
||||||
value += _const;
|
value += _const;
|
||||||
vm->current_frame->local_variable[index] = value;
|
vm->current_frame->local_variable[index] = value;
|
||||||
}
|
}
|
||||||
@ -1227,6 +1228,11 @@ void op_istore_0(struct vm * vm)
|
|||||||
void op_istore_1(struct vm * vm)
|
void op_istore_1(struct vm * vm)
|
||||||
{
|
{
|
||||||
uint32_t value = operand_stack_pop_u32(vm->current_frame);
|
uint32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||||
|
debugf("istore_1: %d\n", value);
|
||||||
|
if (value == 1) {
|
||||||
|
debugf("istore1_1 == 1: %d\n", value);
|
||||||
|
(void)(value);
|
||||||
|
}
|
||||||
vm->current_frame->local_variable[1] = value;
|
vm->current_frame->local_variable[1] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ void op_iflt(struct vm * vm, int32_t branch);
|
|||||||
void op_ifne(struct vm * vm, int32_t branch);
|
void op_ifne(struct vm * vm, int32_t branch);
|
||||||
void op_ifnonnull(struct vm * vm, int32_t branch);
|
void op_ifnonnull(struct vm * vm, int32_t branch);
|
||||||
void op_ifnull(struct vm * vm, int32_t branch);
|
void op_ifnull(struct vm * vm, int32_t branch);
|
||||||
void op_iinc(struct vm * vm, uint32_t index, uint32_t _const);
|
void op_iinc(struct vm * vm, uint32_t index, int32_t _const);
|
||||||
void op_iload(struct vm * vm, uint32_t index);
|
void op_iload(struct vm * vm, uint32_t index);
|
||||||
void op_iload_0(struct vm * vm);
|
void op_iload_0(struct vm * vm);
|
||||||
void op_iload_1(struct vm * vm);
|
void op_iload_1(struct vm * vm);
|
||||||
|
@ -7,26 +7,32 @@
|
|||||||
|
|
||||||
#include "sh7091_scif.h"
|
#include "sh7091_scif.h"
|
||||||
|
|
||||||
#include "p/Native.class.h"
|
#include "p/DreamcastVideo.class.h"
|
||||||
#include "java/lang/String.class.h"
|
#include "java/lang/String.class.h"
|
||||||
|
#include "java/lang/Integer.class.h"
|
||||||
#include "java/lang/System.class.h"
|
#include "java/lang/System.class.h"
|
||||||
#include "java/io/PrintStream.class.h"
|
#include "java/io/PrintStream.class.h"
|
||||||
#include "java/lang/Object.class.h"
|
#include "java/lang/Object.class.h"
|
||||||
|
#include "sega/dreamcast/holly/Holly.class.h"
|
||||||
|
#include "java/misc/Memory.class.h"
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
scif_init(0);
|
scif_init(0);
|
||||||
|
|
||||||
const uint8_t * class_file_buffers[] = {
|
const uint8_t * class_file_buffers[] = {
|
||||||
(const uint8_t *)&_binary_p_Native_class_start,
|
(const uint8_t *)&_binary_p_DreamcastVideo_class_start,
|
||||||
(const uint8_t *)&_binary_java_lang_String_class_start,
|
(const uint8_t *)&_binary_java_lang_String_class_start,
|
||||||
|
(const uint8_t *)&_binary_java_lang_Integer_class_start,
|
||||||
(const uint8_t *)&_binary_java_lang_System_class_start,
|
(const uint8_t *)&_binary_java_lang_System_class_start,
|
||||||
(const uint8_t *)&_binary_java_io_PrintStream_class_start,
|
(const uint8_t *)&_binary_java_io_PrintStream_class_start,
|
||||||
(const uint8_t *)&_binary_java_lang_Object_class_start,
|
(const uint8_t *)&_binary_java_lang_Object_class_start,
|
||||||
|
(const uint8_t *)&_binary_sega_dreamcast_holly_Holly_class_start,
|
||||||
|
(const uint8_t *)&_binary_java_misc_Memory_class_start,
|
||||||
};
|
};
|
||||||
int class_file_buffers_length = (sizeof (class_file_buffers)) / (sizeof (class_file_buffers[0]));
|
int class_file_buffers_length = (sizeof (class_file_buffers)) / (sizeof (class_file_buffers[0]));
|
||||||
|
|
||||||
const uint8_t * main_class = (const uint8_t *)"p/Native";
|
const uint8_t * main_class = (const uint8_t *)"p/DreamcastVideo";
|
||||||
int main_class_length = string_length((const char *)main_class);
|
int main_class_length = string_length((const char *)main_class);
|
||||||
|
|
||||||
int class_hash_table_length;
|
int class_hash_table_length;
|
||||||
|
@ -49,7 +49,7 @@ def parse_arguments(types, arguments):
|
|||||||
|
|
||||||
assert size in {1, 2, 4}
|
assert size in {1, 2, 4}
|
||||||
assert signed is not None
|
assert signed is not None
|
||||||
if name in {"byte", "branch"}:
|
if name in {"byte", "branch", "_const"}:
|
||||||
assert signed == True, name
|
assert signed == True, name
|
||||||
else:
|
else:
|
||||||
assert signed == False, name
|
assert signed == False, name
|
||||||
|
3
generate.sh
Normal file
3
generate.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
python gen_decoder.py > c/decode.inc.c
|
||||||
|
|
||||||
|
python regs/holly.py ../dreamcast/regs/holly.csv > sega/dreamcast/holly/Holly.java
|
6
java.mk
6
java.mk
@ -1,7 +1,7 @@
|
|||||||
%.class: %.java
|
#%.class: %.java
|
||||||
javac $<
|
# javac $<
|
||||||
|
|
||||||
java/%.class: java/%.java
|
%.class: %.java
|
||||||
javac --source 8 --target 8 --boot-class-path . $<
|
javac --source 8 --target 8 --boot-class-path . $<
|
||||||
|
|
||||||
OBJ = \
|
OBJ = \
|
||||||
|
15
java/lang/Integer.class.h
Normal file
15
java/lang/Integer.class.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern uint32_t _binary_java_lang_Integer_class_start __asm("_binary_java_lang_Integer_class_start");
|
||||||
|
extern uint32_t _binary_java_lang_Integer_class_end __asm("_binary_java_lang_Integer_class_end");
|
||||||
|
extern uint32_t _binary_java_lang_Integer_class_size __asm("_binary_java_lang_Integer_class_size");
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
67
java/lang/Integer.java
Normal file
67
java/lang/Integer.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public class Integer {
|
||||||
|
public static final short[] DIGITS;
|
||||||
|
static {
|
||||||
|
short[] digits = new short[100];
|
||||||
|
for (int h = 0; h < 10; h++) {
|
||||||
|
int high = (h + '0') << 8;
|
||||||
|
for (int l = 0; l < 10; l++) {
|
||||||
|
int low = l + '0';
|
||||||
|
digits[h * 10 + l] = (short)(high | low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DIGITS = digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int stringSize(int n) {
|
||||||
|
int sign_digits = 0;
|
||||||
|
if (n < 0) {
|
||||||
|
sign_digits = 1;
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
int digits = 1;
|
||||||
|
int cmp = 10;
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
if (n < cmp)
|
||||||
|
return digits + sign_digits;
|
||||||
|
digits += 1;
|
||||||
|
cmp *= 10;
|
||||||
|
}
|
||||||
|
return 10 + sign_digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toString(int n) {
|
||||||
|
int pos = stringSize(n);
|
||||||
|
byte[] buf = new byte[pos];
|
||||||
|
buf[0] = (char)'0';
|
||||||
|
|
||||||
|
boolean sign = n < 0;
|
||||||
|
if (sign) {
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (n >= 10) {
|
||||||
|
int div = n / 100;
|
||||||
|
pos -= 2;
|
||||||
|
int mod = n - (div * 100);
|
||||||
|
|
||||||
|
short digits = DIGITS[mod];
|
||||||
|
buf[pos] = (byte)(digits >> 8);
|
||||||
|
buf[pos+1] = (byte)(digits);
|
||||||
|
|
||||||
|
n = div;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n != 0) {
|
||||||
|
pos -= 1;
|
||||||
|
buf[pos] = (byte)('0' + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sign) {
|
||||||
|
pos -= 1;
|
||||||
|
buf[pos] = (byte)('-');
|
||||||
|
}
|
||||||
|
return new String(buf);
|
||||||
|
}
|
||||||
|
}
|
15
java/misc/Memory.class.h
Normal file
15
java/misc/Memory.class.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern uint32_t _binary_java_misc_Memory_class_start __asm("_binary_java_misc_Memory_class_start");
|
||||||
|
extern uint32_t _binary_java_misc_Memory_class_end __asm("_binary_java_misc_Memory_class_end");
|
||||||
|
extern uint32_t _binary_java_misc_Memory_class_size __asm("_binary_java_misc_Memory_class_size");
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
BIN
opcodes.ods
BIN
opcodes.ods
Binary file not shown.
15
p/DreamcastVideo.class.h
Normal file
15
p/DreamcastVideo.class.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern uint32_t _binary_p_DreamcastVideo_class_start __asm("_binary_p_DreamcastVideo_class_start");
|
||||||
|
extern uint32_t _binary_p_DreamcastVideo_class_end __asm("_binary_p_DreamcastVideo_class_end");
|
||||||
|
extern uint32_t _binary_p_DreamcastVideo_class_size __asm("_binary_p_DreamcastVideo_class_size");
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
23
p/DreamcastVideo.java
Normal file
23
p/DreamcastVideo.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package p;
|
||||||
|
|
||||||
|
import sega.dreamcast.holly.Holly;
|
||||||
|
import java.misc.Memory;
|
||||||
|
|
||||||
|
class DreamcastVideo {
|
||||||
|
public static void main() {
|
||||||
|
System.out.print("FB_R_SOF1: ");
|
||||||
|
int a = Memory.getU4(Holly.FB_R_SOF1);
|
||||||
|
System.out.println(Integer.toString(Holly.FB_R_SOF1));
|
||||||
|
System.out.println(Integer.toString(a));
|
||||||
|
System.out.print("FB_R_CTRL: ");
|
||||||
|
int b = Memory.getU4(Holly.FB_R_CTRL);
|
||||||
|
System.out.println(Integer.toString(b));
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
int red = 0x000077ff;
|
||||||
|
int fb = 0xa5000000 + a;
|
||||||
|
for (int i = 0; i < 640 * 480; i++) {
|
||||||
|
Memory.putU4(fb + (i * 4), red);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
regs/Foo.java
Normal file
4
regs/Foo.java
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
class Holly {
|
||||||
|
public static final int
|
||||||
|
|
||||||
|
}
|
27
regs/csv_input.py
Normal file
27
regs/csv_input.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import csv
|
||||||
|
|
||||||
|
def as_dict(header, row0):
|
||||||
|
row = [s.strip() for s in row0]
|
||||||
|
return dict(zip(header, row))
|
||||||
|
|
||||||
|
def read_input(filename):
|
||||||
|
with open(filename) as f:
|
||||||
|
reader = csv.reader(f, delimiter=",", quotechar='"')
|
||||||
|
header, *rows = reader
|
||||||
|
|
||||||
|
rows = [
|
||||||
|
as_dict(header, row)
|
||||||
|
for row in rows
|
||||||
|
if "".join(map(str, row)).strip()
|
||||||
|
]
|
||||||
|
|
||||||
|
return rows
|
||||||
|
|
||||||
|
def read_input_headerless(filename):
|
||||||
|
with open(filename) as f:
|
||||||
|
reader = csv.reader(f, delimiter=",", quotechar='"')
|
||||||
|
rows = [
|
||||||
|
[s.strip() for s in row]
|
||||||
|
for row in reader
|
||||||
|
]
|
||||||
|
return rows
|
42
regs/generate.py
Normal file
42
regs/generate.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import io
|
||||||
|
|
||||||
|
def should_autonewline(line):
|
||||||
|
return (
|
||||||
|
"static_assert" not in line
|
||||||
|
and "extern" not in line
|
||||||
|
and (len(line.split()) < 2 or line.split()[1] != '=') # hacky; meh
|
||||||
|
)
|
||||||
|
|
||||||
|
def _render(out, lines, indent_length):
|
||||||
|
indent = " "
|
||||||
|
level = 0
|
||||||
|
namespace = 0
|
||||||
|
for l in lines:
|
||||||
|
if l and (l[0] == "}" or l[0] == ")"):
|
||||||
|
level -= indent_length
|
||||||
|
if level < 0:
|
||||||
|
assert namespace >= 0
|
||||||
|
namespace -= 1
|
||||||
|
level = 0
|
||||||
|
|
||||||
|
if len(l) == 0:
|
||||||
|
out.write("\n")
|
||||||
|
else:
|
||||||
|
out.write(indent * level + l + "\n")
|
||||||
|
|
||||||
|
if l and (l[-1] == "{" or l[-1] == "("):
|
||||||
|
if l.startswith("namespace"):
|
||||||
|
namespace += 1
|
||||||
|
else:
|
||||||
|
level += indent_length
|
||||||
|
|
||||||
|
if level == 0 and l and l[-1] == ";":
|
||||||
|
if should_autonewline(l):
|
||||||
|
out.write("\n")
|
||||||
|
return out
|
||||||
|
|
||||||
|
def renderer(indent_length=2):
|
||||||
|
out = io.StringIO()
|
||||||
|
def render(lines):
|
||||||
|
return _render(out, lines, indent_length)
|
||||||
|
return render, out
|
24
regs/holly.py
Normal file
24
regs/holly.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from register import parse_row, group_by_block
|
||||||
|
from csv_input import read_input
|
||||||
|
import sys
|
||||||
|
from generate import renderer
|
||||||
|
|
||||||
|
def generate_register(base_address, register):
|
||||||
|
yield f"public static final int {register.name} = {hex(base_address + register.address)};"
|
||||||
|
|
||||||
|
def generate_classes(package_name, base_address, blocks):
|
||||||
|
yield f"package sega.dreamcast.{package_name};"
|
||||||
|
yield ""
|
||||||
|
for block, registers in blocks:
|
||||||
|
yield f"public class {block.capitalize()} {{"
|
||||||
|
for register in registers:
|
||||||
|
yield from generate_register(base_address, register)
|
||||||
|
yield "}"
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
rows = read_input(sys.argv[1])
|
||||||
|
blocks = group_by_block(map(parse_row, rows))
|
||||||
|
render, out = renderer(indent_length=4)
|
||||||
|
holly_base_address = 0xa05f8000
|
||||||
|
render(generate_classes("holly", holly_base_address, blocks))
|
||||||
|
sys.stdout.write(out.getvalue())
|
54
regs/register.py
Normal file
54
regs/register.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Register:
|
||||||
|
block: str
|
||||||
|
address: int
|
||||||
|
size: int
|
||||||
|
name: str
|
||||||
|
rw: set[str]
|
||||||
|
description: str
|
||||||
|
|
||||||
|
def parse_address(row):
|
||||||
|
address = int(row["address"], 16)
|
||||||
|
if "offset" in row:
|
||||||
|
offset = int(row["offset"], 16)
|
||||||
|
address += offset << 16
|
||||||
|
return address
|
||||||
|
|
||||||
|
def parse_rw(row):
|
||||||
|
s = set(row["r/w"])
|
||||||
|
assert (s & {"R", "W"}) == s
|
||||||
|
return s
|
||||||
|
|
||||||
|
blocks_names = set()
|
||||||
|
|
||||||
|
def parse_block_name(row):
|
||||||
|
global blocks_names
|
||||||
|
block = row["block"]
|
||||||
|
name = row["name"]
|
||||||
|
key = (block, name)
|
||||||
|
assert key not in blocks_names
|
||||||
|
return block, name
|
||||||
|
|
||||||
|
def parse_row(row):
|
||||||
|
block, name = parse_block_name(row)
|
||||||
|
return Register(
|
||||||
|
block=block,
|
||||||
|
address=parse_address(row),
|
||||||
|
size=int(row["size"]),
|
||||||
|
name=name,
|
||||||
|
rw=parse_rw(row),
|
||||||
|
description=row["description"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def group_by_block(registers):
|
||||||
|
groups = defaultdict(list)
|
||||||
|
for register in registers:
|
||||||
|
groups[register.block].append(register)
|
||||||
|
sorted_groups = []
|
||||||
|
for block, registers in groups.items():
|
||||||
|
sorted_groups.append(
|
||||||
|
(block, list(sorted(registers, key=lambda r: r.address))))
|
||||||
|
return list(sorted(sorted_groups, key=lambda g: g[1][0].address))
|
15
sega/dreamcast/holly/Holly.class.h
Normal file
15
sega/dreamcast/holly/Holly.class.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern uint32_t _binary_sega_dreamcast_holly_Holly_class_start __asm("_binary_sega_dreamcast_holly_Holly_class_start");
|
||||||
|
extern uint32_t _binary_sega_dreamcast_holly_Holly_class_end __asm("_binary_sega_dreamcast_holly_Holly_class_end");
|
||||||
|
extern uint32_t _binary_sega_dreamcast_holly_Holly_class_size __asm("_binary_sega_dreamcast_holly_Holly_class_size");
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
76
sega/dreamcast/holly/Holly.java
Normal file
76
sega/dreamcast/holly/Holly.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package sega.dreamcast.holly;
|
||||||
|
|
||||||
|
|
||||||
|
public class Holly {
|
||||||
|
public static final int ID = 0xa05f8000;
|
||||||
|
public static final int REVISION = 0xa05f8004;
|
||||||
|
public static final int SOFTRESET = 0xa05f8008;
|
||||||
|
public static final int STARTRENDER = 0xa05f8014;
|
||||||
|
public static final int TEST_SELECT = 0xa05f8018;
|
||||||
|
public static final int PARAM_BASE = 0xa05f8020;
|
||||||
|
public static final int REGION_BASE = 0xa05f802c;
|
||||||
|
public static final int SPAN_SORT_CFG = 0xa05f8030;
|
||||||
|
public static final int VO_BORDER_COL = 0xa05f8040;
|
||||||
|
public static final int FB_R_CTRL = 0xa05f8044;
|
||||||
|
public static final int FB_W_CTRL = 0xa05f8048;
|
||||||
|
public static final int FB_W_LINESTRIDE = 0xa05f804c;
|
||||||
|
public static final int FB_R_SOF1 = 0xa05f8050;
|
||||||
|
public static final int FB_R_SOF2 = 0xa05f8054;
|
||||||
|
public static final int FB_R_SIZE = 0xa05f805c;
|
||||||
|
public static final int FB_W_SOF1 = 0xa05f8060;
|
||||||
|
public static final int FB_W_SOF2 = 0xa05f8064;
|
||||||
|
public static final int FB_X_CLIP = 0xa05f8068;
|
||||||
|
public static final int FB_Y_CLIP = 0xa05f806c;
|
||||||
|
public static final int FPU_SHAD_SCALE = 0xa05f8074;
|
||||||
|
public static final int FPU_CULL_VAL = 0xa05f8078;
|
||||||
|
public static final int FPU_PARAM_CFG = 0xa05f807c;
|
||||||
|
public static final int HALF_OFFSET = 0xa05f8080;
|
||||||
|
public static final int FPU_PERP_VAL = 0xa05f8084;
|
||||||
|
public static final int ISP_BACKGND_D = 0xa05f8088;
|
||||||
|
public static final int ISP_BACKGND_T = 0xa05f808c;
|
||||||
|
public static final int ISP_FEED_CFG = 0xa05f8098;
|
||||||
|
public static final int SDRAM_REFRESH = 0xa05f80a0;
|
||||||
|
public static final int SDRAM_ARB_CFG = 0xa05f80a4;
|
||||||
|
public static final int SDRAM_CFG = 0xa05f80a8;
|
||||||
|
public static final int FOG_COL_RAM = 0xa05f80b0;
|
||||||
|
public static final int FOG_COL_VERT = 0xa05f80b4;
|
||||||
|
public static final int FOG_DENSITY = 0xa05f80b8;
|
||||||
|
public static final int FOG_CLAMP_MAX = 0xa05f80bc;
|
||||||
|
public static final int FOG_CLAMP_MIN = 0xa05f80c0;
|
||||||
|
public static final int SPG_TRIGGER_POS = 0xa05f80c4;
|
||||||
|
public static final int SPG_HBLANK_INT = 0xa05f80c8;
|
||||||
|
public static final int SPG_VBLANK_INT = 0xa05f80cc;
|
||||||
|
public static final int SPG_CONTROL = 0xa05f80d0;
|
||||||
|
public static final int SPG_HBLANK = 0xa05f80d4;
|
||||||
|
public static final int SPG_LOAD = 0xa05f80d8;
|
||||||
|
public static final int SPG_VBLANK = 0xa05f80dc;
|
||||||
|
public static final int SPG_WIDTH = 0xa05f80e0;
|
||||||
|
public static final int TEXT_CONTROL = 0xa05f80e4;
|
||||||
|
public static final int VO_CONTROL = 0xa05f80e8;
|
||||||
|
public static final int VO_STARTX = 0xa05f80ec;
|
||||||
|
public static final int VO_STARTY = 0xa05f80f0;
|
||||||
|
public static final int SCALER_CTL = 0xa05f80f4;
|
||||||
|
public static final int PAL_RAM_CTRL = 0xa05f8108;
|
||||||
|
public static final int SPG_STATUS = 0xa05f810c;
|
||||||
|
public static final int FB_BURSTCTRL = 0xa05f8110;
|
||||||
|
public static final int FB_C_SOF = 0xa05f8114;
|
||||||
|
public static final int Y_COEFF = 0xa05f8118;
|
||||||
|
public static final int PT_ALPHA_REF = 0xa05f811c;
|
||||||
|
public static final int TA_OL_BASE = 0xa05f8124;
|
||||||
|
public static final int TA_ISP_BASE = 0xa05f8128;
|
||||||
|
public static final int TA_OL_LIMIT = 0xa05f812c;
|
||||||
|
public static final int TA_ISP_LIMIT = 0xa05f8130;
|
||||||
|
public static final int TA_NEXT_OPB = 0xa05f8134;
|
||||||
|
public static final int TA_ITP_CURRENT = 0xa05f8138;
|
||||||
|
public static final int TA_GLOB_TILE_CLIP = 0xa05f813c;
|
||||||
|
public static final int TA_ALLOC_CTRL = 0xa05f8140;
|
||||||
|
public static final int TA_LIST_INIT = 0xa05f8144;
|
||||||
|
public static final int TA_YUV_TEX_BASE = 0xa05f8148;
|
||||||
|
public static final int TA_YUV_TEX_CTRL = 0xa05f814c;
|
||||||
|
public static final int TA_YUV_TEX_CNT = 0xa05f8150;
|
||||||
|
public static final int TA_LIST_CONT = 0xa05f8160;
|
||||||
|
public static final int TA_NEXT_OPB_INIT = 0xa05f8164;
|
||||||
|
public static final int FOG_TABLE = 0xa05f8200;
|
||||||
|
public static final int TA_OL_POINTERS = 0xa05f8600;
|
||||||
|
public static final int PALETTE_RAM = 0xa05f9000;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user