color vectors

This commit is contained in:
Steven Hugg 2017-02-04 23:19:54 -05:00
parent 41daf862d6
commit 042041e041
6 changed files with 377 additions and 74 deletions

View File

@ -283,6 +283,7 @@ canvas.pixelated {
<script src="local/williams/defender.js"></script>
<script src="local/williams/robotron.js"></script>
<script src="local/atarivec/gravitar/gravitar.js"></script>
<script src="FileSaver.js/FileSaver.min.js"></script>
<script src="octokat.js/dist/octokat.js"></script>

View File

@ -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 {

View File

@ -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);

View File

@ -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<cpuCyclesPerFrame; i++) {
if (debugCond && debugCond()) { debugCond = null; }
clock++;
if (--nmicount == 0) {
//console.log("NMI", cpu.saveState());
var n = cpu.setIRQAndWait(); // TODO: only if I flag set
clock += n;
nmicount = cpuCyclesPerNMI - n;
//console.log(n, clock, nmicount);
}
cpu.clockPulse();
//cpu.executeInstruction();
}
self.restartDebugState();
});
setKeyboardFromMap(video, switches, GRAVITAR_KEYCODE_MAP);
}
this.loadROM = function(title, data) {
this.reset();
}
this.getRasterPosition = function() {
return {x:0, y:0}; // TODO
}
this.isRunning = function() {
return timer.isRunning();
}
this.pause = function() {
timer.stop();
}
this.resume = function() {
timer.start();
}
this.reset = function() {
this.clearDebug();
cpu.reset();
}
this.readAddress = function(addr) {
return bus.read(addr);
}
this.loadState = function(state) {
cpu.loadState(state.c);
cpuram.mem.set(state.cb);
dvgram.mem.set(state.db);
nmicount = state.nmic;
}
this.saveState = function() {
return {
c:cpu.saveState(),
cb:cpuram.mem.slice(0),
db:dvgram.mem.slice(0),
nmic:nmicount
}
}
this.getCPUState = function() {
return cpu.saveState();
}
}
//
var VectorZ80Platform = function(mainElement, proto) {
var Z80ColorVectorPlatform = function(mainElement, proto) {
var self = this;
var cpuFrequency = 3000000.0;
var cpuCyclesPerFrame = Math.round(cpuFrequency/60);
@ -155,34 +309,30 @@ var VectorZ80Platform = function(mainElement, proto) {
}
this.start = function() {
cpuram = new RAM(0x1000);
dvgram = new RAM(0x2000);
//switches[5] = 0xff;
//switches[7] = 0xff;
cpuram = new RAM(0x2000);
dvgram = new RAM(0x4000);
// bus
bus = {
read: new AddressDecoder([
[0x0, 0x3fff, 0, function(a) { return rom[a]; }],
[0x4000, 0x5fff, 0x1fff, function(a) { return dvgram.mem[a]; }],
[0x6000, 0x6fff, 0xfff, function(a) { return cpuram.mem[a]; }],
[0x7001, 0x7001, 0, function(a) { return ((clock/1000) & 1) ? 0xff : 0x00; }],
[0x7000, 0x7007, 0x7, function(a) { return switches[a]; }],
[0x7400, 0x7407, 0x7, function(a) { return switches[a+8]; }],
[0x0, 0x7fff, 0, function(a) { return rom[a]; }],
[0x8000, 0x800f, 0xf, function(a) { return switches[a]; }],
[0xa000, 0xdfff, 0x3fff, function(a) { return dvgram.mem[a]; }],
[0xe000, 0xffff, 0x1fff, function(a) { return cpuram.mem[a]; }],
]),
write: new AddressDecoder([
[0x7000, 0x7000, 0, function(a,v) { dvg.runUntilHalt(); }],
// TODO: draw asynchronous or allow poll of HALT ($2002)
[0x4000, 0x5fff, 0x1fff, function(a,v) { dvgram.mem[a] = v; }],
[0x6000, 0x6fff, 0xfff, function(a,v) { cpuram.mem[a] = v; }],
[0x8840, 0x8840, 0, function(a,v) { dvg.runUntilHalt(0); }],
[0x8880, 0x8880, 0, function(a,v) { dvg.reset(); }],
[0xa000, 0xdfff, 0x3fff, function(a,v) { dvgram.mem[a] = v; }],
[0xe000, 0xffff, 0x1fff, function(a,v) { cpuram.mem[a] = v; }],
])
};
cpu = self.newCPU(bus);
// create video/audio
video = new VectorVideo(mainElement,1024,1024);
dvg = new DVGStateMachine(bus, video);
dvg = new DVGColorStateMachine(bus, video, 0xa000);
audio = new SampleAudio(cpuFrequency);
video.create();
timer = new AnimationTimer(60, function() {
@ -195,7 +345,7 @@ var VectorZ80Platform = function(mainElement, proto) {
}
this.loadROM = function(title, data) {
rom = padBytes(data, 0x4000);
rom = padBytes(data, 0x8000);
this.reset();
}
@ -238,15 +388,15 @@ var VectorZ80Platform = function(mainElement, proto) {
// DIGITAL VIDEO GENERATOR
var DVGStateMachine = function(bus, video) {
var DVGBWStateMachine = function(bus, video, bofs) {
var self = this;
var pc = 0;
var x = 0;
var y = 0;
var gsc = 0;
var bofs = 0x4000;
var pcstack = [];
var running = false;
bofs &= 0xffff;
function readWord(a) {
a &= 0xfff;
@ -262,14 +412,20 @@ var DVGStateMachine = function(bus, video) {
return w;
}
this.go = function() {
this.reset = function() {
pc = 0;
gsc = 7;
running = false;
}
this.go = function() {
this.reset();
running = true;
}
this.runUntilHalt = function() {
this.runUntilHalt = function(startpc) {
this.go();
pc = startpc;
for (var i=0; i<10000; i++) { // TODO: limit execution
if (!running) break;
this.nextInstruction();
@ -302,7 +458,7 @@ var DVGStateMachine = function(bus, video) {
var z = w2 >> 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<<o2);
w = w & ((1<<o2)-1);
if (s)
return w-(1<<o2);
else
return w;
}
this.reset = function() {
pc = 0;
scale = 1.0;
color = 7;
statz = 15;
x = 512;
y = 512;
running = false;
}
this.go = function() {
this.reset();
running = true;
}
this.runUntilHalt = function(startpc) {
this.go();
pc = startpc;
for (var i=0; i<10000; i++) { // TODO: limit execution
if (!running) break;
this.nextInstruction();
}
//console.log('DVG',i);
}
this.nextInstruction = function() {
if (!running) return;
var w = readWord(pc);
var op = w >> 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;

View File

@ -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;
}

View File

@ -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 {