Skip to content

Instantly share code, notes, and snippets.

@jmpinit
Last active December 26, 2015 09:39
Show Gist options
  • Save jmpinit/7130857 to your computer and use it in GitHub Desktop.
Save jmpinit/7130857 to your computer and use it in GitHub Desktop.
Modify bsim 2.0.0 from MIT's Computation Structures (6.004) class to add video out.
$(".tty").prepend( '<div style="float: right;"><canvas id="television" width="192" height="128" style="background-color: lightblue;">xbetahack ERROR: html5 canvas is missing.</canvas></div>');
bhack = {
tv: {
canvas: null,
width: 96,
height: 64,
pos: 0,
fill: function(col) {
var c = bhack.tv.canvas;
var ctx = c.getContext("2d");
ctx.fillStyle = col;
ctx.fillRect(0, 0, c.width, c.height);
},
clear: function() {
bhack.tv.fill("#FFF");
bhack.tv.pos = 0;
},
set_pos: function(newpos) { bhack.tv.pos = newpos % (bhack.tv.width * bhack.tv.height); },
out: function(color) {
var tv = bhack.tv;
var c = tv.canvas;
var ctx = c.getContext("2d");
var style = tv.palette[color];
if(style) {
ctx.fillStyle = style;
var x = tv.pos % tv.width;
var xs = c.width/tv.width;
var y = Math.floor(tv.pos / tv.width);
var ys = c.height/tv.height;
ctx.fillRect(x * xs, y * ys, xs, ys);
}
tv.pos += 1;
tv.pos = tv.pos % (tv.width * tv.height);
},
palette: [
"rgb(124,124,124)",
"rgb(0,0,252)",
"rgb(0,0,188)",
"rgb(68,40,188)",
"rgb(148,0,132)",
"rgb(168,0,32)",
"rgb(168,16,0)",
"rgb(136,20,0)",
"rgb(80,48,0)",
"rgb(0,120,0)",
"rgb(0,104,0)",
"rgb(0,88,0)",
"rgb(0,64,88)",
"rgb(0,0,0)",
"rgb(0,0,0)",
"rgb(0,0,0)",
"rgb(188,188,188)",
"rgb(0,120,248)",
"rgb(0,88,248)",
"rgb(104,68,252)",
"rgb(216,0,204)",
"rgb(228,0,88)",
"rgb(248,56,0)",
"rgb(228,92,16)",
"rgb(172,124,0)",
"rgb(0,184,0)",
"rgb(0,168,0)",
"rgb(0,168,68)",
"rgb(0,136,136)",
"rgb(0,0,0)",
"rgb(0,0,0)",
"rgb(0,0,0)",
"rgb(248,248,248)",
"rgb(60,188,252)",
"rgb(104,136,252)",
"rgb(152,120,248)",
"rgb(248,120,248)",
"rgb(248,88,152)",
"rgb(248,120,88)",
"rgb(252,160,68)",
"rgb(248,184,0)",
"rgb(184,248,24)",
"rgb(88,216,84)",
"rgb(88,248,152)",
"rgb(0,232,216)",
"rgb(120,120,120)",
"rgb(0,0,0)",
"rgb(0,0,0)",
"rgb(252,252,252)",
"rgb(164,228,252)",
"rgb(184,184,248)",
"rgb(216,184,248)",
"rgb(248,184,248)",
"rgb(248,164,192)",
"rgb(240,208,176)",
"rgb(252,224,168)",
"rgb(248,216,120)",
"rgb(216,248,120)",
"rgb(184,248,184)",
"rgb(184,248,216)",
"rgb(0,252,252)",
"rgb(216,216,216)",
"rgb(0,0,0)",
"rgb(0,0,0)"
]
}
}
bhack.tv.canvas = $("#television")[0];
bhack.tv.fill("#FFF");
var x = BSim.Beta.Opcodes[0x00].exec;
BSim.Beta.Opcodes[0x00].exec = function PRIV_OP_MOD(a, literal, c) {
switch(literal) {
case 99: // clear
bhack.tv.clear();
break;
case 100: // set pos
bhack.tv.set_pos(this.readRegister(a));
break;
case 101: // put byte
bhack.tv.out(this.readRegister(a));
break;
default:
x(a, literal, c);
}
}
.include "/shared/bsim/beta.uasm" // include instruction macros
// TELEVISION
.macro TV_CLEAR() PRIV_OP (99)
.macro TV_POS() PRIV_OP (100)
.macro TV_OUT() PRIV_OP (101)
// MACROS
.macro DEC(R) SUBC(R, 1, R)
.macro INC(R) ADDC(R, 1, R)
// INTERRUPTS
. = VEC_RESET
BR(int_reset)
// MAIN
. = 20
int_reset:
BR(__start)
__start:
LDR(stack_base, SP) // setup stack
// setup tv
TV_CLEAR()
BR(draw_mario, LP) // draw our hero
__halt: HALT()
BR(__halt)
pixel_i = R6
line = R7
line_i = R8
line_ptr = R9
color = R10
color_i = R11
color_ptr = R12
draw_mario:
color_loop_init:
CMOVE(0, color_i)
color_loop:
// lookup color
MOVE(color_i, R0)
MULC(R0, 4, R0)
ADDC(R0, mario_colors, R0)
LD(R0, 0, color)
// set bitmap pointer
MULC(color_i, 16*4, color_ptr)
ADDC(color_ptr, mario_bitmap, color_ptr)
MOVE(color_ptr, line_ptr)
line_loop_init:
CMOVE(0, line_i)
line_loop:
// get line
LD(line_ptr, 0, line)
// if line is zero, skip it
BEQ(line, line_loop_end, R31)
pixel_loop_init:
CMOVE(0, pixel_i)
pixel_loop:
// get pixel
SHLC(line, 1, line)
ANDC(line, 0x800, R0)
SHRC(R0, 11, R0)
BEQ(R0, pixel_alpha, R31)
pixel_colored:
MOVE(color, R0)
BR(pixel_out)
pixel_alpha:
CMOVE(0, R0)
SUBC(R0, 1, R0)
pixel_out:
TV_OUT()
pixel_loop_end:
INC(pixel_i)
CMPEQC(pixel_i, 12, R0)
BEQ(R0, pixel_loop)
line_loop_end:
// go to next line in mem
ADDC(line_ptr, 4, line_ptr)
// put tv on next line
SUB(line_ptr, color_ptr, R0)
MULC(R0, 96/4, R0)
TV_POS()
INC(line_i)
CMPEQC(line_i, 16, R0)
BEQ(R0, line_loop)
color_loop_end:
INC(color_i)
CMPEQC(color_i, 3, R0)
BEQ(R0, color_loop)
RTN()
mario_colors:
LONG(0x16) // NES red
LONG(0x09) // NES green
LONG(0x38) // NES yellow
mario_bitmap:
mario_red:
LONG(0x1f0)
LONG(0x3fe)
LONG(0x0)
LONG(0x0)
LONG(0x0)
LONG(0x0)
LONG(0x0)
LONG(0x80)
LONG(0x90)
LONG(0xf0)
LONG(0x168)
LONG(0x1f8)
LONG(0x3fc)
LONG(0x39c)
LONG(0x0)
LONG(0x0)
mario_green:
LONG(0x0)
LONG(0x0)
LONG(0x390)
LONG(0x510)
LONG(0x588)
LONG(0x61e)
LONG(0x0)
LONG(0x370)
LONG(0x76e)
LONG(0xf0f)
LONG(0x204)
LONG(0x0)
LONG(0x0)
LONG(0x0)
LONG(0x70e)
LONG(0xf0f)
mario_yellow:
LONG(0x0)
LONG(0x0)
LONG(0x68)
LONG(0x2ee)
LONG(0x277)
LONG(0x1e0)
LONG(0x1fc)
LONG(0x0)
LONG(0x0)
LONG(0x0)
LONG(0xc93)
LONG(0xe07)
LONG(0xc03)
LONG(0x0)
LONG(0x0)
LONG(0x0)
stack_base:
LONG(.+4) // Pointer to bottom of stack
. = .+0x1000 // Reserve space for stack
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment