Skip to content

Commit

Permalink
Update to v106r144 release.
Browse files Browse the repository at this point in the history
byuu says:

not dead yet. full reed solomon implementation courtesy of merrymage's help
(still no C1/C2 CIRC, but P/Q RSPC is completed). implemented more CDD commands,
far enough along now to get the drive to seek to the start of the data track and
then .............. nothing. But ... progress?
  • Loading branch information
Screwtapello committed May 22, 2019
1 parent c5e4f1f commit 869171a
Show file tree
Hide file tree
Showing 22 changed files with 1,065 additions and 53 deletions.
2 changes: 1 addition & 1 deletion higan/emulator/emulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ using namespace nall;

namespace higan {
static const string Name = "higan";
static const string Version = "106.143";
static const string Version = "106.144";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "https://byuu.org/";
Expand Down
6 changes: 3 additions & 3 deletions higan/md/mcd/cdc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ print("CDC ", hex(address), "=", hex(data), "\n");
if(status.wait && transfer.busy) break;
if(status.read == status.write && !status.empty) status.read++; //unverified: discard oldest byte?
status.fifo[status.write++] = data;
status.empty = false;
status.active = true;
status.busy = true;
status.empty = 0;
status.active = 1;
status.busy = 1;
} break;

case 0x1: { //IFCTRL
Expand Down
154 changes: 140 additions & 14 deletions higan/md/mcd/cdd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,48 @@ auto MCD::CDD::clock() -> void {
statusPending = 0;
irq.raise();
}

switch(io.status) {

case Status::Stopped: {
io.status = mcd.disc ? Status::ReadingTOC : Status::NoDisc;
io.sector = 0;
io.track = 0;
} break;

case Status::ReadingTOC: {
io.sector++;
if(io.sector >= 150) io.status = Status::Paused;
if(io.sector >= 150) io.track = 1;
} break;

case Status::Playing: {
io.sector++;
if(io.sector >= 150) io.status = Status::Paused;
if(io.sector >= 150) io.track = 1;
} break;

}
}

