1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-05-28 08:41:30 +00:00

Deploying to gh-pages from @ sehugg/8bitworkshop@3bacf50409 🚀

This commit is contained in:
sehugg 2023-05-22 16:13:09 +00:00
parent 29255740fa
commit d1024c06c6
44 changed files with 2171 additions and 111 deletions

File diff suppressed because one or more lines are too long

14
gen/c64-5MCMD5YC.js Normal file
View File

@ -0,0 +1,14 @@
import{a as M}from"./chunk-PQDZBFBB.js";import{B as S,I as _,r as g,y as b}from"./chunk-HB3LWF25.js";import{J as n,O as a,U as p,a as l,g as o,u as x}from"./chunk-ATS7PSQG.js";import"./chunk-5XVCUSSZ.js";var f=class extends g{constructor(){super(...arguments);this.numTotalScanlines=312;this.cpuCyclesPerLine=63;this.joymask0=0;this.joymask1=0;this.lightpen_x=0;this.lightpen_y=0}loadBIOS(e){var s=59940-57344+12288;e[s]=96,super.loadBIOS(e)}reset(){super.reset();for(var e=0;e<128;e++)this.exports.machine_key_up(this.sys,e);if(this.romptr&&this.romlen){if(this.exports.machine_load_rom(this.sys,this.romptr,this.romlen),this.prgstart=this.romarr[0]+(this.romarr[1]<<8),this.prgstart==2049)if(this.romarr[6]==158){for(var s=0,t=0;t<5;t++){var e=this.romarr[7+t];if(e==155||e==0)break;s=s*10+(e&15)}this.prgstart=s,console.log("SYS",s,o(s))}else this.prgstart=this.romarr[2]+(this.romarr[3]<<8)+2,console.log("RUN",this.prgstart,o(this.prgstart));if(this.prgstart<32768){this.exports.machine_exec(this.sys,25e4);for(var i="\rSYS "+this.prgstart,t=0;t<i.length;t++){var r=i.charCodeAt(t);this.exports.machine_exec(this.sys,3e4),this.exports.machine_key_down(this.sys,r),this.exports.machine_exec(this.sys,3e4),this.exports.machine_key_up(this.sys,r),this.exports.machine_exec(this.sys,1)}this.exports.machine_key_down(this.sys,13),this.exports.machine_exec(this.sys,1);for(var t=0;t<1e5&&this.getPC()!=this.prgstart;t++)this.exports.machine_tick(this.sys)}else{this.exports.machine_exec(this.sys,100);for(var c=this.romarr[4]+this.romarr[5]*256,t=0;t<15e4&&this.getPC()!=c;t++)this.exports.machine_tick(this.sys)}}}advanceFrame(e){var s=this.getRasterY(),t=Math.floor((this.numTotalScanlines-s)*19656/this.numTotalScanlines),i=this.probe!=null;return i&&this.exports.machine_reset_probe_buffer(),t=super.advanceFrameClock(e,t),i&&this.copyProbeData(),t}getCPUState(){this.exports.machine_save_cpu_state(this.sys,this.cpustateptr);var e=this.cpustatearr,s=e[2]+(e[3]<<8);return{PC:s,SP:e[9],A:e[6],X:e[7],Y:e[8],C:e[10]&1,Z:e[10]&2,I:e[10]&4,D:e[10]&8,V:e[10]&64,N:e[10]&128,o:this.readConst(s),R:e[19]!=55}}saveState(){this.exports.machine_save_state(this.sys,this.stateptr);let e=this.getDebugStateOffset(1),s=this.getDebugStateOffset(2),t=this.getDebugStateOffset(3),i=this.getDebugStateOffset(4),r=this.getDebugStateOffset(5),c=this.getDebugStateOffset(9);return{c:this.getCPUState(),state:this.statearr.slice(0),ram:this.statearr.slice(r,r+65536),cia1:this.statearr.slice(e,e+64),cia2:this.statearr.slice(s,s+64),vic:this.statearr.slice(t+1,t+1+64),sid:this.statearr.slice(i,i+32),pla:this.statearr.slice(c,c+16)}}loadState(e){this.statearr.set(e.state),this.exports.machine_load_state(this.sys,this.stateptr)}getVideoParams(){return{width:392,height:272,overscan:!0,videoFrequency:50,aspect:392/272*.9365}}setKeyInput(e,s,t){if(!(e==16||e==17||e==18||e==224)){var i=0,r=0;switch(e){case 32:i=16;break;case 37:e=8,i=4;break;case 38:e=11,i=1;break;case 39:e=9,i=8;break;case 40:e=10,i=2;break;case 113:e=241;break;case 115:e=243;break;case 119:e=245;break;case 121:e=247;break;case 188:e=t&a.Shift?60:46;break;case 190:e=t&a.Shift?62:44;break;case 191:e=t&a.Shift?63:47;break;case 222:e=t&a.Shift?34:39;break;case 219:e=t&a.Shift?123:91;break;case 221:e=t&a.Shift?125:93;break;case 48:t&a.Shift&&(e=41);break;case 49:t&a.Shift&&(e=33);break;case 50:t&a.Shift&&(e=64);break;case 51:t&a.Shift&&(e=35);break;case 52:t&a.Shift&&(e=36);break;case 53:t&a.Shift&&(e=37);break;case 54:t&a.Shift&&(e=94);break;case 55:t&a.Shift&&(e=38);break;case 56:t&a.Shift&&(e=42);break;case 57:t&a.Shift&&(e=40);break;case 59:t&a.Shift&&(e=58);break;case 61:t&a.Shift&&(e=43);break;case 173:e=t&a.Shift?95:45;break}t&a.KeyDown?(this.exports.machine_key_down(this.sys,e),this.joymask0|=i,this.joymask1|=r):t&a.KeyUp&&(this.exports.machine_key_up(this.sys,e),this.joymask0&=~i,this.joymask1&=~r),this.exports.c64_joystick(this.sys,this.joymask0,this.joymask1)}}getRasterY(){return this.exports.machine_get_raster_line(this.sys)}getDebugStateOffset(e){var s=this.exports.machine_get_debug_pointer(this.sys,e);return s-this.sys}getDebugCategories(){return["CPU","ZPRAM","Stack","PLA","CIA","VIC","SID"]}getDebugInfo(e,s){switch(e){case"PLA":{let t="",i=s.pla[0],r=s.pla[3];return t+=`$0000 - $9FFF RAM
`,t+=`$A000 - $BFFF ${(r&3)==3?"BASIC ROM":"RAM"}
`,t+=`$C000 - $CFFF RAM
`,t+=`$D000 - $DFFF ${i?"I/O":(r&3)!=0?"CHAR ROM":"RAM"}
`,t+=`$E000 - $FFFF ${(r&2)==2?"KERNAL ROM":"RAM"}
`,t}case"CIA":{let t="";for(let i=0;i<2;i++){let r=i?s.cia2:s.cia1;t+=`CIA ${i+1}
`,t+=` A: Data ${o(r[0])} DDR ${o(r[1])} Input ${o(r[2])}`,t+=` Timer ${o(r[10]+r[11]*256,4)}
`,t+=` B: Data ${o(r[4])} DDR ${o(r[5])} Input ${o(r[6])}`,t+=` Timer ${o(r[10+10]+r[11+10]*256,4)}
`}return t}case"VIC":{let t=s.vic,i="",r=(s.cia2[0]&3^3)*16384,c=r+(s.vic[24]&14)*1024,m=r+(s.vic[24]>>4)*1024,h=s.vic[17]&32,A=(s.cia2[0]&1)==1&&(s.vic[24]&12)==4,R=s.state[244],$=this.getRasterY();return i+="Mode:",s.vic[17]&32?i+=" BITMAP":i+=" CHAR",s.vic[22]&16&&(i+=" MULTICOLOR"),s.vic[17]&64&&(i+=" EXTENDED"),i+=`
`,i+=`Raster: (${l(R,3)}, ${l($,3)}) `,i+=`Scroll: (${s.vic[22]&7}, ${s.vic[17]&7})`,i+=`
`,i+=`VIC Bank: $${o(r,4)} Scrn: $${o(m,4)} `,h?i+=`Bitmap: $${o(c&57344,4)}`:A?i+=`Char: ROM $${o(c,4)}`:i+=`Char: $${o(c,4)}`,i+=`
`,i+=p(t,53248,64),i}case"SID":{let t=s.sid,i="";return i+=p(t,54272,32),i}}}setPaddleInput(e,s){e==0&&(this.lightpen_x=s),e==1&&(this.lightpen_y=s);let t=22,i=36,r=228,c=220,m=x(0,255,(this.lightpen_x-t)/(r-t)*160+24),h=x(0,255,(this.lightpen_y-i)/(c-i)*200+50);this.exports.machine_set_mouse(this.sys,m,h)}};var v=[{id:"hello.dasm",name:"Hello World (ASM)"},{id:"23matches.c",name:"23 Matches"},{id:"tgidemo.c",name:"TGI Graphics Demo"},{id:"upandaway.c",name:"Up, Up and Away"},{id:"siegegame.c",name:"Siege Game"},{id:"joymove.c",name:"Sprite Movement"},{id:"sprite_collision.c",name:"Sprite Collision"},{id:"scroll1.c",name:"Scrolling (Single Buffer)"},{id:"scroll2.c",name:"Scrolling (Double Buffer)"},{id:"scroll3.c",name:"Scrolling (Multidirectional)"},{id:"scroll4.c",name:"Scrolling (Color RAM Buffering)"},{id:"scroll5.c",name:"Scrolling (Camera Following)"},{id:"side_scroller.c",name:"Side-Scrolling Game"},{id:"fullscrollgame.c",name:"Full-Scrolling Game"},{id:"test_multiplex.c",name:"Sprite Retriggering"},{id:"test_multispritelib.c",name:"Sprite Multiplexing Library"},{id:"scrolling_text.c",name:"Big Scrolling Text"},{id:"mcbitmap.c",name:"Multicolor Bitmap Mode"},{id:"musicplayer.c",name:"Music Player"},{id:"siddemo.c",name:"SID Player Demo"},{id:"climber.c",name:"Climber Game"}],y={main:[{name:"6510 Registers",start:0,size:2,type:"io"},{name:"BIOS Reserved",start:512,size:167},{name:"Default Screen RAM",start:1024,size:1024,type:"ram"},{name:"Cartridge ROM",start:32768,size:8192,type:"rom"},{name:"BASIC ROM",start:40960,size:8192,type:"rom"},{name:"Upper RAM",start:49152,size:4096,type:"ram"},{name:"Character ROM",start:53248,size:4096,type:"rom"},{name:"VIC-II I/O",start:53248,size:1024,type:"io"},{name:"SID",start:54272,size:1024,type:"io"},{name:"Color RAM",start:55296,size:1024,type:"io"},{name:"CIA 1",start:56320,size:256,type:"io"},{name:"CIA 2",start:56576,size:256,type:"io"},{name:"I/O 1",start:56832,size:256,type:"io"},{name:"I/O 2",start:57088,size:256,type:"io"},{name:"KERNAL ROM",start:57344,size:8192,type:"rom"}]},d=class extends _{newMachine(){return new f("c64")}getPresets(){return v}getDefaultExtension(){return".c"}readAddress(e){return this.machine.readConst(e)}getMemoryMap(){return y}showHelp(){return"https://8bitworkshop.com/docs/platforms/c64/"}getROMExtension(e){return e&&e[0]==1&&e[1]==8?".prg":".bin"}},C=class extends M{constructor(){super(...arguments);this.getToolForFilename=b;this.getOpcodeMetadata=S}getPresets(){return v}getDefaultExtension(){return".c"}loadROM(e,s){if(!this.started)this.startModule(this.mainElement,{jsfile:"mame8bitpc.js",biosfile:"c64.zip",cfgfile:"c64.cfg",driver:"c64",width:418,height:235,romfn:"/emulator/image.crt",romdata:new Uint8Array(s),romsize:65536,extraargs:["-autoboot_delay","5","-autoboot_command",`load "$",8,1
`],preInit:function(i){}});else{this.loadROMFile(s),this.loadRegion(":quickload",s);var t=this.luacall('image:load("/emulator/image.prg")');console.log("load rom",t)}}start(){}getMemoryMap(){return y}};n.c64=d;n["c64.wasm"]=d;n["c64.mame"]=C;
//# sourceMappingURL=c64-5MCMD5YC.js.map

