├── .gitignore ├── 6502.html ├── 6502.js ├── README ├── demo0.asm ├── demo1.asm ├── demo2.asm ├── images ├── bkg.png └── blacktocat.png ├── index.html ├── javascripts └── main.js ├── params.json └── stylesheets ├── pygment_trac.css └── stylesheet.css /.gitignore: -------------------------------------------------------------------------------- 1 | *~ -------------------------------------------------------------------------------- /6502.html: -------------------------------------------------------------------------------- 1 | 2 | 30 | 31 | 32 | 6502 emulator 33 | 46 | 47 | 48 | 49 |
50 | Virtual graphic screen
51 | 52 |
53 |
59 |
60 | 61 |
62 | 63 | 827 | 828 | 829 | -------------------------------------------------------------------------------- /6502.js: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ****************************************************************************** 3 | ** ** 4 | ** Copyright (c) 2012 by Andrea Griffini ** 5 | ** ** 6 | ** Permission is hereby granted, free of charge, to any person obtaining ** 7 | ** a copy of this software and associated documentation files (the ** 8 | ** "Software"), to deal in the Software without restriction, including ** 9 | ** without limitation the rights to use, copy, modify, merge, publish, ** 10 | ** distribute, sublicense, and/or sell copies of the Software, and to ** 11 | ** permit persons to whom the Software is furnished to do so, subject to ** 12 | ** the following conditions: ** 13 | ** ** 14 | ** The above copyright notice and this permission notice shall be ** 15 | ** included in all copies or substantial portions of the Software. ** 16 | ** ** 17 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** 18 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** 19 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ** 20 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ** 21 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ** 22 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ** 23 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ** 24 | ** ** 25 | ****************************************************************************** 26 | ****************************************************************************/ 27 | 28 | // Note: special read/write only works for LDA/STA absolute 29 | 30 | // key=address, value=function(data){...} 31 | let special_write = { }; 32 | 33 | // key=address, value=function(){...} 34 | let special_read = { }; 35 | 36 | // Utility //////////////////////////////////////////////////////////// 37 | 38 | function hex(n,x) 39 | { 40 | let r = ""; 41 | for (let i=0; i>= 4; 45 | } 46 | return r; 47 | } 48 | 49 | function parseHex(x) 50 | { 51 | let r = 0; 52 | for (let i=0; i127);"; } 81 | function ssz(x) { sz(x); ss(x); } 82 | function fz() { let oz=set_z; set_z=""; return oz; } 83 | function fs() { let os=set_s; set_s=""; return os; } 84 | function fsz() { return fz()+fs(); } 85 | 86 | function fszm() 87 | { 88 | // Special case; if current delayed S/Z flags are 89 | // from memory then we must evaluate them before any 90 | // memory write. If they're from registers then 91 | // we can instead just keep delaying... 92 | return ((set_z.indexOf("m")!=-1 ? fz() : "") + 93 | (set_s.indexOf("m")!=-1 ? fs() : "")); 94 | } 95 | 96 | // Addressing modes 97 | 98 | function imm() { return ""+m[ip++]; } 99 | function zpg() { return "m["+m[ip++]+"]"; } 100 | function zpx() { return "m[(x+"+m[ip++]+")&255]"; } 101 | function zpy() { return "m[(y+"+m[ip++]+")&255]"; } 102 | function abs() { ip+=2; return "m["+(m[ip-2]+(m[ip-1]<<8))+"]"; } 103 | function abx() { ip+=2; return "m[(x+"+(m[ip-2]+(m[ip-1]<<8))+")&65535]"; } 104 | function aby() { ip+=2; return "m[(y+"+(m[ip-2]+(m[ip-1]<<8))+")&65535]"; } 105 | function iix() { let z=m[ip++]; return "m[m[("+z+"+x)&255]+(m[("+(z+1)+"+x)&255]<<8)]"; } 106 | function iiy() { let z=m[ip++]; return "m[(m["+z+"]+(m["+((z+1)&255)+"]<<8)+y)&65535]"; } 107 | function rel() { let delta=m[ip++]; if(delta>=128)delta-=256; return ""+((ip+delta)&65535); } 108 | function adr() { ip+=2; return ""+(m[ip-2]+(m[ip-1]<<8)); } 109 | function ind() { let z=m[ip]+m[ip+1]*256; ip+=2; return "m["+z+"]+(m["+((z+1)&65535)+"]<<8)"; } 110 | function acc() { return "a"; } 111 | 112 | // Disassembling addressing modes 113 | 114 | function s_imm(ip) { return [1, "#$" + hex(2,m[ip])]; } 115 | function s_zpg(ip) { return [1, "$" + hex(2,m[ip])]; } 116 | function s_zpx(ip) { return [1, "$" + hex(2,m[ip]) + ",x"]; } 117 | function s_zpy(ip) { return [1, "$" + hex(2,m[ip]) + ",y"]; } 118 | function s_abs(ip) { return [2, "$" + hex(4,m[ip]+m[(ip+1)&65535]*256)]; } 119 | function s_abx(ip) { return [2, "$" + hex(4,m[ip]+m[(ip+1)&65535]*256) + ",x"]; } 120 | function s_aby(ip) { return [2, "$" + hex(4,m[ip]+m[(ip+1)&65535]*256) + ",y"]; } 121 | function s_iix(ip) { return [1, "($" + hex(2,m[ip]) + ",x)"]; } 122 | function s_iiy(ip) { return [1, "($" + hex(2,m[ip]) + "),y"]; } 123 | function s_rel(ip) { let delta = m[ip]; if (delta>=128) delta-=256; return [1, "$" + hex(4,ip+1+delta)]; } 124 | function s_adr(ip) { return [2, "$" + hex(4,m[ip]+m[ip+1]*256)]; } 125 | function s_ind(ip) { return [2, "($" + hex(4,m[ip]+m[ip+1]*256) + ")"]; } 126 | function s_acc(ip) { return [0, "a"]; } 127 | 128 | // Opcode implentation 129 | 130 | function ___() { return "{*Invalid opcode*}"; } 131 | 132 | function adc(m) { ssz("a"); return "w="+m+"+a+c;c=(w>255);v=((a&0x80)!=(w&0x80));a=(w&255);"; } 133 | function and(m) { ssz("a"); return "a&="+m+";"; } 134 | function asl(m) { ssz(m); return "w=("+m+"<<1);c=(w>255);"+m+"=w&255;"; } 135 | function bcc(m) { return "if(!c){"+fsz()+"ip="+m+";return;}"; } 136 | function bcs(m) { return "if(c){"+fsz()+"ip="+m+";return;}"; } 137 | function beq(m) { return fz()+"if(z){"+fs()+"ip="+m+";return;}"; } 138 | function bit(m) { sz("a&"+m); ss(m); return "v=(("+m+"&0x40)!=0);"; } 139 | function bmi(m) { return fs()+"if(s){"+fz()+"ip="+m+";return;}"; } 140 | function bne(m) { return fz()+"if(!z){"+fs()+"ip="+m+";return;}"; } 141 | function bpl(m) { return fs()+"if(!s){"+fz()+"ip="+m+";return;}"; } 142 | function brk(m) { return fsz()+"alert(\"BRK #$" + hex(2, m) + "\");ip=0;return;"; } 143 | function bvc(m) { return "if(!v){"+fsz()+"ip="+m+";return;}"; } 144 | function bvs(m) { return "if(v){"+fsz()+"ip="+m+";return;}"; } 145 | function clc(m) { return "c=0;"; } 146 | function cld(m) { return "d=0;"; } 147 | function cli(m) { throw "Not implemented"; } 148 | function clv(m) { return "v=0;"; } 149 | function cmp(m) { ssz("w"); return "c=(a>="+m+");w=(a-"+m+")&255;"; } 150 | function cpx(m) { ssz("w"); return "c=(x>="+m+");w=(x-"+m+")&255;"; } 151 | function cpy(m) { ssz("w"); return "c=(y>="+m+");w=(y-"+m+")&255;"; } 152 | function dec(m) { ssz(m); return "maykill("+m.substr(2,m.length-3)+");"+m+"=("+m+"-1)&255;if(!alive){ip="+ip+";return;}"; } 153 | function dex(m) { ssz("x"); return "x=(x-1)&255;"; } 154 | function dey(m) { ssz("y"); return "y=(y-1)&255;"; } 155 | function eor(m) { ssz("a"); return "a^="+m+";"; } 156 | function inc(m) { ssz(m); return "maykill("+m.substr(2,m.length-3)+");"+m+"=("+m+"+1)&255;if(!alive){ip="+ip+";return;}"; } 157 | function inx(m) { ssz("x"); return "x=(x+1)&255;"; } 158 | function iny(m) { ssz("y"); return "y=(y+1)&255;"; } 159 | function jmp(m) { return fsz()+"ip="+m+"; return;"; } 160 | function jsr(m) { return fsz()+"m[256+sp]="+((ip-1)&255)+";m[256+((sp+1)&255)]="+((ip-1)>>8)+";sp=(sp+2)&255;ip="+m+";return;"; } 161 | function lda(m) { ssz("a"); return "a="+m+";"; } 162 | function ldx(m) { ssz("x"); return "x="+m+";"; } 163 | function ldy(m) { ssz("y"); return "y="+m+";"; } 164 | function lsr(m) { ssz(m); return "c="+m+"&1;"+m+">>=1;"; } 165 | function nop(m) { return ""; } 166 | function ora(m) { ssz("a"); return "a|="+m+";"; } 167 | function pha(m) { return "m[256+sp]=a;sp=(sp+1)&255;"; } 168 | function php(m) { throw "Not implemented"; } 169 | function pla(m) { ssz("a"); return "sp=(sp-1)&255;a=m[256+sp];"; } 170 | function plp(m) { throw "Not implemented"; } 171 | function rol(m) { ssz(m); return "w="+m+";"+m+"=((w<<1)+c)&255;c=(w>127);"; } 172 | function ror(m) { ssz(m); return "w="+m+";"+m+"=((w>>1)+(c<<7));c=(w&1);"; } 173 | function rti(m) { throw "Not implemented"; } 174 | function rts(m) { return fsz()+"sp=(sp-2)&255;ip=(m[sp+256]+(m[256+((sp+1)&255)]<<8)+1)&65535;"; } 175 | function sbc(m) { ssz("w"); return "w=a-"+m+"-(1-c);c=(w>=0);v=((a&0x80)!=(w&0x80));a=(w&255);"; } 176 | function sec(m) { return "c=1;"; } 177 | function sed(m) { throw "Not implemented"; } 178 | function sei(m) { throw "Not implemented"; } 179 | function sta(m) { return "maykill("+m.substr(2,m.length-3)+");"+fszm()+m+"=a;if(!alive){ip="+ip+";return;}"; } 180 | function stx(m) { return "maykill("+m.substr(2,m.length-3)+");"+fszm()+m+"=x;if(!alive){ip="+ip+";return;}"; } 181 | function sty(m) { return "maykill("+m.susbtr(2,m.length-3)+");"+fszm()+m+"=y;if(!alive){ip="+ip+";return;}"; } 182 | function tax(m) { ssz("a"); return "x=a;"; } 183 | function tay(m) { ssz("a"); return "y=a;"; } 184 | function tsx(m) { ssz("x"); return "x=sp;"; } 185 | function txa(m) { ssz("a"); return "a=x;"; } 186 | function txs(m) { return "sp=x;"; } 187 | function tya(m) { ssz("a"); return "a=y;"; } 188 | function dbg(m) { return "console.log({a,x,y});"; } 189 | 190 | let jitstoppers = ["jmp", "jsr", "rts", "brk"]; 191 | 192 | let opcodes = 193 | /* 0,8 1,9 2,A 3,B 4,C 5,D 6,E 7,F */ 194 | [["brk","imm"],["ora","iix"],["___","___"],["___","___"],["___","___"],["ora","zpg"],["asl","zpg"],["___","___"], // 00 195 | ["php","___"],["ora","imm"],["asl","acc"],["___","___"],["___","___"],["ora","abs"],["asl","abs"],["___","___"], // 08 196 | ["bpl","rel"],["ora","iiy"],["___","___"],["___","___"],["___","___"],["ora","zpx"],["asl","zpx"],["___","___"], // 10 197 | ["clc","___"],["ora","aby"],["___","___"],["___","___"],["___","___"],["ora","abx"],["asl","abx"],["___","___"], // 18 198 | ["jsr","adr"],["and","iix"],["___","___"],["___","___"],["bit","zpg"],["and","zpg"],["rol","zpg"],["___","___"], // 20 199 | ["plp","___"],["and","imm"],["rol","acc"],["___","___"],["bit","abs"],["and","abs"],["rol","abs"],["___","___"], // 28 200 | ["bmi","rel"],["and","iiy"],["___","___"],["___","___"],["___","___"],["and","zpx"],["rol","zpx"],["___","___"], // 30 201 | ["sec","___"],["and","aby"],["___","___"],["___","___"],["___","___"],["and","abx"],["rol","abx"],["___","___"], // 38 202 | ["rti","___"],["eor","iix"],["___","___"],["___","___"],["___","___"],["eor","zpg"],["lsr","zpg"],["___","___"], // 40 203 | ["pha","___"],["eor","imm"],["lsr","acc"],["___","___"],["jmp","adr"],["eor","abs"],["lsr","abs"],["___","___"], // 48 204 | ["bvc","rel"],["eor","iiy"],["___","___"],["___","___"],["___","___"],["eor","zpx"],["lsr","zpx"],["___","___"], // 50 205 | ["cli","___"],["eor","aby"],["___","___"],["___","___"],["___","___"],["eor","abx"],["lsr","abx"],["___","___"], // 58 206 | ["rts","___"],["adc","iix"],["___","___"],["___","___"],["___","___"],["adc","zpg"],["ror","zpg"],["___","___"], // 60 207 | ["pla","___"],["adc","imm"],["ror","acc"],["___","___"],["jmp","ind"],["adc","abs"],["ror","abs"],["___","___"], // 68 208 | ["bvs","rel"],["adc","iiy"],["___","___"],["___","___"],["___","___"],["adc","zpx"],["ror","zpx"],["___","___"], // 70 209 | ["sei","___"],["adc","aby"],["___","___"],["___","___"],["___","___"],["adc","abx"],["ror","abx"],["___","___"], // 78 210 | ["___","___"],["sta","iix"],["___","___"],["___","___"],["sty","zpg"],["sta","zpg"],["stx","zpg"],["___","___"], // 80 211 | ["dey","___"],["___","___"],["txa","___"],["___","___"],["sty","abs"],["sta","abs"],["stx","abs"],["___","___"], // 88 212 | ["bcc","rel"],["sta","iiy"],["___","___"],["___","___"],["sty","zpx"],["sta","zpx"],["stx","zpy"],["___","___"], // 90 213 | ["tya","___"],["sta","aby"],["txs","___"],["___","___"],["___","___"],["sta","abx"],["___","___"],["___","___"], // 98 214 | ["ldy","imm"],["lda","iix"],["ldx","imm"],["___","___"],["ldy","zpg"],["lda","zpg"],["ldx","zpg"],["___","___"], // A0 215 | ["tay","___"],["lda","imm"],["tax","___"],["___","___"],["ldy","abs"],["lda","abs"],["ldx","abs"],["___","___"], // A8 216 | ["bcs","rel"],["lda","iiy"],["___","___"],["___","___"],["ldy","zpx"],["lda","zpx"],["ldx","zpy"],["___","___"], // B0 217 | ["clv","___"],["lda","aby"],["tsx","___"],["___","___"],["ldy","abx"],["lda","abx"],["ldx","aby"],["___","___"], // B8 218 | ["cpy","imm"],["cmp","iix"],["___","___"],["___","___"],["cpy","zpg"],["cmp","zpg"],["dec","zpg"],["___","___"], // C0 219 | ["iny","___"],["cmp","imm"],["dex","___"],["___","___"],["cpy","abs"],["cmp","abs"],["dec","abs"],["___","___"], // C8 220 | ["bne","rel"],["cmp","iiy"],["___","___"],["___","___"],["___","___"],["cmp","zpx"],["dec","zpx"],["___","___"], // D0 221 | ["cld","___"],["cmp","aby"],["___","___"],["___","___"],["___","___"],["cmp","abx"],["dec","abx"],["___","___"], // D8 222 | ["cpx","imm"],["sbc","iix"],["___","___"],["___","___"],["cpx","zpg"],["sbc","zpg"],["inc","zpg"],["___","___"], // E0 223 | ["inx","___"],["sbc","imm"],["nop","___"],["___","___"],["cpx","abs"],["sbc","abs"],["inc","abs"],["___","___"], // E8 224 | ["beq","rel"],["sbc","iiy"],["___","___"],["___","___"],["___","___"],["sbc","zpx"],["inc","zpx"],["___","___"], // F0 225 | ["sed","___"],["sbc","aby"],["___","___"],["___","___"],["___","___"],["sbc","abx"],["inc","abx"],["dbg","___"]]; // F8 226 | 227 | let revopcodes = {}; 228 | (function() { 229 | for (let i=0; i<256; i++) 230 | revopcodes[opcodes[i][0]+"/"+opcodes[i][1]] = i; 231 | })(); 232 | 233 | function disassemble(ip) 234 | { 235 | let op = opcodes[m[ip]]; 236 | if (op[0] == "___") 237 | { 238 | return [0, hex(4, ip) + ": " + hex(2, m[ip]) + " ???"]; 239 | } 240 | else if (op[1] == "___") 241 | { 242 | return [0, hex(4, ip) + ": " + hex(2, m[ip]) + " " + op[0]]; 243 | } 244 | else 245 | { 246 | let ds = window["s_" + op[1]]((ip+1)&65535); 247 | return [ds[0], (hex(4, ip) + ": " + hex(2, m[ip]) + " " + 248 | (ds[0] > 0 ? hex(2, m[(ip+1)&65535]) : " ") + " " + 249 | (ds[0] > 1 ? hex(2, m[(ip+2)&65535]) : " ") + " " + 250 | op[0] + " " + ds[1])]; 251 | } 252 | } 253 | 254 | function maykill(m) 255 | { 256 | let aL = jitmap[m]; 257 | while (aL && aL.length) 258 | { 259 | let f = aL.pop(); 260 | if (f === current_f) alive = false; 261 | for (let i=f.ip0; i -1) 295 | break; 296 | } 297 | if (count == NN) 298 | code += "ip=" + ip + ";"; 299 | } 300 | code += fsz()+"})"; 301 | let f = eval(code); 302 | 303 | for (let i=ip0; i>8]; 371 | } 372 | if ((mm = /^([0-9]+)$/.exec(x))) 373 | { 374 | let x16 = parseInt(x); 375 | return [x16&255, x16>>8]; 376 | } 377 | if ((mm = /^([a-zA-Z][a-zA-Z0-9_]*)$/.exec(x))) 378 | { 379 | fixups.push([ip+1, mm[1], "abs"]); 380 | return [null, null]; 381 | } 382 | throw "Unable to parse value '" + x + "'"; 383 | } 384 | 385 | if ((mm = /^ +([a-z]{3}) *$/.exec(L))) 386 | { 387 | opcode = mm[1]; 388 | mr = ["___"]; 389 | } 390 | else if ((mm = /^ +([a-z]{3}) +[aA] *$/.exec(L))) 391 | { 392 | opcode = mm[1]; 393 | mr = ["acc"]; 394 | } 395 | else if ((mm = /^ +([a-z]{3}) +#(\$[0-9A-Fa-f]+|[0-9]+|[a-zA-Z][a-zA-Z0-9_]*) *$/.exec(L))) 396 | { 397 | opcode = mm[1]; 398 | mr = ["imm", value(mm[2])[0]]; 399 | } 400 | else if ((mm = /^ +([a-z]{3}) +(\$[0-9A-Fa-f]+|[0-9]+|[a-zA-Z][a-zA-Z0-9_]*) *$/.exec(L))) 401 | { 402 | opcode = mm[1]; 403 | addr = value(mm[2]); 404 | if (addr.length == 2) 405 | mr = ["abs", addr[0], addr[1]]; 406 | else 407 | mr = ["zpg", addr[0]]; 408 | } 409 | else if ((mm = /^ +([a-z]{3}) +(\$[0-9A-Fa-f]+|[0-9]+|[a-zA-Z][a-zA-Z0-9_]*),x *$/.exec(L))) 410 | { 411 | opcode = mm[1]; 412 | addr = value(mm[2]); 413 | if (addr.length == 2) 414 | mr = ["abx", addr[0], addr[1]]; 415 | else 416 | mr = ["zpx", addr[0]]; 417 | } 418 | else if ((mm = /^ +([a-z]{3}) +(\$[0-9A-Fa-f]+|[0-9]+|[a-zA-Z][a-zA-Z0-9_]*),y *$/.exec(L))) 419 | { 420 | opcode = mm[1]; 421 | addr = value(mm[2]); 422 | if (addr.length == 2) 423 | mr = ["aby", addr[0], addr[1]]; 424 | else 425 | mr = ["zpy", addr[0]]; 426 | } 427 | else if ((mm = /^ +([a-z]{3}) +\((\$[0-9A-Fa-f]+|[0-9]+|[a-zA-Z][a-zA-Z0-9_]*),x\) *$/.exec(L))) 428 | { 429 | opcode = mm[1]; 430 | mr = ["iix", value(mm[2])[0]]; 431 | } 432 | else if ((mm = /^ +([a-z]{3}) +\((\$[0-9A-Fa-f]+|[0-9]+|[a-zA-Z][a-zA-Z0-9_]*)\),y *$/.exec(L))) 433 | { 434 | opcode = mm[1]; 435 | mr = ["iiy", value(mm[2])]; 436 | } 437 | else if ((mm = /^ +([a-z]{3}) +\((\$[0-9A-Fa-f]+|[0-9]+|[a-zA-Z][a-zA-Z0-9_]*)\) *$/.exec(L))) 438 | { 439 | opcode = mm[1]; 440 | let addr = value(mm[2]); 441 | mr = ["ind", addr[0], addr[1]]; 442 | } 443 | else 444 | { 445 | throw "Unable to parse '" + L + "'"; 446 | } 447 | 448 | if (opcode[0] == "b" && opcode != "bit" && opcode != "brk" && mr[0] == "abs") 449 | { 450 | if (mr[1] == null) 451 | { 452 | fixups[fixups.length-1][2] = "rel"; 453 | mr = ["rel", null]; 454 | } 455 | else 456 | { 457 | let delta = mr[1] + mr[2]*256 - (ip + 2); 458 | if (delta < -128 || delta > 127) 459 | throw "Relative jump out of range"; 460 | mr = ["rel", delta & 255]; 461 | } 462 | } 463 | 464 | if (opcode[0] == "j" && mr[0] == "abs") 465 | mr[0] = "adr"; 466 | 467 | let rop = revopcodes[opcode + "/" + mr[0]]; 468 | if (rop == undefined) throw '"' + L + "\": Invalid operation/addressing mode"; 469 | m[ip] = rop; ip = (ip + 1)&65535; 470 | for (let j=1; j 127) throw "Relative jump to '" + fu[1] + "' out of range"; 494 | m[fu[0]] = delta & 255; 495 | } 496 | else 497 | { 498 | let target = parseHex(addr.substr(1)); 499 | m[fu[0]] = target & 255; 500 | m[fu[0]+1] = target >> 8; 501 | } 502 | } 503 | } 504 | 505 | function run() 506 | { 507 | if (ip == 0) 508 | { 509 | alert("Program execution completed"); 510 | } 511 | else 512 | { 513 | let start = (new Date).getTime(); 514 | let now; 515 | while (ip != 0 && (now = (new Date).getTime()) < start + 50) 516 | { 517 | for (let k=0; ip && k<100; k++) 518 | { 519 | alive = true; 520 | (current_f=(jitcode[ip]||(jitcode[ip]=jit())))(); 521 | } 522 | } 523 | ctx.putImageData(data, 0, 0); 524 | setTimeout(run, 0); 525 | } 526 | } 527 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | **************************************************************************** 2 | ****************************************************************************** 3 | ** ** 4 | ** Copyright (c) 2012 by Andrea Griffini ** 5 | ** ** 6 | ** Permission is hereby granted, free of charge, to any person obtaining ** 7 | ** a copy of this software and associated documentation files (the ** 8 | ** "Software"), to deal in the Software without restriction, including ** 9 | ** without limitation the rights to use, copy, modify, merge, publish, ** 10 | ** distribute, sublicense, and/or sell copies of the Software, and to ** 11 | ** permit persons to whom the Software is furnished to do so, subject to ** 12 | ** the following conditions: ** 13 | ** ** 14 | ** The above copyright notice and this permission notice shall be ** 15 | ** included in all copies or substantial portions of the Software. ** 16 | ** ** 17 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** 18 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** 19 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ** 20 | ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ** 21 | ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ** 22 | ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ** 23 | ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ** 24 | ** ** 25 | ****************************************************************************** 26 | **************************************************************************** 27 | 28 | 6502 Javascript emulator. 29 | 30 | Not an interpreter, but a JIT compiler to Javascript. 31 | 32 | Includes a 6502 disassembler and a small assembler. 33 | 34 | Now with partial support of self-modifying code. Memory can be modified 35 | in MANY ways (including PHA or JSR) and code can be anywhere. Now it works 36 | only if the memory change is done using STA, STX, STY, INC or DEC. -------------------------------------------------------------------------------- /demo0.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Special locations 3 | ; (they work with LDA/STA abs only!) 4 | ; 5 | set_palette = $FF00 ; W: sets current index 6 | write_color = $FF01 ; W++: R, G or B 7 | set_row = $FF02 ; W: pixel row 8 | set_col = $FF03 ; W: pixel col 9 | write_pixel = $FF04 ; W++: writes a pixel 10 | 11 | random = $FF80 ; R: a random byte 12 | clock0 = $FF81 ; R: updates clock and returns low byte 13 | clock1 = $FF82 ; R: returns second byte of clock 14 | clock2 = $FF83 ; R: returns third byte of clock 15 | clock3 = $FF84 ; R: returns fourth byte of clock 16 | 17 | mouse_b = $FF85 ; R: mouse buttons (bits 0/1/2) or 255 if outside 18 | mouse_x = $FF86 ; R: mouse x position (0 if outside) 19 | mouse_y = $FF87 ; R: mouse y position (0 if outside) 20 | 21 | ; 22 | ; Execution begins at "start" and stops when 23 | ; program counter becomes $0000 24 | ; 25 | .org $0200 26 | 27 | ... put your code here ... 28 | -------------------------------------------------------------------------------- /demo1.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Special locations 3 | ; (they work with LDA/STA abs only!) 4 | ; 5 | set_palette = $FF00 ; W: sets current index 6 | write_color = $FF01 ; W++: R, G or B 7 | set_row = $FF02 ; W: pixel row 8 | set_col = $FF03 ; W: pixel col 9 | write_pixel = $FF04 ; W++: writes a pixel 10 | 11 | random = $FF80 ; R: a random byte 12 | clock0 = $FF81 ; R: updates clock and returns low byte 13 | clock1 = $FF82 ; R: returns second byte of clock 14 | clock2 = $FF83 ; R: returns third byte of clock 15 | clock3 = $FF84 ; R: returns fourth byte of clock 16 | 17 | mouse_b = $FF85 ; R: mouse buttons (bits 0/1/2) or 255 if outside 18 | mouse_x = $FF86 ; R: mouse x position (0 if outside) 19 | mouse_y = $FF87 ; R: mouse y position (0 if outside) 20 | 21 | ; 22 | ; Execution begins at "start" and stops when 23 | ; program counter becomes $0000 24 | ; 25 | .org $0200 26 | .db $0c, $02, $35, $02, $6a, $02, $a1, $02, $e0, $02, $5b, $03, $ff, $00, $6f, $05 27 | .db $1a, $07, $19, $07, $19, $07, $19, $07, $1a, $05, $1c, $03, $1c, $05, $1a, $07 28 | .db $18, $09, $19, $05, $1b, $05, $1a, $07, $19, $07, $18, $09, $17, $09, $17, $09 29 | .db $18, $07, $17, $0b, $4a, $ff, $00, $2a, $03, $01, $06, $01, $03, $12, $03, $01 30 | .db $06, $01, $03, $12, $0e, $12, $0e, $12, $0e, $12, $0e, $12, $0e, $13, $0c, $16 31 | .db $08, $18, $08, $17, $0a, $16, $0a, $16, $0a, $16, $0a, $15, $0c, $14, $0c, $14 32 | .db $0c, $14, $0c, $13, $0e, $12, $0e, $12, $0e, $49, $b0, $01, $1f, $02, $1e, $03 33 | .db $1c, $05, $1a, $07, $18, $09, $16, $0b, $14, $0c, $13, $0d, $12, $0e, $11, $0f 34 | .db $12, $06, $01, $07, $13, $01, $04, $08, $16, $0a, $14, $0c, $13, $0c, $14, $0c 35 | .db $13, $0d, $13, $0d, $13, $0d, $14, $0c, $14, $0d, $12, $0e, $11, $10, $10, $10 36 | .db $48, $4f, $02, $1e, $02, $1d, $04, $1b, $06, $19, $07, $19, $06, $02, $01, $16 37 | .db $06, $02, $02, $16, $05, $02, $03, $16, $0a, $17, $08, $18, $08, $1a, $04, $1b 38 | .db $06, $18, $0a, $15, $0c, $17, $06, $19, $08, $18, $08, $18, $08, $17, $0a, $16 39 | .db $0a, $16, $0a, $15, $0c, $14, $0c, $14, $0c, $14, $0c, $15, $0a, $13, $10, $48 40 | .db $cc, $02, $04, $02, $17, $04, $02, $04, $16, $04, $02, $04, $12, $02, $03, $02 41 | .db $04, $02, $03, $02, $0d, $04, $03, $01, $04, $01, $03, $04, $0c, $04, $03, $02 42 | .db $02, $02, $03, $04, $0d, $02, $04, $06, $04, $02, $0f, $02, $03, $06, $03, $02 43 | .db $10, $04, $01, $06, $01, $04, $0c, $02, $02, $10, $02, $02, $07, $04, $02, $0e 44 | .db $02, $04, $06, $04, $02, $0e, $02, $04, $07, $02, $01, $12, $01, $02, $0a, $14 45 | .db $0c, $14, $0d, $12, $0e, $12, $0e, $08, $02, $08, $0f, $01, $0e, $01, $10, $06 46 | .db $01, $02, $01, $06, $10, $01, $01, $02, $03, $02, $03, $02, $01, $01, $10, $06 47 | .db $01, $02, $01, $06, $10, $01, $0e, $01, $10, $10, $48, $8f, $02, $1e, $02, $1c 48 | .db $06, $1a, $06, $14, $04, $04, $02, $04, $04, $0c, $09, $01, $02, $01, $09, $09 49 | .db $18, $08, $03, $03, $0c, $03, $03, $07, $03, $05, $0a, $05, $03, $06, $03, $06 50 | .db $08, $06, $03, $06, $03, $02, $01, $01, $01, $02, $06, $02, $01, $01, $01, $02 51 | .db $03, $06, $03, $03, $01, $04, $04, $04, $01, $03, $03, $06, $04, $01, $01, $01 52 | .db $01, $03, $04, $03, $01, $01, $01, $01, $04, $07, $04, $03, $0a, $03, $04, $08 53 | .db $05, $02, $0a, $02, $05, $08, $06, $01, $0a, $01, $06, $09, $08, $01, $04, $01 54 | .db $08, $0b, $08, $04, $08, $0d, $07, $01, $02, $01, $07, $0e, $06, $01, $01, $02 55 | .db $01, $01, $06, $0f, $01, $0e, $01, $10, $06, $01, $02, $01, $06, $10, $01, $01 56 | .db $02, $03, $02, $03, $02, $01, $01, $10, $06, $01, $02, $01, $06, $10, $01, $0e 57 | .db $01, $10, $10, $48 58 | 59 | ;; Box drawing parameters 60 | x0 = $00 61 | y0 = $01 62 | x1 = $02 63 | y1 = $03 64 | color = $04 65 | 66 | ;; Animated square position and speed 67 | sqx = $05 68 | sqy = $06 69 | sqdx = $07 70 | sqdy = $08 71 | 72 | ;; Line drawing 73 | dx = $09 74 | dy = $0A 75 | ix = $0B 76 | iy = $0C 77 | cx = $0D 78 | cy = $0E 79 | m = $0F 80 | 81 | ;; Counter 82 | count_l = $10 83 | count_h = $11 84 | 85 | ;; Chess piece definition reader 86 | cpdr_l = $12 87 | cpdr_h = $13 88 | 89 | ;; Current and old current square on chessboard, secondary square 90 | bcsq = $15 91 | obcsq = $16 92 | bcsq2 = $17 93 | 94 | ;; Secondary color (foreground) for piece drawing 95 | color2 = $18 96 | 97 | ;; Draws a line from x0, y0 to x1, y1 98 | drawline: 99 | ; dx/ix computation 100 | ldx #$01 101 | lda x1 102 | sec 103 | sbc x0 104 | bcs dlxpos 105 | eor #$FF 106 | sbc #$FE 107 | ldx #$FF 108 | dlxpos: 109 | sta dx 110 | stx ix 111 | 112 | ; dy/iy computation 113 | ldx #$01 114 | lda y1 115 | sec 116 | sbc y0 117 | bcs dlypos 118 | eor #$FF 119 | sbc #$FE 120 | ldx #$FF 121 | dlypos: 122 | sta dy 123 | stx iy 124 | 125 | ; m/cx/cy computation 126 | lda dx 127 | cmp dy 128 | bcs dlxm 129 | lda dy 130 | dlxm: 131 | sta m 132 | tay 133 | bne dlsome 134 | rts 135 | dlsome: 136 | lsr a 137 | sta cx 138 | sta cy 139 | 140 | ; main loop 141 | dlloop: 142 | lda x0 143 | sta set_col 144 | lda y0 145 | sta set_row 146 | lda color 147 | sta write_pixel 148 | 149 | ; x-inc 150 | lda cx 151 | clc 152 | adc dx 153 | sta cx 154 | bcs dlxi 155 | cmp m 156 | bcc dlnoxi 157 | dlxi: 158 | lda x0 159 | clc 160 | adc ix 161 | sta x0 162 | lda cx 163 | sec 164 | sbc m 165 | sta cx 166 | dlnoxi: 167 | 168 | ; y-inc 169 | lda cy 170 | clc 171 | adc dy 172 | sta cy 173 | bcs dlyi 174 | cmp m 175 | bcc dlnoyi 176 | dlyi: 177 | lda y0 178 | clc 179 | adc iy 180 | sta y0 181 | lda cy 182 | sec 183 | sbc m 184 | sta cy 185 | dlnoyi: 186 | 187 | dey 188 | bne dlloop 189 | rts 190 | 191 | 192 | ;; Fills a box with a solid color 193 | fillbox: 194 | lda y0 195 | sta set_row 196 | lda x0 197 | sta set_col 198 | lda x1 199 | sec 200 | sbc x0 201 | tax 202 | lda color 203 | fbxloop: 204 | sta write_pixel 205 | dex 206 | bne fbxloop 207 | inc y0 208 | lda y0 209 | cmp y1 210 | bne fillbox 211 | rts 212 | 213 | ;; Sets square coordinates for bouncing animation 214 | set_square: 215 | lda sqx 216 | clc 217 | adc #$08 218 | sta x0 219 | clc 220 | adc #$10 221 | sta x1 222 | lda sqy 223 | clc 224 | adc #$08 225 | sta y0 226 | clc 227 | adc #$10 228 | sta y1 229 | rts 230 | 231 | ;; Draw chessboard 232 | drawboardsquare: 233 | lda #$00 234 | sta set_palette 235 | sta write_color 236 | sta write_color 237 | sta write_color 238 | lda #$FF 239 | sta write_color 240 | sta write_color 241 | sta write_color 242 | lda #$AA 243 | sta write_color 244 | lda #$BB 245 | sta write_color 246 | lda #$CC 247 | sta write_color 248 | lda #$77 249 | sta write_color 250 | lda #$88 251 | sta write_color 252 | lda #$99 253 | sta write_color 254 | lda #$FF 255 | sta write_color 256 | lda #$00 257 | sta write_color 258 | sta write_color 259 | lda #$C0 260 | sta write_color 261 | lda #$00 262 | sta write_color 263 | sta write_color 264 | lda sqx 265 | asl a 266 | asl a 267 | asl a 268 | asl a 269 | asl a 270 | sta x0 271 | adc #$20 272 | sta x1 273 | lda sqy 274 | asl a 275 | asl a 276 | asl a 277 | asl a 278 | asl a 279 | sta y0 280 | adc #$20 281 | sta y1 282 | lda sqy 283 | asl a 284 | asl a 285 | asl a 286 | adc sqx 287 | cmp bcsq 288 | bne nocurr 289 | lda #$04 290 | bne drawsq 291 | nocurr: 292 | cmp bcsq2 293 | bne nocurr2 294 | lda #$05 295 | bne drawsq 296 | nocurr2: 297 | lda sqx 298 | eor sqy 299 | and #$01 300 | clc 301 | adc #$02 302 | drawsq: 303 | sta color 304 | 305 | lda sqy 306 | asl a 307 | asl a 308 | asl a 309 | adc sqx 310 | tax 311 | lda chesspos,x 312 | bne notempty 313 | jmp fillbox 314 | notempty: 315 | tax 316 | and #$08 317 | lsr a 318 | lsr a 319 | lsr a 320 | eor #$01 321 | sta color2 322 | dex 323 | txa 324 | and #$07 325 | asl a 326 | tax 327 | lda $0200,x 328 | sta cpdr_l 329 | lda $0201,x 330 | sta cpdr_h 331 | 332 | lda sqx 333 | asl a 334 | asl a 335 | asl a 336 | asl a 337 | asl a 338 | sta x0 339 | lda sqy 340 | asl a 341 | asl a 342 | asl a 343 | asl a 344 | asl a 345 | sta y0 346 | 347 | ldy #$FF 348 | lda color2 349 | sta count_h 350 | 351 | loadrun: 352 | lda count_h 353 | eor color 354 | eor color2 355 | sta count_h 356 | iny 357 | lda (cpdr_l),y 358 | sta count_l 359 | beq loadrun 360 | proc1: 361 | lda y0 362 | sta set_row 363 | lda x0 364 | sta set_col 365 | lda count_h 366 | sta write_pixel 367 | inc x0 368 | lda x0 369 | cmp x1 370 | bne noy 371 | lda sqx 372 | asl a 373 | asl a 374 | asl a 375 | asl a 376 | asl a 377 | sta x0 378 | inc y0 379 | lda y0 380 | cmp y1 381 | bne noy 382 | rts 383 | noy: 384 | dec count_l 385 | bne proc1 386 | jmp loadrun 387 | 388 | drawboard: 389 | lda #$00 390 | sta sqx 391 | sta sqy 392 | drawboard2: 393 | jsr drawboardsquare 394 | inc sqx 395 | lda sqx 396 | eor #$08 397 | bne drawboard2 398 | sta sqx 399 | inc sqy 400 | lda sqy 401 | cmp #$08 402 | bne drawboard2 403 | rts 404 | 405 | ;; Main program 406 | start: 407 | ; clear screen to random 408 | lda #$00 409 | tax 410 | tay 411 | cloop: 412 | lda random 413 | sta write_pixel 414 | dex 415 | bne cloop 416 | dey 417 | bne cloop 418 | 419 | ; draw 2048 random lines 420 | ldy #$08 421 | ldx #$00 422 | cloop2: 423 | txa 424 | pha 425 | tya 426 | pha 427 | lda random 428 | sta x1 429 | lda random 430 | sta y1 431 | tya 432 | sta color 433 | jsr drawline 434 | pla 435 | tay 436 | pla 437 | tax 438 | dex 439 | bne cloop2 440 | dey 441 | bne cloop2 442 | 443 | ; Set a green-red bouncing palette 444 | lda #$00 445 | sta set_palette 446 | ldx #$00 447 | ploop1: 448 | txa 449 | sta write_color 450 | eor #$FF 451 | sta write_color 452 | lda #$00 453 | sta write_color 454 | inx 455 | inx 456 | bne ploop1 457 | ploop2: 458 | txa 459 | eor #$FF 460 | sta write_color 461 | eor #$FF 462 | sta write_color 463 | lda #$00 464 | sta write_color 465 | inx 466 | inx 467 | bne ploop2 468 | 469 | ; Set starting position and speed 470 | lda #$01 471 | sta sqx 472 | sta sqy 473 | sta sqdx 474 | sta sqdy 475 | lda #$00 476 | sta count_l 477 | sta count_h 478 | mainloop: 479 | ; Increment square position 480 | lda sqx 481 | clc 482 | adc sqdx 483 | cmp #$DF 484 | bcc xok 485 | lda sqdx 486 | eor #$FF 487 | sta sqdx 488 | inc sqdx 489 | lda sqx 490 | xok: 491 | sta sqx 492 | lda sqy 493 | clc 494 | adc sqdy 495 | cmp #$DD 496 | bcc yok 497 | lda sqdy 498 | eor #$FF 499 | sta sqdy 500 | inc sqdy 501 | lda sqy 502 | yok: 503 | sta sqy 504 | 505 | ; Draw square 506 | jsr set_square 507 | inc color 508 | jsr fillbox 509 | 510 | inc count_l 511 | bne mainloop 512 | inc count_h 513 | bne mainloop 514 | 515 | ; Chessboard 516 | lda #$FF 517 | sta bcsq 518 | sta obcsq 519 | sta bcsq2 520 | jsr drawboard 521 | 522 | mouseloop: 523 | ldx #$00 524 | lda mouse_b 525 | cmp #$FF 526 | beq setsq 527 | tax 528 | lda mouse_y 529 | and #$E0 530 | lsr a 531 | lsr a 532 | sta bcsq 533 | lda mouse_x 534 | lsr a 535 | lsr a 536 | lsr a 537 | lsr a 538 | lsr a 539 | clc 540 | adc bcsq 541 | setsq: 542 | sta bcsq 543 | cpx #$01 544 | bne noclick 545 | tax 546 | waitup: 547 | lda mouse_b 548 | cmp #$01 549 | beq waitup 550 | txa 551 | ldy bcsq2 552 | cpy #$FF 553 | beq nomove 554 | cpx bcsq2 555 | beq updated 556 | lda chesspos,y 557 | sta chesspos,x 558 | lda #$00 559 | sta chesspos,y 560 | updated: 561 | lda #$FF 562 | sta bcsq2 563 | sta bcsq 564 | sta obcsq 565 | jsr drawboard 566 | jmp mouseloop 567 | nomove: 568 | sta bcsq2 569 | noclick: 570 | lda bcsq 571 | cmp obcsq 572 | beq mouseloop 573 | lda obcsq 574 | cmp #$FF 575 | beq no_clear_old 576 | and #$07 577 | sta sqx 578 | lda obcsq 579 | lsr a 580 | lsr a 581 | lsr a 582 | sta sqy 583 | jsr drawboardsquare 584 | no_clear_old: 585 | lda bcsq 586 | sta obcsq 587 | cmp #$FF 588 | beq no_draw_new 589 | and #$07 590 | sta sqx 591 | lda bcsq 592 | lsr a 593 | lsr a 594 | lsr a 595 | sta sqy 596 | jsr drawboardsquare 597 | no_draw_new: 598 | jmp mouseloop 599 | 600 | jmp $0000 601 | 602 | chesspos: 603 | .db $0a, $0b, $0c, $0d, $0e, $0c, $0b, $0a 604 | .db $09, $09, $09, $09, $09, $09, $09, $09 605 | .db $00, $00, $00, $00, $00, $00, $00, $00 606 | .db $00, $00, $00, $00, $00, $00, $00, $00 607 | .db $00, $00, $00, $00, $00, $00, $00, $00 608 | .db $00, $00, $00, $00, $00, $00, $00, $00 609 | .db $01, $01, $01, $01, $01, $01, $01, $01 610 | .db $02, $03, $04, $05, $06, $04, $03, $02 611 | -------------------------------------------------------------------------------- /demo2.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Special locations 3 | ; (they work with LDA/STA abs only!) 4 | ; 5 | set_palette = $FF00 ; W: sets current index 6 | write_color = $FF01 ; W++: R, G or B 7 | set_row = $FF02 ; W: pixel row 8 | set_col = $FF03 ; W: pixel col 9 | write_pixel = $FF04 ; W++: writes a pixel 10 | 11 | random = $FF80 ; R: a random byte 12 | clock0 = $FF81 ; R: updates clock and returns low byte 13 | clock1 = $FF82 ; R: returns second byte of clock 14 | clock2 = $FF83 ; R: returns third byte of clock 15 | clock3 = $FF84 ; R: returns fourth byte of clock 16 | 17 | mouse_b = $FF85 ; R: mouse buttons (bits 0/1/2) or 255 if outside 18 | mouse_x = $FF86 ; R: mouse x position (0 if outside) 19 | mouse_y = $FF87 ; R: mouse y position (0 if outside) 20 | 21 | ; 22 | ; Execution begins at "start" and stops when 23 | ; program counter becomes $0000 24 | ; 25 | .org $0200 26 | 27 | start: 28 | ; 29 | ; "Regular" non-self-modifying code 30 | ; 31 | ldx #$00 32 | ldy #$10 33 | lda #$00 34 | sta set_row 35 | sta set_col 36 | loop1: 37 | sta write_pixel 38 | clc 39 | adc #$01 40 | bne loop1 41 | dex 42 | bne loop1 43 | clc 44 | adc #$01 45 | dey 46 | bne loop1 47 | jmp $0300 48 | 49 | .org $0300 50 | ; 51 | ; Self-modifying code 52 | ; 53 | ldx #$00 54 | ldy #$10 55 | loop2: 56 | lda #$00 ; <----- $00 will be incremented! 57 | sta write_pixel 58 | inc $0305 59 | bne loop2 60 | dex 61 | bne loop2 62 | inc $0305 63 | dey 64 | bne loop2 65 | jmp $0000 66 | -------------------------------------------------------------------------------- /images/bkg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/6502/js6502/3a767967d07cc81477461673e0fa9215df24a636/images/bkg.png -------------------------------------------------------------------------------- /images/blacktocat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/6502/js6502/3a767967d07cc81477461673e0fa9215df24a636/images/blacktocat.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Js6502 by 6502 12 | 13 | 14 | 15 | 16 |
17 |
18 |

