mirror of
https://github.com/cmosher01/Epple-II.git
synced 2024-09-28 14:55:04 +00:00
234 lines
6.3 KiB
C++
234 lines
6.3 KiB
C++
/*
|
|
epple2
|
|
|
|
Copyright © 2018, Christopher Alan Mosher, Shelton, CT, USA. <cmosher01@gmail.com>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY, without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "lss.h"
|
|
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
|
|
static void setcmd(std::uint8_t lssrom[], std::uint8_t x, std::uint8_t cmd) {
|
|
lssrom[x] = (lssrom[x] & 0xF0u) | cmd;
|
|
}
|
|
|
|
static void setseq(std::uint8_t lssrom[], std::uint8_t x, std::uint8_t seq) {
|
|
lssrom[x] = (lssrom[x] & 0x0Fu) | seq;
|
|
}
|
|
|
|
static void setbth(std::uint8_t lssrom[], std::uint8_t x, std::uint8_t both) {
|
|
lssrom[x] = both;
|
|
}
|
|
|
|
static void inst(std::uint8_t seq, std::uint8_t inst) {
|
|
const std::uint8_t next_seq((inst & 0xF0u) >> 4);
|
|
const bool stdseq((seq == 0x0Fu && next_seq == 0x00u) || next_seq == seq+1);
|
|
const std::uint8_t cmd(inst & 0x0Fu);
|
|
|
|
printf("\x1b[31m");
|
|
if (cmd & 8u) {
|
|
switch (cmd & 3u) {
|
|
case 3:
|
|
printf("LDR");
|
|
break;
|
|
case 2:
|
|
printf("SRP");
|
|
break;
|
|
case 1:
|
|
if ((cmd & 4u) >> 2) {
|
|
printf("SL1");
|
|
} else {
|
|
printf("SL0");
|
|
}
|
|
break;
|
|
default:
|
|
printf("\x1b[0m...");
|
|
}
|
|
} else {
|
|
printf("CLR");
|
|
}
|
|
printf("\x1b[0m");
|
|
|
|
if (stdseq) {
|
|
printf(" ");
|
|
} else {
|
|
printf(":\x1b[34m%X\x1b[0m", next_seq);
|
|
}
|
|
printf(" ");
|
|
}
|
|
|
|
static void showua2seq(std::uint8_t lssrom[], std::uint8_t seq) {
|
|
const std::uint8_t s(seq >> 4);
|
|
printf("%1X: | ", s);
|
|
inst(s,lssrom[seq|0x9]);
|
|
inst(s,lssrom[seq|0xB]);
|
|
inst(s,lssrom[seq|0xD]);
|
|
inst(s,lssrom[seq|0xF]);
|
|
printf("| ");
|
|
inst(s,lssrom[seq|0x8]);
|
|
inst(s,lssrom[seq|0xA]);
|
|
inst(s,lssrom[seq|0xC]);
|
|
inst(s,lssrom[seq|0xE]);
|
|
printf("| ");
|
|
inst(s,lssrom[seq|0x1]);
|
|
inst(s,lssrom[seq|0x0]);
|
|
inst(s,lssrom[seq|0x3]);
|
|
inst(s,lssrom[seq|0x2]);
|
|
printf("| ");
|
|
inst(s,lssrom[seq|0x5]);
|
|
inst(s,lssrom[seq|0x4]);
|
|
inst(s,lssrom[seq|0x7]);
|
|
inst(s,lssrom[seq|0x6]);
|
|
printf("\n");
|
|
if (s == 7) {
|
|
printf(" +-------------------------+-------------------------+-------------------------+------------------------\n");
|
|
}
|
|
}
|
|
|
|
LSS::LSS(bool use13SectorDos32LSS):
|
|
use13Sector(use13SectorDos32LSS) {
|
|
/*
|
|
* LSS P6 ROM is stored here with different addressing bits
|
|
* than in the original hardware, just for ease of understanding.
|
|
*
|
|
* Addressing bits:
|
|
* S3 S2 S1 S0: 4-bit sequence number, 0x00-0x0F
|
|
* P: read pulse (from disk) indicator (1=pulse, 0=no pulse)
|
|
* QA: MSB of controller card data register
|
|
* Q7: READ/WRITE ($C08E/F) soft switch
|
|
* Q6: SHIFT/LOAD ($C08C/D) soft switch
|
|
*
|
|
* Original hardware addressing: S3 S2 S0 P Q7 Q6 QA S1
|
|
*
|
|
* Addressing used here: S3 S2 S1 S0 Q7 Q6 QA P
|
|
*/
|
|
|
|
// First fill in some reasonably global default values
|
|
for (std::uint8_t s(0u); s < 0x10u; ++s) {
|
|
std::uint8_t seq(s << 4u);
|
|
for (std::uint8_t adr(0u); adr < 0x10u; ++adr) {
|
|
lssrom[seq|adr] = seq+0x18u;
|
|
if ((adr & 0xCu) == 4u) {
|
|
lssrom[seq|adr] = 0x0Au;
|
|
}
|
|
if (adr == 1u || adr == 3u) {
|
|
lssrom[seq|adr] = 0xD8u;
|
|
}
|
|
}
|
|
}
|
|
|
|
setcmd(lssrom,0x10u,0x0Du);
|
|
setbth(lssrom,0x90u,0x29u);
|
|
setcmd(lssrom,0xA0u,0x0Du);
|
|
setbth(lssrom,0xB0u,0x59u);
|
|
setcmd(lssrom,0xC0u,0x09u);
|
|
setseq(lssrom,0xD0u,0x00u);
|
|
setcmd(lssrom,0xE0u,0x0Du);
|
|
setbth(lssrom,0xF0u,0x4Du);
|
|
|
|
setseq(lssrom,0x01u,0x10u);
|
|
setbth(lssrom,0x11u,0x2Du);
|
|
setbth(lssrom,0xA1u,0xCDu);
|
|
setcmd(lssrom,0xB1u,0x09u);
|
|
setcmd(lssrom,0xC1u,0x09u);
|
|
setbth(lssrom,0xE1u,0xFDu);
|
|
setcmd(lssrom,0xF1u,0x0Du);
|
|
|
|
setseq(lssrom,0x12u,0x30u);
|
|
setseq(lssrom,0x22u,0x20u);
|
|
setbth(lssrom,0xC2u,0xA0u);
|
|
setbth(lssrom,0xF2u,0xE0u);
|
|
|
|
setseq(lssrom,0x03u,0x10u);
|
|
setseq(lssrom,0x13u,0x30u);
|
|
setseq(lssrom,0x23u,0x00u);
|
|
setseq(lssrom,0x33u,0x40u);
|
|
setseq(lssrom,0xD3u,0xE0u);
|
|
setseq(lssrom,0xE3u,0xF0u);
|
|
setbth(lssrom,0xF3u,0xE0u);
|
|
|
|
|
|
|
|
setcmd(lssrom,0x28u,0x09u);
|
|
setseq(lssrom,0x78u,0x00u);
|
|
setcmd(lssrom,0xA8u,0x09u);
|
|
setseq(lssrom,0xF8u,0x80u);
|
|
|
|
setcmd(lssrom,0x29u,0x09u);
|
|
setseq(lssrom,0x79u,0x00u);
|
|
setcmd(lssrom,0xA9u,0x09u);
|
|
setseq(lssrom,0xF9u,0x80u);
|
|
|
|
setcmd(lssrom,0x2Au,0x09u);
|
|
setcmd(lssrom,0xAAu,0x09u);
|
|
|
|
setcmd(lssrom,0x2Bu,0x09u);
|
|
setcmd(lssrom,0xABu,0x09u);
|
|
|
|
setcmd(lssrom,0x2Cu,0x0Bu);
|
|
setseq(lssrom,0x7Cu,0x00u);
|
|
setcmd(lssrom,0xACu,0x0Bu);
|
|
setseq(lssrom,0xFCu,0x80u);
|
|
|
|
setcmd(lssrom,0x2Du,0x0Bu);
|
|
setseq(lssrom,0x7Du,0x00u);
|
|
setcmd(lssrom,0xADu,0x0Bu);
|
|
setseq(lssrom,0xFDu,0x80u);
|
|
|
|
setcmd(lssrom,0x2Eu,0x0Bu);
|
|
setcmd(lssrom,0xAEu,0x0Bu);
|
|
|
|
setcmd(lssrom,0x2Fu,0x0Bu);
|
|
setcmd(lssrom,0xAFu,0x0Bu);
|
|
|
|
|
|
|
|
// build 13-sector LSS based on 16-sector LSS
|
|
std::copy(std::begin(lssrom), std::end(lssrom), std::begin(lss13rom));
|
|
|
|
setcmd(lss13rom,0x10u,0x08u);
|
|
setseq(lss13rom,0x90u,0x00u);
|
|
setseq(lss13rom,0xB0u,0x30u);
|
|
setcmd(lss13rom,0xD0u,0x0Du);
|
|
|
|
setseq(lss13rom,0x01u,0xD0u);
|
|
setbth(lss13rom,0x11u,0xD8u);
|
|
setbth(lss13rom,0xD1u,0x1Du);
|
|
|
|
setseq(lss13rom,0x02u,0x00u);
|
|
setseq(lss13rom,0x12u,0x20u);
|
|
setseq(lss13rom,0x22u,0x30u);
|
|
|
|
setseq(lss13rom,0x13u,0x20u);
|
|
setseq(lss13rom,0x23u,0x30u);
|
|
setseq(lss13rom,0x33u,0xD0u);
|
|
|
|
printf("Disk ][ Controller Logic State Sequencer ROM:\n");
|
|
if (use13Sector) {
|
|
for (unsigned int seq = 0; seq < 0x100u; seq += 0x10u) {
|
|
showua2seq(lss13rom,seq);
|
|
}
|
|
} else {
|
|
for (unsigned int seq = 0; seq < 0x100u; seq += 0x10u) {
|
|
showua2seq(lssrom,seq);
|
|
}
|
|
}
|
|
}
|
|
|
|
LSS::~LSS() {
|
|
}
|