Merge branch 'master' of github.com:sehugg/8bitworkshop

This commit is contained in:
Steven Hugg 2018-05-25 14:11:32 -07:00
commit 4a8380b730
9 changed files with 270 additions and 39 deletions

View File

@ -21,3 +21,7 @@ archive:
git archive --prefix 8bitworkshop- -o release/8bitworkshop-tools.zip HEAD tools
web:
ifconfig | grep inet
python2 -m SimpleHTTPServer 2>> http.out

View File

@ -60,14 +60,6 @@ div.editor {
line-height:1.25;
font-size:12pt;
}
div.emulator {
position:absolute;
left:50%;
top:0;
width:50%;
background-color: #666;
margin-top: 20px auto 0;
}
div.debugwindow {
position:absolute;
left:50%;
@ -98,6 +90,9 @@ div.mem_info {
margin-left:8px;
background-color: #666;
}
.btn_label {
color: #ccc;
}
.btn_group.debug_group {
}
.btn_group.view_group {
@ -189,22 +184,30 @@ a.dropdown-toggle {
-moz-border-radius:6px 0 6px 6px;
border-radius:6px 0 6px 6px;
}
div.emulator {
position:absolute;
left:50%;
top:0;
width:50%;
background-color: #666;
margin-top: 20px auto 0;
height:100%;
}
.emubevel {
width:100%;
height:100%;
padding:4%;
padding:5%;
background:#333;
}
.emuvideo {
border-radius:20px;
border: 4px solid #222;
padding: 30px;
margin-top: 20px;
margin-bottom: 20px;
margin-top: 10px;
margin-bottom: 10px;
background: #000;
outline-color: #666;
width: 100%;
height: 100%;
}
canvas.pixelated {
image-rendering: optimizeSpeed; /* Older versions of FF */

View File

@ -39,10 +39,11 @@ ga('send', 'pageview');
&#9776; <span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="#" id="item_new_file">New File...</a></li>
<li><a class="dropdown-item" href="#" id="item_new_file">New File...</a></li>
<li><a class="dropdown-item" href="#" id="item_share_file">Share File as GitHub Gist...</a></li>
<li><a class="dropdown-item" href="#" id="item_reset_file">Revert to Original...</a></li>
<li><a class="dropdown-item" href="#" id="item_download_rom">Download ROM Image...</a></li>
<li><a class="dropdown-item" href="#" id="item_download_file">Download File</a></li>
<li><a class="dropdown-item" href="#" id="item_download_rom">Download ROM Image</a></li>
<li><a class="dropdown-item" href="#" id="item_record_video">Record Video...</a></li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Debug</a>
@ -50,6 +51,12 @@ ga('send', 'pageview');
<li><a class="dropdown-item" href="#" id="item_debug_expr">Break Expression...</a></li>
</ul>
</li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Options</a>
<ul class="dropdown-menu">
<li><i id="item_low_power_check" style="display:hidden" class="fa fa-check"></i><a class="dropdown-item" href="#" id="item_low_power">Low Power Mode</a></li>
</ul>
</li>
<hr>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Platform</a>
@ -82,7 +89,7 @@ ga('send', 'pageview');
<span class="btn_group view_group" id="speed_bar" style="display:none">
<button id="dbg_slowest" type="submit" title="Slowest"><span class="glyphicon glyphicon-fast-backward" aria-hidden="true"></span></button>
<button id="dbg_slower" type="submit" title="Slower"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></button>
<span id="fps_label">60.00</span> fps
<span class="label"><span id="fps_label">60.00</span> fps</span>
<button id="dbg_faster" type="submit" title="Faster"><span class="glyphicon glyphicon-forward" aria-hidden="true"></span></button>
<button id="dbg_fastest" type="submit" title="Faster"><span class="glyphicon glyphicon-fast-forward" aria-hidden="true"></span></button>
</span>
@ -126,7 +133,7 @@ ga('send', 'pageview');
</div>
</div>
<div class="emulator" id="emulator">
<div style="margin:10px">
<div id="javatari-div" style="margin:10px; display:none">
<div id="javatari-screen" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
<div id="javatari-console-panel" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
</div>
@ -224,8 +231,10 @@ ga('send', 'pageview');
</script>
<script>
/*
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
if (!isFirefox && platform_id != 'vcs') { $("#best_in_firefox").show(); }
*/
</script>
</body>

View File

@ -19,8 +19,8 @@
mov ax,@$4ffe
mov dx,@ClearTiles
jsr dx
mov dx,@ClearSprites
jsr dx
mov ex,@ClearSprites
jsr ex
reset
InitPageTable:
mov ax,@$6000 ; screen buffer

151
presets/verilog/test2.asm Normal file
View File

@ -0,0 +1,151 @@
.include "hvsync_generator.v"
.include "font_cp437_8x8.v"
.include "ram.v"
.include "tile_renderer.v"
.include "sprite_scanline_renderer.v"
.include "lfsr.v"
.include "sound_generator.v"
.include "cpu16.v"
.include "cpu_platform.v"
.module cpu_platform
.arch femto16
.org 0x8000
.len 1024
jmp Start
Start:
mov sp,@$6fff
mov fx,@InitPageTable
jsr fx
mov ax,@$1ffe
mov fx,@ClearTiles
; jsr ex
mov fx,@DrawMaze
jsr fx
mov bx,@HelloWorld
mov cx,@$1f00
mov dx,@$6001
mov fx,@WriteString
jsr fx
mov fx,@ClearSprites
jsr fx
reset
WriteString:
mov ax,[bx]
bz StringDone
xor ax,cx
mov [dx],ax
inc bx
inc dx
jmp WriteString
StringDone:
rts
DrawMaze:
mov dx,@$6040
mov bx,@MazeData
DrawMazeLoop:
mov ax,[bx]
inc bx
mov fx,#4
ShiftMazeChar:
; rotate high 4 bits to low 4 bits
asl ax
rol ax
rol ax
rol ax
mov ex,ax
and ax,#7
adc ax,ex
; lookup character in table
mov ex,ax
and ex,#$f
add ex,@MazeChars
mov ex,[ex]
or ex,@$1e00
; store to video buffer
mov [dx],ex
inc dx
dec fx
bnz ShiftMazeChar
mov ax,dx
sub ax,@$6340
bnz DrawMazeLoop
rts
InitPageTable:
mov ax,@$6000 ; screen buffer
mov bx,@$7e00 ; page table start
mov cx,#32 ; 32 rows
InitPTLoop:
mov [bx],ax
add ax,#32
inc bx
dec cx
bnz InitPTLoop
rts
ClearTiles:
mov bx,@$6000
mov cx,@$3c0
ClearLoop:
mov [bx],ax
inc bx
dec cx
bnz ClearLoop
rts
ClearSprites:
mov bx,@$7f00
mov ax,#0
mov cx,#$40
ClearSLoop:
mov ax,[bx]
add ax,@$101
mov [bx],ax
inc bx
dec cx
bnz ClearSLoop
HelloWorld:
.string HELLO WORLD
.data 0
MazeData:
.data $3111 $1111 $1111 $1114 $3111 $1111 $1111 $1114
.data $2000 $0000 $0000 $0002 $2000 $0000 $0000 $0002
.data $2031 $1114 $0311 $1402 $2031 $1140 $0311 $1402
.data $2051 $1116 $0511 $1605 $6051 $1160 $0511 $1602
.data $2000 $0000 $0000 $0000 $0000 $0000 $0000 $0002
.data $2031 $1114 $0340 $3111 $1114 $0340 $0311 $1402
.data $2051 $1116 $0220 $5114 $3116 $0220 $0511 $1602
.data $2000 $0000 $0220 $0002 $2000 $0220 $0000 $0002
.data $5111 $1114 $0251 $1402 $2031 $1620 $3111 $1116
.data $3111 $1116 $0231 $1605 $6051 $1420 $5111 $1114
.data $2000 $0000 $0220 $0000 $0000 $0220 $0000 $0002
.data $2031 $1114 $0220 $3111 $1114 $0220 $0311 $1402
.data $2051 $1116 $0560 $2ccc $ccc2 $0560 $0511 $1602
.data $2000 $0000 $0000 $2ccc $ccc2 $0000 $0000 $0002
.data $5111 $1114 $0340 $2ccc $ccc2 $0340 $0311 $1116
.data $3111 $1116 $0220 $5111 $1116 $0220 $0511 $1114
.data $2000 $0000 $0220 $0000 $0000 $0220 $0000 $0002
.data $2031 $1114 $0251 $1403 $4031 $1620 $0311 $1402
.data $2051 $1116 $0511 $1605 $6051 $1160 $0511 $1602
.data $2000 $0000 $0000 $0000 $0000 $0000 $0000 $0002
.data $2031 $1114 $0311 $1403 $4031 $1140 $0311 $1402
.data $2051 $1116 $0511 $1602 $2051 $1160 $0511 $1602
.data $2000 $0000 $0000 $0002 $2000 $0000 $0000 $0002
.data $5111 $1111 $1111 $1116 $5111 $1111 $1111 $1116
MazeChars:
.data $f9 ; empty
.data $c4 $b3 ; horizvert
.data $da $bf $c0 $d9 ; corners
.data $c3 $c1 $c2 $b4 ; 3-way
.data $c5 ; 4-way
.data $20 ; empty (no dot)
.data 123 $123
.align $10

View File

@ -44,6 +44,7 @@ var VCSPlatform = function() {
this.getPresets = function() { return VCS_PRESETS; }
this.start = function() {
$("#javatari-div").show();
Javatari.start();
}

View File

@ -372,6 +372,11 @@ function _downloadROMImage(e) {
saveAs(blob, getCurrentFilename()+".rom");
}
function _downloadSourceFile(e) {
var blob = new Blob([editor.getValue()], {type: "text/plain;charset=utf-8"});
saveAs(blob, getCurrentFilename());
}
function populateExamples(sel) {
sel.append($("<option />").text("--------- Examples ---------").attr('disabled',true));
for (var i=0; i<PRESETS.length; i++) {
@ -1312,6 +1317,7 @@ function setupDebugControls(){
else
$("#item_debug_expr").hide();
$("#item_download_rom").click(_downloadROMImage);
$("#item_download_file").click(_downloadSourceFile);
$("#item_record_video").click(_recordVideo);
if (platform.setFrameRate && platform.getFrameRate) {
$("#speed_bar").show();

View File

@ -110,6 +110,39 @@ var Assembler = function(spec) {
outwords[ip++ - origin] = (op >> (nb-1-i)*width) & ((1<<width)-1);
}
}
function addWords(data) {
asmlines.push({
line:linenum,
offset:ip,
nbits:width*data.length
});
for (var i=0; i<data.length; i++) {
outwords[ip++ - origin] = data[i];
}
}
function parseData(toks) {
var data = [];
for (var i=0; i<toks.length; i++) {
data[i] = parseConst(toks[i]);
}
return data;
}
function stringToData(s) {
var data = [];
for (var i=0; i<s.length; i++) {
data[i] = s.charCodeAt(i);
}
return data;
}
function alignIP(align) {
if (align < 1 || align > codelen)
fatal("Invalid alignment value");
else
ip = Math.floor((ip+align-1)/align)*align;
}
function parseConst(s, nbits) {
// TODO: check bit length
@ -124,24 +157,30 @@ var Assembler = function(spec) {
self.buildInstruction = function(rule, m) {
var opcode = 0;
var oplen = 0;
// iterate over each component of the rule output ("bits")
for (var i=0; i<rule.bits.length; i++) {
var b = rule.bits[i];
var n,x;
// is a string? then it's a bit constant
// TODO
if (b.length) {
n = b.length;
x = parseInt(b,2);
} else {
// it's an indexed variable, look up its variable
var id = m[b+1];
var v = spec.vars[rule.varlist[b]];
if (!v) {
return {error:"Could not find matching identifier for '" + m[0] + "'"};
}
n = v.bits;
// is it an enumerated type? look up the index of its keyword
if (v.toks) {
x = v.toks.indexOf(id);
if (x < 0)
return null;
} else {
// otherwise, parse it as a constant
x = parseConst(id, n);
// is it a label? add fixup
if (isNaN(x)) {
@ -158,14 +197,16 @@ var Assembler = function(spec) {
}
if (oplen == 0)
warning("Opcode had zero length");
else if (oplen > 32)
warning("Opcodes > 32 bits not supported");
else if ((oplen % width) != 0)
warning("Opcode was not word-aligned (" + oplen + " bits)");
return {opcode:opcode, nbits:oplen};
}
self.loadArch = function(arch) {
if (self.loadFile) {
var json = self.loadFile(arch + ".json");
if (self.loadJSON) {
var json = self.loadJSON(arch + ".json");
if (json && json.vars && json.rules) {
spec = json;
preprocessRules();
@ -176,20 +217,27 @@ var Assembler = function(spec) {
}
function parseDirective(tokens) {
if (tokens[0] == '.define')
symbols[tokens[1]] = {value:tokens[2]};
else if (tokens[0] == '.org')
var cmd = tokens[0].toLowerCase();
if (cmd == '.define')
symbols[tokens[1].toLowerCase()] = {value:tokens[2]};
else if (cmd == '.org')
ip = origin = parseInt(tokens[1]);
else if (tokens[0] == '.len')
else if (cmd == '.len')
codelen = parseInt(tokens[1]);
else if (tokens[0] == '.width')
else if (cmd == '.width')
width = parseInt(tokens[1]);
else if (tokens[0] == '.arch')
else if (cmd == '.arch')
fatalIf(self.loadArch(tokens[1]));
else if (tokens[0] == '.include')
else if (cmd == '.include')
fatalIf(self.loadInclude(tokens[1]));
else if (tokens[0] == '.module')
else if (cmd == '.module')
fatalIf(self.loadModule(tokens[1]));
else if (cmd == '.data')
addWords(parseData(tokens.slice(1)));
else if (cmd == '.string')
addWords(stringToData(tokens.slice(1).join(' ')));
else if (cmd == '.align')
alignIP(parseConst(tokens[1]));
else
warning("Unrecognized directive: " + tokens);
}
@ -197,14 +245,15 @@ var Assembler = function(spec) {
self.assemble = function(line) {
linenum++;
// remove comments
line = line.replace(/[;].*/g, '');
line = line.trim().toLowerCase();
line = line.replace(/[;].*/g, '').trim();
// is it a directive?
if (line[0] == '.') {
var tokens = line.split(/\s+/);
parseDirective(tokens);
return;
}
// make it lowercase
line = line.toLowerCase();
// find labels
line = line.replace(/(\w+):/, function(_label, label) {
symbols[label] = {value:ip};
@ -274,7 +323,12 @@ var Assembler = function(spec) {
self.assembleFile = function(text) {
var lines = text.split(/\n/g);
for (var i=0; i<lines.length && !aborted; i++) {
self.assemble(lines[i]);
try {
self.assemble(lines[i]);
} catch (e) {
console.log(e);
fatal("Exception during assembly: " + e);
}
}
return self.finish();
}
@ -292,13 +346,16 @@ if (typeof module !== 'undefined' && require.main === module) {
var stdinBuffer = fs.readFileSync(0);
var code = stdinBuffer.toString();
var asm = new Assembler();
asm.loadFile = function(filename) {
return fs.readFileSync(filename, 'utf8');
asm.loadJSON = function(filename) {
return JSON.parse(fs.readFileSync(filename, 'utf8'));
};
asm.loadInclude = function(filename) {
filename = filename.substr(1, filename.length-2); // remove quotes
//return fs.readFileSync(filename, 'utf8');
};
asm.loadModule = function(top_module) {
//TODO
};
var out = asm.assembleFile(code);
if (out.errors) {
console.log(out.errors);
} else {
console.log(out.outwords);
}
console.log(out);
}

View File

@ -1126,7 +1126,7 @@ function compileJSASM(asmcode, platform, options, is_inline) {
load("assembler");
var asm = new Assembler();
var includes = [];
asm.loadFile = function(filename) {
asm.loadJSON = function(filename) {
// TODO: what if it comes from dependencies?
var path = '../../presets/' + platform + '/' + filename;
var xhr = new XMLHttpRequest();