1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-26 10:49:17 +00:00

distinction between include and link dependencies

This commit is contained in:
Steven Hugg 2018-08-03 14:06:08 -04:00
parent 7880602e81
commit cfb5f7f59d
8 changed files with 313 additions and 13 deletions

View File

@ -51,6 +51,7 @@ TODO:
- Revert loads cached files? - Revert loads cached files?
- Verilog compile spins forever? - Verilog compile spins forever?
- how to revert included files? - how to revert included files?
- go to error in include files
WEB WORKER FORMAT WEB WORKER FORMAT

141
presets/nes/ex2.asm Normal file
View File

@ -0,0 +1,141 @@
include "nesdefs.asm"
;;;;; ZERO-PAGE VARIABLES
seg.u Zeropage
org $0
ScrollPos byte ; used during NMI
Rand byte
Temp1 byte
SpriteBuf equ $200
NES_HEADER 0,2,1,0 ; mapper 0, 2 PRGs, 1 CHR, vertical
Start:
NES_INIT ; set up stack pointer, turn off PPU
jsr WaitSync
jsr WaitSync
jsr ClearRAM
jsr WaitSync ;wait for VSYNC
jsr SetPalette ;set colors
jsr FillVRAM ;set PPU RAM
jsr WaitSync ;wait for VSYNC (and PPU warmup)
jsr InitSprites
lda #0
sta PPU_ADDR
sta PPU_ADDR ;PPU addr = 0
sta PPU_SCROLL
sta PPU_SCROLL ;scroll = 0
lda #$90
sta PPU_CTRL ;enable NMI
lda #$1e
sta PPU_MASK ;enable rendering
.endless
jmp .endless ;endless loop
InitSprites: subroutine
lda #1
ldx #0
.loop
sta SpriteBuf,x
jsr NextRandom
inx
bne .loop
rts
MoveSprites: subroutine
lda #1
ldx #0
.loop
sta Temp1
lda Temp1
and #3
clc
adc SpriteBuf,x
sta SpriteBuf,x
lda Temp1
jsr NextRandom
inx
bne .loop
rts
; set palette colors
SetPalette: subroutine
ldy #$00
lda #$3f
sta PPU_ADDR
sty PPU_ADDR
ldx #32
.loop:
lda Palette,y
sta PPU_DATA
iny
dex
bne .loop
rts
;;;;; COMMON SUBROUTINES
include "nesppu.asm"
;;;;; INTERRUPT HANDLERS
NMIHandler:
; save registers
pha ; save A
; load sprites
lda #$02
sta PPU_OAM_DMA
; update scroll position (must be done after VRAM updates)
inc ScrollPos
lda ScrollPos
sta PPU_SCROLL
lda #0
sta PPU_SCROLL
; TODO: write high bits to PPUCTRL
lda ScrollPos
and #0
ora #$90 ; enable NMI
sta PPU_CTRL
; move sprites
jsr MoveSprites
; reload registers
pla ; reload A
rti
;;;;; CONSTANT DATA
align $100
Palette:
hex 1f ;background
hex 09091900 ;bg0
hex 09091900 ;bg1
hex 09091900 ;bg2
hex 09091900 ;bg3
hex 14243400 ;sp0
hex 15253500 ;sp1
hex 16263600 ;sp2
hex 17273700 ;sp3
;;;;; CPU VECTORS
NES_VECTORS
;;;;; TILE SETS
org $10000
REPEAT 64
hex 003c6666766e663c007e181818381818
hex 007e60300c06663c003c66061c06663c
hex 0006067f661e0e06003c6606067c607e
hex 003c66667c60663c00181818180c667e
hex 003c66663c66663c003c66063e66663c
hex 01010101010101010000000000000000
hex ff000000000000000000000000000000
hex 01020408102040800000000000000000
REPEND

64
presets/nes/nesdefs.asm Normal file
View File