7
gen/c64-5MCMD5YC.js.map Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,14 +0,0 @@
import{a as M}from"./chunk-PQDZBFBB.js";import{B as S,I as _,r as g,y as b}from"./chunk-HB3LWF25.js";import{J as n,O as a,U as p,a as l,g as o,u as x}from"./chunk-ATS7PSQG.js";import"./chunk-5XVCUSSZ.js";var d=class extends g{constructor(){super(...arguments);this.numTotalScanlines=312;this.cpuCyclesPerLine=63;this.joymask0=0;this.joymask1=0;this.lightpen_x=0;this.lightpen_y=0}loadBIOS(e){var s=59940-57344+12288;e[s]=96,super.loadBIOS(e)}reset(){super.reset();for(var e=0;e<128;e++)this.exports.machine_key_up(this.sys,e);if(this.romptr&&this.romlen)if(this.exports.machine_load_rom(this.sys,this.romptr,this.romlen),this.prgstart=this.romarr[0]+(this.romarr[1]<<8),this.prgstart==2049&&(this.prgstart=this.romarr[2]+(this.romarr[3]<<8)+2,console.log("prgstart",o(this.prgstart))),this.prgstart<32768){this.exports.machine_exec(this.sys,25e4);for(var s="\rSYS "+this.prgstart+"\r",t=0;t<s.length;t++){var i=s.charCodeAt(t);this.exports.machine_exec(this.sys,2e4),this.exports.machine_key_down(this.sys,i),this.exports.machine_exec(this.sys,5e3),this.exports.machine_key_up(this.sys,i)}for(var t=0;t<1e5&&this.getPC()!=this.prgstart;t++)this.exports.machine_tick(this.sys)}else{this.exports.machine_exec(this.sys,100);for(var r=this.romarr[4]+this.romarr[5]*256,t=0;t<15e4&&this.getPC()!=r;t++)this.exports.machine_tick(this.sys)}}advanceFrame(e){var s=this.getRasterY(),t=Math.floor((this.numTotalScanlines-s)*19656/this.numTotalScanlines),i=this.probe!=null;return i&&this.exports.machine_reset_probe_buffer(),t=super.advanceFrameClock(e,t),i&&this.copyProbeData(),t}getCPUState(){this.exports.machine_save_cpu_state(this.sys,this.cpustateptr);var e=this.cpustatearr,s=e[2]+(e[3]<<8);return{PC:s,SP:e[9],A:e[6],X:e[7],Y:e[8],C:e[10]&1,Z:e[10]&2,I:e[10]&4,D:e[10]&8,V:e[10]&64,N:e[10]&128,o:this.readConst(s),R:e[19]!=55}}saveState(){this.exports.machine_save_state(this.sys,this.stateptr);let e=this.getDebugStateOffset(1),s=this.getDebugStateOffset(2),t=this.getDebugStateOffset(3),i=this.getDebugStateOffset(4),r=this.getDebugStateOffset(5),c=this.getDebugStateOffset(9);return{c:this.getCPUState(),state:this.statearr.slice(0),ram:this.statearr.slice(r,r+65536),cia1:this.statearr.slice(e,e+64),cia2:this.statearr.slice(s,s+64),vic:this.statearr.slice(t+1,t+1+64),sid:this.statearr.slice(i,i+32),pla:this.statearr.slice(c,c+16)}}loadState(e){this.statearr.set(e.state),this.exports.machine_load_state(this.sys,this.stateptr)}getVideoParams(){return{width:392,height:272,overscan:!0,videoFrequency:50,aspect:392/272*.9365}}setKeyInput(e,s,t){if(!(e==16||e==17||e==18||e==224)){var i=0,r=0;switch(e){case 32:i=16;break;case 37:e=8,i=4;break;case 38:e=11,i=1;break;case 39:e=9,i=8;break;case 40:e=10,i=2;break;case 113:e=241;break;case 115:e=243;break;case 119:e=245;break;case 121:e=247;break;case 188:e=t&a.Shift?60:46;break;case 190:e=t&a.Shift?62:44;break;case 191:e=t&a.Shift?63:47;break;case 222:e=t&a.Shift?34:39;break;case 219:e=t&a.Shift?123:91;break;case 221:e=t&a.Shift?125:93;break;case 48:t&a.Shift&&(e=41);break;case 49:t&a.Shift&&(e=33);break;case 50:t&a.Shift&&(e=64);break;case 51:t&a.Shift&&(e=35);break;case 52:t&a.Shift&&(e=36);break;case 53:t&a.Shift&&(e=37);break;case 54:t&a.Shift&&(e=94);break;case 55:t&a.Shift&&(e=38);break;case 56:t&a.Shift&&(e=42);break;case 57:t&a.Shift&&(e=40);break;case 59:t&a.Shift&&(e=58);break;case 61:t&a.Shift&&(e=43);break;case 173:e=t&a.Shift?95:45;break}t&a.KeyDown?(this.exports.machine_key_down(this.sys,e),this.joymask0|=i,this.joymask1|=r):t&a.KeyUp&&(this.exports.machine_key_up(this.sys,e),this.joymask0&=~i,this.joymask1&=~r),this.exports.c64_joystick(this.sys,this.joymask0,this.joymask1)}}getRasterY(){return this.exports.machine_get_raster_line(this.sys)}getDebugStateOffset(e){var s=this.exports.machine_get_debug_pointer(this.sys,e);return s-this.sys}getDebugCategories(){return["CPU","ZPRAM","Stack","PLA","CIA","VIC","SID"]}getDebugInfo(e,s){switch(e){case"PLA":{let t="",i=s.pla[0],r=s.pla[3];return t+=`$0000 - $9FFF RAM
`,t+=`$A000 - $BFFF ${(r&3)==3?"BASIC ROM":"RAM"}
`,t+=`$C000 - $CFFF RAM
`,t+=`$D000 - $DFFF ${i?"I/O":(r&3)!=0?"CHAR ROM":"RAM"}
`,t+=`$E000 - $FFFF ${(r&2)==2?"KERNAL ROM":"RAM"}
`,t}case"CIA":{let t="";for(let i=0;i<2;i++){let r=i?s.cia2:s.cia1;t+=`CIA ${i+1}
`,t+=` A: Data ${o(r[0])} DDR ${o(r[1])} Input ${o(r[2])}`,t+=` Timer ${o(r[10]+r[11]*256,4)}
`,t+=` B: Data ${o(r[4])} DDR ${o(r[5])} Input ${o(r[6])}`,t+=` Timer ${o(r[10+10]+r[11+10]*256,4)}
`}return t}case"VIC":{let t=s.vic,i="",r=(s.cia2[0]&3^3)*16384,c=r+(s.vic[24]&14)*1024,m=r+(s.vic[24]>>4)*1024,h=s.vic[17]&32,R=(s.cia2[0]&1)==1&&(s.vic[24]&12)==4,y=s.state[244],$=this.getRasterY();return i+="Mode:",s.vic[17]&32?i+=" BITMAP":i+=" CHAR",s.vic[22]&16&&(i+=" MULTICOLOR"),s.vic[17]&64&&(i+=" EXTENDED"),i+=`
`,i+=`Raster: (${l(y,3)}, ${l($,3)}) `,i+=`Scroll: (${s.vic[22]&7}, ${s.vic[17]&7})`,i+=`
`,i+=`VIC Bank: $${o(r,4)} Scrn: $${o(m,4)} `,h?i+=`Bitmap: $${o(c&57344,4)}`:R?i+=`Char: ROM $${o(c,4)}`:i+=`Char: $${o(c,4)}`,i+=`
`,i+=p(t,53248,64),i}case"SID":{let t=s.sid,i="";return i+=p(t,54272,32),i}}}setPaddleInput(e,s){e==0&&(this.lightpen_x=s),e==1&&(this.lightpen_y=s);let t=22,i=36,r=228,c=220,m=x(0,255,(this.lightpen_x-t)/(r-t)*160+24),h=x(0,255,(this.lightpen_y-i)/(c-i)*200+50);this.exports.machine_set_mouse(this.sys,m,h)}};var v=[{id:"hello.dasm",name:"Hello World (ASM)"},{id:"23matches.c",name:"23 Matches"},{id:"tgidemo.c",name:"TGI Graphics Demo"},{id:"upandaway.c",name:"Up, Up and Away"},{id:"siegegame.c",name:"Siege Game"},{id:"joymove.c",name:"Sprite Movement"},{id:"sprite_collision.c",name:"Sprite Collision"},{id:"scroll1.c",name:"Scrolling (Single Buffer)"},{id:"scroll2.c",name:"Scrolling (Double Buffer)"},{id:"scroll3.c",name:"Scrolling (Multidirectional)"},{id:"scroll4.c",name:"Scrolling (Color RAM Buffering)"},{id:"scroll5.c",name:"Scrolling (Camera Following)"},{id:"side_scroller.c",name:"Side-Scrolling Game"},{id:"fullscrollgame.c",name:"Full-Scrolling Game"},{id:"test_multiplex.c",name:"Sprite Retriggering"},{id:"test_multispritelib.c",name:"Sprite Multiplexing Library"},{id:"scrolling_text.c",name:"Big Scrolling Text"},{id:"mcbitmap.c",name:"Multicolor Bitmap Mode"},{id:"musicplayer.c",name:"Music Player"},{id:"siddemo.c",name:"SID Player Demo"},{id:"climber.c",name:"Climber Game"}],C={main:[{name:"6510 Registers",start:0,size:2,type:"io"},{name:"BIOS Reserved",start:512,size:167},{name:"Default Screen RAM",start:1024,size:1024,type:"ram"},{name:"Cartridge ROM",start:32768,size:8192,type:"rom"},{name:"BASIC ROM",start:40960,size:8192,type:"rom"},{name:"Upper RAM",start:49152,size:4096,type:"ram"},{name:"Character ROM",start:53248,size:4096,type:"rom"},{name:"VIC-II I/O",start:53248,size:1024,type:"io"},{name:"SID",start:54272,size:1024,type:"io"},{name:"Color RAM",start:55296,size:1024,type:"io"},{name:"CIA 1",start:56320,size:256,type:"io"},{name:"CIA 2",start:56576,size:256,type:"io"},{name:"I/O 1",start:56832,size:256,type:"io"},{name:"I/O 2",start:57088,size:256,type:"io"},{name:"KERNAL ROM",start:57344,size:8192,type:"rom"}]},f=class extends _{newMachine(){return new d("c64")}getPresets(){return v}getDefaultExtension(){return".c"}readAddress(e){return this.machine.readConst(e)}getMemoryMap(){return C}showHelp(){return"https://8bitworkshop.com/docs/platforms/c64/"}getROMExtension(e){return e&&e[0]==1&&e[1]==8?".prg":".bin"}},A=class extends M{constructor(){super(...arguments);this.getToolForFilename=b;this.getOpcodeMetadata=S}getPresets(){return v}getDefaultExtension(){return".c"}loadROM(e,s){if(!this.started)this.startModule(this.mainElement,{jsfile:"mame8bitpc.js",biosfile:"c64.zip",cfgfile:"c64.cfg",driver:"c64",width:418,height:235,romfn:"/emulator/image.crt",romdata:new Uint8Array(s),romsize:65536,extraargs:["-autoboot_delay","5","-autoboot_command",`load "$",8,1
`],preInit:function(i){}});else{this.loadROMFile(s),this.loadRegion(":quickload",s);var t=this.luacall('image:load("/emulator/image.prg")');console.log("load rom",t)}}start(){}getMemoryMap(){return C}};n.c64=f;n["c64.wasm"]=f;n["c64.mame"]=A;
//# sourceMappingURL=c64-73FGKJFH.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
import{a as d}from"./chunk-3XE5YOCV.js";import{o as c}from"./chunk-4TWVHUDP.js";import"./chunk-SXEVG2WS.js";import"./chunk-5SHCNQ2O.js";import"./chunk-4PJ2B2TK.js";import{I as m,o as u,t as h}from"./chunk-HB3LWF25.js";import{$ as i,B as o,J as l,m as n}from"./chunk-ATS7PSQG.js";import"./chunk-5XVCUSSZ.js";var s=31,a=class extends u{constructor(){super();this.cpuFrequency=1e6;this.defaultROMSize=32768;this.cpu=new h;this.ram=new Uint8Array(16384);this.read=i([[0,16383,16383,e=>this.ram[e]],[16384,16384,65535,e=>this.serial.byteAvailable()?128:0],[16385,16385,65535,e=>this.serial.recvByte()],[16386,16386,65535,e=>this.serial.clearToSend()?128:0],[32768,65535,32767,e=>this.rom&&this.rom[e]]]);this.write=i([[0,16383,16383,(e,t)=>{this.ram[e]=t}],[16387,16387,65535,(e,t)=>this.serial.sendByte(t)],[16399,16399,65535,(e,t)=>{this.inputs[s]=1}]]);this.connectCPUMemoryBus(this)}connectSerialIO(e){this.serial=e}readConst(e){return this.read(e)}advanceFrame(e){for(var t=0;t<this.cpuFrequency/60&&!(e&&e());)t+=this.advanceCPU();return t}advanceCPU(){if(this.isHalted())return 1;var e=super.advanceCPU();return this.serial&&this.serial.advance(e),e}reset(){this.inputs[s]=0,super.reset(),this.serial&&this.serial.reset()}isHalted(){return this.inputs[s]!=0}};var S=[{id:"hello.dasm",name:"Hello World (ASM)"}],f=class{constructor(e){e.style.overflowY="auto";var t=$('<div id="gameport"/>').appendTo(e);$('<p class="transcript-header">Serial Output</p>').appendTo(t);var y=$('<div id="windowport" class="transcript"/>').appendTo(t);this.div=y[0]}start(){this.tty=new d(this.div,!1)}reset(){this.tty.clear()}saveState(){return this.tty.saveState()}loadState(e){this.tty.loadState(e)}};function p(r){return r==10?"":r<32?String.fromCharCode(r+9216):String.fromCharCode(r)}var v=class{constructor(){this.bufferedRead=!0;this.cyclesPerByte=1e6/(57600/8);this.maxOutputBytes=4096}clearToSend(){return this.outputBytes.length<this.maxOutputBytes}sendByte(e){this.clearToSend()&&(this.outputBytes.push(e),this.viewer.tty.addtext(p(e),2|32),e==10&&this.viewer.tty.newline(),this.clearToSend()||(this.viewer.tty.newline(),this.viewer.tty.addtext("\u26A0\uFE0F OUTPUT BUFFER FULL \u26A0\uFE0F",4)))}byteAvailable(){return this.readIndex()>this.inputIndex}recvByte(){var e=this.readIndex();this.inputIndex=e;var t=(this.inputBytes&&this.inputBytes[e])|0;return this.viewer.tty.addtext(p(t),2|16),t==10&&this.viewer.tty.newline(),t}readIndex(){return this.bufferedRead?this.inputIndex+1:Math.floor(this.clk/this.cyclesPerByte)}reset(){this.inputIndex=-1,this.clk=0,this.outputBytes=[],this.bufin=""}advance(e){this.clk+=e}saveState(){return{clk:this.clk,idx:this.inputIndex,out:this.outputBytes.slice()}}loadState(e){this.clk=e.clk,this.inputIndex=e.idx,this.outputBytes=e.out.slice()}},x=class extends m{constructor(e){super(e);this.getMemoryMap=function(){return{main:[{name:"RAM",start:0,size:16384,type:"ram"},{name:"ROM",start:32768,size:32768,type:"rom"}]}};this.serview=new f(e)}async start(){super.start(),this.serial=new v,this.serial.viewer=this.serview,this.serview.start(),this.machine.connectSerialIO(this.serial)}reset(){this.serial.inputBytes=o(this.internalFiles["serialin.dat"]),super.reset(),this.serview.reset()}isBlocked(){return this.machine.isHalted()}advance(e){return this.isBlocked()?(this.internalFiles["serialout.dat"]=n(this.serial.outputBytes),c(),0):super.advance(e)}saveState(){var e=super.saveState();return e.serial=this.serial.saveState(),e.serview=this.serview.saveState(),e}loadState(e){super.loadState(e),this.serial.loadState(e.serial),this.serview.loadState(e.serview)}newMachine(){return new a}getPresets(){return S}getDefaultExtension(){return".dasm"}readAddress(e){return this.machine.readConst(e)}};l["devel-6502"]=x;export{v as SerialTestHarness};
//# sourceMappingURL=devel-OECID263.js.map
import{a as d}from"./chunk-3XE5YOCV.js";import{o as c}from"./chunk-R63KYPGV.js";import"./chunk-SXEVG2WS.js";import"./chunk-5SHCNQ2O.js";import"./chunk-Z2IKIN54.js";import{I as m,o as u,t as h}from"./chunk-HB3LWF25.js";import{$ as i,B as o,J as l,m as n}from"./chunk-ATS7PSQG.js";import"./chunk-5XVCUSSZ.js";var s=31,a=class extends u{constructor(){super();this.cpuFrequency=1e6;this.defaultROMSize=32768;this.cpu=new h;this.ram=new Uint8Array(16384);this.read=i([[0,16383,16383,e=>this.ram[e]],[16384,16384,65535,e=>this.serial.byteAvailable()?128:0],[16385,16385,65535,e=>this.serial.recvByte()],[16386,16386,65535,e=>this.serial.clearToSend()?128:0],[32768,65535,32767,e=>this.rom&&this.rom[e]]]);this.write=i([[0,16383,16383,(e,t)=>{this.ram[e]=t}],[16387,16387,65535,(e,t)=>this.serial.sendByte(t)],[16399,16399,65535,(e,t)=>{this.inputs[s]=1}]]);this.connectCPUMemoryBus(this)}connectSerialIO(e){this.serial=e}readConst(e){return this.read(e)}advanceFrame(e){for(var t=0;t<this.cpuFrequency/60&&!(e&&e());)t+=this.advanceCPU();return t}advanceCPU(){if(this.isHalted())return 1;var e=super.advanceCPU();return this.serial&&this.serial.advance(e),e}reset(){this.inputs[s]=0,super.reset(),this.serial&&this.serial.reset()}isHalted(){return this.inputs[s]!=0}};var S=[{id:"hello.dasm",name:"Hello World (ASM)"}],f=class{constructor(e){e.style.overflowY="auto";var t=$('<div id="gameport"/>').appendTo(e);$('<p class="transcript-header">Serial Output</p>').appendTo(t);var y=$('<div id="windowport" class="transcript"/>').appendTo(t);this.div=y[0]}start(){this.tty=new d(this.div,!1)}reset(){this.tty.clear()}saveState(){return this.tty.saveState()}loadState(e){this.tty.loadState(e)}};function p(r){return r==10?"":r<32?String.fromCharCode(r+9216):String.fromCharCode(r)}var v=class{constructor(){this.bufferedRead=!0;this.cyclesPerByte=1e6/(57600/8);this.maxOutputBytes=4096}clearToSend(){return this.outputBytes.length<this.maxOutputBytes}sendByte(e){this.clearToSend()&&(this.outputBytes.push(e),this.viewer.tty.addtext(p(e),2|32),e==10&&this.viewer.tty.newline(),this.clearToSend()||(this.viewer.tty.newline(),this.viewer.tty.addtext("\u26A0\uFE0F OUTPUT BUFFER FULL \u26A0\uFE0F",4)))}byteAvailable(){return this.readIndex()>this.inputIndex}recvByte(){var e=this.readIndex();this.inputIndex=e;var t=(this.inputBytes&&this.inputBytes[e])|0;return this.viewer.tty.addtext(p(t),2|16),t==10&&this.viewer.tty.newline(),t}readIndex(){return this.bufferedRead?this.inputIndex+1:Math.floor(this.clk/this.cyclesPerByte)}reset(){this.inputIndex=-1,this.clk=0,this.outputBytes=[],this.bufin=""}advance(e){this.clk+=e}saveState(){return{clk:this.clk,idx:this.inputIndex,out:this.outputBytes.slice()}}loadState(e){this.clk=e.clk,this.inputIndex=e.idx,this.outputBytes=e.out.slice()}},x=class extends m{constructor(e){super(e);this.getMemoryMap=function(){return{main:[{name:"RAM",start:0,size:16384,type:"ram"},{name:"ROM",start:32768,size:32768,type:"rom"}]}};this.serview=new f(e)}async start(){super.start(),this.serial=new v,this.serial.viewer=this.serview,this.serview.start(),this.machine.connectSerialIO(this.serial)}reset(){this.serial.inputBytes=o(this.internalFiles["serialin.dat"]),super.reset(),this.serview.reset()}isBlocked(){return this.machine.isHalted()}advance(e){return this.isBlocked()?(this.internalFiles["serialout.dat"]=n(this.serial.outputBytes),c(),0):super.advance(e)}saveState(){var e=super.saveState();return e.serial=this.serial.saveState(),e.serview=this.serview.saveState(),e}loadState(e){super.loadState(e),this.serial.loadState(e.serial),this.serview.loadState(e.serview)}newMachine(){return new a}getPresets(){return S}getDefaultExtension(){return".dasm"}readAddress(e){return this.machine.readConst(e)}};l["devel-6502"]=x;export{v as SerialTestHarness};
//# sourceMappingURL=devel-364UXGWH.js.map

