mirror of
https://github.com/pruten/shoebill.git
synced 2025-04-16 11:39:04 +00:00
Dumping a lot of new FPU-related changes in a new branch
A/UX doesn't even come close to booting yet with the new FPU, but we're getting there. I don't want to trash master with a code base that doesn't work. Also, I turned off ethernet in the cocoa GUI, since the TAP driver isn't working right on 10.10 yet.
This commit is contained in:
parent
a155eb7734
commit
688199cf6d
@ -6,8 +6,8 @@ CFLAGS = -O3 -ggdb -flto -Wno-deprecated-declarations
|
||||
|
||||
DEPS = mc68851.h shoebill.h Makefile macro.pl
|
||||
NEED_DECODER = cpu dis
|
||||
NEED_PREPROCESSING = adb fpu mc68851 mem via floppy core_api
|
||||
NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer sound ethernet
|
||||
NEED_PREPROCESSING = adb mc68851 mem via floppy core_api newfpu
|
||||
NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer sound ethernet SoftFloat/softfloat
|
||||
|
||||
# Object files that can be compiled directly from the source
|
||||
OBJ_NEED_NOTHING = $(patsubst %,$(TEMP)/%.o,$(NEED_NOTHING))
|
||||
@ -78,6 +78,7 @@ $(TEMP)/decoder_gen: decoder_gen.c $(DEPS)
|
||||
|
||||
$(TEMP):
|
||||
mkdir -p $(TEMP)
|
||||
mkdir -p $(TEMP)/SoftFloat
|
||||
|
||||
clean:
|
||||
rm -rf $(TEMP)
|
||||
|
@ -651,7 +651,7 @@ uint32_t shoebill_initialize(shoebill_config_t *config)
|
||||
|
||||
shoe.pool = p_new_pool(NULL);
|
||||
|
||||
fpu_setup_jump_table();
|
||||
fpu_initialize();
|
||||
|
||||
// Try to load the ROM
|
||||
if (config->rom_path == NULL) {
|
||||
@ -823,11 +823,7 @@ void shoebill_restart (void)
|
||||
shoe.psr.word = 0;
|
||||
|
||||
// Reset all FPU registers
|
||||
shoe.fpiar = 0;
|
||||
shoe.fpcr.raw = 0;
|
||||
shoe.fpsr.raw = 0;
|
||||
memset(shoe.fp, 0, sizeof(shoe.fp));
|
||||
|
||||
fpu_reset();
|
||||
|
||||
// Free the old unix coff_file,
|
||||
coff_free(shoe.coff);
|
||||
@ -1017,7 +1013,7 @@ void slog(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
return ;
|
||||
// return ;
|
||||
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
|
@ -1398,7 +1398,7 @@ static void inst_cas (void) {
|
||||
~decompose(ext, 0000 000 uuu 000 ccc);
|
||||
|
||||
const uint8_t sz = (1 << s) >> 1; // (01 -> byte, 10 -> word, 11 -> long)
|
||||
|
||||
|
||||
call_ea_read(M, sz);
|
||||
|
||||
/* The dest/source/result operands are reversed here from inst_cmp */
|
||||
@ -1412,7 +1412,7 @@ static void inst_cas (void) {
|
||||
const _Bool Dm = ea_n(sz);
|
||||
const _Bool Rm = mib(R, sz);
|
||||
const _Bool z = (chop(R, sz) == 0);
|
||||
|
||||
|
||||
if (z) {
|
||||
// "If the operands are equal, the instruction writes the
|
||||
// update operand (Du) to the effective address operand"
|
||||
|
@ -1493,14 +1493,8 @@ void begin_definitions()
|
||||
|
||||
/* --- FPU (68881) instructions --- */
|
||||
|
||||
{
|
||||
inst_t *inst = new_inst("fpu_decode", "2", 1);
|
||||
add_range(inst, "1111 001 xxx xxxxxx");
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
/* { // all other fpu ops
|
||||
inst_t *inst = new_inst("fpu_decode", "2", 1);
|
||||
{ // all other fpu ops
|
||||
inst_t *inst = new_inst("fpu_other", "2", 1);
|
||||
add_range(inst, "1111 001 000 MMMMMM");
|
||||
ea_all(inst);
|
||||
}
|
||||
@ -1511,9 +1505,30 @@ void begin_definitions()
|
||||
ea_data_alterable(inst);
|
||||
}
|
||||
|
||||
{ // FDBcc
|
||||
inst_t *inst = new_inst("fdbcc", "2", 1);
|
||||
add_range(inst, "1111 001 001 001xxx");
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
{ // FTRAPcc
|
||||
inst_t *inst = new_inst("ftrapcc", "2", 1);
|
||||
add_range(inst, "1111 001 001 111 010");
|
||||
add_range(inst, "1111 001 001 111 011");
|
||||
add_range(inst, "1111 001 001 111 100");
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
{ // FBcc
|
||||
inst_t *inst = new_inst("fbcc", "2", 1);
|
||||
add_range(inst, "1111 001 01x xxxxxx");
|
||||
sub_range(inst, "1111 001 010 000000"); // fnop
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
{ // fnop
|
||||
inst_t *inst = new_inst("fnop", "2", 1);
|
||||
add_range(inst, "1111 001 010 000000");
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
@ -1529,7 +1544,7 @@ void begin_definitions()
|
||||
add_range(inst, "1111 001 101 MMMMMM");
|
||||
ea_control(inst);
|
||||
ea_add_mode(inst, EA_011);
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
33
core/dis.c
33
core/dis.c
@ -1516,6 +1516,39 @@ void dis_mc68851_decode() {
|
||||
assert(!"never get here");
|
||||
}
|
||||
|
||||
void dis_fscc () {
|
||||
sprintf(dis.str, "fscc??");
|
||||
}
|
||||
|
||||
void dis_fbcc () {
|
||||
sprintf(dis.str, "fbcc??");
|
||||
}
|
||||
|
||||
void dis_fsave () {
|
||||
sprintf(dis.str, "fsave??");
|
||||
}
|
||||
|
||||
void dis_frestore () {
|
||||
sprintf(dis.str, "frestore??");
|
||||
}
|
||||
|
||||
void dis_fpu_other () {
|
||||
sprintf(dis.str, "fpu_other??");
|
||||
}
|
||||
|
||||
void dis_fdbcc () {
|
||||
sprintf(dis.str, "fdbcc??");
|
||||
}
|
||||
|
||||
void dis_ftrapcc () {
|
||||
sprintf(dis.str, "ftrapcc??");
|
||||
}
|
||||
|
||||
void dis_fnop () {
|
||||
const uint16_t ext = dis_next_word();
|
||||
sprintf(dis.str, "fnop");
|
||||
}
|
||||
|
||||
#include "dis_decoder_guts.c"
|
||||
|
||||
/*
|
||||
|
@ -172,7 +172,7 @@ void throw_address_error()
|
||||
shoe.abort = 1;
|
||||
}
|
||||
|
||||
static void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num)
|
||||
void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num)
|
||||
{
|
||||
// set supervisor bit
|
||||
set_sr_s(1);
|
||||
|
@ -157,6 +157,7 @@ static fpu_inst_name_t fpu_decode_op(uint16_t op, uint16_t ext)
|
||||
case ~b(0011111): return fpu_inst_fgetman;
|
||||
case ~b(0100001): return fpu_inst_fmod;
|
||||
case ~b(0100100): return fpu_inst_fsgldiv;
|
||||
case ~b(0100111): return fpu_inst_fsglmul;
|
||||
case ~b(0100101): return fpu_inst_frem;
|
||||
case ~b(0100110): return fpu_inst_fscale;
|
||||
case ~b(0111000): return fpu_inst_fcmp;
|
||||
@ -1346,8 +1347,9 @@ void inst_fmath(uint16_t op, uint16_t ext)
|
||||
case ~b(0100001):
|
||||
// don't forget to set fpu_set_fpsr_quotient();
|
||||
assert(!"fpu_inst_fmod;");
|
||||
|
||||
case ~b(0100100): assert(!"fpu_inst_fsgldiv");
|
||||
|
||||
case ~b(0100100): assert(!"fpu_inst_fsgldiv;");
|
||||
case ~b(0100101): { // fpu_inst_frem
|
||||
assert(source != 0.0);
|
||||
result = remainderl(dest, source);
|
||||
@ -1513,6 +1515,7 @@ void fpu_setup_jump_table()
|
||||
fpu_inst_fgetman,
|
||||
fpu_inst_fmod,
|
||||
fpu_inst_fsgldiv,
|
||||
fpu_inst_fsglmul,
|
||||
fpu_inst_frem,
|
||||
fpu_inst_fscale,
|
||||
fpu_inst_fcmp,
|
||||
|
@ -468,10 +468,21 @@ got_data:
|
||||
char float128_is_nan(float128 a);
|
||||
char float128_is_signaling_nan (float128 a);
|
||||
|
||||
/*
|
||||
* s -> sign, e -> biased exponent
|
||||
* ma -> 48 high bits of the mantissa
|
||||
* mb -> 64 low bits of the mantissa
|
||||
*/
|
||||
#define _assemble_float128(s, e, ma, mb) ({ \
|
||||
const uint64_t _ma = (ma), _mb = (mb); \
|
||||
float128 f = { \
|
||||
.high = (((s) != 0) << 16) | ((e) & 0x7fff), \
|
||||
.low = _mb \
|
||||
}; \
|
||||
f.high = ((f.high) << 48) | _ma; \
|
||||
f; \
|
||||
})
|
||||
|
||||
// 80-bit macros, (should be 128 bit!)
|
||||
// #define is_nan(f) (((f).low << 1) && (((f).high << 1) == 0xfffe))
|
||||
// #define is_signal_nan(f) (is_nan((f)) && ((((f).low >> 62) & 1) == 0))
|
||||
|
||||
static void inst_fmath_fmovecr (void)
|
||||
{
|
||||
@ -481,63 +492,86 @@ static void inst_fmath_fmovecr (void)
|
||||
* FYI: these constants are stored in the "intermediate" 85-bit
|
||||
* format in the 6888x rom. This has the side effect that
|
||||
* they are rounded according to fpcr.mc_rnd.
|
||||
* We emulate the 85-bit format with float128.
|
||||
* We emulate the intermediate 85-bit format with float128.
|
||||
*/
|
||||
|
||||
switch (fpu->fmath_op) {
|
||||
case 0x00: // pi
|
||||
fpu->result = _assemble_float128(0, 0x4000, 0x921fb54442d1, 0x8469898cc51701b8);
|
||||
break;
|
||||
case 0x0b: // log_10(2)
|
||||
fpu->result = _assemble_float128(0, 0x3ffd, 0x34413509f79f, 0xef311f12b35816f9);
|
||||
break;
|
||||
case 0x0c: // e
|
||||
fpu->result = _assemble_float128(0, 0x4000, 0x5bf0a8b14576, 0x95355fb8ac404e7a);
|
||||
break;
|
||||
case 0x0d: // log_2(e)
|
||||
// FIXME: 68881 doesn't set inex2 for this one
|
||||
// (are the three intermediate bits zeros? I didn't check)
|
||||
fpu->result = _assemble_float128(0, 0x3fff, 0x71547652b82f, 0xe1777d0ffda0d23a);
|
||||
break;
|
||||
case 0x0e: // log_10(e)
|
||||
fpu->result = _assemble_float128(0, 0x3ffd, 0xbcb7b1526e50, 0xe32a6ab7555f5a67);
|
||||
break;
|
||||
case 0x0f: // 0.0
|
||||
fpu->result = _assemble_float128(0, 0, 0, 0);
|
||||
break;
|
||||
case 0x30: // ln(2)
|
||||
fpu->result = _assemble_float128(0, 0x3ffe, 0x62e42fefa39e, 0xf35793c7673007e5);
|
||||
break;
|
||||
case 0x31: // ln(10)
|
||||
fpu->result = _assemble_float128(0, 0x4000, 0x26bb1bbb5551, 0x582dd4adac5705a6);
|
||||
break;
|
||||
case 0x32: // 1 (68kprm has typesetting issues everywhere. This one says 100, but means 10^0.)
|
||||
fpu->result = _assemble_float128(0, 0x3fff, 0x0, 0x0);
|
||||
break;
|
||||
case 0x33: // 10
|
||||
fpu->result = _assemble_float128(0, 0x4002, 0x400000000000, 0x0);
|
||||
break;
|
||||
case 0x34: // 10^2
|
||||
fpu->result = _assemble_float128(0, 0x4005, 0x900000000000, 0x0);
|
||||
break;
|
||||
case 0x35: // 10^4
|
||||
fpu->result = _assemble_float128(0, 0x400c, 0x388000000000, 0x0);
|
||||
break;
|
||||
case 0x36: // 10^8
|
||||
fpu->result = _assemble_float128(0, 0x4019, 0x7d7840000000, 0x0);
|
||||
break;
|
||||
case 0x37: // 10^16
|
||||
fpu->result = _assemble_float128(0, 0x4034, 0x1c37937e0800, 0x0);
|
||||
break;
|
||||
case 0x38: // 10^32
|
||||
fpu->result = _assemble_float128(0, 0x4069, 0x3b8b5b5056e1, 0x6b3be04000000000);
|
||||
break;
|
||||
case 0x39: // 10^64
|
||||
fpu->result = _assemble_float128(0, 0x40d3, 0x84f03e93ff9f, 0x4daa797ed6e38ed6);
|
||||
break;
|
||||
case 0x3a: // 10^128
|
||||
fpu->result = _assemble_float128(0, 0x41a8, 0x27748f9301d3, 0x19bf8cde66d86d62);
|
||||
break;
|
||||
case 0x3b: // 10^256
|
||||
fpu->result = _assemble_float128(0, 0x4351, 0x54fdd7f73bf3, 0xbd1bbb77203731fd);
|
||||
break;
|
||||
case 0x3c: // 10^512
|
||||
fpu->result = _assemble_float128(0, 0x46a3, 0xc633415d4c1d, 0x238d98cab8a978a0);
|
||||
break;
|
||||
case 0x3d: // 10^1024
|
||||
fpu->result = _assemble_float128(0, 0x4d48, 0x92eceb0d02ea, 0x182eca1a7a51e316);
|
||||
break;
|
||||
case 0x3e: // 10^2048
|
||||
fpu->result = _assemble_float128(0, 0x5a92, 0x3d1676bb8a7a, 0xbbc94e9a519c6535);
|
||||
break;
|
||||
case 0x3f: // 10^4096
|
||||
fpu->result = _assemble_float128(0, 0x7525, 0x88c0a4051441, 0x2f3592982a7f0094);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* I wanted to include the actual values for the other ROM offsets,
|
||||
* but they might be proprietary. Most of them are 0 anyways, and some
|
||||
* cause FPU exceptions, even with all exceptions disabled... (?)
|
||||
* (Also, looking at the micro/nanocode on a high res 68881/2 die pic,
|
||||
* I can't figure out where these constants are stored.)
|
||||
* 68040 FPSP just returns 0, so we'll do that too.
|
||||
*/
|
||||
// FIXME: 0.0 -> result
|
||||
fpu->result = _assemble_float128(0, 0, 0, 0);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
@ -793,61 +793,11 @@ typedef struct {
|
||||
} bits;
|
||||
} psr;
|
||||
|
||||
// FPU registers
|
||||
uint32_t fpiar; // FPU iaddr
|
||||
// fpu_state_t pointer
|
||||
// (declared here as a void*, to prevent other files
|
||||
// from needing to include SoftFloat/softfloat.h)
|
||||
void *fpu_state;
|
||||
|
||||
union { // fpcr, fpu control register
|
||||
struct {
|
||||
// Mode control byte
|
||||
uint16_t mc_zero : 4; // zero/dummy
|
||||
uint16_t mc_rnd : 2; // rounding mode
|
||||
uint16_t mc_prec : 2; // rounding precision
|
||||
// Exception enable byte
|
||||
uint16_t ee_inex1 : 1; // inexact decimal input
|
||||
uint16_t ee_inex2 : 1; // inxact operation
|
||||
uint16_t ee_dz : 1; // divide by zero
|
||||
uint16_t ee_unfl : 1; // underflow
|
||||
uint16_t ee_ovfl : 1; // overflow
|
||||
uint16_t ee_operr : 1; // operand error
|
||||
uint16_t ee_snan : 1; // signalling not a number
|
||||
uint16_t ee_bsun : 1; // branch/set on unordered
|
||||
} b;
|
||||
|
||||
uint16_t raw;
|
||||
} fpcr;
|
||||
|
||||
union { // fpsr, fpu status register
|
||||
struct {
|
||||
// Accrued exception byte
|
||||
uint32_t dummy1 : 3; // dummy/zero
|
||||
uint32_t ae_inex : 1; // inexact
|
||||
uint32_t ae_dz : 1; // divide by zero
|
||||
uint32_t ae_unfl : 1; // underflow
|
||||
uint32_t ae_ovfl : 1; // overflow
|
||||
uint32_t ae_iop : 1; // invalid operation
|
||||
// Exception status byte
|
||||
uint32_t es_inex1 : 1; // inexact decimal input
|
||||
uint32_t es_inex2 : 1; // inxact operation
|
||||
uint32_t es_dz : 1; // divide by zero
|
||||
uint32_t es_unfl : 1; // underflow
|
||||
uint32_t es_ovfl : 1; // overflow
|
||||
uint32_t es_operr : 1; // operand error
|
||||
uint32_t es_snan : 1; // signalling not a number
|
||||
uint32_t es_bsun : 1; // branch/set on unordered
|
||||
// Quotient byte
|
||||
uint32_t qu_quotient : 7;
|
||||
uint32_t qu_s : 1;
|
||||
// Condition code byte
|
||||
uint32_t cc_nan : 1; // not a number
|
||||
uint32_t cc_i : 1; // infinity
|
||||
uint32_t cc_z : 1; // zero
|
||||
uint32_t cc_n : 1; // negative
|
||||
uint32_t dummy2 : 4; // dummy/zero
|
||||
} b;
|
||||
uint32_t raw;
|
||||
} fpsr;
|
||||
|
||||
long double fp[8]; // 80 bit floating point general registers
|
||||
|
||||
// -- Interrupts/VIA chips --
|
||||
|
||||
@ -878,9 +828,26 @@ typedef struct {
|
||||
extern global_shoebill_context_t shoe; // declared in cpu.c
|
||||
|
||||
// fpu.c functions
|
||||
void inst_fpu_decode(void);
|
||||
void dis_fpu_decode(void);
|
||||
void fpu_setup_jump_table();
|
||||
void inst_fscc();
|
||||
void inst_fbcc();
|
||||
void inst_fsave();
|
||||
void inst_frestore();
|
||||
void inst_ftrapcc();
|
||||
void inst_fdbcc();
|
||||
void inst_fnop();
|
||||
void inst_fpu_other();
|
||||
|
||||
void dis_fscc();
|
||||
void dis_fbcc();
|
||||
void dis_fsave();
|
||||
void dis_frestore();
|
||||
void dis_ftrapcc();
|
||||
void dis_fdbcc();
|
||||
void dis_fnop();
|
||||
void dis_fpu_other();
|
||||
|
||||
void fpu_initialize();
|
||||
void fpu_reset();
|
||||
|
||||
// cpu.c fuctions
|
||||
void cpu_step (void);
|
||||
@ -895,6 +862,7 @@ void throw_illegal_instruction();
|
||||
void throw_privilege_violation();
|
||||
void throw_divide_by_zero();
|
||||
void throw_frame_two (uint16_t sr, uint32_t next_pc, uint32_t vector_num, uint32_t orig_pc);
|
||||
void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num);
|
||||
|
||||
|
||||
// mem.c functions
|
||||
|
@ -373,8 +373,10 @@ void pram_callback (void *param, const uint8_t addr, const uint8_t byte)
|
||||
|
||||
[self createScreenWindow:9 height:height width:width];
|
||||
|
||||
uint8_t ethernet_addr[6] = {0x00, 0x24, 0x7e, 0x14, 0xd7, 0xff};
|
||||
shoebill_install_ethernet_card(&config, 13, ethernet_addr);
|
||||
// If you feel the cravin' for TAP-based ethernet, uncomment these lines
|
||||
//
|
||||
// uint8_t ethernet_addr[6] = {0x00, 0x24, 0x7e, 0x14, 0xd7, 0xff};
|
||||
// shoebill_install_ethernet_card(&config, 13, ethernet_addr);
|
||||
|
||||
shoebill_start();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user