From ba9dfb0c1c1ea54ccb60185a35066afb488e05e7 Mon Sep 17 00:00:00 2001 From: Marcel van Kervinck Date: Wed, 18 Jul 2018 14:24:29 +0200 Subject: [PATCH 1/7] Retire the historic 'theloop.2.rom' name Addresses https://github.com/PhilThomas/gigatron/issues/1 --- README.md | 7 ++++++- src/main.js | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) mode change 100644 => 100755 README.md diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 11a3c6e..1374779 --- a/README.md +++ b/README.md @@ -7,7 +7,12 @@ The `package.json` can install an HTTP server, just do: npm install -Download [`theloop.2.rom`](https://github.com/kervinck/gigatron-rom/raw/master/theloop.2.rom) into the `src` directory. +Pick and download a [`*.rom`](https://github.com/kervinck/gigatron-rom/) file into the `src/` directory and rename it as `gigatron.rom` + +Direct links: + + [`ROM v1`](https://github.com/kervinck/gigatron-rom/raw/master/ROMv1.rom) + [`ROM v2`](https://github.com/kervinck/gigatron-rom/raw/master/ROMv2.rom) Start the HTTP server diff --git a/src/main.js b/src/main.js index ae193d4..aafacef 100644 --- a/src/main.js +++ b/src/main.js @@ -22,7 +22,7 @@ const { } = rxjs.operators; const HZ = 6250000; -const romUrl = 'theloop.2.rom'; +const romUrl = 'gigatron.rom'; $(function() { $('[data-toggle="tooltip"]').tooltip(); From 8ed69d27875cae4c4bb1d84f31a5f4b2901ebec7 Mon Sep 17 00:00:00 2001 From: Marcel van Kervinck Date: Wed, 18 Jul 2018 14:26:55 +0200 Subject: [PATCH 2/7] README.md formatting --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1374779..c30ed58 100755 --- a/README.md +++ b/README.md @@ -10,9 +10,8 @@ The `package.json` can install an HTTP server, just do: Pick and download a [`*.rom`](https://github.com/kervinck/gigatron-rom/) file into the `src/` directory and rename it as `gigatron.rom` Direct links: - - [`ROM v1`](https://github.com/kervinck/gigatron-rom/raw/master/ROMv1.rom) - [`ROM v2`](https://github.com/kervinck/gigatron-rom/raw/master/ROMv2.rom) +[`ROM v1`](https://github.com/kervinck/gigatron-rom/raw/master/ROMv1.rom) +[`ROM v2`](https://github.com/kervinck/gigatron-rom/raw/master/ROMv2.rom) Start the HTTP server From b6b0437a5593f48cb2230231e6e9f5b096417a3f Mon Sep 17 00:00:00 2001 From: Marcel van Kervinck Date: Wed, 18 Jul 2018 14:39:46 +0200 Subject: [PATCH 3/7] Make keymapping the same as BabelFish PS/2 adapter - Can type normal ASCII now in Tiny BASIC, WozMon, Terminal etcetera - Game controller buttons: A = Delete, Backspace or End B = Insert, Home Select = PageDown Start = PageUp - Update image of game controller to match with Gigatron layout - Make gamepad smaller and remove logo to reduce scrolling --- src/gamepad.js | 26 +++++- src/index.html | 229 +++++++++++++++++++++++++++---------------------- src/main.js | 16 ++-- 3 files changed, 160 insertions(+), 111 deletions(-) mode change 100644 => 100755 src/gamepad.js mode change 100644 => 100755 src/index.html mode change 100644 => 100755 src/main.js diff --git a/src/gamepad.js b/src/gamepad.js old mode 100644 new mode 100755 index 10da3fc..445ac78 --- a/src/gamepad.js +++ b/src/gamepad.js @@ -60,6 +60,22 @@ export class Gamepad { this.keyMap[key] = buttonMap[button]; } } + + /* build map of ASCII codes that the Gigatron understands as well */ + this.asciiMap = { + 'Tab': 9, + 'Enter': 10, + 'Escape': 27, + 'Esc': 27, + 'Delete': 127, + 'Backspace': 127, + }; + for (let ascii=32; ascii<127; ascii++) { + this.asciiMap[String.fromCharCode(ascii)] = ascii; + } + for (let fnKey=1; fnKey<=12; fnKey++) { + this.asciiMap['F' + fnKey] = 0xc0 + fnKey; + } } /** start handling key events */ @@ -70,14 +86,22 @@ export class Gamepad { if (bit) { this.pressed |= bit; event.preventDefault(); + } else { + let ascii = this.asciiMap[event.key]; + if (ascii) { + this.pressed = ascii ^ 0xff; /// will be inverted again in tick() + event.preventDefault(); + } } }) .on('keyup', (event) => { let bit = this.keyMap[event.key]; if (bit) { this.pressed &= ~bit; - event.preventDefault(); + } else { + this.pressed = 0; } + event.preventDefault(); }); this.enabled = true; } diff --git a/src/index.html b/src/index.html old mode 100644 new mode 100755 index ae28eb6..f6884c6 --- a/src/index.html +++ b/src/index.html @@ -54,13 +54,14 @@
- + @@ -97,101 +98,93 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SELECT - - - - - - START - - - - - - - - - A - - - - - - - - - B - - - - - +
+
+ + + + + + + + -
+ + + + + + -
-
- -
-
select
-
Q
- -
start
-
W
-
-
-
A
-
A
- -
B
-
S
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT + + + + + + START + + + + + + + + + A + + + + + + + + + B + + + + + + + + + + + + + + +
-
+
@@ -202,19 +195,51 @@
-
-
+

