mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-09-28 15:54:40 +00:00
assembler: added .string .data .align
This commit is contained in:
parent
f0591ef7c4
commit
09fb489c2d
@ -26,6 +26,7 @@
|
|||||||
{"fmt":"rts", "bits":["01001","111","00001","110"]},
|
{"fmt":"rts", "bits":["01001","111","00001","110"]},
|
||||||
{"fmt":"jsr ~reg", "bits":["01110","111","00",0,"110"]},
|
{"fmt":"jsr ~reg", "bits":["01110","111","00",0,"110"]},
|
||||||
{"fmt":"jsr ~imm16", "bits":["0001110001011000",0,"0111011100100110"]},
|
{"fmt":"jsr ~imm16", "bits":["0001110001011000",0,"0111011100100110"]},
|
||||||
|
{"fmt":"jmp ~imm16", "bits":["0001111101011000",0]},
|
||||||
|
|
||||||
{"fmt":"bcc ~rel8", "bits":["10000001",0]},
|
{"fmt":"bcc ~rel8", "bits":["10000001",0]},
|
||||||
{"fmt":"bcs ~rel8", "bits":["10001001",0]},
|
{"fmt":"bcs ~rel8", "bits":["10001001",0]},
|
||||||
|
151
presets/verilog/test2.asm
Normal file
151
presets/verilog/test2.asm
Normal 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
|
||||||
|
|
@ -110,6 +110,39 @@ var Assembler = function(spec) {
|
|||||||
outwords[ip++ - origin] = (op >> (nb-1-i)*width) & ((1<<width)-1);
|
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) {
|
function parseConst(s, nbits) {
|
||||||
// TODO: check bit length
|
// TODO: check bit length
|
||||||
@ -184,20 +217,27 @@ var Assembler = function(spec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseDirective(tokens) {
|
function parseDirective(tokens) {
|
||||||
if (tokens[0] == '.define')
|
var cmd = tokens[0].toLowerCase();
|
||||||
symbols[tokens[1]] = {value:tokens[2]};
|
if (cmd == '.define')
|
||||||
else if (tokens[0] == '.org')
|
symbols[tokens[1].toLowerCase()] = {value:tokens[2]};
|
||||||
|
else if (cmd == '.org')
|
||||||
ip = origin = parseInt(tokens[1]);
|
ip = origin = parseInt(tokens[1]);
|
||||||
else if (tokens[0] == '.len')
|
else if (cmd == '.len')
|
||||||
codelen = parseInt(tokens[1]);
|
codelen = parseInt(tokens[1]);
|
||||||
else if (tokens[0] == '.width')
|
else if (cmd == '.width')
|
||||||
width = parseInt(tokens[1]);
|
width = parseInt(tokens[1]);
|
||||||
else if (tokens[0] == '.arch')
|
else if (cmd == '.arch')
|
||||||
fatalIf(self.loadArch(tokens[1]));
|
fatalIf(self.loadArch(tokens[1]));
|
||||||
else if (tokens[0] == '.include')
|
else if (cmd == '.include')
|
||||||
fatalIf(self.loadInclude(tokens[1]));
|
fatalIf(self.loadInclude(tokens[1]));
|
||||||
else if (tokens[0] == '.module')
|
else if (cmd == '.module')
|
||||||
fatalIf(self.loadModule(tokens[1]));
|
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
|
else
|
||||||
warning("Unrecognized directive: " + tokens);
|
warning("Unrecognized directive: " + tokens);
|
||||||
}
|
}
|
||||||
@ -205,14 +245,15 @@ var Assembler = function(spec) {
|
|||||||
self.assemble = function(line) {
|
self.assemble = function(line) {
|
||||||
linenum++;
|
linenum++;
|
||||||
// remove comments
|
// remove comments
|
||||||
line = line.replace(/[;].*/g, '');
|
line = line.replace(/[;].*/g, '').trim();
|
||||||
line = line.trim().toLowerCase();
|
|
||||||
// is it a directive?
|
// is it a directive?
|
||||||
if (line[0] == '.') {
|
if (line[0] == '.') {
|
||||||
var tokens = line.split(/\s+/);
|
var tokens = line.split(/\s+/);
|
||||||
parseDirective(tokens);
|
parseDirective(tokens);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// make it lowercase
|
||||||
|
line = line.toLowerCase();
|
||||||
// find labels
|
// find labels
|
||||||
line = line.replace(/(\w+):/, function(_label, label) {
|
line = line.replace(/(\w+):/, function(_label, label) {
|
||||||
symbols[label] = {value:ip};
|
symbols[label] = {value:ip};
|
||||||
@ -282,7 +323,12 @@ var Assembler = function(spec) {
|
|||||||
self.assembleFile = function(text) {
|
self.assembleFile = function(text) {
|
||||||
var lines = text.split(/\n/g);
|
var lines = text.split(/\n/g);
|
||||||
for (var i=0; i<lines.length && !aborted; i++) {
|
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();
|
return self.finish();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user