137 lines
4.6 KiB
C
137 lines
4.6 KiB
C
// rsrcProbe.c - Phase 3.4 real Resource Manager smoke probe.
|
|
//
|
|
// Replaces the stub-only probe. Builds a tiny in-memory .rsrc fixture,
|
|
// registers it with mfsRegister, opens it via openResourceFile, loads
|
|
// a known rText resource, and verifies the bytes match the expected
|
|
// payload. This exercises the real parser path top-to-bottom without
|
|
// needing a ProDOS resource fork.
|
|
//
|
|
// Markers (page-1 direct page, per cursorProbe convention):
|
|
// $70 := 0x99 end-of-main success sentinel
|
|
// $71 := 0x01 if openResourceFile succeeded (refnum != 0)
|
|
// $72 := 0x01 if loadResource returned a non-NULL handle whose
|
|
// bytes match "HELLO" and size is 5
|
|
// $73 := 0x01 if loadResource second call returned the SAME handle
|
|
// (cache hit) and closeResourceFile returned RES_OK
|
|
//
|
|
// Build: bash demos/build.sh rsrcProbe
|
|
// Run: bash scripts/runViaFinder.sh demos/rsrcProbe.omf \
|
|
// --check 0x70=0x99 0x71=0x01 0x72=0x01 0x73=0x01
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "iigs/resource.h"
|
|
|
|
|
|
// rResourceMap fixture: header + 5-byte rText payload + one rIndex entry.
|
|
//
|
|
// Header (24 bytes, little-endian):
|
|
// rmVersion = 0x0000
|
|
// rmToIndex = 0x0000001D (29)
|
|
// rmFileNum = 0
|
|
// rmID = 0
|
|
// rmIndexSize = 0x00000014 (20 bytes = 1 entry)
|
|
// rmIndexUsed = 0x00000001
|
|
// rmFreeListSize = 0
|
|
// rmFreeListUsed = 0
|
|
// rmPad = 0
|
|
// Payload (5 bytes) at offset 24: "HELLO"
|
|
// rIndex entry (20 bytes) at offset 29:
|
|
// rType = 0x8014 (rText)
|
|
// rID = 0x00000001
|
|
// rOffset = 0x00000018 (24)
|
|
// rAttr = 0
|
|
// rSize = 0x00000005
|
|
// rHandle = 0
|
|
static const uint8_t kFixture[49] = {
|
|
// header
|
|
0x00, 0x00, // rmVersion
|
|
0x1D, 0x00, 0x00, 0x00, // rmToIndex = 29
|
|
0x00, 0x00, // rmFileNum
|
|
0x00, 0x00, // rmID
|
|
0x14, 0x00, 0x00, 0x00, // rmIndexSize = 20
|
|
0x01, 0x00, 0x00, 0x00, // rmIndexUsed = 1
|
|
0x00, 0x00, // rmFreeListSize
|
|
0x00, 0x00, // rmFreeListUsed
|
|
0x00, 0x00, // rmPad
|
|
// payload at offset 24: "HELLO"
|
|
0x48, 0x45, 0x4C, 0x4C, 0x4F,
|
|
// rIndex entry at offset 29
|
|
0x14, 0x80, // rType = 0x8014
|
|
0x01, 0x00, 0x00, 0x00, // rID = 1
|
|
0x18, 0x00, 0x00, 0x00, // rOffset = 24
|
|
0x00, 0x00, // rAttr
|
|
0x05, 0x00, 0x00, 0x00, // rSize = 5
|
|
0x00, 0x00, 0x00, 0x00 // rHandle
|
|
};
|
|
|
|
|
|
static const char kFixturePath[] = "rsrc.fixture";
|
|
static const char kExpectedText[] = "HELLO";
|
|
static const uint32_t kExpectedSize = 5;
|
|
|
|
|
|
int main(void) {
|
|
volatile uint8_t *mark0 = (volatile uint8_t *)0x70;
|
|
volatile uint8_t *mark1 = (volatile uint8_t *)0x71;
|
|
volatile uint8_t *mark2 = (volatile uint8_t *)0x72;
|
|
volatile uint8_t *mark3 = (volatile uint8_t *)0x73;
|
|
|
|
*mark0 = 0x10;
|
|
*mark1 = 0x00;
|
|
*mark2 = 0x00;
|
|
*mark3 = 0x00;
|
|
|
|
// Stage the fixture as a read-only memory-backed file. Cast away
|
|
// const for the mfsRegister buffer pointer; the resource manager
|
|
// only ever reads.
|
|
if (mfsRegister(kFixturePath, (void *)kFixture, sizeof(kFixture), sizeof(kFixture), 0) != 0) {
|
|
while (1) {
|
|
}
|
|
}
|
|
|
|
resourceProbeInit();
|
|
|
|
int rcOpen = 0;
|
|
ResourceRefNumT ref = openResourceFile(kFixturePath, 0, 0, &rcOpen);
|
|
if (ref != 0 && rcOpen == RES_OK) {
|
|
*mark1 = 0x01;
|
|
}
|
|
|
|
int rcLoad = 0;
|
|
void **h = loadResource(RES_TYPE_RTEXT, 1, &rcLoad);
|
|
if (h && rcLoad == RES_OK) {
|
|
const uint8_t *bytes = (const uint8_t *)*h;
|
|
uint32_t sz = getResourceSize(h);
|
|
int match = (sz == kExpectedSize);
|
|
if (match) {
|
|
for (uint32_t i = 0; i < kExpectedSize; i++) {
|
|
if (bytes[i] != (uint8_t)kExpectedText[i]) {
|
|
match = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (match) {
|
|
*mark2 = 0x01;
|
|
}
|
|
}
|
|
|
|
// Second load - cache hit must return the SAME handle. Then
|
|
// close the file, which must report RES_OK.
|
|
int rcLoad2 = 0;
|
|
void **h2 = loadResource(RES_TYPE_RTEXT, 1, &rcLoad2);
|
|
int sameHandle = (h2 == h && h2 != 0);
|
|
int rcClose = closeResourceFile(ref);
|
|
if (sameHandle && rcClose == RES_OK) {
|
|
*mark3 = 0x01;
|
|
}
|
|
|
|
*mark0 = 0x99;
|
|
|
|
while (1) {
|
|
}
|
|
return 0;
|
|
}
|