initial dreamcast build system
This commit is contained in:
parent
af87766f50
commit
a476201cc1
33
Makefile
33
Makefile
@ -1,34 +1,7 @@
|
||||
%.csv: %.ods
|
||||
libreoffice --headless --convert-to csv:"Text - txt - csv (StarCalc)":44,34,76,,,,true --outdir $(dir $@) $<
|
||||
|
||||
%.class: %.java
|
||||
javac $<
|
||||
|
||||
java/lang/%.class: java/lang/%.java
|
||||
javac --source 8 --target 8 --boot-class-path . $<
|
||||
|
||||
OBJ = \
|
||||
c/decode.o \
|
||||
c/class_file.o \
|
||||
c/debug_class_file.o \
|
||||
c/malloc.o \
|
||||
c/file.o \
|
||||
c/execute.o \
|
||||
c/memory_allocator.o \
|
||||
c/class_resolver.o \
|
||||
c/hash_table.o \
|
||||
c/frame.o \
|
||||
c/printf.o \
|
||||
c/parse.o \
|
||||
c/unparse.o
|
||||
|
||||
MAIN_OBJ = \
|
||||
$(OBJ) \
|
||||
c/main.o
|
||||
|
||||
PRINT_CLASS_OBJ = \
|
||||
$(OBJ) \
|
||||
c/print_class.o \
|
||||
include java.mk
|
||||
|
||||
CC ?= gcc
|
||||
ARCH = -m32
|
||||
@ -39,10 +12,10 @@ DEPFLAGS = -MMD -MP
|
||||
%.o: %.c
|
||||
$(CC) $(ARCH) $(CFLAGS) $(OPT) $(DEPFLAGS) -MF ${<}.d -c $< -o $@
|
||||
|
||||
print_class: $(PRINT_CLASS_OBJ)
|
||||
print_class: $(OBJ) $(PRINT_CLASS_OBJ)
|
||||
$(CC) $(ARCH) $^ -o $@
|
||||
|
||||
main: $(MAIN_OBJ)
|
||||
main: $(OBJ) $(MAIN_HOSTED_OBJ)
|
||||
$(CC) $(ARCH) $^ -o $@
|
||||
|
||||
clean:
|
||||
|
51
Makefile.dreamcast.mk
Normal file
51
Makefile.dreamcast.mk
Normal file
@ -0,0 +1,51 @@
|
||||
all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp))
|
||||
|
||||
OPT = -O0
|
||||
|
||||
MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST)))))
|
||||
LIB ?= $(MAKEFILE_PATH)/dreamcast
|
||||
CFLAGS += -D__dreamcast__ -DDEBUG
|
||||
CFLAGS += -I$(MAKEFILE_PATH)
|
||||
CFLAGS += -I$(MAKEFILE_PATH)/dreamcast/
|
||||
CARCH = -m4-single -ml
|
||||
|
||||
include dreamcast/base.mk
|
||||
include dreamcast/common.mk
|
||||
include dreamcast/headers.mk
|
||||
|
||||
include java.mk
|
||||
|
||||
%.class.o: %.class
|
||||
$(BUILD_BINARY_O)
|
||||
|
||||
%.class.h: %.class
|
||||
$(BUILD_BINARY_H)
|
||||
|
||||
libgcc/%.o: $(LIBGCC)
|
||||
@mkdir -p $(dir $@)
|
||||
ar x --output $(dir $@) $(LIBGCC) $(notdir $@)
|
||||
sh4-none-elf-objdump -t $@ \
|
||||
| grep -E '[.]hidden' \
|
||||
| grep -vE 'UND' \
|
||||
| cut -d' ' -f10 \
|
||||
| xargs rebind --visibility=default $@
|
||||
|
||||
LIBGCC_OBJ = \
|
||||
libgcc/_divdi3.o \
|
||||
libgcc/_udiv_qrnnd_16.o \
|
||||
libgcc/_clz.o \
|
||||
libgcc/_moddi3.o \
|
||||
libgcc/_fixdfdi.o \
|
||||
libgcc/_fixunsdfdi.o \
|
||||
libgcc/_fixunssfdi.o \
|
||||
libgcc/_floatdisf.o \
|
||||
libgcc/_floatdidf.o \
|
||||
libgcc/_sdivsi3.o \
|
||||
libgcc/_fixsfdi.o \
|
||||
libgcc/_div_table.o
|
||||
|
||||
CLASS_FILES = \
|
||||
p/Multiply.class.o
|
||||
|
||||
main.elf: LDSCRIPT = $(LIB)/main.lds
|
||||
main.elf: $(START_OBJ) $(OBJ) $(MAIN_OBJ) $(MAIN_DREAMCAST_OBJ) $(LIBGCC_OBJ) $(CLASS_FILES)
|
10
c/assert.h
10
c/assert.h
@ -1,11 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__linux__)
|
||||
#include "assert_hosted.h"
|
||||
#elif defined(_WIN32)
|
||||
#include "assert_hosted.h"
|
||||
#elif defined(__APPLE__)
|
||||
#include "assert_hosted.h"
|
||||
#else
|
||||
#if defined(__dreamcast__)
|
||||
#include "assert_dreamcast.h"
|
||||
#else
|
||||
#include "assert_hosted.h"
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#define assert(b)
|
||||
#include "printf.h"
|
||||
|
||||
#define assert(b) \
|
||||
do { \
|
||||
if (!(b)) { \
|
||||
printf("%s:%d %s: assertion `%s` failed\n", __FILE__, __LINE__, __func__, #b); \
|
||||
while (1); \
|
||||
} \
|
||||
} while (0);
|
||||
|
@ -147,9 +147,9 @@ static void class_resolver_allocate_attribute_entry(struct class_entry * class_e
|
||||
class_entry->attribute_entry = attribute_entry;
|
||||
}
|
||||
|
||||
struct hash_table_entry * class_resolver_load_from_buffers(const uint8_t * class_names[],
|
||||
const int class_names_length[],
|
||||
uint8_t * buffers[],
|
||||
struct hash_table_entry * class_resolver_load_from_buffers(const uint8_t ** class_names,
|
||||
const int * class_names_length,
|
||||
const uint8_t ** buffers,
|
||||
int length,
|
||||
int * hash_table_length)
|
||||
{
|
||||
|
@ -48,9 +48,9 @@ struct class_entry {
|
||||
} methods;
|
||||
};
|
||||
|
||||
struct hash_table_entry * class_resolver_load_from_buffers(const uint8_t * class_names[],
|
||||
const int class_names_length[],
|
||||
uint8_t * buffers[],
|
||||
struct hash_table_entry * class_resolver_load_from_buffers(const uint8_t ** class_names,
|
||||
const int * class_names_length,
|
||||
const uint8_t ** buffers,
|
||||
int length,
|
||||
int * hash_table_length);
|
||||
struct class_entry * class_resolver_lookup_class(int class_hash_table_length,
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "class_file.h"
|
||||
@ -51,7 +50,7 @@ void print_constant(struct constant * constant)
|
||||
*(float *)(&constant->_float.bytes));
|
||||
break;
|
||||
case CONSTANT_Long:
|
||||
debugf("CONSTANT_Long bytes=%" PRId64 "\n",
|
||||
debugf("CONSTANT_Long bytes=%l\n",
|
||||
constant->_long.bytes);
|
||||
break;
|
||||
case CONSTANT_Double:
|
||||
|
12
c/frame.c
12
c/frame.c
@ -2,7 +2,6 @@
|
||||
|
||||
#include "assert.h"
|
||||
#include "class_file.h"
|
||||
#include "memory.h"
|
||||
#include "debug_class_file.h"
|
||||
#include "bytes.h"
|
||||
#include "decode.h"
|
||||
@ -75,9 +74,17 @@ static int descriptor_nargs(struct constant * descriptor_constant, uint8_t * ret
|
||||
nargs += 1;
|
||||
while (descriptor_constant->utf8.bytes[i] != ';') i += 1;
|
||||
break;
|
||||
default:
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z':
|
||||
nargs += 1;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
@ -399,6 +406,7 @@ void vm_start(int class_hash_table_length,
|
||||
class_hash_table,
|
||||
main_class,
|
||||
main_class_length);
|
||||
|
||||
assert(class_entry != nullptr);
|
||||
|
||||
const char * method_name = "main";
|
||||
|
41
c/main_dreamcast.c
Normal file
41
c/main_dreamcast.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "string.h"
|
||||
#include "class_resolver.h"
|
||||
#include "frame.h"
|
||||
#include "printf.h"
|
||||
|
||||
#include "sh7091_scif.h"
|
||||
|
||||
#include "p/Multiply.class.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
scif_init(0);
|
||||
|
||||
const uint8_t * class_names[1];
|
||||
int class_names_length[1];
|
||||
|
||||
class_names[0] = (const uint8_t *)"p/Multiply";
|
||||
class_names_length[0] = string_length((const char *)class_names[0]);
|
||||
|
||||
const uint8_t * buffers[1];
|
||||
buffers[0] = (const uint8_t *)&_binary_p_Multiply_class_start;
|
||||
|
||||
const uint8_t * main_class = class_names[0];
|
||||
int main_class_length = class_names_length[0];
|
||||
|
||||
int length = (sizeof (class_names)) / (sizeof (class_names[0]));
|
||||
|
||||
int class_hash_table_length;
|
||||
struct hash_table_entry * class_hash_table = class_resolver_load_from_buffers(class_names,
|
||||
class_names_length,
|
||||
buffers,
|
||||
length,
|
||||
&class_hash_table_length);
|
||||
|
||||
vm_start(class_hash_table_length,
|
||||
class_hash_table,
|
||||
main_class,
|
||||
main_class_length);
|
||||
}
|
@ -31,7 +31,7 @@ static struct hash_table_entry * load_from_filenames(const char * filenames[], i
|
||||
|
||||
struct hash_table_entry * class_hash_table = class_resolver_load_from_buffers(class_names,
|
||||
class_names_length,
|
||||
buffers,
|
||||
(const uint8_t **)buffers,
|
||||
length,
|
||||
hash_table_length);
|
||||
|
@ -3,6 +3,62 @@
|
||||
|
||||
#include "sh7091_scif.h"
|
||||
|
||||
void scif_init_wait()
|
||||
{
|
||||
sh7091.TMU.TSTR &= (~tmu::tstr::str1::counter_start) & 0xff; // stop TCNT1
|
||||
sh7091.TMU.TOCR = tmu::tocr::tcoe::tclk_is_external_clock_or_input_capture;
|
||||
sh7091.TMU.TCR1 = tmu::tcr1::tpsc::p_phi_1024; // 1024 / 50MHz = 20.48 μs
|
||||
sh7091.TMU.TCOR1 = 0xffff'ffff;
|
||||
sh7091.TMU.TCNT1 = 0xffff'ffff;
|
||||
sh7091.TMU.TSTR |= tmu::tstr::str1::counter_start;
|
||||
|
||||
uint32_t start = sh7091.TMU.TCNT1;
|
||||
while ((start - sh7091.TMU.TCNT1) < 20);
|
||||
|
||||
sh7091.TMU.TSTR &= (~tmu::tstr::str1::counter_start) & 0xff; // stop TCNT1
|
||||
}
|
||||
|
||||
void scif_init(int bit_rate)
|
||||
{
|
||||
using namespace scif;
|
||||
|
||||
sh7091.SCIF.SCSCR2 = 0; // disable transmission / reception
|
||||
|
||||
sh7091.SCIF.SCSPTR2 = 0; // clear output data pins
|
||||
|
||||
sh7091.SCIF.SCFCR2 = scfcr2::tfrst::reset_operation_enabled
|
||||
| scfcr2::rfrst::reset_operation_enabled;
|
||||
|
||||
sh7091.SCIF.SCSMR2 = scsmr2::chr::_8_bit_data
|
||||
| scsmr2::pe::parity_disabled
|
||||
| scsmr2::stop::_1_stop_bit
|
||||
| scsmr2::cks::p_phi_clock;
|
||||
|
||||
sh7091.SCIF.SCBRR2 = bit_rate; // bps = 1562500 / (SCBRR2 + 1)
|
||||
|
||||
sh7091.SCIF.SCFSR2 = (~scfsr2::er::bit_mask)
|
||||
& (~scfsr2::tend::bit_mask)
|
||||
& (~scfsr2::tdfe::bit_mask)
|
||||
& (~scfsr2::brk::bit_mask)
|
||||
& (~scfsr2::rdf::bit_mask)
|
||||
& (~scfsr2::dr::bit_mask)
|
||||
& 0xffff;
|
||||
|
||||
|
||||
// wait 1 bit interval
|
||||
scif_init_wait();
|
||||
|
||||
sh7091.SCIF.SCFCR2 = scfcr2::rtrg::trigger_on_1_byte
|
||||
| scfcr2::ttrg::trigger_on_8_bytes
|
||||
//| scfcr2::mce::modem_signals_enabled
|
||||
;
|
||||
|
||||
sh7091.SCIF.SCSCR2 = scscr2::te::transmission_enabled
|
||||
| scscr2::re::reception_enabled;
|
||||
|
||||
sh7091.SCIF.SCLSR2 = 0; // clear ORER
|
||||
}
|
||||
|
||||
void scif_character(const char c)
|
||||
{
|
||||
using namespace scif;
|
||||
|
@ -4,6 +4,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void scif_init_wait();
|
||||
void scif_init(int bit_rate);
|
||||
void scif_character(const char c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
31
java.mk
Normal file
31
java.mk
Normal file
@ -0,0 +1,31 @@
|
||||
%.class: %.java
|
||||
javac $<
|
||||
|
||||
java/lang/%.class: java/lang/%.java
|
||||
javac --source 8 --target 8 --boot-class-path . $<
|
||||
|
||||
OBJ = \
|
||||
c/decode.o \
|
||||
c/class_file.o \
|
||||
c/debug_class_file.o \
|
||||
c/malloc.o \
|
||||
c/execute.o \
|
||||
c/memory_allocator.o \
|
||||
c/class_resolver.o \
|
||||
c/hash_table.o \
|
||||
c/frame.o \
|
||||
c/printf.o \
|
||||
c/parse.o \
|
||||
c/unparse.o
|
||||
|
||||
MAIN_DREAMCAST_OBJ = \
|
||||
c/sh7091_scif.o \
|
||||
c/main_dreamcast.o
|
||||
|
||||
MAIN_HOSTED_OBJ = \
|
||||
c/file.o \
|
||||
c/main_hosted.o
|
||||
|
||||
PRINT_CLASS_OBJ = \
|
||||
c/file.o \
|
||||
c/print_class.o
|
15
p/Multiply.class.h
Normal file
15
p/Multiply.class.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t _binary_p_Multiply_class_start __asm("_binary_p_Multiply_class_start");
|
||||
extern uint32_t _binary_p_Multiply_class_end __asm("_binary_p_Multiply_class_end");
|
||||
extern uint32_t _binary_p_Multiply_class_size __asm("_binary_p_Multiply_class_size");
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
10
p/Multiply.java
Normal file
10
p/Multiply.java
Normal file
@ -0,0 +1,10 @@
|
||||
package p;
|
||||
|
||||
class Multiply {
|
||||
static int test(int a, int b) {
|
||||
return a * b;
|
||||
}
|
||||
public static void main() {
|
||||
test(6, 8);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user