View File

@ -1,2 +1,2 @@
import{b as w,c as x}from"./chunk-4PJ2B2TK.js";import{D as v,J as c,k as m,l as u,x as g,z as p}from"./chunk-ATS7PSQG.js";import{e as I}from"./chunk-5XVCUSSZ.js";var h=I(x()),i,a,l,y=function(e){if(!e||e.length==0)return{};for(var r={},t=0;t<e.length;++t){var o=e[t].split("=",2);o.length==1?r[o[0]]="":r[o[0]]=decodeURIComponent(o[1].replace(/\+/g," "))}return r}(window.location.search.substr(1).split("&"));function P(){typeof window.onerror=="object"&&(window.onerror=function(e,r,t,o,n){var s=e+" "+r+" "+t+":"+o+", "+n;$.get("/error?msg="+encodeURIComponent(s),"text")})}function M(){var e=!1;document.addEventListener("visibilitychange",function(r){document.visibilityState=="hidden"&&a.isRunning()?(a.pause(),e=!0):document.visibilityState=="visible"&&e&&(a.resume(),e=!1)}),$(window).on("focus",function(){e&&(a.resume(),e=!1)}),$(window).on("blur",function(){a.isRunning()&&(a.pause(),e=!0)})}async function k(e,r){if(!r){alert("No ROM found.");return}console.log(r.length+" bytes"),await a.loadROM(e,r),a.resume()}function R(){return $("#emulator").find("canvas")}function E(e,r,t){v("gif.js/dist/gif.js").then(()=>{var o=R()[0];if(!o){alert("Could not find canvas element to record video!");return}var n=0;o.style&&o.style.transform&&(o.style.transform.indexOf("rotate(-90deg)")>=0?n=-1:o.style.transform.indexOf("rotate(90deg)")>=0&&(n=1));var s=new GIF({workerScript:"gif.js/dist/gif.worker.js",workers:4,quality:10,rotate:n});s.on("finished",function(C){console.log("finished encoding GIF"),t(C)}),e=e||100+(Math.random()*256&3),r=r||100+(Math.random()*256&15);var f=0;console.log("Recording video",o);var d=()=>{f++>r?(console.log("Rendering video"),s.render()):(s.addFrame(o,{delay:e,copy:!0}),setTimeout(d,e))};d()})}async function S(e){if(!c[i])throw Error("Invalid platform '"+i+"'.");a=new c[i]($("#emuscreen")[0]),await a.start(),e.rec&&R().on("focus",()=>{a.resume()});var r=e.n||"Game",t,o=e.url,n=e.r;if(o)return console.log(o),g(o,f=>{k(r,f)},"arraybuffer"),!0;if(n){var s=u(atob(n));t=new m().decode(s)}return M(),k(r,t),!0}async function b(e){if(e.data&&(e=e.data),i=e.p,!i)throw new Error("No platform variable!");try{var r=await w(p(i));console.log("starting platform",i),await S(e)}catch(t){console.log(t),alert('Platform "'+i+'" not supported.')}}function F(){P(),y.p&&b(y)}window.addEventListener("message",O,!1);function O(e){if(e.data){var r=e.data.cmd;if(r=="start"&&!a)b(e);else if(r=="reset")a.reset(),l.reset();else if(r=="getReplay"){var t={frameCount:l.frameCount,checkpoints:l.checkpoints,framerecs:l.framerecs,checkpointInterval:l.checkpointInterval,maxCheckpoints:l.maxCheckpoints};e.source.postMessage({ack:r,replay:t},e.origin)}else if(r=="watchState"){var o=new Function("platform","state",e.data.fn);l.callbackNewCheckpoint=n=>{e.source.postMessage({ack:r,state:o(a,n)},e.origin)}}else r=="recordVideo"?E(e.data.intervalMsec,e.data.maxFrames,function(n){e.data.filename&&(0,h.saveAs)(n,e.data.filename),e.source.postMessage({ack:r,gif:n},e.origin)}):console.log("Unknown data.cmd: "+r)}}self===top&&(document.body.style.backgroundColor="#555");F();export{a as platform,i as platform_id,F as startEmbed,l as stateRecorder};
import{b as w,c as x}from"./chunk-Z2IKIN54.js";import{D as v,J as c,k as m,l as u,x as g,z as p}from"./chunk-ATS7PSQG.js";import{e as I}from"./chunk-5XVCUSSZ.js";var h=I(x()),i,a,l,y=function(e){if(!e||e.length==0)return{};for(var r={},t=0;t<e.length;++t){var o=e[t].split("=",2);o.length==1?r[o[0]]="":r[o[0]]=decodeURIComponent(o[1].replace(/\+/g," "))}return r}(window.location.search.substr(1).split("&"));function P(){typeof window.onerror=="object"&&(window.onerror=function(e,r,t,o,n){var s=e+" "+r+" "+t+":"+o+", "+n;$.get("/error?msg="+encodeURIComponent(s),"text")})}function M(){var e=!1;document.addEventListener("visibilitychange",function(r){document.visibilityState=="hidden"&&a.isRunning()?(a.pause(),e=!0):document.visibilityState=="visible"&&e&&(a.resume(),e=!1)}),$(window).on("focus",function(){e&&(a.resume(),e=!1)}),$(window).on("blur",function(){a.isRunning()&&(a.pause(),e=!0)})}async function k(e,r){if(!r){alert("No ROM found.");return}console.log(r.length+" bytes"),await a.loadROM(e,r),a.resume()}function R(){return $("#emulator").find("canvas")}function E(e,r,t){v("gif.js/dist/gif.js").then(()=>{var o=R()[0];if(!o){alert("Could not find canvas element to record video!");return}var n=0;o.style&&o.style.transform&&(o.style.transform.indexOf("rotate(-90deg)")>=0?n=-1:o.style.transform.indexOf("rotate(90deg)")>=0&&(n=1));var s=new GIF({workerScript:"gif.js/dist/gif.worker.js",workers:4,quality:10,rotate:n});s.on("finished",function(C){console.log("finished encoding GIF"),t(C)}),e=e||100+(Math.random()*256&3),r=r||100+(Math.random()*256&15);var f=0;console.log("Recording video",o);var d=()=>{f++>r?(console.log("Rendering video"),s.render()):(s.addFrame(o,{delay:e,copy:!0}),setTimeout(d,e))};d()})}async function S(e){if(!c[i])throw Error("Invalid platform '"+i+"'.");a=new c[i]($("#emuscreen")[0]),await a.start(),e.rec&&R().on("focus",()=>{a.resume()});var r=e.n||"Game",t,o=e.url,n=e.r;if(o)return console.log(o),g(o,f=>{k(r,f)},"arraybuffer"),!0;if(n){var s=u(atob(n));t=new m().decode(s)}return M(),k(r,t),!0}async function b(e){if(e.data&&(e=e.data),i=e.p,!i)throw new Error("No platform variable!");try{var r=await w(p(i));console.log("starting platform",i),await S(e)}catch(t){console.log(t),alert('Platform "'+i+'" not supported.')}}function F(){P(),y.p&&b(y)}window.addEventListener("message",O,!1);function O(e){if(e.data){var r=e.data.cmd;if(r=="start"&&!a)b(e);else if(r=="reset")a.reset(),l.reset();else if(r=="getReplay"){var t={frameCount:l.frameCount,checkpoints:l.checkpoints,framerecs:l.framerecs,checkpointInterval:l.checkpointInterval,maxCheckpoints:l.maxCheckpoints};e.source.postMessage({ack:r,replay:t},e.origin)}else if(r=="watchState"){var o=new Function("platform","state",e.data.fn);l.callbackNewCheckpoint=n=>{e.source.postMessage({ack:r,state:o(a,n)},e.origin)}}else r=="recordVideo"?E(e.data.intervalMsec,e.data.maxFrames,function(n){e.data.filename&&(0,h.saveAs)(n,e.data.filename),e.source.postMessage({ack:r,gif:n},e.origin)}):console.log("Unknown data.cmd: "+r)}}self===top&&(document.body.style.backgroundColor="#555");F();export{a as platform,i as platform_id,F as startEmbed,l as stateRecorder};
//# sourceMappingURL=embedui.js.map

