1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-06 09:29:33 +00:00

nes: fixed binary GET for Firefox, DASM errors, disassembler

This commit is contained in:
Steven Hugg 2019-03-02 17:15:03 -06:00
parent a243044ed5
commit ce019b5632
9 changed files with 87 additions and 66 deletions

View File

@ -13,17 +13,19 @@
;;;;; START OF CODE
Start:
; wait for PPU warmup; clear CPU RAM
NES_INIT ; set up stack pointer, turn off PPU
jsr WaitSync ; wait for VSYNC
jsr ClearRAM ; clear RAM
jsr WaitSync ; wait for VSYNC (and PPU warmup)
; set palette
lda #$3f ; $3F -> A register
sta PPU_ADDR ; write high byte first
lda #$00 ; $00 -> A register
sta PPU_ADDR ; $3F00 -> PPU address
lda #$1c ; $1C = light blue color
sta PPU_DATA ; $1C -> PPU data
; activate PPU graphics
lda #CTRL_NMI
sta PPU_CTRL ; enable NMI
lda #MASK_COLOR

View File

@ -13,17 +13,21 @@
;;;;; START OF CODE
Start:
; wait for PPU warmup; clear CPU RAM
NES_INIT ; set up stack pointer, turn off PPU
jsr WaitSync ; wait for VSYNC
jsr ClearRAM ; clear RAM
jsr WaitSync ; wait for VSYNC (and PPU warmup)
; set palette and nametable VRAM
jsr SetPalette ; set palette colors
jsr HelloVRAM ; set PPU video RAM
jsr HelloVRAM ; print message in name table
; reset PPU address and scroll registers
lda #0
sta PPU_ADDR
sta PPU_ADDR ; PPU addr = $0000
sta PPU_SCROLL
sta PPU_SCROLL ; scroll = $0000
sta PPU_SCROLL ; PPU scroll = $0000
; activate PPU graphics
lda #CTRL_NMI
sta PPU_CTRL ; enable NMI
lda #MASK_BG
@ -88,4 +92,3 @@ Palette:
org $10000
incbin "jroatch.chr"

View File

@ -15,18 +15,21 @@ ScrollPos word ; used during NMI
;;;;; START OF CODE
Start:
; wait for PPU warmup; clear CPU RAM
NES_INIT ; set up stack pointer, turn off PPU
jsr WaitSync ; wait for VSYNC
jsr ClearRAM ; clear RAM
jsr WaitSync ; wait for VSYNC (and PPU warmup)
; set palette and nametable VRAM
jsr SetPalette ; set palette colors
jsr FillVRAM ; set PPU video RAM
; reset PPU address and scroll registers
lda #0
sta PPU_ADDR
sta PPU_ADDR ; PPU addr = $0000
sta PPU_SCROLL
sta PPU_SCROLL ; scroll = $0000
; activate PPU graphics
lda #CTRL_NMI
sta PPU_CTRL ; enable NMI
lda #MASK_BG
@ -41,7 +44,7 @@ FillVRAM: subroutine
.loop:
tya ; Y -> A
ora #$40 ; A = A OR $40
sta PPU_DATA ; X -> PPU data port
sta PPU_DATA ; A -> PPU data port
inx ; X = X + 1
bne .loop ; repeat until 256 bytes
dey ; Y = Y - 1

View File

