diff --git a/index.html b/index.html index db5070ed..8ef7247e 100644 --- a/index.html +++ b/index.html @@ -283,6 +283,7 @@ canvas.pixelated { + diff --git a/src/disasm.js b/src/disasm.js index 84755bdc..cfa7ebd2 100644 --- a/src/disasm.js +++ b/src/disasm.js @@ -2,7 +2,7 @@ var OPS_6502 = [ {mn:"BRK",am:"",nb:1,il:0,c1:7,c2:0}, // 00 {mn:"ORA",am:"(aa,x)",nb:2,il:0,c1:6,c2:0}, // 01 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 02 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 02 {mn:"SLO",am:"(aa,x)",nb:2,il:1,c1:8,c2:1}, // 03 {mn:"NOP",am:"aa",nb:2,il:1,c1:3,c2:0}, // 04 {mn:"ORA",am:"aa",nb:2,il:0,c1:3,c2:0}, // 05 @@ -18,7 +18,7 @@ var OPS_6502 = [ {mn:"SLO",am:"AAAA",nb:3,il:1,c1:6,c2:0}, // 0F {mn:"BPL",am:"branch",nb:2,il:0,c1:2,c2:2}, // 10 {mn:"ORA",am:"(aa),y",nb:2,il:0,c1:5,c2:1}, // 11 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 12 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 12 {mn:"SLO",am:"(aa),y",nb:2,il:1,c1:8,c2:1}, // 13 {mn:"NOP",am:"aa,x",nb:2,il:1,c1:4,c2:0}, // 14 {mn:"ORA",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // 15 @@ -26,7 +26,7 @@ var OPS_6502 = [ {mn:"SLO",am:"aa,x",nb:2,il:1,c1:6,c2:1}, // 17 {mn:"CLC",am:"",nb:1,il:0,c1:2,c2:0}, // 18 {mn:"ORA",am:"AAAA,y",nb:3,il:0,c1:4,c2:1}, // 19 - {mn:"NOP",am:"",nb:0,il:1,c1:0,c2:0}, // 1A + {mn:"NOP",am:"",nb:1,il:1,c1:0,c2:0}, // 1A {mn:"SLO",am:"AAAA,y",nb:3,il:1,c1:7,c2:1}, // 1B {mn:"NOP",am:"AAAA,x",nb:3,il:1,c1:4,c2:1}, // 1C {mn:"ORA",am:"AAAA,x",nb:3,il:0,c1:4,c2:1}, // 1D @@ -34,7 +34,7 @@ var OPS_6502 = [ {mn:"SLO",am:"AAAA,x",nb:3,il:1,c1:7,c2:1}, // 1F {mn:"JSR",am:"AAAA",nb:3,il:0,c1:6,c2:0}, // 20 {mn:"AND",am:"(aa,x)",nb:2,il:0,c1:6,c2:0}, // 21 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 22 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 22 {mn:"RLA",am:"(aa,x)",nb:2,il:1,c1:8,c2:1}, // 23 {mn:"BIT",am:"aa",nb:2,il:0,c1:3,c2:0}, // 24 {mn:"AND",am:"aa",nb:2,il:0,c1:3,c2:0}, // 25 @@ -50,7 +50,7 @@ var OPS_6502 = [ {mn:"RLA",am:"AAAA",nb:3,il:1,c1:6,c2:0}, // 2F {mn:"BMI",am:"branch",nb:2,il:0,c1:2,c2:2}, // 30 {mn:"AND",am:"(aa),y",nb:2,il:0,c1:5,c2:1}, // 31 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 32 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 32 {mn:"RLA",am:"(aa),y",nb:2,il:1,c1:8,c2:1}, // 33 {mn:"NOP",am:"aa,x",nb:2,il:1,c1:4,c2:0}, // 34 {mn:"AND",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // 35 @@ -58,7 +58,7 @@ var OPS_6502 = [ {mn:"RLA",am:"aa,x",nb:2,il:1,c1:6,c2:1}, // 37 {mn:"SEC",am:"",nb:1,il:0,c1:2,c2:0}, // 38 {mn:"AND",am:"AAAA,y",nb:3,il:0,c1:4,c2:1}, // 39 - {mn:"NOP",am:"",nb:0,il:1,c1:0,c2:0}, // 3A + {mn:"NOP",am:"",nb:1,il:1,c1:0,c2:0}, // 3A {mn:"RLA",am:"AAAA,y",nb:3,il:1,c1:7,c2:1}, // 3B {mn:"NOP",am:"AAAA,x",nb:3,il:1,c1:4,c2:1}, // 3C {mn:"AND",am:"AAAA,x",nb:3,il:0,c1:4,c2:1}, // 3D @@ -66,7 +66,7 @@ var OPS_6502 = [ {mn:"RLA",am:"AAAA,x",nb:3,il:1,c1:7,c2:1}, // 3F {mn:"RTI",am:"",nb:1,il:0,c1:6,c2:0}, // 40 {mn:"EOR",am:"(aa,x)",nb:2,il:0,c1:6,c2:0}, // 41 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 42 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 42 {mn:"SRE",am:"(aa,x)",nb:2,il:1,c1:8,c2:1}, // 43 {mn:"NOP",am:"aa",nb:2,il:1,c1:3,c2:0}, // 44 {mn:"EOR",am:"aa",nb:2,il:0,c1:3,c2:0}, // 45 @@ -82,7 +82,7 @@ var OPS_6502 = [ {mn:"SRE",am:"AAAA",nb:3,il:1,c1:6,c2:0}, // 4F {mn:"BVC",am:"branch",nb:2,il:0,c1:2,c2:2}, // 50 {mn:"EOR",am:"(aa),y",nb:2,il:0,c1:5,c2:1}, // 51 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 52 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 52 {mn:"SRE",am:"(aa),y",nb:2,il:1,c1:8,c2:1}, // 53 {mn:"NOP",am:"aa,x",nb:2,il:1,c1:4,c2:0}, // 54 {mn:"EOR",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // 55 @@ -90,7 +90,7 @@ var OPS_6502 = [ {mn:"SRE",am:"aa,x",nb:2,il:1,c1:6,c2:1}, // 57 {mn:"CLI",am:"",nb:1,il:0,c1:2,c2:0}, // 58 {mn:"EOR",am:"AAAA,y",nb:3,il:0,c1:4,c2:1}, // 59 - {mn:"NOP",am:"",nb:0,il:1,c1:0,c2:0}, // 5A + {mn:"NOP",am:"",nb:1,il:1,c1:0,c2:0}, // 5A {mn:"SRE",am:"AAAA,y",nb:3,il:1,c1:7,c2:1}, // 5B {mn:"NOP",am:"AAAA,x",nb:3,il:1,c1:4,c2:1}, // 5C {mn:"EOR",am:"AAAA,x",nb:3,il:0,c1:4,c2:1}, // 5D @@ -98,7 +98,7 @@ var OPS_6502 = [ {mn:"SRE",am:"AAAA,x",nb:3,il:1,c1:7,c2:1}, // 5F {mn:"RTS",am:"",nb:1,il:0,c1:6,c2:0}, // 60 {mn:"ADC",am:"(aa,x)",nb:2,il:0,c1:6,c2:0}, // 61 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 62 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 62 {mn:"RRA",am:"(aa,x)",nb:2,il:1,c1:8,c2:1}, // 63 {mn:"NOP",am:"aa",nb:2,il:1,c1:3,c2:0}, // 64 {mn:"ADC",am:"aa",nb:2,il:0,c1:3,c2:0}, // 65 @@ -114,7 +114,7 @@ var OPS_6502 = [ {mn:"RRA",am:"AAAA",nb:3,il:1,c1:6,c2:0}, // 6F {mn:"BVS",am:"branch",nb:2,il:0,c1:2,c2:2}, // 70 {mn:"ADC",am:"(aa),y",nb:2,il:0,c1:5,c2:1}, // 71 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 72 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 72 {mn:"RRA",am:"(aa),y",nb:2,il:1,c1:8,c2:1}, // 73 {mn:"NOP",am:"aa,x",nb:2,il:1,c1:4,c2:0}, // 74 {mn:"ADC",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // 75 @@ -122,32 +122,32 @@ var OPS_6502 = [ {mn:"RRA",am:"aa,x",nb:2,il:1,c1:6,c2:1}, // 77 {mn:"SEI",am:"",nb:1,il:0,c1:2,c2:0}, // 78 {mn:"ADC",am:"AAAA,y",nb:3,il:0,c1:4,c2:1}, // 79 - {mn:"NOP",am:"",nb:0,il:1,c1:0,c2:0}, // 7A + {mn:"NOP",am:"",nb:1,il:1,c1:0,c2:0}, // 7A {mn:"RRA",am:"AAAA,y",nb:3,il:1,c1:7,c2:1}, // 7B {mn:"NOP",am:"AAAA,x",nb:3,il:1,c1:4,c2:1}, // 7C {mn:"ADC",am:"AAAA,x",nb:3,il:0,c1:4,c2:1}, // 7D {mn:"ROR",am:"AAAA,x",nb:3,il:0,c1:7,c2:0}, // 7E {mn:"RRA",am:"AAAA,x",nb:3,il:1,c1:7,c2:1}, // 7F - {mn:"NOP",am:"#aa",nb:0,il:1,c1:0,c2:0}, // 80 + {mn:"NOP",am:"#aa",nb:2,il:1,c1:0,c2:0}, // 80 {mn:"STA",am:"(aa,x)",nb:2,il:0,c1:6,c2:0}, // 81 - {mn:"NOP",am:"#aa",nb:0,il:1,c1:0,c2:0}, // 82 + {mn:"NOP",am:"#aa",nb:2,il:1,c1:0,c2:0}, // 82 {mn:"SAX",am:"(aa,x)",nb:2,il:1,c1:6,c2:1}, // 83 {mn:"STY",am:"aa",nb:2,il:0,c1:3,c2:0}, // 84 {mn:"STA",am:"aa",nb:2,il:0,c1:3,c2:0}, // 85 {mn:"STX",am:"aa",nb:2,il:0,c1:3,c2:0}, // 86 {mn:"SAX",am:"aa",nb:2,il:1,c1:3,c2:0}, // 87 {mn:"DEY",am:"",nb:1,il:0,c1:2,c2:0}, // 88 - {mn:"NOP",am:"#aa",nb:0,il:1,c1:0,c2:0}, // 89 + {mn:"NOP",am:"#aa",nb:2,il:1,c1:0,c2:0}, // 89 {mn:"TXA",am:"",nb:1,il:0,c1:2,c2:0}, // 8A - {mn:"ANE",am:"#aa",nb:0,il:1,c1:0,c2:0}, // 8B + {mn:"ANE",am:"#aa",nb:2,il:1,c1:0,c2:0}, // 8B {mn:"STY",am:"AAAA",nb:3,il:0,c1:4,c2:0}, // 8C {mn:"STA",am:"AAAA",nb:3,il:0,c1:4,c2:0}, // 8D {mn:"STX",am:"AAAA",nb:3,il:0,c1:4,c2:0}, // 8E {mn:"SAX",am:"AAAA",nb:3,il:1,c1:4,c2:0}, // 8F {mn:"BCC",am:"branch",nb:2,il:0,c1:2,c2:2}, // 90 {mn:"STA",am:"(aa),y",nb:2,il:0,c1:6,c2:0}, // 91 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // 92 - {mn:"SHA",am:"(aa),y",nb:0,il:1,c1:0,c2:0}, // 93 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // 92 + {mn:"SHA",am:"(aa),y",nb:2,il:1,c1:0,c2:0}, // 93 {mn:"STY",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // 94 {mn:"STA",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // 95 {mn:"STX",am:"aa,y",nb:2,il:0,c1:4,c2:0}, // 96 @@ -155,11 +155,11 @@ var OPS_6502 = [ {mn:"TYA",am:"",nb:1,il:0,c1:2,c2:0}, // 98 {mn:"STA",am:"AAAA,y",nb:3,il:0,c1:5,c2:0}, // 99 {mn:"TXS",am:"",nb:1,il:0,c1:2,c2:0}, // 9A - {mn:"SHS",am:"AAAA,y",nb:0,il:1,c1:0,c2:0}, // 9B - {mn:"SHY",am:"AAAA,x",nb:0,il:1,c1:0,c2:0}, // 9C + {mn:"SHS",am:"AAAA,y",nb:3,il:1,c1:0,c2:0}, // 9B + {mn:"SHY",am:"AAAA,x",nb:3,il:1,c1:0,c2:0}, // 9C {mn:"STA",am:"AAAA,x",nb:3,il:0,c1:5,c2:0}, // 9D - {mn:"SHX",am:"AAAA,y",nb:0,il:1,c1:0,c2:0}, // 9E - {mn:"SHA",am:"AAAA,y",nb:0,il:1,c1:0,c2:0}, // 9F + {mn:"SHX",am:"AAAA,y",nb:3,il:1,c1:0,c2:0}, // 9E + {mn:"SHA",am:"AAAA,y",nb:3,il:1,c1:0,c2:0}, // 9F {mn:"LDY",am:"#aa",nb:2,il:0,c1:2,c2:0}, // A0 {mn:"LDA",am:"(aa,x)",nb:2,il:0,c1:6,c2:0}, // A1 {mn:"LDX",am:"#aa",nb:2,il:0,c1:2,c2:0}, // A2 @@ -171,14 +171,14 @@ var OPS_6502 = [ {mn:"TAY",am:"",nb:1,il:0,c1:2,c2:0}, // A8 {mn:"LDA",am:"#aa",nb:2,il:0,c1:2,c2:0}, // A9 {mn:"TAX",am:"",nb:1,il:0,c1:2,c2:0}, // AA - {mn:"LXA",am:"#aa",nb:0,il:1,c1:0,c2:0}, // AB + {mn:"LXA",am:"#aa",nb:2,il:1,c1:0,c2:0}, // AB {mn:"LDY",am:"AAAA",nb:3,il:0,c1:4,c2:0}, // AC {mn:"LDA",am:"AAAA",nb:3,il:0,c1:4,c2:0}, // AD {mn:"LDX",am:"AAAA",nb:3,il:0,c1:4,c2:0}, // AE {mn:"LAX",am:"AAAA",nb:3,il:1,c1:4,c2:0}, // AF {mn:"BCS",am:"branch",nb:2,il:0,c1:2,c2:2}, // B0 {mn:"LDA",am:"(aa),y",nb:2,il:0,c1:5,c2:1}, // B1 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // B2 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // B2 {mn:"LAX",am:"(aa),y",nb:2,il:1,c1:5,c2:1}, // B3 {mn:"LDY",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // B4 {mn:"LDA",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // B5 @@ -187,14 +187,14 @@ var OPS_6502 = [ {mn:"CLV",am:"",nb:1,il:0,c1:2,c2:0}, // B8 {mn:"LDA",am:"AAAA,y",nb:3,il:0,c1:4,c2:1}, // B9 {mn:"TSX",am:"",nb:1,il:0,c1:2,c2:0}, // BA - {mn:"LAS",am:"AAAA,y",nb:0,il:1,c1:0,c2:0}, // BB + {mn:"LAS",am:"AAAA,y",nb:3,il:1,c1:0,c2:0}, // BB {mn:"LDY",am:"AAAA,x",nb:3,il:0,c1:4,c2:1}, // BC {mn:"LDA",am:"AAAA,x",nb:3,il:0,c1:4,c2:1}, // BD {mn:"LDX",am:"AAAA,y",nb:3,il:0,c1:4,c2:1}, // BE {mn:"LAX",am:"AAAA,y",nb:3,il:1,c1:4,c2:1}, // BF {mn:"CPY",am:"#aa",nb:2,il:0,c1:2,c2:0}, // C0 {mn:"CMP",am:"(aa,x)",nb:2,il:0,c1:6,c2:0}, // C1 - {mn:"NOP",am:"#aa",nb:0,il:1,c1:0,c2:0}, // C2 + {mn:"NOP",am:"#aa",nb:2,il:1,c1:0,c2:0}, // C2 {mn:"DCP",am:"(aa,x)",nb:2,il:1,c1:8,c2:1}, // C3 {mn:"CPY",am:"aa",nb:2,il:0,c1:3,c2:0}, // C4 {mn:"CMP",am:"aa",nb:2,il:0,c1:3,c2:0}, // C5 @@ -210,7 +210,7 @@ var OPS_6502 = [ {mn:"DCP",am:"AAAA",nb:3,il:1,c1:6,c2:0}, // CF {mn:"BNE",am:"branch",nb:2,il:0,c1:2,c2:2}, // D0 {mn:"CMP",am:"(aa),y",nb:2,il:0,c1:5,c2:1}, // D1 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // D2 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // D2 {mn:"DCP",am:"(aa),y",nb:2,il:1,c1:8,c2:1}, // D3 {mn:"NOP",am:"aa,x",nb:2,il:1,c1:4,c2:0}, // D4 {mn:"CMP",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // D5 @@ -218,7 +218,7 @@ var OPS_6502 = [ {mn:"DCP",am:"aa,x",nb:2,il:1,c1:6,c2:1}, // D7 {mn:"CLD",am:"",nb:1,il:0,c1:2,c2:0}, // D8 {mn:"CMP",am:"AAAA,y",nb:3,il:0,c1:4,c2:1}, // D9 - {mn:"NOP",am:"",nb:0,il:1,c1:0,c2:0}, // DA + {mn:"NOP",am:"",nb:1,il:1,c1:0,c2:0}, // DA {mn:"DCP",am:"AAAA,y",nb:3,il:1,c1:7,c2:1}, // DB {mn:"NOP",am:"AAAA,x",nb:3,il:1,c1:4,c2:1}, // DC {mn:"CMP",am:"AAAA,x",nb:3,il:0,c1:4,c2:1}, // DD @@ -226,7 +226,7 @@ var OPS_6502 = [ {mn:"DCP",am:"AAAA,x",nb:3,il:1,c1:7,c2:1}, // DF {mn:"CPX",am:"#aa",nb:2,il:0,c1:2,c2:0}, // E0 {mn:"SBC",am:"(aa,x)",nb:2,il:0,c1:6,c2:0}, // E1 - {mn:"NOP",am:"#aa",nb:0,il:1,c1:0,c2:0}, // E2 + {mn:"NOP",am:"#aa",nb:2,il:1,c1:0,c2:0}, // E2 {mn:"ISB",am:"(aa,x)",nb:2,il:1,c1:8,c2:1}, // E3 {mn:"CPX",am:"aa",nb:2,il:0,c1:3,c2:0}, // E4 {mn:"SBC",am:"aa",nb:2,il:0,c1:3,c2:0}, // E5 @@ -235,14 +235,14 @@ var OPS_6502 = [ {mn:"INX",am:"",nb:1,il:0,c1:2,c2:0}, // E8 {mn:"SBC",am:"#aa",nb:2,il:0,c1:2,c2:0}, // E9 {mn:"NOP",am:"",nb:1,il:0,c1:2,c2:0}, // EA - {mn:"SBC",am:"#aa",nb:0,il:1,c1:0,c2:0}, // EB + {mn:"SBC",am:"#aa",nb:2,il:1,c1:0,c2:0}, // EB {mn:"CPX",am:"AAAA",nb:3,il:0,c1:4,c2:0}, // EC {mn:"SBC",am:"AAAA",nb:3,il:0,c1:4,c2:0}, // ED {mn:"INC",am:"AAAA",nb:3,il:0,c1:6,c2:0}, // EE {mn:"ISB",am:"AAAA",nb:3,il:1,c1:6,c2:0}, // EF {mn:"BEQ",am:"branch",nb:2,il:0,c1:2,c2:2}, // F0 {mn:"SBC",am:"(aa),y",nb:2,il:0,c1:5,c2:1}, // F1 - {mn:"KIL",am:"",nb:0,il:1,c1:0,c2:0}, // F2 + {mn:"KIL",am:"",nb:1,il:1,c1:0,c2:0}, // F2 {mn:"ISB",am:"(aa),y",nb:2,il:1,c1:8,c2:1}, // F3 {mn:"NOP",am:"aa,x",nb:2,il:1,c1:4,c2:0}, // F4 {mn:"SBC",am:"aa,x",nb:2,il:0,c1:4,c2:0}, // F5 @@ -250,7 +250,7 @@ var OPS_6502 = [ {mn:"ISB",am:"aa,x",nb:2,il:1,c1:6,c2:1}, // F7 {mn:"SED",am:"",nb:1,il:0,c1:2,c2:0}, // F8 {mn:"SBC",am:"AAAA,y",nb:3,il:0,c1:4,c2:1}, // F9 - {mn:"NOP",am:"",nb:0,il:1,c1:0,c2:0}, // FA + {mn:"NOP",am:"",nb:1,il:1,c1:0,c2:0}, // FA {mn:"ISB",am:"AAAA,y",nb:3,il:1,c1:7,c2:1}, // FB {mn:"NOP",am:"AAAA,x",nb:3,il:1,c1:4,c2:1}, // FC {mn:"SBC",am:"AAAA,x",nb:3,il:0,c1:4,c2:1}, // FD @@ -281,7 +281,7 @@ function disassemble6502(pc, b0, b1, b2) { var s = op.mn; var am = op.am; if (am == 'branch') { - var offset = (b1 < 0x80) ? (pc+b1) : (pc-(256-b1)); + var offset = (b1 < 0x80) ? (pc+2+b1) : (pc+2-(256-b1)); offset &= 0xffff; am = '$'+formatHex(offset, 4); } else { diff --git a/src/emu.js b/src/emu.js index a40e33ed..4f637735 100644 --- a/src/emu.js +++ b/src/emu.js @@ -154,12 +154,24 @@ var VectorVideo = function(mainElement, width, height) { ctx.globalCompositeOperation = 'lighter'; } - this.drawLine = function(x1, y1, x2, y2, intensity) { + var COLORS = [ + '#000000', + '#0000ff', + '#00ff00', + '#00ffff', + '#ff0000', + '#ff00ff', + '#ffff00', + '#ffffff' + ]; + + this.drawLine = function(x1, y1, x2, y2, intensity, color) { //console.log(x1, y1, x2, y2, intensity); if (intensity > 0) { // TODO: landscape vs portrait + ctx.globalAlpha = intensity / 255.0; ctx.beginPath(); - // TODO: dots + // TODO: bright dots var jx = jitter * (Math.random() - 0.5); var jy = jitter * (Math.random() - 0.5); x1 += jx; @@ -168,8 +180,7 @@ var VectorVideo = function(mainElement, width, height) { y2 += jy; ctx.moveTo(x1, height-y1); ctx.lineTo(x2+1, height-y2); - ctx.strokeStyle = '#ffffff'; - ctx.lineWidth = intensity*0.1; + ctx.strokeStyle = COLORS[color & 7]; ctx.stroke(); } } @@ -492,7 +503,7 @@ var Base6502Platform = function() { } this.runUntilReturn = function() { var depth = 1; - self.runEval(function(c) { + this.runEval(function(c) { if (depth <= 0 && c.T == 0) return true; if (c.o == 0x20) @@ -678,7 +689,7 @@ var BaseZ80Platform = function() { this.runUntilReturn = function() { var self = this; var depth = 1; - self.runEval(function(c) { + this.runEval(function(c) { if (depth <= 0) return true; var op = self.readAddress(c.PC); diff --git a/src/platform/vector.js b/src/platform/vector.js index 946ab31a..a0ae2a81 100644 --- a/src/platform/vector.js +++ b/src/platform/vector.js @@ -1,5 +1,8 @@ "use strict"; +// http://www.computerarcheology.com/Arcade/Asteroids/DVG.html +// http://arcarc.xmission.com/Tech/neilw_xy.txt + var VECTOR_PRESETS = [ ] @@ -16,6 +19,17 @@ var ASTEROIDS_KEYCODE_MAP = makeKeycodeMap([ [Keys.VK_LEFT, 15, 0xff], ]); +var GRAVITAR_KEYCODE_MAP = makeKeycodeMap([ + [Keys.VK_SHIFT, 1, -0x1], + [Keys.VK_SPACE, 1, -0x2], + [Keys.VK_5, 0, 0x2], + [Keys.VK_6, 0, 0x1], + [Keys.VK_1, 2, 0x20], + [Keys.VK_2, 2, 0x40], + [Keys.VK_UP, 1, -0x10], + [Keys.VK_RIGHT, 1, -0x4], + [Keys.VK_LEFT, 1, -0x8], +]); var AtariVectorPlatform = function(mainElement) { var self = this; @@ -54,7 +68,7 @@ var AtariVectorPlatform = function(mainElement) { write: new AddressDecoder([ [0x0, 0x3ff, 0x3ff, function(a,v) { cpuram.mem[a] = v; }], - [0x3000, 0x3000, 0, function(a,v) { dvg.runUntilHalt(); }], + [0x3000, 0x3000, 0, function(a,v) { dvg.runUntilHalt(0); }], // TODO: draw asynchronous or allow poll of HALT ($2002) [0x4000, 0x5fff, 0x1fff, function(a,v) { dvgram.mem[a] = v; }], ], {gmask:0x7fff}) @@ -63,7 +77,7 @@ var AtariVectorPlatform = function(mainElement) { cpu = self.newCPU(bus); // create video/audio video = new VectorVideo(mainElement,1024,1024); - dvg = new DVGStateMachine(bus, video); + dvg = new DVGBWStateMachine(bus, video, 0x4000); audio = new SampleAudio(cpuFrequency); video.create(); timer = new AnimationTimer(60, function() { @@ -137,9 +151,149 @@ var AtariVectorPlatform = function(mainElement) { } } +var AtariColorVectorPlatform = function(mainElement) { + var self = this; + var masterFrequency = 12096000.0; + var cpuFrequency = masterFrequency / 8; + var nmiFrequency = masterFrequency / 4096 / 12; + var cpuCyclesPerNMI = Math.round(cpuFrequency / nmiFrequency); + var cpuCyclesPerFrame = Math.round(cpuFrequency / 60); + var cpu, cpuram, dvgram, rom, vecrom, bus, dvg, earom; + var video, audio, timer; + var clock; + var switches = new RAM(16).mem; + var nmicount = cpuCyclesPerNMI; + var earom_offset, earom_data; + + this.__proto__ = new Base6502Platform(); + + this.getPresets = function() { + return VECTOR_PRESETS; + } + + this.start = function() { + cpuram = new RAM(0x800); + dvgram = new RAM(0x2000); + earom = new RAM(0x40); + rom = padBytes(new lzgmini().decode(GRAVITAR_ROM).slice(0), 0x7000+1); + vecrom = padBytes(new lzgmini().decode(GRAVITAR_VECROM).slice(0), 0x6000-0x2800+1); + switches[0] = 0xff; + switches[1] = 0xff; + switches[2] = 0xff; + // bus + bus = { + + read: new AddressDecoder([ + [0x0, 0x7ff, 0x7ff, function(a) { return cpuram.mem[a]; }], + [0x2000, 0x27ff, 0x7ff, function(a) { return dvgram.mem[a]; }], + [0x2800, 0x5fff, 0x7fff, function(a) { return vecrom[a - 0x2800]; }], + //[0x2001, 0x2001, 0, function(a) { return ((clock/500) & 1) ? 0xff : 0x00; }], + //[0x6000, 0x67ff, 0x7ff, function(a) { /* pokey1 */ return 0; }], + //[0x6800, 0x6fff, 0x7ff, function(a) { /* pokey2 */ return 0; }], + [0x7800, 0x7800, 0, function(a) { return switches[0]; }], + [0x8000, 0x8000, 0, function(a) { return switches[1]; }], + [0x8800, 0x8800, 0, function(a) { return switches[2]; }], + //[0x7000, 0x7000, 0, function(a) { /* EAROM read */ return 0; }], + //[0x8940, 0x897f, 0x3f, function(a) { /* EAROM data */ return 0; }], + [0x8900, 0x8900, 0, function(a) { /* EAROM read */ return earom_data; }], + [0x9000, 0xffff, 0xffff, function(a) { return rom[a - 0x9000]; }], + ]), + + write: new AddressDecoder([ + [0x0, 0x7ff, 0x7ff, function(a,v) { cpuram.mem[a] = v; }], + [0x2000, 0x27ff, 0x7ff, function(a,v) { dvgram.mem[a] = v; }], + [0x6000, 0x67ff, 0x7ff, function(a,v) { /* pokey1 */ }], + [0x6800, 0x6fff, 0x7ff, function(a,v) { /* pokey2 */ }], + [0x8800, 0x8800, 0, function(a,v) { /* LEDs, etc */ }], + [0x8840, 0x8840, 0, function(a,v) { dvg.runUntilHalt(0); }], + [0x8880, 0x8880, 0, function(a,v) { dvg.reset(); }], + [0x88c0, 0x88c0, 0, function(a,v) { /* IRQ ACK */ }], + [0x8900, 0x8900, 0, function(a,v) { /* EAROM ctrl */ + if (v == 9) earom_data=earom.mem[earom_offset]; + if (v == 12) earom.mem[earom_offset]=earom_data; + }], + [0x8940, 0x897f, 0x3f, function(a,v) { /* EAROM data */ earom_offset = a; earom_data = v; }], + [0x8980, 0x8980, 0, function(a,v) { /* TODO: watchdog */ }], + // TODO: draw asynchronous or allow poll of HALT ($2002) + //[0, 0xffff, 0, function(a,v) { console.log(hex(a,4),hex(v,2)); }], + ]) + + }; + cpu = self.newCPU(bus); + // create video/audio + video = new VectorVideo(mainElement,1024,1024); + dvg = new DVGColorStateMachine(bus, video, 0x2000); + audio = new SampleAudio(cpuFrequency); + video.create(); + timer = new AnimationTimer(60, function() { + video.clear(); + var debugCond = self.getDebugCallback(); + clock = 0; + for (var i=0; i> 12; var x2 = x + ((decodeSigned(w2, 10) << 7) >> sc); var y2 = y + ((decodeSigned(w, 10) << 7) >> sc); - video.drawLine(x, y, x2, y2, z); + video.drawLine(x, y, x2, y2, z, 255); //console.log(pc.toString(16), w.toString(16), w2.toString(16), gsc, sc, x, y, x2, y2); x = x2; y = y2; @@ -332,7 +488,7 @@ var DVGStateMachine = function(bus, video) { var x2 = x + ((decodeSigned(w, 2) << 7) >> sc); var y2 = y + ((decodeSigned(w>>8, 2) << 7) >> sc); var z = (w >> 4) & 0xf; - video.drawLine(x, y, x2, y2, z); + video.drawLine(x, y, x2, y2, z, 255); x = x2; y = y2; break; @@ -341,7 +497,126 @@ var DVGStateMachine = function(bus, video) { } } +var DVGColorStateMachine = function(bus, video, bofs) { + var self = this; + var pc = 0; + var x = 0; + var y = 0; + var scale = 1.0; + var color; + var statz; + var pcstack = []; + var running = false; + bofs &= 0xffff; + + function readWord(a) { + a &= 0x1fff; + return bus.read(a*2+bofs) + (bus.read(a*2+bofs+1) << 8); + } + + // twos complement + function decodeSigned(w, o2) { + var s = w & (1<> 13; + //video.drawLine(pc, 1023, pc+1, 1023-op, 7); + //console.log(hex(pc), hex(w), op); + pc++; + switch (op) { + case 0: { // VCTR + var w2 = readWord(pc++); + var z = w2 >> 13; + if (z == 2) z = statz; + var x2 = x + Math.round(decodeSigned(w2, 12) * scale); + var y2 = y + Math.round(decodeSigned(w, 12) * scale); + video.drawLine(x, y, x2, y2, z<<4, color); + x = x2; + y = y2; + break; + } + case 1: // HALT + running = false; + break; + case 2: { // SVEC + var x2 = x + Math.round(decodeSigned(w, 4) * scale * 2); + var y2 = y + Math.round(decodeSigned(w>>8, 4) * scale * 2); + var z = (w >> 5) & 0x7; + if (z == 2) z = statz; + video.drawLine(x, y, x2, y2, z<<4, color); + x = x2; + y = y2; + break; + } + case 3: { // STAT/SCAL + if (w & 0x1000) { + var b = ((w >> 8) & 0x07)+8; + var l = (~w) & 0xff; + scale = ((l << 16) >> b) / 32768.0; + } else { + color = w & 7; + statz = (w >> 4) & 0xf; + } + break; + } + case 4: // CNTR + x = 512; + y = 512; + break; + case 6: // RTSL + if (pcstack.length == 0) { + //console.log("stack underflow"); // TODO: error? + } else { + pc = pcstack.pop(); + } + break; + case 5: // JSRL + pcstack.push(pc); + case 7: // JMPL + if (pc == 0) + running = false; + else + pc = w & 0x1fff; + break; + } + } +} + // PLATFORMS['vector-ataribw'] = AtariVectorPlatform; -PLATFORMS['vector-z80'] = VectorZ80Platform; +PLATFORMS['vector-ataricolor'] = AtariColorVectorPlatform; +PLATFORMS['vector-z80color'] = Z80ColorVectorPlatform; diff --git a/src/ui.js b/src/ui.js index 6d4551ac..2ea9e04e 100644 --- a/src/ui.js +++ b/src/ui.js @@ -530,12 +530,26 @@ function getCurrentLine() { return editor.getCursor().line+1; } -function runToCursor() { - setupBreakpoint(); +function getCurrentPC() { var line = getCurrentLine(); var pc = sourcefile.line2offset[line]; + if (!(pc >= 0)) { + line = disasmview.getCursor().line; + if (line) { + var toks = disasmview.getLine(line).split(/\s+/); + if (toks) { + pc = parseInt(toks[0], 16); + } + } + } + return pc; +} + +function runToCursor() { + setupBreakpoint(); + var pc = getCurrentPC(); if (pc >= 0) { - console.log("Run to", line, pc.toString(16)); + console.log("Run to", pc.toString(16)); platform.runEval(function(c) { return c.PC == pc; }); @@ -795,7 +809,7 @@ function updateDisassembly() { s += dline; if (a == pc) selline = curline; curline++; - a += disasm.nbytes; + a += disasm.nbytes || 1; } return s; } diff --git a/src/worker/workermain.js b/src/worker/workermain.js index 0f3c09af..a4c3dc6e 100644 --- a/src/worker/workermain.js +++ b/src/worker/workermain.js @@ -25,11 +25,11 @@ var PLATFORM_PARAMS = { data_start: 0x9000, data_size: 0x3000, }, - 'vector-z80': { + 'vector-z80color': { code_start: 0x0, - code_size: 0x4000, - data_start: 0x6000, - data_size: 0x1000, + code_size: 0x8000, + data_start: 0xe000, + data_size: 0x2000, }, }; @@ -650,13 +650,15 @@ function compileSDCC(code, platform) { //'--asm=z80asm', '--fomit-frame-pointer', '--opt-code-speed', '-o', 'main.asm']); + /* // ignore if all are warnings (TODO?) var nwarnings = 0; for (var err of msvc_errors) { if (err.type && err.type.startsWith("warning")) nwarnings++; } - if (msvc_errors.length && nwarnings < msvc_errors.length) { + */ + if (msvc_errors.length /* && nwarnings < msvc_errors.length*/) { return {errors:msvc_errors}; } try {