-

-
-
-
- - + + +
+
+ + +
-
- + + +
+ +
+ + Keyboard shortcuts: +

+

+
Up
+
Up arrow
+ +
Down
+
Down arrow
+ +
Right
+
Right arrow
+ +
Left
+
Left arrow
+ +
A button
+
Delete/End key
+ +
B button
+
Insert/Home key
+ +
Select button
+
PageDown key
+ +
Start button
+
PageUp key
+ +
diff --git a/src/main.js b/src/main.js old mode 100644 new mode 100755 index aafacef..00927b3 --- a/src/main.js +++ b/src/main.js @@ -64,10 +64,10 @@ $(function() { }); } - bindKeyToButton($('.gamepad-btn-a'), 'A'); - bindKeyToButton($('.gamepad-btn-b'), 'S'); - bindKeyToButton($('.gamepad-btn-start'), 'W'); - bindKeyToButton($('.gamepad-btn-select'), 'Q'); + bindKeyToButton($('.gamepad-btn-a'), 'Delete'); + bindKeyToButton($('.gamepad-btn-b'), 'Insert'); + bindKeyToButton($('.gamepad-btn-start'), 'PageUp'); + bindKeyToButton($('.gamepad-btn-select'), 'PageDown'); bindKeyToButton($('.gamepad-btn-up'), 'ArrowUp'); bindKeyToButton($('.gamepad-btn-down'), 'ArrowDown'); bindKeyToButton($('.gamepad-btn-left'), 'ArrowLeft'); @@ -155,10 +155,10 @@ $(function() { down: ['ArrowDown'], left: ['ArrowLeft'], right: ['ArrowRight'], - select: ['Q', 'q'], - start: ['W', 'w'], - a: ['A', 'a'], - b: ['S', 's'], + select: ['PageDown'], + start: ['PageUp'], + a: ['Delete', 'Backspace', 'End'], + b: ['Insert', 'Home'], }); let loader = new Loader(cpu); From ec818e2258b291e1995cc86c90bbbcc5d2351edf Mon Sep 17 00:00:00 2001 From: Marcel van Kervinck Date: Wed, 18 Jul 2018 14:40:56 +0200 Subject: [PATCH 4/7] Unde unintended chmod change of previous commit --- src/gamepad.js | 0 src/index.html | 0 src/main.js | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/gamepad.js mode change 100755 => 100644 src/index.html mode change 100755 => 100644 src/main.js diff --git a/src/gamepad.js b/src/gamepad.js old mode 100755 new mode 100644 diff --git a/src/index.html b/src/index.html old mode 100755 new mode 100644 diff --git a/src/main.js b/src/main.js old mode 100755 new mode 100644 From 9b2a5e6fb8433545143321c73f40954805def192 Mon Sep 17 00:00:00 2001 From: Marcel van Kervinck Date: Wed, 18 Jul 2018 14:49:55 +0200 Subject: [PATCH 5/7] Document file drop function --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c30ed58..379c305 100755 --- a/README.md +++ b/README.md @@ -23,4 +23,4 @@ Use the cursor keys for the D-pad. ## GT1 Files -GT1 files can be loaded by starting the `Loader` and dropping a `.gt1` file onto the VGA display from File Explorer or Finder. +GT1 files can be loaded by dropping a `.gt1` file onto the VGA display from File Explorer or Finder. From d32317dfd67af71ec38cdac06f40b2ec6bc405da Mon Sep 17 00:00:00 2001 From: Marcel van Kervinck Date: Sun, 26 Aug 2018 21:27:12 -0400 Subject: [PATCH 6/7] Handle control key and map to sub-31 ASCII range Ctrl-Space = ASCII 0 (NUL) Ctrl-? = ASCII 127 (DEL) Ctrl-Other = ASCII 1..31 (e.g. Ctrl-C = ASCII 3 = ETX = BREAK) --- src/gamepad.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gamepad.js b/src/gamepad.js index 445ac78..296c2e7 100644 --- a/src/gamepad.js +++ b/src/gamepad.js @@ -89,6 +89,12 @@ export class Gamepad { } else { let ascii = this.asciiMap[event.key]; if (ascii) { + if (event.ctrlKey) { + // Control codes (e.g. Ctrl-C for ETX or BREAK) + if (ascii == 63 /*'?'*/) ascii = 127; + else if (ascii == 32 /*' '*/) ascii = 0; + else ascii &= 31; + } this.pressed = ascii ^ 0xff; /// will be inverted again in tick() event.preventDefault(); } From 607842cd22c648510971bc138b60f52d6cf2b41d Mon Sep 17 00:00:00 2001 From: Marcel van Kervinck Date: Sun, 26 Aug 2018 22:55:38 -0400 Subject: [PATCH 7/7] Visible area was shifted down by 2 scanline (last two never shown) Caused by a combination of - not including the pulse length in the countdown from vPulse start to visible pixels (losing 2 lines) - off-by-one error in row counting (winning back 1 line) - using 34 as vertical backporch instead of 33 (to compensate the off-by-one?) In reality, Gigatron signals are slightly different from standard VGA anyway. Now made the code more symmetric and use the typical Gigatron numbers. --- src/main.js | 6 ++++-- src/vga.js | 11 +++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main.js b/src/main.js index 00927b3..3afc33f 100644 --- a/src/main.js +++ b/src/main.js @@ -136,12 +136,14 @@ $(function() { let vga = new Vga(vgaCanvas.get(0), cpu, { horizontal: { frontPorch: 16, + pulse: 96, backPorch: 48, visible: 640, }, vertical: { - frontPorch: 10, - backPorch: 34, + frontPorch: 6, + pulse: 8, + backPorch: 27, visible: 480, }, }); diff --git a/src/vga.js b/src/vga.js index 1751c56..31cb4a7 100644 --- a/src/vga.js +++ b/src/vga.js @@ -21,10 +21,10 @@ export class Vga { this.pixels = this.imageData.data; this.cpu = cpu; this.row = 0; - this.minRow = options.vertical.backPorch; + this.minRow = options.vertical.backPorch + options.vertical.pulse; this.maxRow = this.minRow + options.vertical.visible; this.col = 0; - this.minCol = options.horizontal.backPorch; + this.minCol = options.horizontal.backPorch + options.horizontal.pulse; this.maxCol = this.minCol + options.horizontal.visible; this.pixel = 0; this.out = 0; @@ -46,7 +46,7 @@ export class Vga { let falling = this.out & ~out; if (falling & VSYNC) { - this.row = 0; + this.row = -1; // After 4 more CPU cycles HSYNC increments row to 0 this.pixel = 0; this.render(); } @@ -60,11 +60,6 @@ export class Vga { // if it follows immediately after it, so it got moved down here this.out = out; - if ((out & (VSYNC | HSYNC)) != (VSYNC | HSYNC)) { - // blanking interval - return; - } - if ((this.row >= this.minRow && this.row < this.maxRow) && (this.col >= this.minCol && this.col < this.maxCol)) { let pixels = this.pixels;