@ -43,55 +43,53 @@ Start:
; fill video RAM
FillVRAM: subroutine
PPU_SETADDR $2000
PPU_SETADDR $2000
ldy #$10
.loop:
stx PPU_DATA
inx
bne .loop
dey
bne .loop
rts
stx PPU_DATA ; X -> PPU data port
inx ; X = X + 1
bne .loop ; repeat until 256 bytes
dey ; Y = Y - 1
bne .loop ; repeat until Y is 0
rts ; return to caller
;
; initialize OAM data
InitSprites: subroutine
lda #1
ldx #0
lda #1 ; A = 1
ldx #0 ; X = 0
.loop
sta SpriteBuf,x
jsr NextRandom
inx
bne .loop
rts
sta SpriteBuf,x ; store to OAM buffer
jsr NextRandom ; get next random number
inx ; X = X + 1
bne .loop ; loop until X wraps
rts ; return to caller
;
; move sprite data
MoveSprites: subroutine
lda #1
ldx #0
lda #1 ; A = 1
ldx #0 ; X = 0
.loop
sta Temp1
and #3
clc
adc SpriteBuf,x
sta SpriteBuf,x
lda Temp1
jsr NextRandom
inx
bne .loop
rts
sta Temp1 ; save A
and #3 ; keep lower 2 bits
clc ; clear carry before add
adc SpriteBuf,x ; add to sprite buffer
sta SpriteBuf,x ; store in sprite buffer
lda Temp1 ; restore A
jsr NextRandom ; get next random number
inx ; X = X + 1
bne .loop ; loop until X wraps
rts ; return to caller
; set palette colors
SetPalette: subroutine
PPU_SETADDR $3f00
ldx #32
PPU_SETADDR $3f00
.loop:
lda Palette,y
sta PPU_DATA
iny
dex
bne .loop
rts
lda Palette,y ; lookup byte in ROM
sta PPU_DATA ; store byte to PPU data
iny ; Y = Y + 1
cpy #32 ; is Y equal to 32?
bne .loop ; not yet, loop
rts ; return to caller
;;;;; COMMON SUBROUTINES

View File

