mirror of
https://github.com/pruten/shoebill.git
synced 2024-09-29 06:54:51 +00:00
Implemented trapv/trapcc + a few more FPU instructions.
Implemented the divide-by-zero exception. Made some progress toward 16/24-bit video.
This commit is contained in:
parent
ba8b9e80d1
commit
cc2bb3c605
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
.DS_Store
|
||||
*.xcworkspace
|
||||
xcuserdata
|
||||
/gui/build
|
||||
|
@ -46,6 +46,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
video_ctx_color_t *direct_buf, *clut;
|
||||
uint8_t *indexed_buf, *rom;
|
||||
uint8_t *cur_buf;
|
||||
|
||||
uint32_t pixels;
|
||||
|
||||
|
83
core/cpu.c
83
core/cpu.c
@ -69,11 +69,81 @@ global_shoebill_context_t shoe;
|
||||
})
|
||||
|
||||
~inst(trapcc, {
|
||||
assert(!"trapcc: error: not implemented\n");
|
||||
~decompose(shoe.op, 0101 cccc 11111 xyz);
|
||||
|
||||
// (xyz) == (100) -> sz=0
|
||||
// (xyz) == (010) -> sz=2
|
||||
// (xyz) == (011) -> sz=4
|
||||
const uint32_t sz = y << (z+1); // too clever
|
||||
const uint32_t next_pc = shoe.orig_pc + 2 + sz;
|
||||
|
||||
const uint8_t C = sr_c();
|
||||
const uint8_t Z = sr_z();
|
||||
const uint8_t V = sr_v();
|
||||
const uint8_t N = sr_n();
|
||||
|
||||
uint8_t set = 0;
|
||||
|
||||
switch (c) {
|
||||
case 0: // trapt
|
||||
set = 1; // FIXME: do-trap unconditionally?
|
||||
break;
|
||||
case 1: // trapf
|
||||
set = 0; // FIXME: do-not-trap unconditionally?
|
||||
break;
|
||||
case 2:
|
||||
if (!C && !Z) set = 1; // traphi
|
||||
break;
|
||||
case 3:
|
||||
if (C || Z) set = 1; // trapls
|
||||
break;
|
||||
case 4:
|
||||
if (!C) set = 1; // trapcc
|
||||
break;
|
||||
case 5:
|
||||
if (C) set = 1; // trapcs
|
||||
break;
|
||||
case 6:
|
||||
if (!Z) set = 1; // trapne
|
||||
break;
|
||||
case 7:
|
||||
if (Z) set = 1; // trapeq
|
||||
break;
|
||||
case 8:
|
||||
if (!V) set = 1; // trapvc
|
||||
break;
|
||||
case 9:
|
||||
if (V) set = 1; // trapvs
|
||||
break;
|
||||
case 10:
|
||||
if (!N) set = 1; // trappl
|
||||
break;
|
||||
case 11:
|
||||
if (N) set = 1; // trapmi
|
||||
break;
|
||||
case 12:
|
||||
if ( (N && V) || (!N && !V) ) set = 1; // trapge
|
||||
break;
|
||||
case 13:
|
||||
if ( (N && !V) || (!N && V) ) set = 1; // traplt
|
||||
break;
|
||||
case 14:
|
||||
if ( (N && V && !Z) || (!N && !V && !Z) ) set = 1; // trapgt
|
||||
break;
|
||||
case 15:
|
||||
if ( (Z || (N && !V) || (!N && V) ) ) set = 1; // traple
|
||||
break;
|
||||
}
|
||||
|
||||
if (set)
|
||||
throw_frame_two(shoe.sr, next_pc, 7, shoe.orig_pc);
|
||||
else
|
||||
shoe.pc = next_pc;
|
||||
})
|
||||
|
||||
~inst(trapv, {
|
||||
assert(!"trapv: error: not implemented\n");
|
||||
if (sr_v())
|
||||
throw_frame_two(shoe.sr, shoe.pc, 7, shoe.orig_pc);
|
||||
})
|
||||
|
||||
~inst(asx_reg, {
|
||||
@ -344,7 +414,7 @@ global_shoebill_context_t shoe;
|
||||
const uint16_t divisor = (uint16_t)shoe.dat;
|
||||
|
||||
if (divisor == 0) {
|
||||
throw_divide_by_zero();
|
||||
throw_frame_two(shoe.orig_sr, shoe.uncommitted_ea_read_pc, 5, shoe.orig_pc);
|
||||
return ;
|
||||
}
|
||||
|
||||
@ -371,7 +441,7 @@ global_shoebill_context_t shoe;
|
||||
const int16_t s_divisor = (int16_t)shoe.dat;
|
||||
|
||||
if (s_divisor == 0) {
|
||||
throw_divide_by_zero();
|
||||
throw_frame_two(shoe.orig_sr, shoe.uncommitted_ea_read_pc, 5, shoe.orig_pc);
|
||||
return ;
|
||||
}
|
||||
|
||||
@ -976,14 +1046,15 @@ global_shoebill_context_t shoe;
|
||||
~decompose(shoe.op, 0100 1100 01 MMMMMM);
|
||||
~decompose(ext, 0 qqq u s 0000000 rrr);
|
||||
call_ea_read(M, 4);
|
||||
call_ea_read_commit(M, 4);
|
||||
|
||||
const uint32_t divisor = shoe.dat;
|
||||
if (divisor == 0) {
|
||||
throw_divide_by_zero();
|
||||
throw_frame_two(shoe.orig_sr, shoe.uncommitted_ea_read_pc, 5, shoe.orig_pc);
|
||||
return ;
|
||||
}
|
||||
|
||||
call_ea_read_commit(M, 4);
|
||||
|
||||
uint64_t dividend;
|
||||
if (s)
|
||||
dividend = (((uint64_t)shoe.d[r])<<32) | shoe.d[q];
|
||||
|
@ -239,13 +239,6 @@ void throw_privilege_violation()
|
||||
//printf("throw_privilege_violation(): I'm throwing a privilege violation exception! (shoe.orig_pc = 0x%08x op=0x%04x\n", shoe.orig_pc, shoe.op);
|
||||
|
||||
throw_frame_zero(shoe.orig_sr, shoe.orig_pc, 8);
|
||||
shoe.abort = 1;
|
||||
// shoe.abort = 1;
|
||||
|
||||
}
|
||||
|
||||
void throw_divide_by_zero()
|
||||
{
|
||||
printf("throw_divide_by_zero(): I'm throwing a divide-by-zero exception!\n");
|
||||
assert(0);
|
||||
shoe.abort = 1;
|
||||
}
|
@ -1374,7 +1374,7 @@ done:
|
||||
uint32_t size;
|
||||
char error_str[1024];
|
||||
|
||||
buf = extract_kernel(argv[1], argv[2], error_str, &size);
|
||||
buf = shoebill_extract_kernel(argv[1], argv[2], error_str, &size);
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
|
28
core/fpu.c
28
core/fpu.c
@ -1304,10 +1304,17 @@ void inst_fmath(uint16_t op, uint16_t ext)
|
||||
break;
|
||||
case ~b(0001000): assert(!"fpu_inst_fetoxm1;");
|
||||
case ~b(0001001): assert(!"fpu_inst_ftanh;");
|
||||
case ~b(0001010): assert(!"fpu_inst_fatan;");
|
||||
case ~b(0001010): // fatan
|
||||
printf("inst_fatan dest = %Lf source = %Lf\n", dest, source);
|
||||
result = atanl(source);
|
||||
break;
|
||||
|
||||
case ~b(0001100): assert(!"fpu_inst_fasin;");
|
||||
case ~b(0001101): assert(!"fpu_inst_fatanh;");
|
||||
case ~b(0001110): assert(!"fpu_inst_fsin;");
|
||||
case ~b(0001110): // fsin
|
||||
printf("inst_fsin dest = %Lf source = %Lf\n", dest, source);
|
||||
result = sinl(source);
|
||||
break;
|
||||
case ~b(0001111): assert(!"fpu_inst_ftan;");
|
||||
case ~b(0010000): // fetox
|
||||
printf("inst_fetox dest = %Lf source = %Lf\n", dest, source);
|
||||
@ -1320,7 +1327,11 @@ void inst_fmath(uint16_t op, uint16_t ext)
|
||||
case ~b(0010110): assert(!"fpu_inst_flog2;");
|
||||
case ~b(0011001): assert(!"fpu_inst_fcosh;");
|
||||
case ~b(0011100): assert(!"fpu_inst_facos;");
|
||||
case ~b(0011101): assert(!"fpu_inst_fcos;");
|
||||
case ~b(0011101): // fcos
|
||||
printf("fpu_inst_fcos dest = %Lf source = %Lf\n", dest, source);
|
||||
result = cosl(source);
|
||||
break;
|
||||
|
||||
case ~b(0011110): assert(!"fpu_inst_fgetexp;");
|
||||
case ~b(0011111): assert(!"fpu_inst_fgetman;");
|
||||
case ~b(0100001):
|
||||
@ -1380,10 +1391,13 @@ void inst_fmath(uint16_t op, uint16_t ext)
|
||||
break;
|
||||
}
|
||||
|
||||
case ~b(0011010):
|
||||
case ~b(1011010):
|
||||
case ~b(1011110):
|
||||
assert(!"fpu_inst_fneg;");
|
||||
assert(!"fneg: can't handle");
|
||||
case ~b(0011010): // fneg
|
||||
printf("inst_fneg dest = %Lf source = %Lf\n", dest, source);
|
||||
result = -source;
|
||||
break;
|
||||
|
||||
case ~b(1000001):
|
||||
case ~b(1000101):
|
||||
@ -1458,6 +1472,10 @@ void fpu_setup_jump_table()
|
||||
fpu_inst_fsqrt,
|
||||
fpu_inst_flognp1,
|
||||
fpu_inst_fetox,
|
||||
fpu_inst_fsin,
|
||||
fpu_inst_fcos,
|
||||
fpu_inst_fneg,
|
||||
fpu_inst_fatan,
|
||||
};
|
||||
|
||||
const fpu_inst_name_t dyadic[] = {
|
||||
|
128
core/video.c
128
core/video.c
@ -26,7 +26,6 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <GLUT/glut.h>
|
||||
#include "shoebill.h"
|
||||
#include "core_api.h"
|
||||
|
||||
@ -56,85 +55,6 @@ typedef struct __attribute__ ((__packed__)) {
|
||||
uint32_t plane_bytes;
|
||||
} video_params_t;
|
||||
|
||||
/*void nubus_video_display_func (void)
|
||||
{
|
||||
uint32_t myw = glutGet(GLUT_WINDOW_WIDTH);
|
||||
uint32_t myh = glutGet(GLUT_WINDOW_HEIGHT);
|
||||
uint32_t slotnum, i;
|
||||
int32_t my_window_id = glutGetWindow();
|
||||
|
||||
for (slotnum = 0; slotnum < 16; slotnum++)
|
||||
if (shoe.slots[slotnum].glut_window_id == my_window_id)
|
||||
break;
|
||||
|
||||
video_ctx_t *ctx = (video_ctx_t*)shoe.slots[slotnum].ctx;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, myw, 0, myh, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glColor3f(0.1, 0.1, 0.8);
|
||||
|
||||
uint32_t gli = 0;
|
||||
|
||||
switch (ctx->depth) {
|
||||
case 1: {
|
||||
for (i=0; i < ctx->pixels/8; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 8 + 0] = ctx->clut[(byte >> 7) & 1];
|
||||
ctx->direct_buf[i * 8 + 1] = ctx->clut[(byte >> 6) & 1];
|
||||
ctx->direct_buf[i * 8 + 2] = ctx->clut[(byte >> 5) & 1];
|
||||
ctx->direct_buf[i * 8 + 3] = ctx->clut[(byte >> 4) & 1];
|
||||
ctx->direct_buf[i * 8 + 4] = ctx->clut[(byte >> 3) & 1];
|
||||
ctx->direct_buf[i * 8 + 5] = ctx->clut[(byte >> 2) & 1];
|
||||
ctx->direct_buf[i * 8 + 6] = ctx->clut[(byte >> 1) & 1];
|
||||
ctx->direct_buf[i * 8 + 7] = ctx->clut[(byte >> 0) & 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
for (i=0; i < ctx->pixels/4; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 4 + 0] = ctx->clut[(byte >> 6) & 3];
|
||||
ctx->direct_buf[i * 4 + 1] = ctx->clut[(byte >> 4) & 3];
|
||||
ctx->direct_buf[i * 4 + 2] = ctx->clut[(byte >> 2) & 3];
|
||||
ctx->direct_buf[i * 4 + 3] = ctx->clut[(byte >> 0) & 3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
for (i=0; i < ctx->pixels/2; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 2 + 0] = ctx->clut[(byte >> 4) & 0xf];
|
||||
ctx->direct_buf[i * 2 + 1] = ctx->clut[(byte >> 0) & 0xf];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
for (i=0; i < ctx->pixels; i++)
|
||||
ctx->direct_buf[i] = ctx->clut[ctx->indexed_buf[i]];
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(!"unknown depth");
|
||||
}
|
||||
|
||||
glViewport(0, 0, myw, myh);
|
||||
glRasterPos2i(0, myh);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glPixelZoom(1.0, -1.0);
|
||||
|
||||
glDrawPixels(myw, myh, GL_RGBA, GL_UNSIGNED_BYTE, ctx->direct_buf);
|
||||
|
||||
glFlush();
|
||||
}*/
|
||||
|
||||
uint32_t compute_nubus_crc(uint8_t *rom, uint32_t len)
|
||||
{
|
||||
uint32_t i, sum = 0;
|
||||
@ -156,6 +76,15 @@ uint32_t compute_nubus_crc(uint8_t *rom, uint32_t len)
|
||||
return sum;
|
||||
}
|
||||
|
||||
static void _switch_depth(shoebill_card_video_t *ctx, uint32_t depth)
|
||||
{
|
||||
ctx->depth = depth;
|
||||
if (depth > 8)
|
||||
ctx->cur_buf = (uint8_t*)ctx->direct_buf;
|
||||
else
|
||||
ctx->cur_buf = ctx->indexed_buf;
|
||||
}
|
||||
|
||||
void nubus_video_init(void *_ctx, uint8_t slotnum,
|
||||
uint16_t width, uint16_t height, uint16_t scanline_width,
|
||||
double refresh_rate)
|
||||
@ -172,7 +101,7 @@ void nubus_video_init(void *_ctx, uint8_t slotnum,
|
||||
ctx->rom = malloc(4096);
|
||||
|
||||
// Set the depth and clut for B&W
|
||||
ctx->depth = 1;
|
||||
_switch_depth(ctx, 1);
|
||||
bzero(ctx->clut, 256 * 4);
|
||||
ctx->clut[0].r = 0xff;
|
||||
ctx->clut[0].g = 0xff;
|
||||
@ -199,6 +128,14 @@ void nubus_video_init(void *_ctx, uint8_t slotnum,
|
||||
params[3].right = htons(width);
|
||||
params[3].bottom = htons(height);
|
||||
|
||||
/*params[4].line_width = htons(scanline_width * 2);
|
||||
params[4].right = htons(width);
|
||||
params[4].bottom = htons(height);
|
||||
|
||||
params[5].line_width = htons(scanline_width * 4);
|
||||
params[5].right = htons(width);
|
||||
params[5].bottom = htons(height);*/
|
||||
|
||||
// Recompute the rom crc
|
||||
compute_nubus_crc(ctx->rom, 4096);
|
||||
|
||||
@ -274,8 +211,30 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size,
|
||||
break;
|
||||
}
|
||||
case 1: { // Set depth
|
||||
const uint32_t depth = 1 << (data - 128); // FIXME: this won't work for direct mode
|
||||
ctx->depth = depth;
|
||||
uint32_t newdepth;
|
||||
switch (data) {
|
||||
case 128:
|
||||
newdepth = 1;
|
||||
break;
|
||||
case 129:
|
||||
newdepth = 2;
|
||||
break;
|
||||
case 130:
|
||||
newdepth = 4;
|
||||
break;
|
||||
case 131:
|
||||
newdepth = 8;
|
||||
break;
|
||||
case 132:
|
||||
newdepth = 16;
|
||||
break;
|
||||
case 133:
|
||||
newdepth = 32;
|
||||
break;
|
||||
default:
|
||||
assert(!"driver tried to set bogus depth");
|
||||
}
|
||||
_switch_depth(ctx, newdepth);
|
||||
printf("nubus_magic: set depth = %u\n", ctx->depth);
|
||||
break;
|
||||
}
|
||||
@ -312,13 +271,14 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size,
|
||||
}
|
||||
|
||||
// Else, this is video ram
|
||||
// uint32_t i, myaddr = addr % ctx->indexed_buf_len, mydata = data;
|
||||
|
||||
uint32_t myaddr, mydata;
|
||||
for (myaddr = addr + size, mydata = data; addr < myaddr; ) {
|
||||
// assert(myaddr < ctx->pixels)
|
||||
ctx->indexed_buf[(--myaddr) % ctx->pixels] = mydata & 0xff;
|
||||
mydata >>= 8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user