View File

@ -118,8 +118,16 @@ class CodeProject {
}
this.callbackBuildResult(data);
}
getToolForFilename(path) {
if (this.remoteTool) {
return "remote:" + this.remoteTool;
}
else {
return this.platform.getToolForFilename(path);
}
}
preloadWorker(path) {
var tool = this.platform.getToolForFilename(path);
var tool = this.getToolForFilename(path);
if (tool && !this.tools_preloaded[tool]) {
this.worker.postMessage({ preload: tool, platform: this.platform_id });
this.tools_preloaded[tool] = true;
@ -256,7 +264,7 @@ class CodeProject {
path: mainfilename,
files: [mainfilename].concat(depfiles),
platform: this.platform_id,
tool: this.platform.getToolForFilename(this.mainPath),
tool: this.getToolForFilename(this.mainPath),
mainfile: true
});
for (var dep of depends) {
@ -267,7 +275,7 @@ class CodeProject {
path: dep.filename,
files: [dep.filename].concat(depfiles),
platform: this.platform_id,
tool: this.platform.getToolForFilename(dep.path)
tool: this.getToolForFilename(dep.path)
});
}
}

File diff suppressed because one or more lines are too long

View File

@ -217,6 +217,7 @@ async function newFilesystem() {
async function initProject() {
var filesystem = await newFilesystem();
exports.current_project = new project_1.CodeProject(newWorker(), exports.platform_id, exports.platform, filesystem);
exports.current_project.remoteTool = exports.qs.tool || null;
exports.projectWindows = new windows_1.ProjectWindows($("#workspace")[0], exports.current_project);
exports.current_project.callbackBuildResult = (result) => {
setCompileOutput(result);

File diff suppressed because one or more lines are too long

View File

@ -31,23 +31,40 @@ class C64_WASMMachine extends wasmplatform_1.BaseWASMMachine {
this.prgstart = this.romarr[0] + (this.romarr[1] << 8); // get load address
// look for BASIC program start
if (this.prgstart == 0x801) {
this.prgstart = this.romarr[2] + (this.romarr[3] << 8) + 2; // point to after BASIC program
console.log("prgstart", (0, util_1.hex)(this.prgstart));
// decode SYS address from decimal?
if (this.romarr[6] == 0x9e) {
var addr = 0;
for (var i = 0; i < 5; i++) {
var ch = this.romarr[7 + i];
if (ch == 0x9b || ch == 0)
break;
addr = addr * 10 + (ch & 0xf);
}
this.prgstart = addr;
console.log("SYS", addr, (0, util_1.hex)(addr));
}
else {
this.prgstart = this.romarr[2] + (this.romarr[3] << 8) + 2; // point to after BASIC program
console.log("RUN", this.prgstart, (0, util_1.hex)(this.prgstart));
}
}
// is program loaded into RAM?
if (this.prgstart < 0x8000) {
// advance BIOS a few frames
this.exports.machine_exec(this.sys, 250000);
// type in command (SYS 2061)
var cmd = "\rSYS " + this.prgstart + "\r";
var cmd = "\rSYS " + this.prgstart;
for (var i = 0; i < cmd.length; i++) {
var key = cmd.charCodeAt(i);
this.exports.machine_exec(this.sys, 20000);
this.exports.machine_exec(this.sys, 30000);
this.exports.machine_key_down(this.sys, key);
this.exports.machine_exec(this.sys, 5000);
this.exports.machine_exec(this.sys, 30000);
this.exports.machine_key_up(this.sys, key);
this.exports.machine_exec(this.sys, 1); // chips/kbd.c has a "sticky counter"
}
// advance clock until program starts
this.exports.machine_key_down(this.sys, 13);
this.exports.machine_exec(this.sys, 1); // chips/kbd.c has a "sticky counter"
for (var i = 0; i < 100000 && this.getPC() != this.prgstart; i++) {
this.exports.machine_tick(this.sys);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n,p as o,q as p,r as q,s as r,t as s,u as t,v as u,w as v,x as w}from"./chunk-4TWVHUDP.js";import"./chunk-SXEVG2WS.js";import"./chunk-5SHCNQ2O.js";import"./chunk-4PJ2B2TK.js";import"./chunk-HB3LWF25.js";import"./chunk-ATS7PSQG.js";import"./chunk-5XVCUSSZ.js";export{l as clearBreakpoint,h as compparams,f as current_project,u as emulationHalted,p as getPlatformAndRepo,t as getSaveState,s as getTestOutput,n as haltEmulation,w as highlightSearch,i as lastDebugState,e as platform,b as platform_id,g as projectWindows,a as qs,v as reloadWorkspaceFile,d as repo_id,k as runToPC,m as setFrameRateUI,r as setTestInput,j as setupBreakpoint,o as setupSplits,q as startUI,c as store_id};
import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n,p as o,q as p,r as q,s as r,t as s,u as t,v as u,w as v,x as w}from"./chunk-R63KYPGV.js";import"./chunk-SXEVG2WS.js";import"./chunk-5SHCNQ2O.js";import"./chunk-Z2IKIN54.js";import"./chunk-HB3LWF25.js";import"./chunk-ATS7PSQG.js";import"./chunk-5XVCUSSZ.js";export{l as clearBreakpoint,h as compparams,f as current_project,u as emulationHalted,p as getPlatformAndRepo,t as getSaveState,s as getTestOutput,n as haltEmulation,w as highlightSearch,i as lastDebugState,e as platform,b as platform_id,g as projectWindows,a as qs,v as reloadWorkspaceFile,d as repo_id,k as runToPC,m as setFrameRateUI,r as setTestInput,j as setupBreakpoint,o as setupSplits,q as startUI,c as store_id};
//# sourceMappingURL=ui.js.map

View File

@ -36,6 +36,24 @@
return v + "";
}
}
function stringToByteArray(s) {
var a = new Uint8Array(s.length);
for (var i = 0; i < s.length; i++)
a[i] = s.charCodeAt(i);
return a;
}
function byteArrayToString(data) {
var str = "";
if (data != null) {
var charLUT = new Array();
for (var i = 0; i < 256; ++i)
charLUT[i] = String.fromCharCode(i);
var len = data.length;
for (var i = 0; i < len; i++)
str += charLUT[data[i]];
}
return str;
}
function getBasePlatform(platform) {
return platform.split(".")[0];
}
@ -8733,6 +8751,54 @@ ${this.scopeSymbol(name)} = ${name}::__Start`;
}
}
// src/common/workertypes.ts
function isUnchanged(result) {
return "unchanged" in result;
}
function isErrorResult(result) {
return "errors" in result;
}
function isOutputResult(result) {
return "output" in result;
}
// src/worker/tools/remote.ts
var REMOTE_URL = "http://localhost:3009/build";
var sessionID = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
async function buildRemote(step) {
gatherFiles(step);
var binpath = "a.out";
if (staleFiles(step, [binpath])) {
let updates = [];
for (var i = 0; i < step.files.length; i++) {
let path = step.files[i];
let entry = store.workfs[path];
let data = typeof entry.data === "string" ? entry.data : btoa(byteArrayToString(entry.data));
updates.push({ path, data });
}
let cmd = { buildStep: step, updates, sessionID };
console.log("POST", cmd);
let result = await fetch(REMOTE_URL, {
method: "POST",
mode: "cors",
body: JSON.stringify(cmd),
headers: {
"Content-Type": "application/json"
}
});
let json = await result.json();
if (isUnchanged(json))
return json;
if (isErrorResult(json))
return json;
if (isOutputResult(json)) {
json.output = stringToByteArray(atob(json.output));
return json;
}
throw new Error(`Unexpected result from remote build: ${JSON.stringify(json)}`);
}
}
// src/worker/workermain.ts
var ENVIRONMENT_IS_WEB = typeof window === "object";
var ENVIRONMENT_IS_WORKER = typeof importScripts === "function";
@ -9181,9 +9247,14 @@ ${this.scopeSymbol(name)} = ${name}::__Start`;
while (this.steps.length) {
var step = this.steps.shift();
var platform = step.platform;
var toolfn = TOOLS[step.tool];
if (!toolfn)
throw Error("no tool named " + step.tool);
var [tool, remoteTool] = step.tool.split(":", 2);
var toolfn = TOOLS[tool];
if (!toolfn) {
throw Error(`no tool named "${tool}"`);
}
if (remoteTool) {
step.tool = remoteTool;
}
step.params = PLATFORM_PARAMS[getBasePlatform(platform)];
try {
step.result = await toolfn(step);
@ -9755,7 +9826,8 @@ ${this.scopeSymbol(name)} = ${name}::__Start`;
"wiz": compileWiz,
"armips": assembleARMIPS,
"vasmarm": assembleVASMARM,
"ecs": assembleECS
"ecs": assembleECS,
"remote": buildRemote
};
var TOOL_PRELOADFS = {
"cc65-apple2": "65-apple2",

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,201 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServerBuildEnv = exports.TOOLS = exports.findBestTool = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const child_process_1 = require("child_process");
const workertypes_1 = require("../../common/workertypes");
const util_1 = require("../../common/util");
const workermain_1 = require("../workermain");
const clang_1 = require("./clang");
const LLVM_MOS_TOOL = {
name: 'llvm-mos',
version: '',
extensions: ['.c'],
archs: ['6502'],
platforms: ['atari8', 'c64', 'nes'],
platform_configs: {
default: {
binpath: 'llvm-mos/bin',
command: 'mos-clang',
args: ['-Os', '-g', '-o', '$OUTFILE', '$INFILES'],
},
debug: {
binpath: 'llvm-mos/bin',
command: 'llvm-objdump',
args: ['-l', '-t', '$WORKDIR/a.out.elf', '>$WORKDIR/debug.out']
},
c64: {
command: 'mos-c64-clang',
},
atari8: {
command: 'mos-atari8-clang',
},
nes: {
command: 'mos-nes-nrom-clang',
libargs: ['-lneslib']
},
}
};
function findBestTool(step) {
if (!(step === null || step === void 0 ? void 0 : step.tool))
throw new Error('No tool specified');
const [name, version] = step.tool.split('@');
for (let tool of exports.TOOLS) {
if (tool.name === name && (!version || version === 'latest' || tool.version === version)) {
return tool;
}
}
throw new Error(`Tool not found: ${step.tool}`);
}
exports.findBestTool = findBestTool;
exports.TOOLS = [
Object.assign({}, LLVM_MOS_TOOL, { version: '0.13.2' }),
];
class ServerBuildEnv {
constructor(rootdir, sessionID, tool) {
this.rootdir = path_1.default.resolve(rootdir);
this.sessionID = sessionID;
this.tool = tool;
// make sure sessionID is well-formed
if (!sessionID.match(/^[a-zA-Z0-9_-]+$/)) {
throw new Error(`Invalid sessionID: ${sessionID}`);
}
// create sessionID directory if it doesn't exist
this.sessionDir = path_1.default.join(this.rootdir, 'sessions', sessionID);
if (!fs_1.default.existsSync(this.sessionDir)) {
fs_1.default.mkdirSync(this.sessionDir);
}
}
async addFileUpdate(file) {
// make sure file.path contains no path components
if (file.path.match(/[\\\/]/)) {
throw new Error(`Invalid file path: ${file.path}`);
}
await fs_1.default.promises.writeFile(path_1.default.join(this.sessionDir, file.path), file.data);
}
async build(step, platform) {
// build config
let platformID = platform || (0, util_1.getRootBasePlatform)(step.platform);
let config = this.tool.platform_configs[platformID];
if (!config) {
throw new Error(`No config for platform ${platformID}`);
}
let defaultConfig = this.tool.platform_configs.default;
if (!defaultConfig) {
throw new Error(`No default config for tool ${this.tool.name}`);
}
config = Object.assign({}, defaultConfig, config); // combine configs
// copy args
let args = config.args.slice(0); //copy array
let command = config.command;
// replace $OUTFILE
let outfile = path_1.default.join(this.sessionDir, 'a.out'); // TODO? a.out
for (let i = 0; i < args.length; i++) {
args[i] = args[i].replace(/\$OUTFILE/g, outfile);
args[i] = args[i].replace(/\$WORKDIR/g, this.sessionDir);
}
// replace $INFILES with the list of input files
// TODO
let infiles = [];
for (let i = 0; i < step.files.length; i++) {
let f = step.files[i];
if (f.endsWith(this.tool.extensions[0])) {
infiles.push(path_1.default.join(this.sessionDir, f));
}
}
for (let i = 0; i < args.length; i++) {
if (args[i] === '$INFILES') {
args = args.slice(0, i).concat(infiles).concat(args.slice(i + 1));
break;
}
}
if (config.libargs) {
args = args.concat(config.libargs);
}
console.log(`Running: ${command} ${args.join(' ')}`);
// spawn after setting PATH env var
// TODO
let childProcess = (0, child_process_1.spawn)(command, args, {
shell: true,
cwd: this.rootdir,
env: { PATH: path_1.default.join(this.rootdir, config.binpath)
}
});
let outputData = '';
let errorData = '';
// TODO?
childProcess.stdout.on('data', (data) => {
outputData += data.toString();
});
childProcess.stderr.on('data', (data) => {
errorData += data.toString();
});
return new Promise((resolve, reject) => {
childProcess.on('close', async (code) => {
if (code === 0) {
if (platform === 'debug') {
resolve(this.processDebugInfo(step));
}
else {
resolve(this.processOutput(step));
}
}
else {
let errorResult = await this.processErrors(step, errorData);
if (errorResult.errors.length === 0) {
errorResult.errors.push({ line: 0, msg: `Build failed.\n\n${errorData}` });
}
resolve(errorResult);
}
});
});
}
async processErrors(step, errorData) {
let errors = [];
// split errorData into lines
let errorMatcher = (0, workermain_1.makeErrorMatcher)(errors, /([^:/]+):(\d+):(\d+):\s*(.+)/, 2, 4, step.path, 1);
for (let line of errorData.split('\n')) {
errorMatcher(line);
}
return { errors };
}
async processOutput(step) {
let outfile = path_1.default.join(this.sessionDir, 'a.out');
let output = await fs_1.default.promises.readFile(outfile, { encoding: 'base64' });
return { output };
}
async processDebugInfo(step) {
let dbgfile = path_1.default.join(this.sessionDir, 'debug.out');
let dbglist = await fs_1.default.promises.readFile(dbgfile);
let listings = (0, clang_1.parseObjDumpListing)(dbglist.toString());
let symbolmap = (0, clang_1.parseObjDumpSymbolTable)(dbglist.toString());
return { output: [], listings, symbolmap };
}
async compileAndLink(step, updates) {
for (let file of updates) {
await this.addFileUpdate(file);
}
try {
let result = await this.build(step);
// did we succeed?
if ((0, workertypes_1.isOutputResult)(result)) {
// do the debug info
const debugInfo = await this.build(step, 'debug');
if ((0, workertypes_1.isOutputResult)(debugInfo)) {
result.listings = debugInfo.listings;
result.symbolmap = debugInfo.symbolmap;
}
}
return result;
}
catch (err) {
return { errors: [{ line: 0, msg: err.toString() }] };
}
}
}
exports.ServerBuildEnv = ServerBuildEnv;
//# sourceMappingURL=buildenv.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,57 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseObjDumpListing = exports.parseObjDumpSymbolTable = void 0;
const path_1 = __importDefault(require("path"));
function parseObjDumpSymbolTable(symbolTable) {
const lines = symbolTable.split('\n');
const result = {};
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith('00')) {
const parts = line.split(/\s+/);
if (parts.length < 5)
continue;
const symbol = parts[parts.length - 1];
const address = parseInt(parts[0], 16);
result[symbol] = address;
}
}
return result;
}
exports.parseObjDumpSymbolTable = parseObjDumpSymbolTable;
function parseObjDumpListing(lst) {
const lines = lst.split('\n');
const result = {};
var lastListing = null;
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith(';')) {
const fileInfoIndex = line.indexOf(':');
if (fileInfoIndex !== -1) {
const fileInfo = line.substring(1).trim();
const fileParts = fileInfo.split(':');
const file = path_1.default.basename(fileParts[0].trim()).split('.')[0] + '.lst';
const lineNumber = parseInt(fileParts[1], 10);
if (lineNumber > 0) {
if (!result[file])
result[file] = { lines: [], text: lst };
lastListing = result[file];
lastListing.lines.push({ line: lineNumber, offset: null });
}
}
}
else if (lastListing && line.match(/^\s*[A-F0-9]+:.+/i)) {
const offsetIndex = line.indexOf(':');
if (offsetIndex !== -1) {
const offset = parseInt(line.substring(0, offsetIndex).trim(), 16);
lastListing.lines[lastListing.lines.length - 1].offset = offset;
}
}
}
return result;
}
exports.parseObjDumpListing = parseObjDumpListing;
//# sourceMappingURL=clang.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"clang.js","sourceRoot":"","sources":["../../../src/worker/server/clang.ts"],"names":[],"mappings":"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"}

View File

@ -0,0 +1,65 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const express_1 = __importDefault(require("express"));
const cors_1 = __importDefault(require("cors"));
const buildenv_1 = require("./buildenv");
////////////////////
const app = (0, express_1.default)();
app.use((0, cors_1.default)());
app.use(express_1.default.json({ limit: 1024 * 1024 })); // limit 1 MB
app.get('/info', (req, res) => {
// send a list of supported tools
res.json({ tools: buildenv_1.TOOLS });
});
app.get('/test', async (req, res, next) => {
// quick test of the build
try {
const updates = [{ path: 'test.c', data: 'int main() { return 0; }' }];
const buildStep = { tool: 'llvm-mos', platform: 'c64', files: ['test.c'] };
const env = new buildenv_1.ServerBuildEnv(SERVER_ROOT, 'test', buildenv_1.TOOLS[0]);
const result = await env.compileAndLink(buildStep, updates);
res.json(result);
}
catch (err) {
return next(err);
}
});
app.post('/build', async (req, res, next) => {
try {
const updates = req.body.updates;
const buildStep = req.body.buildStep;
const sessionID = req.body.sessionID;
const bestTool = (0, buildenv_1.findBestTool)(buildStep);
const env = new buildenv_1.ServerBuildEnv(SERVER_ROOT, sessionID, bestTool);
const result = await env.compileAndLink(buildStep, updates);
res.json(result);
}
catch (err) {
return next(err);
}
});
// Catch errors
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// Start the server
const port = 3009;
/*{
origin: [`http://localhost:${port}`, 'http://localhost:8000']
}));*/
const SERVER_ROOT = process.env['8BITWS_SERVER_ROOT'] || path_1.default.resolve('./server-root');
const SESSION_ROOT = path_1.default.join(SERVER_ROOT, 'sessions');
if (!fs_1.default.existsSync(SESSION_ROOT)) {
fs_1.default.mkdirSync(SESSION_ROOT);
}
process.chdir(SESSION_ROOT);
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});
//# sourceMappingURL=server.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/worker/server/server.ts"],"names":[],"mappings":"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"}