@ -80,13 +80,13 @@ const _JSNESPlatform = function(mainElement) {
var frameindex = 0;
var ntvideo;
var ntlastbuf;
class JSNESPlatform extends Base6502Platform implements Platform {
getPresets() { return JSNES_PRESETS; }
start() {
var self = this;
this.debugPCDelta = 1;
var debugbar = $("<div>").appendTo(mainElement);
audio = new SampleAudio(audioFrequency);
video = new RasterVideo(mainElement,256,224,{overscan:true});
@ -99,7 +99,7 @@ const _JSNESPlatform = function(mainElement) {
// toggle buttons
$('<button>').text("Video").appendTo(debugbar).click(() => { $(video.canvas).toggle() });
$('<button>').text("Nametable").appendTo(debugbar).click(() => { $(ntvideo.canvas).toggle() });
var idata = video.getFrameData();
nes = new jsnes.NES({
onFrame: (frameBuffer : number[]) => {
@ -121,31 +121,31 @@ const _JSNESPlatform = function(mainElement) {
//TODO: onBatteryRamWrite
});
//nes.ppu.clipToTvSize = false;
nes.stop = function() {
nes.stop = () => {
// TODO: trigger breakpoint
self.pause();
this.pause();
console.log(nes.cpu.toJSON());
throw ("CPU STOPPED @ PC $" + hex(nes.cpu.REG_PC));
};
// insert debug hook
nes.cpu._emulate = nes.cpu.emulate;
nes.cpu.emulate = function() {
nes.cpu.emulate = () => {
var cycles = nes.cpu._emulate();
//if (self.debugCondition && !self.debugBreakState && self.debugClock < 100) console.log(self.debugClock, nes.cpu.REG_PC);
self.evalDebugCondition();
this.evalDebugCondition();
// TODO: doesn't stop on breakpoint
return cycles;
}
timer = new AnimationTimer(60, this.nextFrame.bind(this));
// set keyboard map
setKeyboardFromMap(video, [], JSNES_KEYCODE_MAP, function(o,key,code,flags) {
setKeyboardFromMap(video, [], JSNES_KEYCODE_MAP, (o,key,code,flags) => {
if (flags & KeyFlags.KeyDown)
nes.buttonDown(o.index+1, o.mask); // controller, button
else if (flags & KeyFlags.KeyUp)
nes.buttonUp(o.index+1, o.mask); // controller, button
});
}
advance(novideo : boolean) {
try {
nes.frame();
@ -156,7 +156,7 @@ const _JSNESPlatform = function(mainElement) {
this.breakpointHit(this.debugClock);
}
}
updateDebugViews() {
// don't update if view is hidden
if (! $(ntvideo.canvas).is(":visible"))
@ -208,7 +208,7 @@ const _JSNESPlatform = function(mainElement) {
return (this.readAddress(0xfffa) | (this.readAddress(0xfffb) << 8)) & 0xffff;
}
getDefaultExtension() { return ".c"; };
reset() {
//nes.cpu.reset(); // doesn't work right, crashes
nes.cpu.requestIrq(nes.cpu.IRQ_RESET);

View File

@ -7,7 +7,7 @@ type BuildResultCallback = (result:WorkerResult) => void;
type BuildStatusCallback = (busy:boolean) => void;
type LoadFilesCallback = (err:string, result?:Dependency[]) => void;
type IterateFilesCallback = (path:string, data:FileData) => void;
type GetRemoteCallback = any; // TODO (path:string, (text:string) => FileData) => void;
type GetRemoteCallback = (path:string, callback:(data:FileData) => void, datatype:'text'|'arraybuffer') => any;
export class CodeProject {
filedata : {[path:string]:FileData} = {};
@ -36,7 +36,7 @@ export class CodeProject {
this.receiveWorkerMessage(e.data);
};
}
receiveWorkerMessage(data : WorkerResult) {
var notfinal = this.pendingWorkerMessages > 1;
if (notfinal) {
@ -61,7 +61,7 @@ export class CodeProject {
this.tools_preloaded[tool] = true;
}
}
pushAllFiles(files:string[], fn:string) {
// look for local and preset files
files.push('local/'+fn);
@ -71,7 +71,7 @@ export class CodeProject {
if (dir.length > 0 && dir != 'local') // TODO
files.push(dir + '/' + fn);
}
parseIncludeDependencies(text:string):string[] {
var files = [];
var m;
@ -94,7 +94,7 @@ export class CodeProject {
} else {
// for .asm -- [.]include "file"
// for .c -- #include "file"
var re2 = /^\s*([.#]?include|incbin)\s+"(.+?)"/gmi;
var re2 = /^\s*[.#]?(include|incbin)\s+"(.+?)"/gmi;
while (m = re2.exec(text)) {
this.pushAllFiles(files, m[2]);
}
@ -208,14 +208,16 @@ export class CodeProject {
if (this.platform_id.startsWith('vcs') && path.indexOf('.') <= 0)
webpath += ".a"; // legacy stuff
// try to GET file, use file ext to determine text/binary
this.callbackGetRemote( webpath, (text:FileData) => {
console.log("GET",webpath,text.length,'bytes');
this.filedata[path] = text; // do not update store, just cache
addResult(path, text);
this.callbackGetRemote( webpath, (data:FileData) => {
if (data instanceof ArrayBuffer)
data = new Uint8Array(data); // convert to typed array
console.log("GET",webpath,data.length,'bytes');
this.filedata[path] = data; // do not update store, just cache
addResult(path, data);
loadNext();
}, isProbablyBinary(path) ? 'arraybuffer' : 'text')
.fail( (err:XMLHttpRequest) => {
console.log("Could not load preset", path, err.status);
console.log("Could not load preset file", path, err.status);
// only cache result if status is 404 (not found)
if (err.status && err.status == 404)
this.filedata[path] = null; // mark cache entry as invalid

View File

@ -94,10 +94,21 @@ function setLastPreset(id:string) {
}
}
// firefox doesn't do GET with binary files
function getWithBinary(url:string, success:(text:FileData)=>void, datatype:'text'|'arraybuffer') {
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = datatype;
oReq.onload = function (oEvent) {
success(oReq.response);
}
oReq.send(null);
}
function initProject() {
current_project = new CodeProject(newWorker(), platform_id, platform, store);
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
current_project.callbackGetRemote = $.get;
current_project.callbackGetRemote = getWithBinary;
current_project.callbackBuildResult = (result:WorkerResult) => {
setCompileOutput(result);
refreshWindowList();

View File

@ -712,6 +712,8 @@ function assembleDASM(step:BuildStep) {
}
} else if (s.startsWith("Warning:")) {
errors.push({line:0, msg:s.substr(9)});
} else if (s.startsWith("unable ")) {
errors.push({line:0, msg:s});
} else {
errorMatcher(s);
}

2
tss

@ -1 +1 @@
Subproject commit 5b5ee67fc06956bc7dce51726e98812d2d897eaa
Subproject commit d630ddcb29d74a178cde043d74188fac35d6a21f