auto MCD::CDD::process() -> void {
//print("CDD ", command[0], ":", command[3], "\n");
if(command[0]) print("CDD ", command[0], ":", command[3], "\n");

if(!valid()) {
//unverified
print("CDD checksum error\n");
status[0] = Status::ChecksumError;
return;
io.status = Status::ChecksumError;
}

else
switch(command[0]) {

case Command::Idle: { //simulates the status changing shortly after the Stop command
status[0] = io.status;
case Command::Idle: {
} break;

case Command::Stop: {
status[0] = Status::Stopped; status[1] = 0x0;
io.status = Status::Stopped;
status[1] = 0x0;
status[2] = 0x0; status[3] = 0x0;
status[4] = 0x0; status[5] = 0x0;
status[6] = 0x0; status[7] = 0x0;
Expand All @@ -41,25 +63,74 @@ auto MCD::CDD::process() -> void {
case Command::Request: {
switch(command[3]) {

case Request::DiscCompletionTime: { //time in mm:ss:ff
status[0] = io.status; status[1] = command[3];
status[2] = 0x0; status[3] = 0x0;
case Request::AbsoluteTime: {
uint sector = io.sector;
uint minute = sector / 75 / 60 % 60;
uint second = sector / 75 % 60;
uint frame = sector % 75;
status[1] = command[3];
status[2] = minute / 10; status[3] = minute % 10;
status[4] = second / 10; status[5] = second % 10;
status[6] = frame / 10; status[7] = frame % 10;
status[8] = toc.tracks[io.track].type << 2;
} break;

case Request::RelativeTime: {
uint sector = io.sector - toc.tracks[io.track].start;
uint minute = sector / 75 / 60 % 60;
uint second = sector / 75 % 60;
uint frame = sector % 75;
status[1] = command[3];
status[2] = minute / 10; status[3] = minute % 10;
status[4] = second / 10; status[5] = second % 10;
status[6] = frame / 10; status[7] = frame / 10;
status[8] = toc.tracks[io.track].type << 2;
} break;

case Request::TrackInformation: {
status[1] = command[3];
status[2] = io.track / 10; status[3] = io.track % 10;
status[4] = 0x0; status[5] = 0x0;
status[6] = 0x0; status[7] = 0x0;
status[8] = 0x0;
} break;

case Request::DiscCompletionTime: { //time in mm:ss:ff
uint minute = 4;
uint second = 0;
uint frame = 0;
status[1] = command[3];
status[2] = minute / 10; status[3] = minute % 10;
status[4] = second / 10; status[5] = second % 10;
status[6] = frame / 10; status[7] = frame % 10;
status[8] = 0x0;
} break;

case Request::DiscTracks: { //first and last track numbers
status[0] = io.status; status[1] = command[3];
status[2] = 0x0; status[3] = 0x0;
status[4] = 0x0; status[5] = 0x0;
status[1] = command[3];
status[2] = toc.first / 10; status[3] = toc.first % 10;
status[4] = toc.last / 10; status[5] = toc.last % 10;
status[6] = 0x0; status[7] = 0x0;
status[8] = 0x0;
} break;

case Request::TrackStartTime: {
uint track = command[4] << 4 | command[5] << 0;
uint sector = toc.tracks[track].start;
uint minute = sector / 75 / 60 % 60;
uint second = sector / 75 % 60;
uint frame = sector % 75;
status[1] = command[3];
status[2] = minute / 10; status[3] = minute % 10;
status[4] = second / 10; status[5] = second % 10;
status[6] = frame / 10; status[7] = frame % 10;
status[6].bit(3) = toc.tracks[track].type;
status[8] = track % 10;
} break;

case Request::ErrorInformation: {
//always report no errors
status[0] = io.status; status[1] = command[3];
status[1] = command[3];
status[2] = 0x0; status[3] = 0x0;
status[4] = 0x0; status[5] = 0x0;
status[6] = 0x0; status[7] = 0x0;
Expand All @@ -69,8 +140,38 @@ auto MCD::CDD::process() -> void {
}
} break;

case Command::Read: {
io.status = Status::Playing;
status[1] = 0xf;
status[2] = 0x0; status[3] = 0x0;
status[4] = 0x0; status[5] = 0x0;
status[6] = 0x0; status[7] = 0x0;
status[8] = 0x0;
} break;

case Command::Seek: {
uint minute = command[2] * 10 + command[3];
uint second = command[4] * 10 + command[5];
uint frame = command[6] * 10 + command[7];

io.status = Status::Paused;
io.sector = minute * 60 * 75 + second * 75 + frame;
io.track = 0;

status[1] = 0xf;
status[2] = 0x0; status[3] = 0x0;
status[4] = 0x0; status[5] = 0x0;
status[6] = 0x0; status[7] = 0x0;
status[8] = 0x0;
} break;

case Command::Pause: {
io.status = Status::Paused;
} break;

}

status[0] = io.status;
checksum();
statusPending = 1;
}
Expand All @@ -89,10 +190,35 @@ auto MCD::CDD::checksum() -> void {
status[9] = checksum;
}

auto MCD::CDD::insert() -> void {
toc = {};
for(auto& track : toc.tracks) track = {};

if(!mcd.disc) {
io.status = Status::NoDisc;
return;
}

io.status = Status::ReadingTOC;
io.sector = 0;
io.track = 0;

toc.first = 1;
toc.last = 1;

toc.tracks[1].valid = 1;
toc.tracks[1].start = 150;
toc.tracks[1].type = 1;
}

auto MCD::CDD::eject() -> void {
io.status = Status::NoDisc;
}

auto MCD::CDD::power(bool reset) -> void {
fader = {};
io = {};
io.status = mcd.disc ? Status::Stopped : Status::NoDisc;
insert();
for(uint index : range(10)) status [index] = 0x0;
for(uint index : range(10)) command[index] = 0x0;
checksum();
Expand Down
4 changes: 2 additions & 2 deletions higan/md/mcd/mcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ auto MCD::connect(Node::Peripheral with) -> void {
disc = Node::Peripheral::create("Mega CD");
disc->load(with);
tray->prepend(disc);
cdd.io.status = CDD::Status::Stopped;
cdd.insert();
}
}

auto MCD::disconnect() -> void {
if(!disc) return;
disc = {};
cdd.io.status = CDD::Status::NoDisc;
cdd.eject();
}

auto MCD::unload() -> void {
Expand Down
23 changes: 22 additions & 1 deletion higan/md/mcd/mcd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ struct MCD : M68K, Thread {
auto process() -> void;
auto valid() -> bool;
auto checksum() -> void;
auto insert() -> void;
auto eject() -> void;
auto power(bool reset) -> void;

//serialization.cpp
Expand All @@ -250,14 +252,33 @@ struct MCD : M68K, Thread {
IRQ irq;
uint16 counter;

struct Track {
uint1 valid;
uint24 start;

//Q-channel control headers
uint1 channels; //0 = 2-channels, 1 = 4-channels
uint1 type; //0 = audio, 1 = data
uint1 copyable; //0 = uncopyable, 1 = copyable
uint1 emphasis; //0 = no emphasis, 1 = pre-emphasis
};

struct TOC {
Track tracks[100];
uint7 first; //0-99
uint7 last; //0-99
} toc;

struct Fader {
uint1 spindleSpeed; //0 = normal-speed, 1 = double-speed
uint2 deemphasis; //0 = off, 1 = 44.1khz, 2 = 32khz, 3 = 48khz
uint11 volume;
} fader;

struct IO {
uint4 status = Status::Stopped;
uint4 status = Status::NoDisc;
uint24 sector; //current chhannel frame#
uint7 track; //current track#
} io;

uint1 hostClockEnable;
Expand Down
5 changes: 3 additions & 2 deletions hiro/core/monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ struct Monitor {

//DPI scale X
inline auto sx(float x) -> float {
static auto scale = Monitor::dpi().x() / 96.0;
//round DPI scalar to increments of 0.5 (eg 1.0, 1.5, 2.0, ...)
static auto scale = round(Monitor::dpi().x() / 96.0 * 2.0) / 2.0;
return x * scale;
}

//DPI scale y
inline auto sy(float y) -> float {
static auto scale = Monitor::dpi().y() / 96.0;
static auto scale = round(Monitor::dpi().y() / 96.0 * 2.0) / 2.0;
return y * scale;
}

Expand Down
7 changes: 7 additions & 0 deletions hiro/core/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ auto mWindow::setFullScreen(bool fullScreen) -> type& {
}

auto mWindow::setGeometry(Geometry geometry) -> type& {
//round fractional bits of geometry coordinates that window managers cannot display.
//the pWindow classes lose this precision and so not doing so here can cause off-by-1 issues.
geometry.setX(round(geometry.x()));
geometry.setY(round(geometry.y()));
geometry.setWidth(round(geometry.width()));
geometry.setHeight(round(geometry.height()));

state.geometry = geometry;
signal(setGeometry, geometry);
if(auto& sizable = state.sizable) sizable->setGeometry(sizable->geometry());
Expand Down
5 changes: 5 additions & 0 deletions nall/array.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <nall/array-span.hpp>
#include <nall/array-view.hpp>
#include <nall/range.hpp>
#include <nall/view.hpp>
Expand All @@ -19,6 +20,10 @@ template<typename T, uint Size> struct array<T[Size]> {
}
}

operator array_span<T>() {
return {data(), size()};
}

operator array_view<T>() const {
return {data(), size()};
}
Expand Down
6 changes: 3 additions & 3 deletions nall/bit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,23 @@ namespace bit {
}

//count number of bits set in a byte
inline auto count(uintmax x) -> uint {
constexpr inline auto count(uintmax x) -> uint {
uint count = 0;
while(x) x &= x - 1, count++; //clear the least significant bit
return count;
}

//return index of the first bit set (or zero of no bits are set)
//first(0b1000) == 3
inline auto first(uintmax x) -> uint {
constexpr inline auto first(uintmax x) -> uint {
uint first = 0;
while(x) { if(x & 1) break; x >>= 1; first++; }
return first;
}

//round up to next highest single bit:
//round(15) == 16, round(16) == 16, round(17) == 32
inline auto round(uintmax x) -> uintmax {
constexpr inline auto round(uintmax x) -> uintmax {
if((x & (x - 1)) == 0) return x;
while(x & (x - 1)) x &= x - 1;
return x << 1;
Expand Down
27 changes: 27 additions & 0 deletions nall/cd.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

/* CD-ROM sector functions.
*
* Implemented:
* eight-to-fourteen modulation (encoding and decoding)
* sync header creation and verification
* error detection code creation and verification
* reed-solomon product-code creation and verification
* sector scrambling and descrambling (currently unverified)
*
* Unimplemented:
* reed-solomon product-code correction
* cross-interleave reed-solomon creation, verification, and correction
* CD-ROM XA mode 2 forms 1 & 2 support
* subcode insertion and removal
* subcode decoding from CUE files
* channel frame expansion and reduction
*/

#include <nall/galois-field.hpp>

#include <nall/cd/efm.hpp>
#include <nall/cd/sync.hpp>
#include <nall/cd/edc.hpp>
#include <nall/cd/rspc.hpp>
#include <nall/cd/scrambler.hpp>
Loading

0 comments on commit 869171a

Please sign in to comment.