View File

@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildRemote = void 0;
const util_1 = require("../../common/util");
const workertypes_1 = require("../../common/workertypes");
const workermain_1 = require("../workermain");
// TODO: are we running from 8bitworkshop.com in this worker?
const REMOTE_URL = "http://localhost:3009/build";
// create random UID
const sessionID = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
async function buildRemote(step) {
(0, workermain_1.gatherFiles)(step); // TODO?
var binpath = "a.out"; // TODO?
if ((0, workermain_1.staleFiles)(step, [binpath])) {
// grab files from store
let updates = [];
for (var i = 0; i < step.files.length; i++) {
let path = step.files[i];
let entry = workermain_1.store.workfs[path];
// convert to base64
let data = typeof entry.data === 'string' ? entry.data : btoa((0, util_1.byteArrayToString)(entry.data));
updates.push({ path, data });
}
// build the command
let cmd = { buildStep: step, updates, sessionID };
// do a POST to the remote server, sending step as JSON
console.log('POST', cmd);
let result = await fetch(REMOTE_URL, {
method: "POST",
mode: "cors",
body: JSON.stringify(cmd),
headers: {
"Content-Type": "application/json"
}
});
// return the result as JSON
let json = await result.json();
// parse the result as JSON
if ((0, workertypes_1.isUnchanged)(json))
return json;
if ((0, workertypes_1.isErrorResult)(json))
return json;
if ((0, workertypes_1.isOutputResult)(json)) {
json.output = (0, util_1.stringToByteArray)(atob(json.output));
return json;
}
throw new Error(`Unexpected result from remote build: ${JSON.stringify(json)}`);
}
}
exports.buildRemote = buildRemote;
//# sourceMappingURL=remote.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../../src/worker/tools/remote.ts"],"names":[],"mappings":";;;AAAA,4CAAyE;AACzE,0DAAwG;AACxG,8CAA2F;AAE3F,6DAA6D;AAC7D,MAAM,UAAU,GAAG,6BAA6B,CAAC;AAEjD,oBAAoB;AACpB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAErG,KAAK,UAAU,WAAW,CAAC,IAAe;IAC7C,IAAA,wBAAW,EAAC,IAAI,CAAC,CAAC,CAAC,QAAQ;IAC3B,IAAI,OAAO,GAAG,OAAO,CAAC,CAAC,QAAQ;IAC/B,IAAI,IAAA,uBAAU,EAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE;QAC7B,wBAAwB;QACxB,IAAI,OAAO,GAAwB,EAAE,CAAC;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACxC,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,KAAK,GAAG,kBAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC/B,oBAAoB;YACpB,IAAI,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAA,wBAAiB,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7F,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;SAChC;QACD,oBAAoB;QACpB,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAClD,uDAAuD;QACvD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACzB,IAAI,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;YACjC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;YACzB,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;SACJ,CAAC,CAAC;QACH,4BAA4B;QAC5B,IAAI,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/B,2BAA2B;QAC3B,IAAI,IAAA,yBAAW,EAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACnC,IAAI,IAAA,2BAAa,EAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,IAAI,IAAA,4BAAc,EAAC,IAAI,CAAC,EAAE;YACtB,IAAI,CAAC,MAAM,GAAG,IAAA,wBAAiB,EAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;SACf;QACD,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KACnF;AACL,CAAC;AApCD,kCAoCC"}