@ -0,0 +1,64 @@
processor 6502
;;;;; CONSTANTS
PPU_CTRL equ $2000
PPU_MASK equ $2001
PPU_STATUS equ $2002
OAM_ADDR equ $2003
OAM_DATA equ $2004
PPU_SCROLL equ $2005
PPU_ADDR equ $2006
PPU_DATA equ $2007
PPU_OAM_DMA equ $4014
DMC_FREQ equ $4010
APU_STATUS equ $4015
;;;;; CARTRIDGE FILE HEADER
NES_MIRR_HORIZ equ 0
NES_MIRR_VERT equ 1
NES_MIRR_QUAD equ 8
MAC NES_HEADER
seg Header
org $7ff0
.NES_MAPPER SET {1} ;mapper number
.NES_PRG_BANKS SET {2} ;number of 16K PRG banks, change to 2 for NROM256
.NES_CHR_BANKS SET {3} ;number of 8K CHR banks (0 = RAM)
.NES_MIRRORING SET {4} ;0 horizontal, 1 vertical, 8 four screen
byte $4e,$45,$53,$1a ; header
byte .NES_PRG_BANKS
byte .NES_CHR_BANKS
byte .NES_MIRRORING|(.NES_MAPPER<<4)
byte .NES_MAPPER&$f0
byte 0,0,0,0,0,0,0,0 ; reserved, set to zero
seg Code
org $8000
ENDM
;;;;; NES_INIT SETUP MACRO (place at start)
MAC NES_INIT
sei ;disable IRQs
cld ;decimal mode not supported
ldx #$ff
txs ;set up stack pointer
inx ;increment X to 0
stx PPU_MASK ;disable rendering
stx DMC_FREQ ;disable DMC interrupts
stx PPU_CTRL ;disable NMI interrupts
bit PPU_STATUS ;clear VBL flag
ENDM
;;;;; NES_VECTORS - CPU vectors at end of address space
MAC NES_VECTORS
seg Vectors
org $fffa
.word NMIHandler ;$fffa vblank nmi
.word Start ;$fffc reset
.word NMIHandler ;$fffe irq / brk (not used)
ENDM

59
presets/nes/nesppu.asm Normal file
View File

@ -0,0 +1,59 @@
;;;;; SUBROUTINES
ClearRAM: subroutine
lda #0
tax
.clearRAM
sta $0,x
cpx #$fe ; don't clear last 2 bytes of stack
bcs .skipStack
sta $100,x
.skipStack
; skip $200-$2FF, used for OAM display list
sta $300,x
sta $400,x
sta $500,x
sta $600,x
sta $700,x
inx
bne .clearRAM
rts
; fill video RAM
FillVRAM: subroutine
txa
ldy #$20
sty PPU_ADDR
sta PPU_ADDR
ldy #$10
.loop:
sta PPU_DATA
adc #7
inx
bne .loop
dey
bne .loop
rts
; wait for VSYNC to start
WaitSync:
bit PPU_STATUS
bpl WaitSync
rts
;;;;; RANDOM NUMBERS
NextRandom subroutine
lsr
bcc .NoEor
eor #$d4
.NoEor:
rts
; Get previous random value
PrevRandom subroutine
asl
bcc .NoEor
eor #$a9
.NoEor:
rts

View File

