joeylib2/tests/amiga/fastRam.c

114 lines
3.8 KiB
C

// Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
// See LICENSE.md for license information.
// SPDX-License-Identifier: MIT
//
// FASTRAM, scripts/verify-amiga-fastram.sh's program: a surface made after
// chip RAM runs out lands in Fast RAM, where the blitter cannot reach it,
// and must draw and copy exactly as a chip one does. It fills chip RAM with
// ballast, makes the surface, frees the ballast, then runs the same fills,
// lines, circles, and copies (both ways, rects and whole surfaces, and onto
// the stage) on it and on a chip surface and compares their hashes.
#include <joey/joey.h>
#include <exec/memory.h>
#include <proto/exec.h>
#include "amigaPlanar.h"
#define BALLAST_BYTES 4096ul
#define BALLAST_MAX 600u
static void ops(jlSurfaceT *s, jlSurfaceT *src);
static void same(const char *what, jlSurfaceT *a, jlSurfaceT *b);
static void *gBallast[BALLAST_MAX];
static uint16_t gFails;
// The same drawing on every surface: fills of every shape the fill paths
// split on (full width, ragged edges, one pixel, the last pixel), a filled
// circle, a diagonal line, and two rect copies from src.
static void ops(jlSurfaceT *s, jlSurfaceT *src) {
jlSurfaceClear(s, 5);
jlFillRect(s, 0, 0, 320, 40, 9);
jlFillRect(s, 3, 50, 17, 30, 12);
jlFillRect(s, 100, 60, 1, 1, 15);
jlFillRect(s, 33, 90, 250, 7, 6);
jlFillRect(s, 319, 199, 1, 1, 3);
jlFillCircle(s, 160, 120, 40, 2);
jlDrawLine(s, 0, 199, 319, 0, 14);
jlSurfaceCopyRect(s, src, 16, 16, 64, 48);
jlSurfaceCopyRect(s, src, 160, 150, 16, 8);
}
static void same(const char *what, jlSurfaceT *a, jlSurfaceT *b) {
uint32_t ha;
uint32_t hb;
ha = jlSurfaceHash(a);
hb = jlSurfaceHash(b);
if (ha != hb) {
gFails++;
jlLogF("FASTRAM: mismatch after %s: chip %08lx fast %08lx", what, (unsigned long)ha, (unsigned long)hb);
}
}
int main(void) {
jlConfigT cfg;
jlSurfaceT *source;
jlSurfaceT *chipSurf;
jlSurfaceT *fastSurf;
AmigaPlanarT *pd;
uint16_t n;
uint16_t i;
cfg.codegenBytes = 0;
cfg.noAudio = true;
if (!jlInit(&cfg)) {
return 1;
}
source = jlSurfaceCreate();
chipSurf = jlSurfaceCreate();
for (n = 0; n < BALLAST_MAX; n++) {
gBallast[n] = AllocMem(BALLAST_BYTES, MEMF_CHIP);
if (gBallast[n] == NULL) {
break;
}
}
fastSurf = jlSurfaceCreate();
for (i = 0; i < n; i++) {
FreeMem(gBallast[i], BALLAST_BYTES);
}
if (source == NULL || chipSurf == NULL || fastSurf == NULL) {
jlLogF("FASTRAM: FAIL: a surface was not made (%p %p %p)", (void *)source, (void *)chipSurf, (void *)fastSurf);
jlLogF("FASTRAM: done");
jlShutdown();
return 0;
}
pd = (AmigaPlanarT *)chipSurf->portData;
jlLogF("FASTRAM: chip surface chip=%d, ballast %u x %lu", (int)pd->chip, (unsigned)n, BALLAST_BYTES);
pd = (AmigaPlanarT *)fastSurf->portData;
jlLogF("FASTRAM: fast surface chip=%d memtype %lx", (int)pd->chip, (unsigned long)TypeOfMem(pd->planes[0]));
jlSurfaceClear(source, 0);
jlFillRect(source, 10, 10, 200, 150, 7);
jlFillCircle(source, 100, 100, 30, 11);
ops(chipSurf, source);
ops(fastSurf, source);
same("ops", chipSurf, fastSurf);
jlSurfaceCopy(jlStageGet(), fastSurf);
same("copy fast to stage", jlStageGet(), chipSurf);
jlSurfaceCopyRect(chipSurf, fastSurf, 0, 0, 320, 200);
jlSurfaceCopyRect(fastSurf, chipSurf, 32, 32, 128, 64);
same("rect copies both ways", chipSurf, fastSurf);
jlSurfaceCopy(fastSurf, source);
jlSurfaceCopy(chipSurf, source);
same("whole copies", chipSurf, fastSurf);
jlStagePresent();
jlLogF("FASTRAM: %s (fails=%u)", gFails == 0 ? "PASS" : "FAIL", (unsigned)gFails);
jlLogF("FASTRAM: done");
jlShutdown();
return 0;
}