Js6502

19 |

Javascript 6502 emulator

20 | 21 |
22 | Download as .zip 23 | Download as .tar.gz 24 | View on GitHub 25 | Open in browser 26 |
27 |
28 |
29 | 30 |
31 |
32 |

6502 Javascript emulator.

33 | 34 |

Not an interpreter, but a JIT compiler to Javascript (that in 35 | turn gets JIT compiled to native code in many browsers)

36 | 37 |

Includes a 6502 disassembler and a small assembler.

38 | 39 |

Now with partial support of self-modifying code.

40 | 41 |

Memory can be modified in MANY ways (including PHA or JSR) and code 42 | can be anywhere (including in the stack!). Current implementation 43 | works only if the memory change is done using STA, STX, STY, INC or 44 | DEC.

45 | 46 |

Another shortcut is that "special locations" used for I/O do work 47 | only if accessed using STA abs / LDA abs instructions (normally on 48 | hardware implementations any read/write triggers the special behavior).

49 |
50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /javascripts/main.js: -------------------------------------------------------------------------------- 1 | console.log('This would be the main JS file.'); 2 | -------------------------------------------------------------------------------- /params.json: -------------------------------------------------------------------------------- 1 | {"google":"","tagline":"Javascript 6502 emulator","note":"Don't delete this file! It's used internally to help with page regeneration.","name":"Js6502","body":"6502 Javascript emulator.\r\n\r\nNot an interpreter, but a JIT compiler to Javascript (that in\r\nturn gets JIT compiled to native code in many browsers)\r\n\r\nIncludes a 6502 disassembler and a small assembler.\r\n\r\nNow with partial support of self-modifying code.\r\n\r\nMemory can be modified in MANY ways (including PHA or JSR) and code\r\ncan be anywhere (including in the stack!). Current implementation\r\nworks only if the memory change is done using STA, STX, STY, INC or\r\nDEC.\r\n\r\nAnother shortcut is that \"special locations\" used for I/O do work\r\nonly if accessed using STA abs / LDA abs instructions (normally on\r\nhardware implementations any read/write triggers the special behavior)."} -------------------------------------------------------------------------------- /stylesheets/pygment_trac.css: -------------------------------------------------------------------------------- 1 | .highlight .c { color: #999988; font-style: italic } /* Comment */ 2 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 3 | .highlight .k { font-weight: bold } /* Keyword */ 4 | .highlight .o { font-weight: bold } /* Operator */ 5 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 6 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ 7 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ 8 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 9 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 10 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ 11 | .highlight .ge { font-style: italic } /* Generic.Emph */ 12 | .highlight .gr { color: #aa0000 } /* Generic.Error */ 13 | .highlight .gh { color: #999999 } /* Generic.Heading */ 14 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 15 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ 16 | .highlight .go { color: #888888 } /* Generic.Output */ 17 | .highlight .gp { color: #555555 } /* Generic.Prompt */ 18 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 19 | .highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ 20 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */ 21 | .highlight .kc { font-weight: bold } /* Keyword.Constant */ 22 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */ 23 | .highlight .kn { font-weight: bold } /* Keyword.Namespace */ 24 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */ 25 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */ 26 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 27 | .highlight .m { color: #009999 } /* Literal.Number */ 28 | .highlight .s { color: #d14 } /* Literal.String */ 29 | .highlight .na { color: #008080 } /* Name.Attribute */ 30 | .highlight .nb { color: #0086B3 } /* Name.Builtin */ 31 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ 32 | .highlight .no { color: #008080 } /* Name.Constant */ 33 | .highlight .ni { color: #800080 } /* Name.Entity */ 34 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ 35 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ 36 | .highlight .nn { color: #555555 } /* Name.Namespace */ 37 | .highlight .nt { color: #CBDFFF } /* Name.Tag */ 38 | .highlight .nv { color: #008080 } /* Name.Variable */ 39 | .highlight .ow { font-weight: bold } /* Operator.Word */ 40 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 41 | .highlight .mf { color: #009999 } /* Literal.Number.Float */ 42 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */ 43 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */ 44 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */ 45 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */ 46 | .highlight .sc { color: #d14 } /* Literal.String.Char */ 47 | .highlight .sd { color: #d14 } /* Literal.String.Doc */ 48 | .highlight .s2 { color: #d14 } /* Literal.String.Double */ 49 | .highlight .se { color: #d14 } /* Literal.String.Escape */ 50 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */ 51 | .highlight .si { color: #d14 } /* Literal.String.Interpol */ 52 | .highlight .sx { color: #d14 } /* Literal.String.Other */ 53 | .highlight .sr { color: #009926 } /* Literal.String.Regex */ 54 | .highlight .s1 { color: #d14 } /* Literal.String.Single */ 55 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */ 56 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ 57 | .highlight .vc { color: #008080 } /* Name.Variable.Class */ 58 | .highlight .vg { color: #008080 } /* Name.Variable.Global */ 59 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */ 60 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ 61 | 62 | .type-csharp .highlight .k { color: #0000FF } 63 | .type-csharp .highlight .kt { color: #0000FF } 64 | .type-csharp .highlight .nf { color: #000000; font-weight: normal } 65 | .type-csharp .highlight .nc { color: #2B91AF } 66 | .type-csharp .highlight .nn { color: #000000 } 67 | .type-csharp .highlight .s { color: #A31515 } 68 | .type-csharp .highlight .sc { color: #A31515 } 69 | -------------------------------------------------------------------------------- /stylesheets/stylesheet.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | background: #151515 url("../images/bkg.png") 0 0; 5 | color: #eaeaea; 6 | font: 16px; 7 | line-height: 1.5; 8 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; 9 | } 10 | 11 | /* General & 'Reset' Stuff */ 12 | 13 | .container { 14 | width: 90%; 15 | max-width: 600px; 16 | margin: 0 auto; 17 | } 18 | 19 | section { 20 | display: block; 21 | margin: 0 0 20px 0; 22 | } 23 | 24 | h1, h2, h3, h4, h5, h6 { 25 | margin: 0 0 20px; 26 | } 27 | 28 | li { 29 | line-height: 1.4 ; 30 | } 31 | 32 | /* Header,
33 | header - container 34 | h1 - project name 35 | h2 - project description 36 | */ 37 | 38 | header { 39 | background: rgba(0, 0, 0, 0.1); 40 | width: 100%; 41 | border-bottom: 1px dashed #b5e853; 42 | padding: 20px 0; 43 | margin: 0 0 40px 0; 44 | } 45 | 46 | header h1 { 47 | font-size: 30px; 48 | line-height: 1.5; 49 | margin: 0 0 0 -40px; 50 | font-weight: bold; 51 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; 52 | color: #b5e853; 53 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1), 54 | 0 0 5px rgba(181, 232, 83, 0.1), 55 | 0 0 10px rgba(181, 232, 83, 0.1); 56 | letter-spacing: -1px; 57 | -webkit-font-smoothing: antialiased; 58 | } 59 | 60 | header h1:before { 61 | content: "./ "; 62 | font-size: 24px; 63 | } 64 | 65 | header h2 { 66 | font-size: 18px; 67 | font-weight: 300; 68 | color: #666; 69 | } 70 | 71 | #downloads .btn { 72 | display: inline-block; 73 | text-align: center; 74 | margin: 0; 75 | } 76 | 77 | /* Main Content 78 | */ 79 | 80 | #main_content { 81 | width: 100%; 82 | -webkit-font-smoothing: antialiased; 83 | } 84 | section img { 85 | max-width: 100% 86 | } 87 | 88 | h1, h2, h3, h4, h5, h6 { 89 | font-weight: normal; 90 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; 91 | color: #b5e853; 92 | letter-spacing: -0.03em; 93 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1), 94 | 0 0 5px rgba(181, 232, 83, 0.1), 95 | 0 0 10px rgba(181, 232, 83, 0.1); 96 | } 97 | 98 | #main_content h1 { 99 | font-size: 30px; 100 | } 101 | 102 | #main_content h2 { 103 | font-size: 24px; 104 | } 105 | 106 | #main_content h3 { 107 | font-size: 18px; 108 | } 109 | 110 | #main_content h4 { 111 | font-size: 14px; 112 | } 113 | 114 | #main_content h5 { 115 | font-size: 12px; 116 | text-transform: uppercase; 117 | margin: 0 0 5px 0; 118 | } 119 | 120 | #main_content h6 { 121 | font-size: 12px; 122 | text-transform: uppercase; 123 | color: #999; 124 | margin: 0 0 5px 0; 125 | } 126 | 127 | dt { 128 | font-style: italic; 129 | font-weight: bold; 130 | } 131 | 132 | ul li { 133 | list-style: none; 134 | } 135 | 136 | ul li:before { 137 | content: ">>"; 138 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; 139 | font-size: 13px; 140 | color: #b5e853; 141 | margin-left: -37px; 142 | margin-right: 21px; 143 | line-height: 16px; 144 | } 145 | 146 | blockquote { 147 | color: #aaa; 148 | padding-left: 10px; 149 | border-left: 1px dotted #666; 150 | } 151 | 152 | pre { 153 | background: rgba(0, 0, 0, 0.9); 154 | border: 1px solid rgba(255, 255, 255, 0.15); 155 | padding: 10px; 156 | font-size: 14px; 157 | color: #b5e853; 158 | border-radius: 2px; 159 | -moz-border-radius: 2px; 160 | -webkit-border-radius: 2px; 161 | text-wrap: normal; 162 | overflow: auto; 163 | overflow-y: hidden; 164 | } 165 | 166 | table { 167 | width: 100%; 168 | margin: 0 0 20px 0; 169 | } 170 | 171 | th { 172 | text-align: left; 173 | border-bottom: 1px dashed #b5e853; 174 | padding: 5px 10px; 175 | } 176 | 177 | td { 178 | padding: 5px 10px; 179 | } 180 | 181 | hr { 182 | height: 0; 183 | border: 0; 184 | border-bottom: 1px dashed #b5e853; 185 | color: #b5e853; 186 | } 187 | 188 | /* Buttons 189 | */ 190 | 191 | .btn { 192 | display: inline-block; 193 | background: -webkit-linear-gradient(top, rgba(40, 40, 40, 0.3), rgba(35, 35, 35, 0.3) 50%, rgba(10, 10, 10, 0.3) 50%, rgba(0, 0, 0, 0.3)); 194 | padding: 8px 18px; 195 | border-radius: 50px; 196 | border: 2px solid rgba(0, 0, 0, 0.7); 197 | border-bottom: 2px solid rgba(0, 0, 0, 0.7); 198 | border-top: 2px solid rgba(0, 0, 0, 1); 199 | color: rgba(255, 255, 255, 0.8); 200 | font-family: Helvetica, Arial, sans-serif; 201 | font-weight: bold; 202 | font-size: 13px; 203 | text-decoration: none; 204 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.75); 205 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05); 206 | } 207 | 208 | .btn:hover { 209 | background: -webkit-linear-gradient(top, rgba(40, 40, 40, 0.6), rgba(35, 35, 35, 0.6) 50%, rgba(10, 10, 10, 0.8) 50%, rgba(0, 0, 0, 0.8)); 210 | } 211 | 212 | .btn .icon { 213 | display: inline-block; 214 | width: 16px; 215 | height: 16px; 216 | margin: 1px 8px 0 0; 217 | float: left; 218 | } 219 | 220 | .btn-github .icon { 221 | opacity: 0.6; 222 | background: url("../images/blacktocat.png") 0 0 no-repeat; 223 | } 224 | 225 | /* Links 226 | a, a:hover, a:visited 227 | */ 228 | 229 | a { 230 | color: #63c0f5; 231 | text-shadow: 0 0 5px rgba(104, 182, 255, 0.5); 232 | } 233 | 234 | /* Clearfix */ 235 | 236 | .cf:before, .cf:after { 237 | content:""; 238 | display:table; 239 | } 240 | 241 | .cf:after { 242 | clear:both; 243 | } 244 | 245 | .cf { 246 | zoom:1; 247 | } --------------------------------------------------------------------------------