View File

@ -481,9 +481,14 @@ class Builder {
while (this.steps.length) {
var step = this.steps.shift(); // get top of array
var platform = step.platform;
var toolfn = TOOLS[step.tool];
if (!toolfn)
throw Error("no tool named " + step.tool);
var [tool, remoteTool] = step.tool.split(':', 2);
var toolfn = TOOLS[tool];
if (!toolfn) {
throw Error(`no tool named "${tool}"`);
}
if (remoteTool) {
step.tool = remoteTool;
}
step.params = PLATFORM_PARAMS[(0, util_1.getBasePlatform)(platform)];
try {
step.result = await toolfn(step);
@ -1108,6 +1113,7 @@ const z80 = __importStar(require("./tools/z80"));
const x86 = __importStar(require("./tools/x86"));
const arm = __importStar(require("./tools/arm"));
const ecs = __importStar(require("./tools/ecs"));
const remote = __importStar(require("./tools/remote"));
var TOOLS = {
'dasm': dasm.assembleDASM,
//'acme': assembleACME,
@ -1144,6 +1150,7 @@ var TOOLS = {
'vasmarm': arm.assembleVASMARM,
//'js': script.runJavascript,
'ecs': ecs.assembleECS,
'remote': remote.buildRemote
};
var TOOL_PRELOADFS = {
'cc65-apple2': '65-apple2',

File diff suppressed because one or more lines are too long

1207
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,8 @@
"octokat": "^0.10.0",
"preact": "^10.5.14",
"split.js": "^1.6.2",
"atob": "^2.1.x",
"btoa": "^1.2.x",
"yufka": "^2.0.1"
},
"devDependencies": {
@ -40,11 +42,11 @@
"@types/jquery": "^3.5.5",
"@types/mocha": "^9.1.0",
"@types/node": "^14.14.20",
"atob": "^2.1.x",
"bootstrap": "^3.4.1",
"bootstrap-tourist": "^0.2.1",
"btoa": "^1.2.x",
"command-exists": "^1.2.9",
"cors": "^2.8.5",
"express": "^4.18.2",
"esbuild": "^0.12.29",
"jsdom": "^21.1.0",
"lzg": "^1.0.x",
@ -62,14 +64,21 @@
"rgbquant": "^1.1.2",
"typedoc": "^0.22.11"
},
"overrides": {
"fetch-vcr": {
"node-fetch": "2.6.7"
}
},
"scripts": {
"build": "make prepare",
"test": "npm run test-node",
"tsbuild": "tsc --build tsconfig.json",
"esbuild": "npm run esbuild-worker && npm run esbuild-ui",
"esbuild-clean": "rm -f ./gen/*.*",
"esbuild-server": "esbuild src/worker/server/server.ts --platform=node --bundle --sourcemap --target=es2020 --outfile=./gen/server/server.js",
"esbuild-worker": "esbuild src/worker/workermain.ts --bundle --sourcemap --target=es2017 --outfile=./gen/worker/bundle.js",
"esbuild-ui": "esbuild src/ide/ui.ts src/ide/embedui.ts --splitting --format=esm --bundle --minify --sourcemap --target=es2017 --outdir=./gen/ --external:path --external:fs",
"server": "npm run esbuild-server && rm -fr ./server-root/sessions && node gen/server/server.js",
"test-one": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000",
"test-node": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 test/cli gen/test",
"test-profile": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 --prof test/cli gen/test",
@ -97,7 +106,7 @@
"build": {
"appId": "com.8bitworkshop.ide",
"icon": "meta/icons/8bitworkshop-icon-1024.png",
"copyright": "Copyright (c) 2021 Puzzling Plans LLC",
"copyright": "Copyright (c) 2023 Puzzling Plans LLC",
"linux": {
"category": "Development"
}

View File

@ -101,6 +101,7 @@ export class CodeProject {
filename2path = {}; // map stripped paths to full paths
filesystem : ProjectFilesystem;
dataItems : WorkerItemUpdate[];
remoteTool? : string;
callbackBuildResult : BuildResultCallback;
callbackBuildStatus : BuildStatusCallback;
@ -135,8 +136,16 @@ export class CodeProject {
this.callbackBuildResult(data);
}
getToolForFilename(path) {
if (this.remoteTool) {
return "remote:" + this.remoteTool;
} else {
return this.platform.getToolForFilename(path);
}
}
preloadWorker(path:string) {
var tool = this.platform.getToolForFilename(path);
var tool = this.getToolForFilename(path);
if (tool && !this.tools_preloaded[tool]) {
this.worker.postMessage({preload:tool, platform:this.platform_id});
this.tools_preloaded[tool] = true;
@ -277,7 +286,7 @@ export class CodeProject {
path:mainfilename,
files:[mainfilename].concat(depfiles),
platform:this.platform_id,
tool:this.platform.getToolForFilename(this.mainPath),
tool:this.getToolForFilename(this.mainPath),
mainfile:true});
for (var dep of depends) {
if (dep.data && dep.link) {
@ -287,7 +296,7 @@ export class CodeProject {
path:dep.filename,
files:[dep.filename].concat(depfiles),
platform:this.platform_id,
tool:this.platform.getToolForFilename(dep.path)});
tool:this.getToolForFilename(dep.path)});
}
}
if (this.dataItems) msg.setitems = this.dataItems;

View File

@ -46,6 +46,7 @@ interface UIQueryString {
file0_name? : string;
file0_data? : string;
file0_type? : string;
tool?: string;
}
export var qs : UIQueryString = decodeQueryString(window.location.search||'?') as UIQueryString;
@ -252,6 +253,7 @@ async function newFilesystem() {
async function initProject() {
var filesystem = await newFilesystem();
current_project = new CodeProject(newWorker(), platform_id, platform, filesystem);
current_project.remoteTool = qs.tool || null;
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
current_project.callbackBuildResult = (result:WorkerResult) => {
setCompileOutput(result);

View File

@ -44,23 +44,38 @@ export class C64_WASMMachine extends BaseWASMMachine
this.prgstart = this.romarr[0] + (this.romarr[1]<<8); // get load address
// look for BASIC program start
if (this.prgstart == 0x801) {
this.prgstart = this.romarr[2] + (this.romarr[3]<<8) + 2; // point to after BASIC program
console.log("prgstart", hex(this.prgstart));
// decode SYS address from decimal?
if (this.romarr[6] == 0x9e) {
var addr = 0;
for (var i=0; i<5; i++) {
var ch = this.romarr[7+i];
if (ch == 0x9b || ch == 0) break;
addr = addr * 10 + (ch & 0xf);
}
this.prgstart = addr;
console.log("SYS", addr, hex(addr));
} else {
this.prgstart = this.romarr[2] + (this.romarr[3]<<8) + 2; // point to after BASIC program
console.log("RUN", this.prgstart, hex(this.prgstart));
}
}
// is program loaded into RAM?
if (this.prgstart < 0x8000) {
// advance BIOS a few frames
this.exports.machine_exec(this.sys, 250000);
// type in command (SYS 2061)
var cmd = "\rSYS "+this.prgstart+"\r";
var cmd = "\rSYS "+this.prgstart;
for (var i=0; i<cmd.length; i++) {
var key = cmd.charCodeAt(i);
this.exports.machine_exec(this.sys, 20000);
this.exports.machine_exec(this.sys, 30000);
this.exports.machine_key_down(this.sys, key);
this.exports.machine_exec(this.sys, 5000);
this.exports.machine_exec(this.sys, 30000);
this.exports.machine_key_up(this.sys, key);
this.exports.machine_exec(this.sys, 1); // chips/kbd.c has a "sticky counter"
}
// advance clock until program starts
this.exports.machine_key_down(this.sys, 13);
this.exports.machine_exec(this.sys, 1); // chips/kbd.c has a "sticky counter"
for (var i=0; i<100000 && this.getPC() != this.prgstart; i++) {
this.exports.machine_tick(this.sys);
}

View File

@ -0,0 +1,224 @@
import fs from 'fs';
import path from 'path';
import { spawn } from 'child_process';
import { CodeListingMap, WorkerBuildStep, WorkerError, WorkerErrorResult, WorkerFileUpdate, WorkerResult, isOutputResult } from '../../common/workertypes';
import { getBasePlatform, getRootBasePlatform } from '../../common/util';
import { BuildStep, makeErrorMatcher } from '../workermain';
import { parseObjDumpListing, parseObjDumpSymbolTable } from './clang';
const LLVM_MOS_TOOL: ServerBuildTool = {
name: 'llvm-mos',
version: '',
extensions: ['.c'],
archs: ['6502'],
platforms: ['atari8', 'c64', 'nes'],
platform_configs: {
default: {
binpath: 'llvm-mos/bin',
command: 'mos-clang',
args: ['-Os', '-g', '-o', '$OUTFILE', '$INFILES'],
},
debug: { // TODO
binpath: 'llvm-mos/bin',
command: 'llvm-objdump',
args: ['-l', '-t', '$WORKDIR/a.out.elf', '>$WORKDIR/debug.out']
},
c64: {
command: 'mos-c64-clang',
},
atari8: {
command: 'mos-atari8-clang',
},
nes: {
command: 'mos-nes-nrom-clang', // TODO
libargs: ['-lneslib']
},
}
}
export function findBestTool(step: BuildStep) {
if (!step?.tool) throw new Error('No tool specified');
const [name, version] = step.tool.split('@');
for (let tool of TOOLS) {
if (tool.name === name && (!version || version === 'latest' || tool.version === version)) {
return tool;
}
}
throw new Error(`Tool not found: ${step.tool}`);
}
export const TOOLS: ServerBuildTool[] = [
Object.assign({}, LLVM_MOS_TOOL, { version: '0.13.2' }),
];
interface ServerBuildTool {
name: string;
version: string;
extensions: string[];
archs: string[];
platforms: string[];
platform_configs: { [platform: string]: ServerBuildToolPlatformConfig };
}
interface ServerBuildToolPlatformConfig {
binpath?: string;
command?: string;
args?: string[];
libargs?: string[];
}
export class ServerBuildEnv {
rootdir: string;
sessionID: string;
tool: ServerBuildTool;
sessionDir: string;
constructor(rootdir: string, sessionID: string, tool: ServerBuildTool) {
this.rootdir = path.resolve(rootdir);
this.sessionID = sessionID;
this.tool = tool;
// make sure sessionID is well-formed
if (!sessionID.match(/^[a-zA-Z0-9_-]+$/)) {
throw new Error(`Invalid sessionID: ${sessionID}`);
}
// create sessionID directory if it doesn't exist
this.sessionDir = path.join(this.rootdir, 'sessions', sessionID);
if (!fs.existsSync(this.sessionDir)) {
fs.mkdirSync(this.sessionDir);
}
}
async addFileUpdate(file: WorkerFileUpdate) {
// make sure file.path contains no path components
if (file.path.match(/[\\\/]/)) {
throw new Error(`Invalid file path: ${file.path}`);
}
await fs.promises.writeFile(path.join(this.sessionDir, file.path), file.data);
}
async build(step: WorkerBuildStep, platform?: string): Promise<WorkerResult> {
// build config
let platformID = platform || getRootBasePlatform(step.platform);
let config = this.tool.platform_configs[platformID];
if (!config) {
throw new Error(`No config for platform ${platformID}`);
}
let defaultConfig = this.tool.platform_configs.default;
if (!defaultConfig) {
throw new Error(`No default config for tool ${this.tool.name}`);
}
config = Object.assign({}, defaultConfig, config); // combine configs
// copy args
let args = config.args.slice(0); //copy array
let command = config.command;
// replace $OUTFILE
let outfile = path.join(this.sessionDir, 'a.out'); // TODO? a.out
for (let i = 0; i < args.length; i++) {
args[i] = args[i].replace(/\$OUTFILE/g, outfile);
args[i] = args[i].replace(/\$WORKDIR/g, this.sessionDir);
}
// replace $INFILES with the list of input files
// TODO
let infiles = [];
for (let i = 0; i < step.files.length; i++) {
let f = step.files[i];
if (f.endsWith(this.tool.extensions[0])) {
infiles.push(path.join(this.sessionDir, f));
}
}
for (let i = 0; i < args.length; i++) {
if (args[i] === '$INFILES') {
args = args.slice(0, i).concat(infiles).concat(args.slice(i + 1));
break;
}
}
if (config.libargs) {
args = args.concat(config.libargs);
}
console.log(`Running: ${command} ${args.join(' ')}`);
// spawn after setting PATH env var
// TODO
let childProcess = spawn(command, args, {
shell: true,
cwd: this.rootdir,
env: { PATH: path.join(this.rootdir, config.binpath)
} });
let outputData = '';
let errorData = '';
// TODO?
childProcess.stdout.on('data', (data) => {
outputData += data.toString();
});
childProcess.stderr.on('data', (data) => {
errorData += data.toString();
});
return new Promise((resolve, reject) => {
childProcess.on('close', async (code) => {
if (code === 0) {
if (platform === 'debug') {
resolve(this.processDebugInfo(step));
} else {
resolve(this.processOutput(step));
}
} else {
let errorResult = await this.processErrors(step, errorData);
if (errorResult.errors.length === 0) {
errorResult.errors.push({ line: 0, msg: `Build failed.\n\n${errorData}` });
}
resolve(errorResult);
}
});
});
}
async processErrors(step: WorkerBuildStep, errorData: string): Promise<WorkerErrorResult> {
let errors = [];
// split errorData into lines
let errorMatcher = makeErrorMatcher(errors, /([^:/]+):(\d+):(\d+):\s*(.+)/, 2, 4, step.path, 1);
for (let line of errorData.split('\n')) {
errorMatcher(line);
}
return { errors };
}
async processOutput(step: WorkerBuildStep): Promise<WorkerResult> {
let outfile = path.join(this.sessionDir, 'a.out');
let output = await fs.promises.readFile(outfile, { encoding: 'base64' });
return { output };
}
async processDebugInfo(step: WorkerBuildStep): Promise<WorkerResult> {
let dbgfile = path.join(this.sessionDir, 'debug.out');
let dbglist = await fs.promises.readFile(dbgfile);
let listings = parseObjDumpListing(dbglist.toString());
let symbolmap = parseObjDumpSymbolTable(dbglist.toString());
return { output: [], listings, symbolmap };
}
async compileAndLink(step: WorkerBuildStep, updates: WorkerFileUpdate[]): Promise<WorkerResult> {
for (let file of updates) {
await this.addFileUpdate(file);
}
try {
let result = await this.build(step);
// did we succeed?
if (isOutputResult(result)) {
// do the debug info
const debugInfo = await this.build(step, 'debug');
if (isOutputResult(debugInfo)) {
result.listings = debugInfo.listings;
result.symbolmap = debugInfo.symbolmap;
}
}
return result;
} catch (err) {
return { errors: [{line:0, msg: err.toString()}] };
}
}
}

View File

@ -0,0 +1,49 @@
import path from 'path';
import { CodeListing, CodeListingMap } from "../../common/workertypes";
export function parseObjDumpSymbolTable(symbolTable) {
const lines = symbolTable.split('\n');
const result = {};
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith('00')) {
const parts = line.split(/\s+/);
if (parts.length < 5) continue;
const symbol = parts[parts.length-1];
const address = parseInt(parts[0], 16);
result[symbol] = address;
}
}
return result;
}
export function parseObjDumpListing(lst: string): CodeListingMap {
const lines = lst.split('\n');
const result: CodeListingMap = {};
var lastListing : CodeListing = null;
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith(';')) {
const fileInfoIndex = line.indexOf(':');
if (fileInfoIndex !== -1) {
const fileInfo = line.substring(1).trim();
const fileParts = fileInfo.split(':');
const file = path.basename(fileParts[0].trim()).split('.')[0] + '.lst';
const lineNumber = parseInt(fileParts[1], 10);
if (lineNumber > 0) {
if (!result[file]) result[file] = { lines: [], text: lst };
lastListing = result[file];
lastListing.lines.push({ line: lineNumber, offset: null });
}
}
} else if (lastListing && line.match(/^\s*[A-F0-9]+:.+/i)) {
const offsetIndex = line.indexOf(':');
if (offsetIndex !== -1) {
const offset = parseInt(line.substring(0, offsetIndex).trim(), 16);
lastListing.lines[lastListing.lines.length - 1].offset = offset;
}
}
}
return result;
}

View File

@ -0,0 +1,71 @@
import fs from 'fs';
import path from 'path';
import express, { Request, Response } from 'express';
import cors from 'cors';
import { WorkerBuildStep, WorkerFileUpdate } from '../../common/workertypes';
import { ServerBuildEnv, TOOLS, findBestTool } from './buildenv';
////////////////////
const app = express();
app.use(cors());
app.use(express.json({ limit: 1024*1024 })); // limit 1 MB
app.get('/info', (req: Request, res: Response) => {
// send a list of supported tools
res.json({ tools: TOOLS });
});
app.get('/test', async (req: Request, res: Response, next) => {
// quick test of the build
try {
const updates: WorkerFileUpdate[] = [{ path: 'test.c', data: 'int main() { return 0; }' }];
const buildStep: WorkerBuildStep = { tool: 'llvm-mos', platform: 'c64', files: ['test.c'] };
const env = new ServerBuildEnv(SERVER_ROOT, 'test', TOOLS[0]);
const result = await env.compileAndLink(buildStep, updates);
res.json(result);
} catch (err) {
return next(err);
}
});
app.post('/build', async (req: Request, res: Response, next) => {
try {
const updates: WorkerFileUpdate[] = req.body.updates;
const buildStep: WorkerBuildStep = req.body.buildStep;
const sessionID = req.body.sessionID;
const bestTool = findBestTool(buildStep);
const env = new ServerBuildEnv(SERVER_ROOT, sessionID, bestTool);
const result = await env.compileAndLink(buildStep, updates);
res.json(result);
} catch (err) {
return next(err);
}
});
// Catch errors
app.use((err: Error, req: Request, res: Response, next: Function) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// Start the server
const port = 3009;
/*{
origin: [`http://localhost:${port}`, 'http://localhost:8000']
}));*/
const SERVER_ROOT = process.env['8BITWS_SERVER_ROOT'] || path.resolve('./server-root');
const SESSION_ROOT = path.join(SERVER_ROOT, 'sessions');
if (!fs.existsSync(SESSION_ROOT)) {
fs.mkdirSync(SESSION_ROOT);
}
process.chdir(SESSION_ROOT);
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});

View File

@ -0,0 +1,47 @@
import { byteArrayToString, stringToByteArray } from "../../common/util";
import { WorkerFileUpdate, isErrorResult, isOutputResult, isUnchanged } from "../../common/workertypes";
import { BuildStep, BuildStepResult, gatherFiles, staleFiles, store } from "../workermain";
// TODO: are we running from 8bitworkshop.com in this worker?
const REMOTE_URL = "http://localhost:3009/build";
// create random UID
const sessionID = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
export async function buildRemote(step: BuildStep): Promise<BuildStepResult> {
gatherFiles(step); // TODO?
var binpath = "a.out"; // TODO?
if (staleFiles(step, [binpath])) {
// grab files from store
let updates : WorkerFileUpdate[] = [];
for (var i = 0; i < step.files.length; i++) {
let path = step.files[i];
let entry = store.workfs[path];
// convert to base64
let data = typeof entry.data === 'string' ? entry.data : btoa(byteArrayToString(entry.data));
updates.push({ path, data });
}
// build the command
let cmd = { buildStep: step, updates, sessionID };
// do a POST to the remote server, sending step as JSON
console.log('POST', cmd);
let result = await fetch(REMOTE_URL, {
method: "POST",
mode: "cors",
body: JSON.stringify(cmd),
headers: {
"Content-Type": "application/json"
}
});
// return the result as JSON
let json = await result.json();
// parse the result as JSON
if (isUnchanged(json)) return json;
if (isErrorResult(json)) return json;
if (isOutputResult(json)) {
json.output = stringToByteArray(atob(json.output));
return json;
}
throw new Error(`Unexpected result from remote build: ${JSON.stringify(json)}`);
}
}

View File

@ -516,8 +516,14 @@ class Builder {
while (this.steps.length) {
var step = this.steps.shift(); // get top of array
var platform = step.platform;
var toolfn = TOOLS[step.tool];
if (!toolfn) throw Error("no tool named " + step.tool);
var [tool, remoteTool] = step.tool.split(':', 2);
var toolfn = TOOLS[tool];
if (!toolfn) {
throw Error(`no tool named "${tool}"`);
}
if (remoteTool) {
step.tool = remoteTool;
}
step.params = PLATFORM_PARAMS[getBasePlatform(platform)];
try {
step.result = await toolfn(step);
@ -1121,6 +1127,7 @@ import * as x86 from './tools/x86'
import * as arm from './tools/arm'
import * as script from './tools/script'
import * as ecs from './tools/ecs'
import * as remote from './tools/remote'
var TOOLS = {
'dasm': dasm.assembleDASM,
@ -1158,6 +1165,7 @@ var TOOLS = {
'vasmarm': arm.assembleVASMARM,
//'js': script.runJavascript,
'ecs': ecs.assembleECS,
'remote': remote.buildRemote
}
var TOOL_PRELOADFS = {