@ -1,8 +1,9 @@
"use strict"; "use strict";
var JSNES_PRESETS = [ var JSNES_PRESETS = [
{id:'ex0.asm', name:'Initialization (ASM)'}, {id:'ex0.asm', name:'Initialization'},
{id:'ex1.asm', name:'Scrolling Demo (ASM)'}, {id:'ex1.asm', name:'Scrolling Demo'},
{id:'ex2.asm', name:'Sprite Demo'},
// {id:'hello.c', name:'C: Hello PPU'}, // {id:'hello.c', name:'C: Hello PPU'},
// {id:'conio.c', name:'C: Hello Console I/O'}, // {id:'conio.c', name:'C: Hello Console I/O'},
{id:'siegegame.c', name:'Siege Game (C)'}, {id:'siegegame.c', name:'Siege Game (C)'},

View File

@ -52,8 +52,7 @@ export class CodeProject {
} }
} }
// TODO: support link-time and compile-time (include) dependencies parseIncludeDependencies(text:string):string[] {
parseFileDependencies(text:string):string[] {
var files = []; var files = [];
if (this.platform_id == 'verilog') { if (this.platform_id == 'verilog') {
var re = /^\s*(`include|[.]include)\s+"(.+?)"/gm; var re = /^\s*(`include|[.]include)\s+"(.+?)"/gm;
@ -63,6 +62,21 @@ export class CodeProject {
//files.push('local/'+m[2]); // TODO: shows up 2x in interface //files.push('local/'+m[2]); // TODO: shows up 2x in interface
} }
} else { } else {
// for .asm -- [.]include "file"
var re2 = /^\s+([.]?include)\s+"(.+?)"/gm;
while (m = re2.exec(text)) {
files.push(m[2]);
}
}
return files;
}
parseLinkDependencies(text:string):string[] {
var files = [];
if (this.platform_id == 'verilog') {
//
} else {
// for .c -- //#link "file" (or ;link or #link)
var re = /^\s*([;#]|[/][/][#])link\s+"(.+?)"/gm; var re = /^\s*([;#]|[/][/][#])link\s+"(.+?)"/gm;
var m; var m;
while (m = re.exec(text)) { while (m = re.exec(text)) {
@ -73,8 +87,15 @@ export class CodeProject {
} }
loadFileDependencies(text:string, callback:LoadFilesCallback) { loadFileDependencies(text:string, callback:LoadFilesCallback) {
var paths = this.parseFileDependencies(text); var includes = this.parseIncludeDependencies(text);
this.loadFiles(paths, callback); var linkfiles = this.parseLinkDependencies(text);
var allfiles = includes.concat(linkfiles);
this.loadFiles(allfiles, (err:string, result?:Dependency[]) => {
if (result)
for (var dep of result)
dep.link = linkfiles.indexOf(dep.filename) >= 0;
callback(err, result);
});
} }
okToSend():boolean { okToSend():boolean {
@ -96,11 +117,17 @@ export class CodeProject {
// TODO: add preproc directive for __MAINFILE__ // TODO: add preproc directive for __MAINFILE__
var mainfilename = getFilenameForPath(this.mainpath); var mainfilename = getFilenameForPath(this.mainpath);
var maintext = this.getFile(this.mainpath); var maintext = this.getFile(this.mainpath);
var files = [mainfilename];
msg.updates.push({path:mainfilename, data:maintext}); msg.updates.push({path:mainfilename, data:maintext});
msg.buildsteps.push({path:mainfilename, platform:this.platform_id, tool:this.platform.getToolForFilename(this.mainpath), mainfile:true}); for (var dep of depends) {
for (var i=0; i<depends.length; i++) { if (!dep.link) {
var dep = depends[i]; msg.updates.push({path:dep.filename, data:dep.data});
if (dep.data) { files.push(dep.filename);
}
}
msg.buildsteps.push({path:mainfilename, files:files, platform:this.platform_id, tool:this.platform.getToolForFilename(this.mainpath), mainfile:true});
for (var dep of depends) {
if (dep.data && dep.link) {
this.preloadWorker(dep.filename); this.preloadWorker(dep.filename);
msg.updates.push({path:dep.filename, data:dep.data}); msg.updates.push({path:dep.filename, data:dep.data});
msg.buildsteps.push({path:dep.filename, platform:this.platform_id, tool:this.platform.getToolForFilename(dep.path)}); msg.buildsteps.push({path:dep.filename, platform:this.platform_id, tool:this.platform.getToolForFilename(dep.path)});
@ -116,6 +143,7 @@ export class CodeProject {
result.push({ result.push({
path:path, path:path,
filename:getFilenameForPath(path), filename:getFilenameForPath(path),
link:true,
data:data data:data
}); });
} }
@ -170,6 +198,7 @@ export class CodeProject {
return this.filedata[path]; return this.filedata[path];
} }
// TODO: purge files not included in latest build?
iterateFiles(callback:IterateFilesCallback) { iterateFiles(callback:IterateFilesCallback) {
for (var path in this.filedata) { for (var path in this.filedata) {
callback(path, this.getFile(path)); callback(path, this.getFile(path));

View File

@ -503,10 +503,13 @@ function assembleDASM(step) {
load("dasm"); load("dasm");
var re_usl = /(\w+)\s+0000\s+[?][?][?][?]/; var re_usl = /(\w+)\s+0000\s+[?][?][?][?]/;
var unresolved = {}; var unresolved = {};
var errors = [];
function match_fn(s) { function match_fn(s) {
var matches = re_usl.exec(s); var matches = re_usl.exec(s);
if (matches) { if (matches) {
unresolved[matches[1]] = 0; unresolved[matches[1]] = 0;
} else if (s.startsWith("Warning:")) {
errors.push({line:1, msg:s.substr(9)});
} }
} }
var Module = DASM({ var Module = DASM({
@ -523,8 +526,9 @@ function assembleDASM(step) {
execMain(step, Module, [step.path, "-l"+lstpath, "-o"+binpath, "-s"+sympath ]); execMain(step, Module, [step.path, "-l"+lstpath, "-o"+binpath, "-s"+sympath ]);
var alst = FS.readFile(lstpath, {'encoding':'utf8'}); var alst = FS.readFile(lstpath, {'encoding':'utf8'});
var listing = parseDASMListing(alst, unresolved, step.path); var listing = parseDASMListing(alst, unresolved, step.path);
if (listing.errors.length) { errors = errors.concat(listing.errors);
return {errors:listing.errors}; if (errors.length) {
return {errors:errors};
} }
var aout = FS.readFile(binpath); var aout = FS.readFile(binpath);
var asym = FS.readFile(lstpath, {'encoding':'utf8'}); var asym = FS.readFile(lstpath, {'encoding':'utf8'});
@ -547,7 +551,7 @@ function assembleDASM(step) {
return { return {
output:aout.slice(2), output:aout.slice(2),
listings:listings, listings:listings,
errors:listing.errors, errors:errors,
symbolmap:symbolmap, symbolmap:symbolmap,
intermediate:{listing:alst, symbols:asym}, intermediate:{listing:alst, symbols:asym},
}; };

View File

@ -45,6 +45,7 @@ export class SourceFile {
export interface Dependency { export interface Dependency {
path:string, path:string,
filename:string, filename:string,
link:boolean,
data:FileData // TODO: or binary? data:FileData // TODO: or binary?
} }