gcc 4.9 compatibility
This commit is contained in:
parent
44fbfc7f29
commit
a30c3f54c1
@ -1,6 +1,8 @@
|
||||
all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp))
|
||||
|
||||
OPT = -Og
|
||||
OPT = -O2
|
||||
|
||||
CSTD = -std=gnu11
|
||||
|
||||
MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST)))))
|
||||
LIB ?= $(MAKEFILE_PATH)/dreamcast
|
||||
@ -48,7 +50,8 @@ LIBGCC_OBJ = \
|
||||
libgcc/_sdivsi3.o \
|
||||
libgcc/_fixsfdi.o \
|
||||
libgcc/_div_table.o \
|
||||
libgcc/_movmem_i4.o
|
||||
libgcc/_movmem_i4.o \
|
||||
libgcc/_set_fpscr.o
|
||||
|
||||
include classpath.mk
|
||||
|
||||
|
@ -6,6 +6,10 @@
|
||||
#include "native_types_allocate.h"
|
||||
#include "vm_instance.h"
|
||||
|
||||
int abort() {
|
||||
while (1);
|
||||
}
|
||||
|
||||
struct objectref * backtrace_allocate(struct vm * vm)
|
||||
{
|
||||
struct objectref * objectref = vm_instance_create(vm, "java/lang/Backtrace");
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "native_types.h"
|
||||
#include "vm.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct backtrace_entry {
|
||||
struct class_file * class_file;
|
||||
|
@ -144,8 +144,8 @@ struct class_file * class_file_parse(const uint8_t * buf)
|
||||
case CONSTANT_Class:
|
||||
constant->class.name_index = parse_u2(&buf);
|
||||
break;
|
||||
case CONSTANT_Fieldref: [[fallthrough]];
|
||||
case CONSTANT_Methodref: [[fallthrough]];
|
||||
case CONSTANT_Fieldref: /* fall through */;
|
||||
case CONSTANT_Methodref: /* fall through */;
|
||||
case CONSTANT_InterfaceMethodref:
|
||||
constant->fieldref.class_index = parse_u2(&buf);
|
||||
constant->fieldref.name_and_type_index = parse_u2(&buf);
|
||||
@ -153,11 +153,11 @@ struct class_file * class_file_parse(const uint8_t * buf)
|
||||
case CONSTANT_String:
|
||||
constant->string.string_index = parse_u2(&buf);
|
||||
break;
|
||||
case CONSTANT_Integer: [[fallthrough]];
|
||||
case CONSTANT_Integer: /* fall through */;
|
||||
case CONSTANT_Float:
|
||||
constant->integer.bytes = parse_u4(&buf);
|
||||
break;
|
||||
case CONSTANT_Long: [[fallthrough]];
|
||||
case CONSTANT_Long: /* fall through */;
|
||||
case CONSTANT_Double:
|
||||
{
|
||||
uint64_t high_bytes = parse_u4(&buf);
|
||||
@ -183,12 +183,12 @@ struct class_file * class_file_parse(const uint8_t * buf)
|
||||
case CONSTANT_MethodType:
|
||||
constant->methodtype.descriptor_index = parse_u2(&buf);
|
||||
break;
|
||||
case CONSTANT_Dynamic: [[fallthrough]];
|
||||
case CONSTANT_Dynamic: /* fall through */;
|
||||
case CONSTANT_InvokeDynamic:
|
||||
constant->dynamic.bootstrap_method_attr_index = parse_u2(&buf);
|
||||
constant->dynamic.name_and_type_index = parse_u2(&buf);
|
||||
break;
|
||||
case CONSTANT_Module: [[fallthrough]];
|
||||
case CONSTANT_Module: /* fall through */;
|
||||
case CONSTANT_Package:
|
||||
constant->module.name_index = parse_u2(&buf);
|
||||
break;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compat.h"
|
||||
|
||||
typedef uint64_t u8;
|
||||
typedef uint32_t u4;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "hash_table.h"
|
||||
#include "native_types.h"
|
||||
#include "vm.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct hash_table_entry * class_resolver_load_from_buffers(const uint8_t ** buffers,
|
||||
int length,
|
||||
|
25
c/compat.h
Normal file
25
c/compat.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) __builtin_offsetof (type, member)
|
||||
#endif
|
||||
|
||||
#ifndef bool
|
||||
#define bool int
|
||||
#endif
|
||||
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#ifndef static_assert
|
||||
#define static_assert(s) _Static_assert(s, "");
|
||||
#endif
|
||||
|
||||
#ifndef nullptr
|
||||
#define nullptr ((void *)0)
|
||||
#endif
|
@ -157,9 +157,9 @@ static void print_methodhandle_constant(const char * indent, struct constant * m
|
||||
for (int i = 0; i < (sizeof (indent2)) - 1; i++) indent2[i] = ' ';
|
||||
|
||||
switch (methodhandle_constant->methodhandle.reference_kind) {
|
||||
case REF_getField: [[fallthrough]];
|
||||
case REF_getStatic: [[fallthrough]];
|
||||
case REF_putField: [[fallthrough]];
|
||||
case REF_getField: /* fall through */;
|
||||
case REF_getStatic: /* fall through */;
|
||||
case REF_putField: /* fall through */;
|
||||
case REF_putStatic:
|
||||
// If the value of the reference_kind item is 1 (REF_getField), 2
|
||||
// (REF_getStatic), 3 (REF_putField), or 4 (REF_putStatic), then the
|
||||
@ -169,7 +169,7 @@ static void print_methodhandle_constant(const char * indent, struct constant * m
|
||||
assert(constant->tag == CONSTANT_Fieldref);
|
||||
print_methodref(indent2, constant, constant_pool);
|
||||
break;
|
||||
case REF_invokeVirtual: [[fallthrough]];
|
||||
case REF_invokeVirtual: /* fall through */;
|
||||
case REF_newInvokeSpecial:
|
||||
// If the value of the reference_kind item is 5 (REF_invokeVirtual) or 8
|
||||
// (REF_newInvokeSpecial), then the constant_pool entry at that index must be
|
||||
@ -178,7 +178,7 @@ static void print_methodhandle_constant(const char * indent, struct constant * m
|
||||
assert(constant->tag == CONSTANT_Methodref);
|
||||
print_methodref(indent2, constant, constant_pool);
|
||||
break;
|
||||
case REF_invokeStatic: [[fallthrough]];
|
||||
case REF_invokeStatic: /* fall through */;
|
||||
case REF_invokeSpecial:
|
||||
// If the value of the reference_kind item is 6 (REF_invokeStatic) or 7
|
||||
// (REF_invokeSpecial), [...] the constant_pool entry at that index must be
|
||||
|
64
c/execute.c
64
c/execute.c
@ -772,20 +772,20 @@ void op_getfield(struct vm * vm, uint32_t index)
|
||||
debugf("getfield instance_index %d\n", field_entry->instance_index);
|
||||
|
||||
switch (field_descriptor_constant->utf8.bytes[0]) {
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'L': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z': [[fallthrough]];
|
||||
case 'B': /* fall through */;
|
||||
case 'C': /* fall through */;
|
||||
case 'F': /* fall through */;
|
||||
case 'I': /* fall through */;
|
||||
case 'L': /* fall through */;
|
||||
case 'S': /* fall through */;
|
||||
case 'Z': /* fall through */;
|
||||
case '[':
|
||||
{
|
||||
void * value = objectref->oref[field_entry->instance_index];
|
||||
operand_stack_push_ref(vm->current_frame, value);
|
||||
}
|
||||
break;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'D': /* fall through */;
|
||||
case 'J':
|
||||
{
|
||||
void * low = objectref->oref[field_entry->instance_index];
|
||||
@ -818,20 +818,20 @@ void op_getstatic(struct vm * vm, uint32_t index)
|
||||
return;
|
||||
|
||||
switch (field_descriptor_constant->utf8.bytes[0]) {
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'L': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z': [[fallthrough]];
|
||||
case 'B': /* fall through */;
|
||||
case 'C': /* fall through */;
|
||||
case 'F': /* fall through */;
|
||||
case 'I': /* fall through */;
|
||||
case 'L': /* fall through */;
|
||||
case 'S': /* fall through */;
|
||||
case 'Z': /* fall through */;
|
||||
case '[':
|
||||
{
|
||||
uint32_t value = class_entry->static_fields[field_entry->static_index];
|
||||
operand_stack_push_u32(vm->current_frame, value);
|
||||
}
|
||||
break;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'D': /* fall through */;
|
||||
case 'J':
|
||||
{
|
||||
uint32_t low = class_entry->static_fields[field_entry->static_index];
|
||||
@ -1942,13 +1942,13 @@ void op_putfield(struct vm * vm, uint32_t index)
|
||||
debugf("putfield instance_index %d\n", field_entry->instance_index);
|
||||
|
||||
switch (field_descriptor_constant->utf8.bytes[0]) {
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'L': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z': [[fallthrough]];
|
||||
case 'B': /* fall through */;
|
||||
case 'C': /* fall through */;
|
||||
case 'F': /* fall through */;
|
||||
case 'I': /* fall through */;
|
||||
case 'L': /* fall through */;
|
||||
case 'S': /* fall through */;
|
||||
case 'Z': /* fall through */;
|
||||
case '[':
|
||||
{
|
||||
uint32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
@ -1958,7 +1958,7 @@ void op_putfield(struct vm * vm, uint32_t index)
|
||||
objectref->u32[field_entry->instance_index] = value;
|
||||
}
|
||||
break;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'D': /* fall through */;
|
||||
case 'J':
|
||||
{
|
||||
uint32_t high = operand_stack_pop_u32(vm->current_frame);
|
||||
@ -2002,20 +2002,20 @@ void op_putstatic(struct vm * vm, uint32_t index)
|
||||
return;
|
||||
|
||||
switch (field_descriptor_constant->utf8.bytes[0]) {
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'L': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z': [[fallthrough]];
|
||||
case 'B': /* fall through */;
|
||||
case 'C': /* fall through */;
|
||||
case 'F': /* fall through */;
|
||||
case 'I': /* fall through */;
|
||||
case 'L': /* fall through */;
|
||||
case 'S': /* fall through */;
|
||||
case 'Z': /* fall through */;
|
||||
case '[':
|
||||
{
|
||||
uint32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
class_entry->static_fields[field_entry->static_index] = value;
|
||||
}
|
||||
break;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'D': /* fall through */;
|
||||
case 'J':
|
||||
{
|
||||
uint32_t high = operand_stack_pop_u32(vm->current_frame);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "vm.h"
|
||||
|
||||
void op_aaload(struct vm * vm);
|
||||
|
@ -3,16 +3,16 @@
|
||||
static inline int field_size(uint8_t c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'L': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z': [[fallthrough]];
|
||||
case 'B': /* fall through */;
|
||||
case 'C': /* fall through */;
|
||||
case 'F': /* fall through */;
|
||||
case 'I': /* fall through */;
|
||||
case 'L': /* fall through */;
|
||||
case 'S': /* fall through */;
|
||||
case 'Z': /* fall through */;
|
||||
case '[':
|
||||
return 1;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'D': /* fall through */;
|
||||
case 'J':
|
||||
return 2;
|
||||
default:
|
||||
@ -23,18 +23,18 @@ static inline int field_size(uint8_t c)
|
||||
static inline int field_size_array(uint8_t c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'Z': [[fallthrough]]; // boolean
|
||||
case 'Z': /* fall through */; // boolean
|
||||
case 'B': // byte
|
||||
return 1;
|
||||
case 'C': [[fallthrough]]; // char
|
||||
case 'C': /* fall through */; // char
|
||||
case 'S': // short
|
||||
return 2;
|
||||
case 'F': [[fallthrough]]; // float
|
||||
case 'I': [[fallthrough]]; // int
|
||||
case 'L': [[fallthrough]]; // classref
|
||||
case 'F': /* fall through */; // float
|
||||
case 'I': /* fall through */; // int
|
||||
case 'L': /* fall through */; // classref
|
||||
case '[': // arrayref
|
||||
return 4;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'D': /* fall through */;
|
||||
case 'J':
|
||||
return 8;
|
||||
default:
|
||||
|
1
c/file.h
1
c/file.h
@ -2,5 +2,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "compat.h"
|
||||
|
||||
uint8_t * file_read(const char * path, size_t * file_size);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "class_file.h"
|
||||
#include "compat.h"
|
||||
|
||||
int find_code_name_index(struct class_file * class_file);
|
||||
int find_constantvalue_name_index(struct class_file * class_file);
|
||||
|
1
c/gc.h
1
c/gc.h
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "vm.h"
|
||||
#include "compat.h"
|
||||
|
||||
void gc_mark(struct vm * vm);
|
||||
void gc_sweep();
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compat.h"
|
||||
|
||||
struct hash_table_entry {
|
||||
const uint8_t * key;
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
void main()
|
||||
{
|
||||
scif_init(0);
|
||||
//scif_init(0);
|
||||
|
||||
const uint8_t * class_file_buffers[] = {
|
||||
#include "classpath.inc.c"
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compat.h"
|
||||
|
||||
void malloc_class_arena_reset();
|
||||
void * malloc_class_arena(uint32_t size);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compat.h"
|
||||
|
||||
void memory_reset_free_list();
|
||||
void * memory_allocate(uint32_t size);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "vm.h"
|
||||
|
||||
void native_java_lang_class_getname_1(struct vm * vm, uint32_t * args);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "vm.h"
|
||||
|
||||
void native_jvm_internal_libcinputstream_open_1(struct vm * vm, uint32_t * args);
|
||||
|
@ -1,18 +1,28 @@
|
||||
#include "math.h"
|
||||
|
||||
void __attribute__ ((noinline)) __attribute__ ((optimize(0)))
|
||||
float __attribute__ ((noinline)) cosf(float f)
|
||||
{
|
||||
return __builtin_cosf(f);
|
||||
}
|
||||
|
||||
float __attribute__ ((noinline)) sinf(float f)
|
||||
{
|
||||
return __builtin_sinf(f);
|
||||
}
|
||||
|
||||
void
|
||||
native_java_lang_math_sin_1(struct vm * vm, uint32_t * args)
|
||||
{
|
||||
float arg = ((float *)args)[0];
|
||||
float value = __builtin_sinf(arg);
|
||||
float value = sinf(arg);
|
||||
operand_stack_push_f32(vm->current_frame, value);
|
||||
}
|
||||
|
||||
void __attribute__ ((noinline)) __attribute__ ((optimize(0)))
|
||||
void
|
||||
native_java_lang_math_cos_1(struct vm * vm, uint32_t * args)
|
||||
{
|
||||
float arg = ((float *)args)[0];
|
||||
float value = __builtin_cosf(arg);
|
||||
float value = cosf(arg);
|
||||
operand_stack_push_f32(vm->current_frame, value);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "vm.h"
|
||||
|
||||
void native_java_lang_object_getclass_1(struct vm * vm, uint32_t * args);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "vm.h"
|
||||
|
||||
void native_java_io_printstream_write_ba_1(struct vm * vm, uint32_t * args);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "vm.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct hash_table_entry * native_init_hash_table(int * hash_table_length);
|
||||
|
||||
|
@ -64,20 +64,20 @@ enum ARRAY_TYPE {
|
||||
static inline int array_element_size(int atype)
|
||||
{
|
||||
switch (atype) {
|
||||
case T_BOOLEAN: [[fallthrough]]; // 1 byte
|
||||
case T_BYTE: // 1 byte
|
||||
case T_BOOLEAN: /* fall through */; // 1 byte
|
||||
case T_BYTE: // 1 byte
|
||||
return 1;
|
||||
break;
|
||||
case T_CHAR: [[fallthrough]]; // 2 bytes
|
||||
case T_SHORT: // 2 bytes
|
||||
case T_CHAR: /* fall through */; // 2 bytes
|
||||
case T_SHORT: // 2 bytes
|
||||
return 2;
|
||||
break;
|
||||
case T_FLOAT: [[fallthrough]]; // 4 bytes
|
||||
case T_INT: // 4 bytes
|
||||
case T_FLOAT: /* fall through */; // 4 bytes
|
||||
case T_INT: // 4 bytes
|
||||
return 4;
|
||||
break;
|
||||
case T_DOUBLE: [[fallthrough]]; // 8 bytes
|
||||
case T_LONG: // 8 bytes
|
||||
case T_DOUBLE: /* fall through */; // 8 bytes
|
||||
case T_LONG: // 8 bytes
|
||||
return 8;
|
||||
break;
|
||||
default:
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "gc.h"
|
||||
#include "vm.h"
|
||||
#include "memory_allocator.h"
|
||||
#include "compat.h"
|
||||
|
||||
static inline void * gc_memory_allocate(struct vm * vm, int size)
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compat.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -143,7 +143,7 @@ void _printf(const char * format, ...)
|
||||
print_char('0');
|
||||
print_char('x');
|
||||
}
|
||||
[[fallthrough]];
|
||||
/* fall through */;
|
||||
case FORMAT_BASE16:
|
||||
{
|
||||
uint32_t num = va_arg(args, uint32_t);
|
||||
|
65
c/sh7091_scif.c
Normal file
65
c/sh7091_scif.c
Normal file
@ -0,0 +1,65 @@
|
||||
#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 = 0xffffffff;
|
||||
sh7091_TMU.TCNT1 = 0xffffffff;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// wait for transmit fifo to become partially empty
|
||||
while ((sh7091_SCIF.SCFSR2 & scfsr2__tdfe__bit_mask) == 0);
|
||||
|
||||
sh7091_SCIF.SCFSR2 &= ~scfsr2__tdfe__bit_mask;
|
||||
|
||||
sh7091_SCIF.SCFTDR2 = (uint8_t)(c);
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
#include "sh7091/sh7091.hpp"
|
||||
#include "sh7091/sh7091_bits.hpp"
|
||||
|
||||
#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;
|
||||
// wait for transmit fifo to become partially empty
|
||||
while ((sh7091.SCIF.SCFSR2 & scfsr2::tdfe::bit_mask) == 0);
|
||||
|
||||
sh7091.SCIF.SCFSR2 &= ~scfsr2::tdfe::bit_mask;
|
||||
|
||||
sh7091.SCIF.SCFTDR2 = static_cast<uint8_t>(c);
|
||||
}
|
100
c/sh7091_scif.h
100
c/sh7091_scif.h
@ -1,13 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compat.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef volatile uint8_t reg8;
|
||||
typedef volatile uint16_t reg16;
|
||||
typedef volatile uint32_t reg32;
|
||||
|
||||
static_assert((sizeof (reg8)) == 1);
|
||||
static_assert((sizeof (reg16)) == 2);
|
||||
static_assert((sizeof (reg32)) == 4);
|
||||
|
||||
struct scif_reg {
|
||||
reg16 SCSMR2; /* Serial mode register 2 */
|
||||
reg8 _pad0[2];
|
||||
reg8 SCBRR2; /* Bit rate register 2 */
|
||||
reg8 _pad1[3];
|
||||
reg16 SCSCR2; /* Serial control register 2 */
|
||||
reg8 _pad2[2];
|
||||
reg8 SCFTDR2; /* Transmit FIFO data register 2 */
|
||||
reg8 _pad3[3];
|
||||
reg16 SCFSR2; /* Serial status register 2 */
|
||||
reg8 _pad4[2];
|
||||
reg8 SCFRDR2; /* Receive FIFO data register 2 */
|
||||
reg8 _pad5[3];
|
||||
reg16 SCFCR2; /* FIFO control register */
|
||||
reg8 _pad6[2];
|
||||
reg16 SCFDR2; /* FIFO data count register */
|
||||
reg8 _pad7[2];
|
||||
reg16 SCSPTR2; /* Serial port register 2 */
|
||||
reg8 _pad8[2];
|
||||
reg16 SCLSR2; /* Line status register 2 */
|
||||
};
|
||||
|
||||
static_assert((offsetof (struct scif_reg, SCSMR2)) == 0x0);
|
||||
static_assert((offsetof (struct scif_reg, SCBRR2)) == 0x4);
|
||||
static_assert((offsetof (struct scif_reg, SCSCR2)) == 0x8);
|
||||
static_assert((offsetof (struct scif_reg, SCFTDR2)) == 0xc);
|
||||
static_assert((offsetof (struct scif_reg, SCFSR2)) == 0x10);
|
||||
static_assert((offsetof (struct scif_reg, SCFRDR2)) == 0x14);
|
||||
static_assert((offsetof (struct scif_reg, SCFCR2)) == 0x18);
|
||||
static_assert((offsetof (struct scif_reg, SCFDR2)) == 0x1c);
|
||||
static_assert((offsetof (struct scif_reg, SCSPTR2)) == 0x20);
|
||||
static_assert((offsetof (struct scif_reg, SCLSR2)) == 0x24);
|
||||
|
||||
struct tmu_reg {
|
||||
reg8 TOCR; /* Timer output control register */
|
||||
reg8 _pad0[3];
|
||||
reg8 TSTR; /* Timer start register */
|
||||
reg8 _pad1[3];
|
||||
reg32 TCOR0; /* Timer constant register 0 */
|
||||
reg32 TCNT0; /* Timer counter 0 */
|
||||
reg16 TCR0; /* Timer control register 0 */
|
||||
reg8 _pad2[2];
|
||||
reg32 TCOR1; /* Timer constant register 1 */
|
||||
reg32 TCNT1; /* Timer counter 1 */
|
||||
reg16 TCR1; /* Timer control register 1 */
|
||||
reg8 _pad3[2];
|
||||
reg32 TCOR2; /* Timer constant register 2 */
|
||||
reg32 TCNT2; /* Timer counter 2 */
|
||||
reg16 TCR2; /* Timer control register 2 */
|
||||
reg8 _pad4[2];
|
||||
reg32 TCPR2; /* Timer input capture register 2 */
|
||||
};
|
||||
|
||||
static_assert((offsetof (struct tmu_reg, TOCR)) == 0x0);
|
||||
static_assert((offsetof (struct tmu_reg, TSTR)) == 0x4);
|
||||
static_assert((offsetof (struct tmu_reg, TCOR0)) == 0x8);
|
||||
static_assert((offsetof (struct tmu_reg, TCNT0)) == 0xc);
|
||||
static_assert((offsetof (struct tmu_reg, TCR0)) == 0x10);
|
||||
static_assert((offsetof (struct tmu_reg, TCOR1)) == 0x14);
|
||||
static_assert((offsetof (struct tmu_reg, TCNT1)) == 0x18);
|
||||
static_assert((offsetof (struct tmu_reg, TCR1)) == 0x1c);
|
||||
static_assert((offsetof (struct tmu_reg, TCOR2)) == 0x20);
|
||||
static_assert((offsetof (struct tmu_reg, TCNT2)) == 0x24);
|
||||
static_assert((offsetof (struct tmu_reg, TCR2)) == 0x28);
|
||||
static_assert((offsetof (struct tmu_reg, TCPR2)) == 0x2c);
|
||||
|
||||
#define tmu__tstr__str1__counter_start (1 << 2)
|
||||
#define tmu__tocr__tcoe__tclk_is_external_clock_or_input_capture (0 << 0)
|
||||
#define tmu__tcr1__tpsc__p_phi_1024 (0b100 << 0)
|
||||
#define scfcr2__tfrst__reset_operation_enabled (1 << 2)
|
||||
#define scfcr2__rfrst__reset_operation_enabled (1 << 1)
|
||||
#define scsmr2__chr__8_bit_data (0 << 6)
|
||||
#define scsmr2__pe__parity_disabled (0 << 5)
|
||||
#define scsmr2__stop__1_stop_bit (0 << 3)
|
||||
#define scsmr2__cks__p_phi_clock (0b00 << 0)
|
||||
#define scfsr2__er__bit_mask (0x1 << 7)
|
||||
#define scfsr2__tend__bit_mask (0x1 << 6)
|
||||
#define scfsr2__tdfe__bit_mask (0x1 << 5)
|
||||
#define scfsr2__brk__bit_mask (0x1 << 4)
|
||||
#define scfsr2__rdf__bit_mask (0x1 << 1)
|
||||
#define scfsr2__dr__bit_mask (0x1 << 0)
|
||||
#define scfcr2__rtrg__trigger_on_1_byte (0b00 << 6)
|
||||
#define scfcr2__ttrg__trigger_on_8_bytes (0b00 << 4)
|
||||
#define scscr2__te__transmission_enabled (1 << 5)
|
||||
#define scscr2__re__reception_enabled (1 << 4)
|
||||
|
||||
void scif_init_wait();
|
||||
void scif_init(int bit_rate);
|
||||
void scif_character(const char c);
|
||||
|
||||
extern struct tmu_reg sh7091_TMU __asm("sh7091_TMU");
|
||||
extern struct scif_reg sh7091_SCIF __asm("sh7091_SCIF");
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
static inline int string_length(const char * s)
|
||||
{
|
||||
const char * si = s;
|
||||
|
@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compat.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
28
c/vm.c
28
c/vm.c
@ -33,7 +33,7 @@ int descriptor_nargs(struct constant * descriptor_constant, uint8_t * return_typ
|
||||
switch (byte) {
|
||||
case '[':
|
||||
break;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'D': /* fall through */;
|
||||
case 'J':
|
||||
nargs += 2;
|
||||
break;
|
||||
@ -41,11 +41,11 @@ int descriptor_nargs(struct constant * descriptor_constant, uint8_t * return_typ
|
||||
nargs += 1;
|
||||
while (descriptor_constant->utf8.bytes[i] != ';') i += 1;
|
||||
break;
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'B': /* fall through */;
|
||||
case 'C': /* fall through */;
|
||||
case 'F': /* fall through */;
|
||||
case 'I': /* fall through */;
|
||||
case 'S': /* fall through */;
|
||||
case 'Z':
|
||||
nargs += 1;
|
||||
break;
|
||||
@ -304,20 +304,20 @@ void vm_method_return(struct vm * vm)
|
||||
*/
|
||||
|
||||
switch (old_frame->return_type) {
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'L': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'Z': [[fallthrough]];
|
||||
case 'B': /* fall through */;
|
||||
case 'C': /* fall through */;
|
||||
case 'F': /* fall through */;
|
||||
case 'I': /* fall through */;
|
||||
case 'L': /* fall through */;
|
||||
case 'S': /* fall through */;
|
||||
case 'Z': /* fall through */;
|
||||
case '[':
|
||||
{
|
||||
uint32_t value = operand_stack_pop_u32(old_frame);
|
||||
operand_stack_push_u32(vm->current_frame, value);
|
||||
}
|
||||
break;
|
||||
case 'D': [[fallthrough]];
|
||||
case 'D': /* fall through */;
|
||||
case 'J':
|
||||
{
|
||||
uint64_t value = operand_stack_pop_u64(old_frame);
|
||||
|
1
c/vm.h
1
c/vm.h
@ -2,6 +2,7 @@
|
||||
|
||||
#include "frame_stack.h"
|
||||
#include "class_file.h"
|
||||
#include "compat.h"
|
||||
|
||||
bool vm_initialize_class(struct vm * vm, struct class_entry * class_entry);
|
||||
void vm_special_method_call(struct vm * vm, struct class_entry * class_entry, struct method_entry * method_entry);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "vm.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct objectref * vm_instance_create(struct vm * vm, const char * class_name);
|
||||
struct objectref * vm_instance_string_from_constant(struct vm * vm, struct constant * constant);
|
||||
|
@ -221,14 +221,14 @@ set -eux
|
||||
|
||||
find . -name '*.class' -not -path "./classes/java/*" -exec rm -f {} \;
|
||||
|
||||
make -f Makefile.dreamcast.mk $(boot_sources | java_to_class)
|
||||
make -f Makefile.dreamcast.mk TARGET=sh-elf- $(boot_sources | java_to_class)
|
||||
find . -name '*.class' | rename_class_files
|
||||
boot_classes | classpath_mk
|
||||
boot_classes | classpath_inc_c
|
||||
boot_classes | make_header
|
||||
boot_classes | classpath_h
|
||||
|
||||
make -f Makefile.dreamcast.mk $(application_sources | java_to_class)
|
||||
make -f Makefile.dreamcast.mk TARGET=sh-elf- $(application_sources | java_to_class)
|
||||
find . -name '*.class' | rename_class_files
|
||||
|
||||
boot_classes | sort > classes.txt
|
||||
|
@ -2,5 +2,5 @@ set -eux
|
||||
|
||||
sh generate_classpath.sh
|
||||
rm -f main.bin main.elf jvm.iso
|
||||
make -f Makefile.dreamcast.mk jvm.iso
|
||||
make -f Makefile.dreamcast.mk TARGET=sh-elf- jvm.iso
|
||||
../cdi4dc jvm.iso jvm.cdi > /dev/null
|
||||
|
Loading…
x
Reference in New Issue
Block a user