diff --git a/css/apple2.css b/css/apple2.css index b24ece2..e7250d3 100644 --- a/css/apple2.css +++ b/css/apple2.css @@ -44,7 +44,7 @@ body { } #display { - margin: 5px 0px; + margin: 5px auto; } .overscan { @@ -137,6 +137,36 @@ canvas { image-rendering: optimize-contrast; } +@media all and (device-width: 320px) { + canvas { + width: 537px; + height: 368px; + left: 30px; + top: 24px; + } + #scanlines: { + width: 537px; + height: 368px; + left: 30px; + top: 24px; + } +} + +@media all and (device-width: 768px) { + canvas { + width: 564px; + height: 386px; + left: 14px; + top: 15px; + } + #scanlines { + width: 564px; + height: 386px; + left: 14px; + top: 15px; + } +} + :-webkit-full-screen { width: 100%; height: 100%; @@ -227,7 +257,11 @@ canvas { padding: 0px; height: 42px; font-family: Helvetica; - width: 605px; + width: 570px; +} + +.apple2e #keyboard .row { + width: 610px; } #keyboard .row0 { diff --git a/js/canvas2.js b/js/canvas2.js index d00d890..6ac8ed7 100644 --- a/js/canvas2.js +++ b/js/canvas2.js @@ -28,10 +28,15 @@ var context = null; function LoresPage(page) { + // $00-$3F inverse + // $40-$7F flashing + // $80-$FF normal + var _page = page; var _buffer = []; var _refreshing = false; var _greenMode = false; + var _blink = false; var _black = [0x00,0x00,0x00]; var _white = [0xff,0xff,0xff]; @@ -86,7 +91,13 @@ function LoresPage(page) _init(); return { - start: function() { return (0x04 * _page); }, + start: function() { + var self = this; + window.setInterval(function() { + self.blink(); + }, 267); + return (0x04 * _page); + }, end: function() { return (0x04 * _page) + 0x03; }, read: function(page, off) { var addr = (page << 8) | off, @@ -119,7 +130,7 @@ function LoresPage(page) off = (col * 7 + row * 280 * 8) * 4; if (textMode || (mixedMode && row > 19)) { - if (val & 0x80) { + if (val & 0x80 || ((val & 0x40) && _blink)) { fore = _greenMode ? _green : _white; back = _black; } else { @@ -161,6 +172,18 @@ function LoresPage(page) } _refreshing = false; }, + blink: function() { + var addr = 0x400 * _page; + _refreshing = true; + _blink = !_blink; + for (var idx = 0; idx < 0x400; idx++, addr++) { + var b = _buffer[idx]; + if ((b & 0xC0) == 0x40) { + this.write(addr >> 8, addr & 0xff, _buffer[idx]); + } + } + _refreshing = false; + }, green: function(on) { _greenMode = on; this.refresh(); diff --git a/js/canvas2e.js b/js/canvas2e.js index ab596ad..97cdf62 100644 --- a/js/canvas2e.js +++ b/js/canvas2e.js @@ -35,10 +35,15 @@ var context = null; function LoresPage(page) { + // $00-$3F inverse + // $40-$7F flashing + // $80-$FF normal + var _page = page; var _buffer = []; var _refreshing = false; var _greenMode = false; + var _blink = false; var _black = [0x00,0x00,0x00]; var _white = [0xff,0xff,0xff]; @@ -76,6 +81,12 @@ function LoresPage(page) _init(); return { + start: function() { + var self = this; + window.setInterval(function() { + self.blink(); + }, 267); + }, bank0: function() { var self = this; return { @@ -114,7 +125,9 @@ function LoresPage(page) // These are used by both bank 0 and 1 - _start: function() { return (0x04 * _page); }, + _start: function() { + return (0x04 * _page); + }, _end: function() { return (0x04 * _page) + 0x03; }, _read: function(page, off, bank) { var addr = (page << 8) | off, @@ -151,13 +164,15 @@ function LoresPage(page) var color; if (textMode || (mixedMode && row > 19)) { var b; - fore = _greenMode ? _green : _white; - back = _black; + var flash = ((val & 0xc0) == 0x40) && + _blink && !_80colMode; + fore = flash ? _black : (_greenMode ? _green : _white); + back = flash ? _white : _black; if (!altCharMode && !_80colMode) { val = (val >= 0x40 && val < 0x80) ? val - 0x40 : val; } - + if (_80colMode) { off = (col * 14 + (bank ? 0 : 1) * 7 + row * 560 * 8) * 4; for (jdx = 0; jdx < 8; jdx++) { @@ -238,6 +253,18 @@ function LoresPage(page) } _refreshing = false; }, + blink: function() { + var addr = 0x400 * _page; + _refreshing = true; + _blink = !_blink; + for (var idx = 0; idx < 0x400; idx++, addr++) { + var b = _buffer[0][idx]; + if ((b & 0xC0) == 0x40) { + this._write(addr >> 8, addr & 0xff, _buffer[0][idx], 0); + } + } + _refreshing = false; + }, green: function(on) { _greenMode = on; }, diff --git a/js/mmu.js b/js/mmu.js index bcb64c8..65c9aa3 100644 --- a/js/mmu.js +++ b/js/mmu.js @@ -569,6 +569,8 @@ function MMU(cpu, lores1, lores2, hires1, hires2, io, rom) start: function mmu_start() { // Fake call start to register switches io.start(); + lores1.start(); + lores2.start(); // Do us afterward because we override some of the above io.registerSwitches(this, LOC); diff --git a/js/ui/keyboard2.js b/js/ui/keyboard2.js index 023bb8a..693b7fe 100644 --- a/js/ui/keyboard2.js +++ b/js/ui/keyboard2.js @@ -14,9 +14,8 @@ /*globals debug: false, toHex: false, reset: false */ /*exported KeyBoard */ -// keycode: [plain, cntl, shift] - function KeyBoard(io) { + // keycode: [plain, cntl, shift] var keymap = { // Most of these won't happen 0x00: [0x00, 0x00, 0x00], // @@ -165,6 +164,26 @@ function KeyBoard(io) { return 0xFF; }, + shiftKey: function keyboard_shiftKey(down) { + shifted = down; + if (down) { + io.buttonDown(2); + $("#keyboard .key-SHIFT").addClass("active"); + } else { + io.buttonUp(2); + $("#keyboard .key-SHIFT").removeClass("active"); + } + }, + + controlKey: function keyboard_controlKey(down) { + controlled = down; + if (down) { + $("#keyboard .key-CTRL").addClass("active"); + } else { + $("#keyboard .key-CTRL").removeClass("active"); + } + }, + create: function keyboard_create(kb) { var x, y, row, key, key1, key2, label, label1, label2; @@ -177,17 +196,16 @@ function KeyBoard(io) { return span; } - function _mousedown() { - $(this).addClass("pressed"); + function _mousedown(ev) { + $(ev.currentTarget).addClass("pressed"); } - function _mouseup() { - $(this).removeClass("pressed"); + function _mouseup(ev) { + $(ev.currentTarget).removeClass("pressed"); } - function _click() { - var self = this, - key = $(self).data(shifted ? "key2" : "key1"); + function _click(ev) { + var key = $(ev.currentTarget).data(shifted ? "key2" : "key1"); switch (key) { case "BELL": key = "G"; @@ -215,11 +233,11 @@ function KeyBoard(io) { switch (key) { case "SHIFT": shifted = !shifted; - $("#keyboard .key-SHIFT").toggleClass("shifted"); + $("#keyboard .key-SHIFT").toggleClass("active"); break; case "CTRL": controlled = !controlled; - $("#keyboard .key-CTRL").toggleClass("controlled"); + $("#keyboard .key-CTRL").toggleClass("active"); break; case "RESET": reset(); @@ -265,10 +283,20 @@ function KeyBoard(io) { label.append(label1); key.append(label); key.data({"key1": key1, "key2": key2}); - key.bind("mousedown", _mousedown); - key.bind("mouseup mouseout", _mouseup); - - key.click(_click); + + if (window.ontouchstart === undefined) { + key.bind("mousedown", function(event) { + _mousedown(event); + _click(event); + }); + key.bind("mouseup mouseout", _mouseup); + } else { + key.bind("touchstart", function(event) { + _mousedown(event); + _click(event); + }); + key.bind("touchend touchleave", _mouseup); + } row.append(key); } } diff --git a/js/ui/keyboard2e.js b/js/ui/keyboard2e.js index 30046b7..8a3cf45 100644 --- a/js/ui/keyboard2e.js +++ b/js/ui/keyboard2e.js @@ -261,8 +261,8 @@ function KeyBoard(io) { $(this).removeClass("pressed"); } - function _click() { - var key = $(this).data(shifted ? "key2" : "key1"); + function _click(ev) { + var key = $(ev.currentTarget).data(shifted ? "key2" : "key1"); switch (key) { case "BELL": key = "G"; @@ -366,9 +366,21 @@ function KeyBoard(io) { label.append(label1); key.append(label); key.data({"key1": key1, "key2": key2}); - key.bind("mousedown", _mousedown); - key.bind("mouseup mouseout", _mouseup); - key.click(_click); + + if (window.ontouchstart === undefined) { + key.bind("mousedown", function(event) { + _mousedown(event); + _click(event); + }); + key.bind("mouseup mouseout", _mouseup); + } else { + key.bind("touchstart", function(event) { + _mousedown(event); + _click(event); + }); + key.bind("touchend touchleave", _mouseup); + } + row.append(key); } }