mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
D13 support, closer to real hardward behavior.
This commit is contained in:
parent
bdb792f8fb
commit
c02ea762d8
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*exported DiskII */
|
/*exported DiskII */
|
||||||
/*globals bytify: false, debug: false
|
/*globals bytify: false, debug: false, toHex: false
|
||||||
base64_decode: false, base64_encode: false
|
base64_decode: false, base64_encode: false
|
||||||
Uint8Array: false
|
Uint8Array: false
|
||||||
*/
|
*/
|
||||||
@ -72,42 +72,65 @@ function DiskII(io, slot, callbacks)
|
|||||||
|
|
||||||
// var DO = [0x0,0x7,0xE,0x6,0xD,0x5,0xC,0x4,
|
// var DO = [0x0,0x7,0xE,0x6,0xD,0x5,0xC,0x4,
|
||||||
// 0xB,0x3,0xA,0x2,0x9,0x1,0x8,0xF];
|
// 0xB,0x3,0xA,0x2,0x9,0x1,0x8,0xF];
|
||||||
var _DO = [0x0,0xD,0xB,0x9,0x7,0x5,0x3,0x1,
|
var _DO = [
|
||||||
0xE,0xC,0xA,0x8,0x6,0x4,0x2,0xF];
|
0x0,0xD,0xB,0x9,0x7,0x5,0x3,0x1,
|
||||||
|
0xE,0xC,0xA,0x8,0x6,0x4,0x2,0xF
|
||||||
|
];
|
||||||
|
|
||||||
// var PO = [0x0,0x8,0x1,0x9,0x2,0xa,0x3,0xb,
|
// var PO = [0x0,0x8,0x1,0x9,0x2,0xa,0x3,0xb,
|
||||||
// 0x4,0xc,0x5,0xd,0x6,0xe,0x7,0xf];
|
// 0x4,0xc,0x5,0xd,0x6,0xe,0x7,0xf];
|
||||||
var _PO = [0x0,0x2,0x4,0x6,0x8,0xa,0xc,0xe,
|
var _PO = [
|
||||||
0x1,0x3,0x5,0x7,0x9,0xb,0xd,0xf];
|
0x0,0x2,0x4,0x6,0x8,0xa,0xc,0xe,
|
||||||
|
0x1,0x3,0x5,0x7,0x9,0xb,0xd,0xf
|
||||||
|
];
|
||||||
|
|
||||||
var _trans = [0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
|
// var D13O = [
|
||||||
0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
|
// 0x0, 0xa, 0x7, 0x4, 0x1, 0xb, 0x8, 0x5, 0x2, 0xc, 0x9, 0x6, 0x3
|
||||||
0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
|
// ];
|
||||||
0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3,
|
|
||||||
0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
|
|
||||||
0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec,
|
|
||||||
0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
|
|
||||||
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff];
|
|
||||||
|
|
||||||
var _detrans = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
var _D13O = [
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
];
|
||||||
0x00, 0x00, 0x02, 0x03, 0x00, 0x04, 0x05, 0x06,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08,
|
var _trans53 = [
|
||||||
0x00, 0x00, 0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
|
0xab, 0xad, 0xae, 0xaf, 0xb5, 0xb6, 0xb7, 0xba,
|
||||||
0x00, 0x00, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
|
0xbb, 0xbd, 0xbe, 0xbf, 0xd6, 0xd7, 0xda, 0xdb,
|
||||||
0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
|
0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xed, 0xee, 0xef,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xf5, 0xf6, 0xf7, 0xfa, 0xfb, 0xfd, 0xfe, 0xff
|
||||||
0x00, 0x00, 0x00, 0x1B, 0x00, 0x1C, 0x1D, 0x1E,
|
];
|
||||||
0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x20, 0x21,
|
|
||||||
0x00, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
var _trans62 = [
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x2A, 0x2B,
|
0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
|
||||||
0x00, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
|
0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
|
||||||
0x00, 0x00, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
|
||||||
0x00, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F];
|
0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3,
|
||||||
|
0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
|
||||||
|
0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec,
|
||||||
|
0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
|
||||||
|
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||||
|
];
|
||||||
|
|
||||||
|
var _detrans62 = [
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x02, 0x03, 0x00, 0x04, 0x05, 0x06,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08,
|
||||||
|
0x00, 0x00, 0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
|
||||||
|
0x00, 0x00, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
|
||||||
|
0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x1B, 0x00, 0x1C, 0x1D, 0x1E,
|
||||||
|
0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x20, 0x21,
|
||||||
|
0x00, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x2A, 0x2B,
|
||||||
|
0x00, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
|
||||||
|
0x00, 0x00, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
||||||
|
0x00, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
|
||||||
|
];
|
||||||
|
|
||||||
function _debug() {
|
function _debug() {
|
||||||
// debug.apply(this, arguments);
|
console.log.apply(this, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _init() {
|
function _init() {
|
||||||
@ -133,7 +156,7 @@ function DiskII(io, slot, callbacks)
|
|||||||
return ((xx << 1) | 0x01) & yy;
|
return ((xx << 1) | 0x01) & yy;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _explodeSector(volume, track, sector, data) {
|
function _explodeSector16(volume, track, sector, data) {
|
||||||
var checksum;
|
var checksum;
|
||||||
|
|
||||||
var buf = [], idx;
|
var buf = [], idx;
|
||||||
@ -209,10 +232,113 @@ function DiskII(io, slot, callbacks)
|
|||||||
var last = 0;
|
var last = 0;
|
||||||
for (idx = 0; idx < 0x156; idx++) {
|
for (idx = 0; idx < 0x156; idx++) {
|
||||||
var val = nibbles[idx];
|
var val = nibbles[idx];
|
||||||
buf.push(_trans[last ^ val]);
|
buf.push(_trans62[last ^ val]);
|
||||||
last = val;
|
last = val;
|
||||||
}
|
}
|
||||||
buf.push(_trans[last]);
|
buf.push(_trans62[last]);
|
||||||
|
|
||||||
|
buf = buf.concat([0xde, 0xaa, 0xf2]); // Epilog DE AA F2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gap 3
|
||||||
|
*/
|
||||||
|
|
||||||
|
buf.push(0xff);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _explodeSector13(volume, track, sector, data) {
|
||||||
|
var checksum;
|
||||||
|
|
||||||
|
var buf = [], idx;
|
||||||
|
|
||||||
|
var gap;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gap 1/3 (40/0x28 bytes)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (sector === 0) // Gap 1
|
||||||
|
gap = 0x80;
|
||||||
|
else { // Gap 3
|
||||||
|
gap = track === 0 ? 0x28 : 0x26;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (idx = 0; idx < gap; idx++) {
|
||||||
|
buf.push(0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Address Field
|
||||||
|
*/
|
||||||
|
|
||||||
|
checksum = volume ^ track ^ sector;
|
||||||
|
buf = buf.concat([0xd5, 0xaa, 0xb5]); // Address Prolog D5 AA B5
|
||||||
|
buf = buf.concat(_fourXfour(volume));
|
||||||
|
buf = buf.concat(_fourXfour(track));
|
||||||
|
buf = buf.concat(_fourXfour(sector));
|
||||||
|
buf = buf.concat(_fourXfour(checksum));
|
||||||
|
buf = buf.concat([0xde, 0xaa, 0xeb]); // Epilog DE AA EB
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gap 2 (5 bytes)
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (idx = 0; idx < 0x05; idx++) {
|
||||||
|
buf.push(0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data Field
|
||||||
|
*/
|
||||||
|
|
||||||
|
buf = buf.concat([0xd5, 0xaa, 0xad]); // Data Prolog D5 AA AD
|
||||||
|
|
||||||
|
var nibbles = [];
|
||||||
|
|
||||||
|
var jdx = 0;
|
||||||
|
for (idx = 0x32; idx >= 0; idx--) {
|
||||||
|
var a5 = data[jdx] >> 3;
|
||||||
|
var a3 = data[jdx] & 0x07;
|
||||||
|
jdx++;
|
||||||
|
var b5 = data[jdx] >> 3;
|
||||||
|
var b3 = data[jdx] & 0x07;
|
||||||
|
jdx++;
|
||||||
|
var c5 = data[jdx] >> 3;
|
||||||
|
var c3 = data[jdx] & 0x07;
|
||||||
|
jdx++;
|
||||||
|
var d5 = data[jdx] >> 3;
|
||||||
|
var d3 = data[jdx] & 0x07;
|
||||||
|
jdx++;
|
||||||
|
var e5 = data[jdx] >> 3;
|
||||||
|
var e3 = data[jdx] & 0x07;
|
||||||
|
jdx++;
|
||||||
|
nibbles[idx + 0x00] = a5;
|
||||||
|
nibbles[idx + 0x33] = b5;
|
||||||
|
nibbles[idx + 0x66] = c5;
|
||||||
|
nibbles[idx + 0x99] = d5;
|
||||||
|
nibbles[idx + 0xcc] = e5;
|
||||||
|
nibbles[idx + 0x100] = a3 << 2 | (d3 & 0x4) >> 1 | (e3 & 0x4) >> 2;
|
||||||
|
nibbles[idx + 0x133] = b3 << 2 | (d3 & 0x2) | (e3 & 0x2) >> 1;
|
||||||
|
nibbles[idx + 0x166] = c3 << 2 | (d3 & 0x1) << 1 | (e3 & 0x1);
|
||||||
|
}
|
||||||
|
nibbles[0xff] = data[jdx] >> 3;
|
||||||
|
nibbles[0x199] = data[jdx] & 0x07;
|
||||||
|
|
||||||
|
var val;
|
||||||
|
var last = 0;
|
||||||
|
for (idx = 0x199; idx >= 0x100; idx--) {
|
||||||
|
val = nibbles[idx];
|
||||||
|
buf.push(_trans53[last ^ val]);
|
||||||
|
last = val;
|
||||||
|
}
|
||||||
|
for (idx = 0x0; idx < 0x100; idx++) {
|
||||||
|
val = nibbles[idx];
|
||||||
|
buf.push(_trans53[last ^ val]);
|
||||||
|
last = val;
|
||||||
|
}
|
||||||
|
buf.push(_trans53[last]);
|
||||||
|
|
||||||
buf = buf.concat([0xde, 0xaa, 0xeb]); // Epilog DE AA EB
|
buf = buf.concat([0xde, 0xaa, 0xeb]); // Epilog DE AA EB
|
||||||
|
|
||||||
@ -240,12 +366,12 @@ function DiskII(io, slot, callbacks)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return JSON.stringify({'type': format,
|
return JSON.stringify({
|
||||||
'encoding': 'base64',
|
'type': format,
|
||||||
'volume': cur.volume,
|
'encoding': 'base64',
|
||||||
'data': data},
|
'volume': cur.volume,
|
||||||
null,
|
'data': data
|
||||||
pretty ? ' ' : null);
|
}, null, pretty ? ' ' : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _json_decode(drive, data) {
|
function _json_decode(drive, data) {
|
||||||
@ -258,7 +384,7 @@ function DiskII(io, slot, callbacks)
|
|||||||
for (var s = 0; s < json.data[t].length; s++) {
|
for (var s = 0; s < json.data[t].length; s++) {
|
||||||
var _s = 15 - s;
|
var _s = 15 - s;
|
||||||
var d = base64_decode(json.data[t][_s]);
|
var d = base64_decode(json.data[t][_s]);
|
||||||
track = track.concat(_explodeSector(v, t, _DO[_s], d));
|
track = track.concat(_explodeSector16(v, t, _DO[_s], d));
|
||||||
}
|
}
|
||||||
tracks[t] = bytify(track);
|
tracks[t] = bytify(track);
|
||||||
}
|
}
|
||||||
@ -267,33 +393,31 @@ function DiskII(io, slot, callbacks)
|
|||||||
_cur.tracks = tracks;
|
_cur.tracks = tracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _readNext() {
|
function _readWriteNext() {
|
||||||
var result = 0;
|
|
||||||
if (_skip || _writeMode) {
|
if (_skip || _writeMode) {
|
||||||
var t = _cur.tracks[_cur.track >> 1];
|
var track = _cur.tracks[_cur.track >> 1];
|
||||||
if (t && t.length) {
|
if (track && track.length) {
|
||||||
if (_cur.head >= t.length)
|
if (_cur.head >= track.length) {
|
||||||
_cur.head = 0;
|
_cur.head = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (_writeMode) {
|
if (_writeMode) {
|
||||||
t[_cur.head] = _latch;
|
if (!_cur.readOnly) {
|
||||||
} else
|
track[_cur.head] = _latch;
|
||||||
result = t[_cur.head];
|
if (!_cur.dirty) {
|
||||||
|
_updateDirty(_drive, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_latch = track[_cur.head];
|
||||||
|
}
|
||||||
|
|
||||||
++_cur.head;
|
++_cur.head;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_latch = 0;
|
||||||
}
|
}
|
||||||
_skip = (++_skip % 4);
|
_skip = (++_skip % 2);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _writeNext(val) {
|
|
||||||
if (_writeMode) {
|
|
||||||
_latch = val;
|
|
||||||
if (!_cur.dirty) {
|
|
||||||
_updateDirty(_drive, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _readSector(drive, track, sector) {
|
function _readSector(drive, track, sector) {
|
||||||
@ -345,12 +469,12 @@ function DiskII(io, slot, callbacks)
|
|||||||
var data2 = [];
|
var data2 = [];
|
||||||
var last = 0;
|
var last = 0;
|
||||||
for (jdx = 0x55; jdx >= 0; jdx--) {
|
for (jdx = 0x55; jdx >= 0; jdx--) {
|
||||||
val = _detrans[_readNext() - 0x80] ^ last;
|
val = _detrans62[_readNext() - 0x80] ^ last;
|
||||||
data2[jdx] = val;
|
data2[jdx] = val;
|
||||||
last = val;
|
last = val;
|
||||||
}
|
}
|
||||||
for (jdx = 0; jdx < 0x100; jdx++) {
|
for (jdx = 0; jdx < 0x100; jdx++) {
|
||||||
val = _detrans[_readNext() - 0x80] ^ last;
|
val = _detrans62[_readNext() - 0x80] ^ last;
|
||||||
data[jdx] = val;
|
data[jdx] = val;
|
||||||
last = val;
|
last = val;
|
||||||
}
|
}
|
||||||
@ -388,7 +512,7 @@ function DiskII(io, slot, callbacks)
|
|||||||
[ 1,-2,-1, 0]];
|
[ 1,-2,-1, 0]];
|
||||||
|
|
||||||
function setPhase(phase, on) {
|
function setPhase(phase, on) {
|
||||||
_debug('phase ' + phase + (on ? ' on' : ' off'));
|
// _debug('phase ' + phase + (on ? ' on' : ' off'));
|
||||||
if (on) {
|
if (on) {
|
||||||
_cur.track += _phase_delta[_cur.phase][phase];
|
_cur.track += _phase_delta[_cur.phase][phase];
|
||||||
_cur.phase = phase;
|
_cur.phase = phase;
|
||||||
@ -407,44 +531,46 @@ function DiskII(io, slot, callbacks)
|
|||||||
|
|
||||||
function _access(off, val) {
|
function _access(off, val) {
|
||||||
var result = 0;
|
var result = 0;
|
||||||
|
var readMode = val === undefined;
|
||||||
|
|
||||||
switch (off & 0x8f) {
|
switch (off & 0x8f) {
|
||||||
case LOC.PHASE0OFF:
|
case LOC.PHASE0OFF: // 0x00
|
||||||
setPhase(0, false);
|
setPhase(0, false);
|
||||||
break;
|
break;
|
||||||
case LOC.PHASE0ON:
|
case LOC.PHASE0ON: // 0x01
|
||||||
setPhase(0, true);
|
setPhase(0, true);
|
||||||
break;
|
break;
|
||||||
case LOC.PHASE1OFF:
|
case LOC.PHASE1OFF: // 0x02
|
||||||
setPhase(1, false);
|
setPhase(1, false);
|
||||||
break;
|
break;
|
||||||
case LOC.PHASE1ON:
|
case LOC.PHASE1ON: // 0x03
|
||||||
setPhase(1, true);
|
setPhase(1, true);
|
||||||
break;
|
break;
|
||||||
case LOC.PHASE2OFF:
|
case LOC.PHASE2OFF: // 0x04
|
||||||
setPhase(2, false);
|
setPhase(2, false);
|
||||||
break;
|
break;
|
||||||
case LOC.PHASE2ON:
|
case LOC.PHASE2ON: // 0x05
|
||||||
setPhase(2, true);
|
setPhase(2, true);
|
||||||
break;
|
break;
|
||||||
case LOC.PHASE3OFF:
|
case LOC.PHASE3OFF: // 0x06
|
||||||
setPhase(3, false);
|
setPhase(3, false);
|
||||||
break;
|
break;
|
||||||
case LOC.PHASE3ON:
|
case LOC.PHASE3ON: // 0x07
|
||||||
setPhase(3, true);
|
setPhase(3, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOC.DRIVEOFF:
|
case LOC.DRIVEOFF: // 0x08
|
||||||
_debug('Drive Off');
|
_debug('Drive Off');
|
||||||
_on = false;
|
_on = false;
|
||||||
if (callbacks.driveLight) { callbacks.driveLight(_drive, false); }
|
if (callbacks.driveLight) { callbacks.driveLight(_drive, false); }
|
||||||
break;
|
break;
|
||||||
case LOC.DRIVEON:
|
case LOC.DRIVEON: // 0x09
|
||||||
_debug('Drive On');
|
_debug('Drive On');
|
||||||
_on = true;
|
_on = true;
|
||||||
if (callbacks.driveLight) { callbacks.driveLight(_drive, true); }
|
if (callbacks.driveLight) { callbacks.driveLight(_drive, true); }
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOC.DRIVE1:
|
case LOC.DRIVE1: // 0x0a
|
||||||
_debug('Disk 1');
|
_debug('Disk 1');
|
||||||
_drive = 1;
|
_drive = 1;
|
||||||
_cur = _drives[_drive - 1];
|
_cur = _drives[_drive - 1];
|
||||||
@ -453,7 +579,7 @@ function DiskII(io, slot, callbacks)
|
|||||||
callbacks.driveLight(1, true);
|
callbacks.driveLight(1, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOC.DRIVE2:
|
case LOC.DRIVE2: // 0x0b
|
||||||
_debug('Disk 2');
|
_debug('Disk 2');
|
||||||
_drive = 2;
|
_drive = 2;
|
||||||
_cur = _drives[_drive - 1];
|
_cur = _drives[_drive - 1];
|
||||||
@ -463,29 +589,46 @@ function DiskII(io, slot, callbacks)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOC.DRIVEREAD:
|
case LOC.DRIVEREAD: // 0x0c
|
||||||
result = _readNext();
|
_readWriteNext();
|
||||||
// _debug('read: ' + toHex(result));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOC.DRIVEWRITE:
|
case LOC.DRIVEWRITE: // 0x0d
|
||||||
// _debug('write: ' + toHex(val));
|
if (readMode && !_writeMode) {
|
||||||
if (val !== undefined) {
|
if (_cur.readOnly) {
|
||||||
_writeNext(val);
|
_latch = _latch | 0x80;
|
||||||
|
_debug('Setting readOnly');
|
||||||
|
} else {
|
||||||
|
_latch = _latch & 0x7f;
|
||||||
|
_debug('Clearing readOnly');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOC.DRIVEREADMODE:
|
|
||||||
|
case LOC.DRIVEREADMODE: // 0x0e
|
||||||
_debug('Read Mode');
|
_debug('Read Mode');
|
||||||
_writeMode = false;
|
_writeMode = false;
|
||||||
result = (_readNext() & 0x7f) | (_cur.readOnly ? 0x80 : 0x00);
|
|
||||||
break;
|
break;
|
||||||
case LOC.DRIVEWRITEMODE:
|
case LOC.DRIVEWRITEMODE: // 0x0f
|
||||||
_debug('Write Mode');
|
_debug('Write Mode');
|
||||||
_writeMode = true;
|
_writeMode = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (readMode) {
|
||||||
|
if ((off & 0x01) === 0) {
|
||||||
|
result = _latch;
|
||||||
|
// _debug('Read', toHex(result));
|
||||||
|
} else {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
} else if (_writeMode) {
|
||||||
|
_latch = val;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,7 +706,6 @@ function DiskII(io, slot, callbacks)
|
|||||||
0x03,0x4c,0x01,0x03,0x4c,0x2d,0xff,0xff
|
0x03,0x4c,0x01,0x03,0x4c,0x2d,0xff,0xff
|
||||||
];
|
];
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_init();
|
_init();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -645,12 +787,13 @@ function DiskII(io, slot, callbacks)
|
|||||||
_cur = _drives[_drive - 1];
|
_cur = _drives[_drive - 1];
|
||||||
},
|
},
|
||||||
rwts: function disk2_rwts(disk, track, sector) {
|
rwts: function disk2_rwts(disk, track, sector) {
|
||||||
return _readSector(disk, track, sector);
|
var s = _drives[disk - 1].fmt == 'po' ? _PO[sector] : _DO[sector];
|
||||||
|
return _readSector(disk, track, s);
|
||||||
},
|
},
|
||||||
setDisk: function disk2_setDisk(drive, disk) {
|
setDisk: function disk2_setDisk(drive, disk) {
|
||||||
var fmt = disk.type, readOnly = disk.readOnly;
|
var fmt = disk.type, readOnly = disk.readOnly;
|
||||||
|
|
||||||
var data, t, s;
|
var data, t, s, _s;
|
||||||
if (disk.encoding == 'base64') {
|
if (disk.encoding == 'base64') {
|
||||||
data = [];
|
data = [];
|
||||||
for (t = 0; t < disk.data.length; t++) {
|
for (t = 0; t < disk.data.length; t++) {
|
||||||
@ -682,20 +825,26 @@ function DiskII(io, slot, callbacks)
|
|||||||
var track = [];
|
var track = [];
|
||||||
if (fmt === 'nib') {
|
if (fmt === 'nib') {
|
||||||
track = data[t];
|
track = data[t];
|
||||||
|
} else if (fmt === 'd13') { // DOS 3.2 Order
|
||||||
|
for (s = 0; s < data[t].length; s++) {
|
||||||
|
track = track.concat(
|
||||||
|
_explodeSector13(v, t, _D13O[s], data[t][_D13O[s]])
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (s = 0; s < data[t].length; s++) {
|
for (s = 0; s < data[t].length; s++) {
|
||||||
var _s = 15 - s;
|
_s = 15 - s;
|
||||||
if (fmt === 'po') { // ProDOS Order
|
if (fmt === 'po') { // ProDOS Order
|
||||||
track = track.concat(
|
track = track.concat(
|
||||||
_explodeSector(v, t, _PO[s], data[t][s])
|
_explodeSector16(v, t, _PO[s], data[t][s])
|
||||||
);
|
);
|
||||||
} else if (fmt === 'dsk') { // DOS Order
|
} else if (fmt === 'dsk') { // DOS 3.3 Order
|
||||||
track = track.concat(
|
track = track.concat(
|
||||||
_explodeSector(v, t, _DO[_s], data[t][_s])
|
_explodeSector16(v, t, _DO[_s], data[t][_s])
|
||||||
);
|
);
|
||||||
} else { // flat
|
} else { // flat
|
||||||
track = track.concat(
|
track = track.concat(
|
||||||
_explodeSector(v, t, s, data[t][s])
|
_explodeSector16(v, t, s, data[t][s])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -752,25 +901,34 @@ function DiskII(io, slot, callbacks)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var t = 0; t < 35; t++) {
|
for (var t = 0; t < 35; t++) {
|
||||||
var track, off, d;
|
var track, off, d, s, _s;
|
||||||
if (fmt === 'nib') {
|
if (fmt === 'nib') {
|
||||||
off = t * 0x1a00;
|
off = t * 0x1a00;
|
||||||
track = new Uint8Array(data.slice(off, off + 0x1a00));
|
track = new Uint8Array(data.slice(off, off + 0x1a00));
|
||||||
|
} else if (fmt == 'd13') { // DOS 3.2 Order
|
||||||
|
track = [];
|
||||||
|
for (s = 0; s < 13; s++) {
|
||||||
|
off = (13 * t + _D13O[s]) * 256;
|
||||||
|
d = new Uint8Array(data.slice(off, off + 256));
|
||||||
|
track = track.concat(
|
||||||
|
_explodeSector13(v, t, _D13O[s], d)
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
track = [];
|
track = [];
|
||||||
for (var s = 0; s < 16; s++) {
|
for (s = 0; s < 16; s++) {
|
||||||
var _s = 15 - s;
|
_s = 15 - s;
|
||||||
if (fmt == 'po') { // ProDOS Order
|
if (fmt == 'po') { // ProDOS Order
|
||||||
off = (16 * t + s) * 256;
|
off = (16 * t + s) * 256;
|
||||||
d = new Uint8Array(data.slice(off, off + 256));
|
d = new Uint8Array(data.slice(off, off + 256));
|
||||||
track = track.concat(
|
track = track.concat(
|
||||||
_explodeSector(v, t, _PO[s], d)
|
_explodeSector16(v, t, _PO[s], d)
|
||||||
);
|
);
|
||||||
} else if (fmt == 'dsk') { // DOS Order
|
} else if (fmt == 'dsk') { // DOS 3.3 Order
|
||||||
off = (16 * t + _s) * 256;
|
off = (16 * t + _s) * 256;
|
||||||
d = new Uint8Array(data.slice(off, off + 256));
|
d = new Uint8Array(data.slice(off, off + 256));
|
||||||
track = track.concat(
|
track = track.concat(
|
||||||
_explodeSector(v, t, _DO[_s], d)
|
_explodeSector16(v, t, _DO[_s], d)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user