Skip to content

Commit

Permalink
Implement original disk behavior, remove copy protection workaround
Browse files Browse the repository at this point in the history
Add a pre-access hook for disk access, and emulate disk controller
behavior as necessary to satisfy the game's copy protection. This makes
it possible to remove the periodic poking into gamestate to defuse it.

Thanks to Wayne Holder for explaining how the system works, it would
have been much harder to figure out without that.

This removes the last TODO.
  • Loading branch information
laanwj committed Dec 26, 2023
1 parent 496c4ef commit bae4abd
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 256 deletions.
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,6 @@ have been implemented, Though I cannot guarantee that there aren't any bugs
left. If so, please report them through the issue tracker, along with a saved
state if possible.

### To be done

Non-critical:

- The copy protection (integrity check) is mitigated in an ugly and brittle
way. It would be better to emulate the underlying mechanism (which is known)
in the simulated disk controller.

P-system
-----------

Expand Down
236 changes: 0 additions & 236 deletions doc/weirddiskscan_debug.md

This file was deleted.

12 changes: 11 additions & 1 deletion src/psys/psys_rsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static psys_word unitrw(struct psys_state *state, struct psys_rsp_state *rsp, bo
} break;
case PSYS_UNIT_DISK0: {
unsigned x, srcblk;
if (ctrl & 2) { /* physical addressing starts a second earlier */
if (ctrl & 2) { /* physical addressing starts a track earlier */
len = 512;
srcblk = block;
} else {
Expand All @@ -170,6 +170,9 @@ static psys_word unitrw(struct psys_state *state, struct psys_rsp_state *rsp, bo
if (PDBG(state, RSP)) {
psys_debug("%s 0x%04x 0x%04x 0x%04x\n", wr ? "write" : "read", buf_addr + x, srcblk * PSYS_BLOCK_SIZE, remainder);
}
if (rsp->pre_access_hook) {
rsp->pre_access_hook(rsp->pre_access_hook_data, unit, srcblk, wr);
}
if (wr) {
memcpy(rsp->disk0 + srcblk * PSYS_BLOCK_SIZE, buf + x, remainder);
} else {
Expand Down Expand Up @@ -766,6 +769,13 @@ void psys_rsp_set_disk(struct psys_binding *b, int n, void *data, size_t size, s
rsp->disk0_wrap = wrap;
}

void psys_rsp_set_pre_access_hook(struct psys_binding *b, psys_rsp_pre_access_hook *pre_access_hook, void *data)
{
struct psys_rsp_state *rsp = (struct psys_rsp_state *)b->userdata;
rsp->pre_access_hook = pre_access_hook;
rsp->pre_access_hook_data = data;
}

void psys_rsp_event(struct psys_binding *b, psys_word event, bool taskswitch)
{
struct psys_rsp_state *rsp = (struct psys_rsp_state *)b->userdata;
Expand Down
7 changes: 7 additions & 0 deletions src/psys/psys_rsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ enum {
GDIR_ENTRY_SIZE = 0x1a,
};

typedef void(psys_rsp_pre_access_hook)(void *data, int disk, unsigned blk, bool wr);

#define PSYS_MAX_EVENTS 64

struct psys_rsp_state {
Expand All @@ -97,13 +99,18 @@ struct psys_rsp_state {

/* simulated inputs */
unsigned time;

/* hooks */
psys_rsp_pre_access_hook *pre_access_hook;
void *pre_access_hook_data;
};

/* Fixed I/O block size */
#define PSYS_BLOCK_SIZE 512

extern struct psys_binding *psys_new_rsp(struct psys_state *state);
extern void psys_rsp_set_disk(struct psys_binding *b, int n, void *data, size_t size, size_t track, bool wrap);
extern void psys_rsp_set_pre_access_hook(struct psys_binding *b, psys_rsp_pre_access_hook *pre_access_hook, void *data);
extern void psys_destroy_rsp(struct psys_binding *b);

/* Trigger event */
Expand Down
Loading

0 comments on commit bae4abd

Please sign in to comment.