mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-22 14:33:51 +00:00
nes: fixed binary GET for Firefox, DASM errors, disassembler
This commit is contained in:
parent
a243044ed5
commit
ce019b5632
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
13
src/ui.ts
13
src/ui.ts
@ -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();
|
||||
|
@ -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
2
tss
@ -1 +1 @@
|
||||
Subproject commit 5b5ee67fc06956bc7dce51726e98812d2d897eaa
|
||||
Subproject commit d630ddcb29d74a178cde043d74188fac35d6a21f
|
Loading…
Reference in New Issue
Block a user