// 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 #include #include #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; }