joeylib2/include/joey/platform.h

502 lines
23 KiB
C

// JoeyLib platform, CPU, endian, and capability defines.
//
// Exactly one JOEYLIB_PLATFORM_* must be defined per build. The build
// system normally sets this via -D; if absent, the header attempts to
// auto-detect from compiler-predefined macros.
#ifndef JOEYLIB_PLATFORM_H
#define JOEYLIB_PLATFORM_H
// ----- Auto-detect platform from compiler macros if not preset -----
#if !defined(JOEYLIB_PLATFORM_IIGS) && \
!defined(JOEYLIB_PLATFORM_AMIGA) && \
!defined(JOEYLIB_PLATFORM_ATARIST) && \
!defined(JOEYLIB_PLATFORM_DOS) && \
!defined(JOEYLIB_PLATFORM_X68000) && \
!defined(JOEYLIB_PLATFORM_BLANK)
#if defined(__DJGPP__) || defined(__MSDOS__)
#define JOEYLIB_PLATFORM_DOS
#elif defined(__amigaos__) || defined(AMIGA) || defined(__amigaos4__)
#define JOEYLIB_PLATFORM_AMIGA
#elif defined(__atarist__) || defined(__MINT__) || defined(__TOS__)
#define JOEYLIB_PLATFORM_ATARIST
#elif defined(__APPLE2GS__) || defined(__GNO__)
#define JOEYLIB_PLATFORM_IIGS
#elif defined(__x68k__) || defined(__X68000__) || defined(__HUMAN68K__)
#define JOEYLIB_PLATFORM_X68000
#else
#error "JoeyLib: unknown platform; define JOEYLIB_PLATFORM_<TARGET> explicitly via -D"
#endif
#endif
// JOEYLIB_PLATFORM_BLANK is the copy-to-start template for a new port (see
// src/blank/blank.c). It has no auto-detect macro -- bring it up by building
// with -DJOEYLIB_PLATFORM_BLANK.
// ----- Validate exactly one platform is defined -----
#if (defined(JOEYLIB_PLATFORM_IIGS) + \
defined(JOEYLIB_PLATFORM_AMIGA) + \
defined(JOEYLIB_PLATFORM_ATARIST) + \
defined(JOEYLIB_PLATFORM_DOS) + \
defined(JOEYLIB_PLATFORM_X68000) + \
defined(JOEYLIB_PLATFORM_BLANK)) != 1
#error "JoeyLib: exactly one JOEYLIB_PLATFORM_* must be defined"
#endif
// ----- Derived CPU markers -----
#if defined(JOEYLIB_PLATFORM_IIGS)
#define JOEYLIB_CPU_65816
#define JOEYLIB_ENDIAN_LITTLE
#define JOEYLIB_NATIVE_CHUNKY
#define JOEYLIB_PLATFORM_NAME "Apple IIgs"
#elif defined(JOEYLIB_PLATFORM_AMIGA)
#define JOEYLIB_CPU_68000
#define JOEYLIB_ENDIAN_BIG
#define JOEYLIB_NATIVE_PLANAR
#define JOEYLIB_HAS_BLITTER
#define JOEYLIB_HAS_COPPER
#define JOEYLIB_PLATFORM_NAME "Commodore Amiga"
#elif defined(JOEYLIB_PLATFORM_ATARIST)
#define JOEYLIB_CPU_68000
#define JOEYLIB_ENDIAN_BIG
#define JOEYLIB_NATIVE_PLANAR
#define JOEYLIB_PLATFORM_NAME "Atari ST"
#elif defined(JOEYLIB_PLATFORM_DOS)
#define JOEYLIB_CPU_X86
#define JOEYLIB_ENDIAN_LITTLE
#define JOEYLIB_NATIVE_CHUNKY
#define JOEYLIB_PLATFORM_NAME "MS-DOS"
#elif defined(JOEYLIB_PLATFORM_X68000)
// BRING-UP STATE: chunky stage in main RAM, expanded to GVRAM by jlpPresent.
// This is deliberately the slow-but-correct path -- it makes every one of the
// 772 lines of src/generic work unmodified, so the port renders correctly
// before a single native primitive exists.
//
// The native storage model is NOT yet decided. The two candidates are GVRAM
// (2 bytes/pixel, trivial primitives) and the text plane at $E00000 (four
// 1bpp planes 128 KB apart -- byte-for-byte the Amiga layout with stride 40
// replaced by 128, so src/amiga adapts by changing one constant). Measured
// under MAME with the wait-state patch: TVRAM costs 1.92 cycles/access
// against GVRAM's 1.03, but needs only 0.25 word-writes per 16-colour pixel
// against GVRAM's 1.0 -- so the text plane still wins ~2x. See
// docs/x68000_mame_crtc_timing.md. Do not switch to JOEYLIB_NATIVE_PLANAR
// until that is settled and measured.
#define JOEYLIB_CPU_68000
#define JOEYLIB_ENDIAN_BIG
#define JOEYLIB_NATIVE_PLANAR
#define JOEYLIB_PLATFORM_NAME "Sharp X68000"
#elif defined(JOEYLIB_PLATFORM_BLANK)
// Chunky little-endian is the simplest baseline for a new port: the generic
// backend gives you fully-working software rendering out of the box. Adjust
// these (or switch to JOEYLIB_NATIVE_PLANAR) once you know your hardware.
#define JOEYLIB_ENDIAN_LITTLE
#define JOEYLIB_NATIVE_CHUNKY
#define JOEYLIB_PLATFORM_NAME "Blank Template"
#endif
// ----- Per-machine op override registry (JL_HAS_<OP>) -----
//
// A machine #define-s JL_HAS_<OP> for each overridable platform op it replaces
// with its own (asm / native) implementation in src/<machine>/. Ops a machine
// does NOT claim fall back to the portable-C default in src/generic/, selected
// at compile time (no runtime dispatch). The jlp<Op> macros/prototypes in
// src/core/port.h read this table. This is the new lib's equivalent of the
// original joeylib's joey.h JL_HAS_* table.
#if defined(JOEYLIB_PLATFORM_IIGS)
#define JL_HAS_SURFACE_CLEAR // iigsSurfaceClearFastInner (stage), macro
#define JL_HAS_DRAW_PIXEL // iigsDrawPixelInner, macro
#define JL_HAS_DRAW_LINE // iigsDrawLineInner, macro
#define JL_HAS_DRAW_CIRCLE // iigsDrawCircleInner, macro
#define JL_HAS_FILL_CIRCLE // iigsFillCircleInner (stage), macro -- returns bool
#define JL_HAS_FILL_RECT // iigsFillRectMark (stage, fused mark), macro -> generic else
#define JL_HAS_TILE_FILL // iigsTileFillInner, macro
#define JL_HAS_TILE_COPY // iigsTileCopyInner, macro
#define JL_HAS_TILE_COPY_MASKED // iigsTileCopyMaskedInner, macro
#define JL_HAS_TILE_PASTE // iigsTilePasteInner, macro
#define JL_HAS_TILE_PASTE_MONO // iigsTilePasteMonoInner (stage), macro -> generic else
#define JL_HAS_TILE_SNAP // iigsTileSnapInner, macro
#define JL_HAS_SURFACE_COPY_RECT // jlpSurfaceCopyRect: inline word copy for
// short spans (llvm-mos memcpy is a slow far
// byte-loop, finding #79), function
#define JL_HAS_SPRITE_DRAW // chunky -> codegen; planes mirror is noop macro
#define JL_HAS_SPRITE_SAVE // noop macro (codegen path saves)
#define JL_HAS_SPRITE_RESTORE // noop macro
#define JL_HAS_FLOOD_WALK_AND_SCANS // iigsFloodWalkAndScansInner (all-in-one), macro
#define JL_HAS_BIG_ALLOC // Memory Manager NewHandle/DisposeHandle, function
#define JL_HAS_STAGE_ALLOC_PIXELS // pinned $01:2000 display memory, function
#define JL_HAS_STAGE_FREE_PIXELS // no-op (pinned), function
#define JL_HAS_FRAME_HZ // runtime 50/60 from battery RAM, function
// (frameCount: port.h #defines jlpFrameCount straight to iigsGetTickWord,
// the GetTick asm wrapper -- no function override to register here.)
#define JL_HAS_WAIT_VBL // $C019 VBL poll, function
// audio: every real port implements the full engine
#define JL_HAS_AUDIO_INIT
#define JL_HAS_AUDIO_SHUTDOWN
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
#define JL_HAS_AUDIO_TONE
#define JL_HAS_AUDIO_VOICE
#define JL_HAS_AUDIO_NOISE
#define JL_HAS_AUDIO_TICK_REGISTER
#define JL_HAS_AUDIO_CRITICAL_ENTER
#define JL_HAS_AUDIO_CRITICAL_EXIT
#define JL_HAS_AUDIO_FRAME_TICK
// SAMPLE side (src/x68000/audioPcm.c): libxmp-lite + the shared 5-slot SFX
// overlay, encoded to MSM6258 ADPCM and played via _iocs_adpcmlot. Separate
// device from the OPM, so chip music and digital audio do not contend.
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
// lifecycle / present / input (every real port implements)
#define JL_HAS_INIT
#define JL_HAS_SHUTDOWN
#define JL_HAS_PRESENT
#define JL_HAS_INPUT_INIT
#define JL_HAS_INPUT_SHUTDOWN
#define JL_HAS_INPUT_POLL
#define JL_HAS_JOYSTICK_RESET
// serial add-on (optional; SCC modem/printer + 6551 Super Serial Card)
#define JL_HAS_SERIAL_OPEN
#define JL_HAS_SERIAL_CLOSE
#define JL_HAS_SERIAL_POLL
#define JL_HAS_SERIAL_READ
#define JL_HAS_SERIAL_WRITE
#define JL_HAS_SERIAL_AVAILABLE
#define JL_HAS_SERIAL_FLUSH
// save files + disk space: delete (GS/OS Destroy), dir-ensure (GS/OS Create
// $2001, storageType 13), disk-free (GS/OS Volume $2008 via prefix 0).
#define JL_HAS_SAVE_DIR_ENSURE
#define JL_HAS_SAVE_DELETE
#define JL_HAS_DISK_FREE
// millisElapsed: generic frameCount*1000/frameHz (no override)
#elif defined(JOEYLIB_PLATFORM_AMIGA)
#define JL_HAS_SURFACE_CLEAR // planar clear, function
#define JL_HAS_DRAW_PIXEL // amigaPlanarSetPixel, function
#define JL_HAS_DRAW_LINE // amigaPlanarLine, function
#define JL_HAS_DRAW_CIRCLE // amiga planar circle, function
#define JL_HAS_FILL_CIRCLE // amiga planar fill circle, function -- returns bool
#define JL_HAS_FILL_RECT // amiga planar fill rect, function
#define JL_HAS_TILE_FILL // amiga planar tile fill, inline (amigaTile.h)
#define JL_HAS_TILE_COPY // amiga planar tile copy, inline (amigaTile.h)
#define JL_HAS_TILE_COPY_MASKED // amiga planar masked copy, inline (amigaTile.h)
#define JL_HAS_TILE_PASTE // amiga planar tile paste, inline (amigaTile.h)
#define JL_HAS_TILE_SNAP // amiga planar tile snap, inline (amigaTile.h)
#define JL_HAS_TILE_PASTE_MONO // amiga planar mono colorize+paste, inline (amigaTile.h)
#define JL_HAS_SPRITE_DRAW // amiga planar sprite draw, function
#define JL_HAS_SPRITE_SAVE // amiga planar sprite save, function
#define JL_HAS_SPRITE_RESTORE // amiga planar sprite restore, function
#define JL_HAS_FLOOD_WALK_PLANES // amiga planar flood walk-out, function
#define JL_HAS_FLOOD_SCAN_ROW_PLANES // amiga planar flood scan-row, function
#define JL_HAS_SURFACE_COPY_PLANES // amiga blitter plane copy, function
#define JL_HAS_SURFACE_COPY_RECT // amiga per-plane rect row copy, function
#define JL_HAS_SAMPLE_PIXEL // amiga planar nibble decode, function
#define JL_HAS_SURFACE_HASH // amiga planar hash, function
#define JL_HAS_SURFACE_LOAD_FILE // amiga planar load, function
#define JL_HAS_SURFACE_SAVE_FILE // amiga planar save, function
#define JL_HAS_STAGE_ALLOC_PIXELS // amiga: NULL (no chunky stage shadow), function
#define JL_HAS_SURFACE_ALLOC_PIXELS // amiga: NULL (planar storage), function
#define JL_HAS_SURFACE_ALLOC_PORT_DATA // amiga AmigaPlanarT + chip planes, function
#define JL_HAS_SURFACE_FREE_PORT_DATA // amiga FreeMem planes, function
#define JL_HAS_FRAME_HZ // PAL 50, function
#define JL_HAS_FRAME_COUNT // VBL-server counter, function
#define JL_HAS_WAIT_VBL // WaitTOF, function
// audio: every real port implements the full engine
#define JL_HAS_AUDIO_INIT
#define JL_HAS_AUDIO_SHUTDOWN
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
#define JL_HAS_AUDIO_TONE
#define JL_HAS_AUDIO_VOICE
#define JL_HAS_AUDIO_NOISE
#define JL_HAS_AUDIO_TICK_REGISTER
#define JL_HAS_AUDIO_CRITICAL_ENTER
#define JL_HAS_AUDIO_CRITICAL_EXIT
#define JL_HAS_AUDIO_FRAME_TICK
// SAMPLE side (src/x68000/audioPcm.c): libxmp-lite + the shared 5-slot SFX
// overlay, encoded to MSM6258 ADPCM and played via _iocs_adpcmlot. Separate
// device from the OPM, so chip music and digital audio do not contend.
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
// lifecycle / present / input (every real port implements)
#define JL_HAS_INIT
#define JL_HAS_SHUTDOWN
#define JL_HAS_PRESENT
#define JL_HAS_INPUT_INIT
#define JL_HAS_INPUT_SHUTDOWN
#define JL_HAS_INPUT_POLL
#define JL_HAS_JOYSTICK_RESET
// serial add-on (optional; serial.device)
#define JL_HAS_SERIAL_OPEN
#define JL_HAS_SERIAL_CLOSE
#define JL_HAS_SERIAL_POLL
#define JL_HAS_SERIAL_READ
#define JL_HAS_SERIAL_WRITE
#define JL_HAS_SERIAL_AVAILABLE
#define JL_HAS_SERIAL_FLUSH
// save files + disk space (CreateDir/DeleteFile/Info via dos.library)
#define JL_HAS_SAVE_DIR_ENSURE
#define JL_HAS_SAVE_DELETE
#define JL_HAS_DISK_FREE
// millisElapsed: generic frameCount*1000/frameHz (no override)
#elif defined(JOEYLIB_PLATFORM_ATARIST)
#define JL_HAS_SURFACE_CLEAR // planar clear, function
#define JL_HAS_DRAW_PIXEL // stPlanarSetPixel, function
#define JL_HAS_DRAW_LINE // stPlanarLine, function
#define JL_HAS_DRAW_CIRCLE // st planar circle, function
#define JL_HAS_FILL_CIRCLE // st planar fill circle, function -- returns bool
#define JL_HAS_FILL_RECT // st planar fill rect, function
#define JL_HAS_TILE_FILL // st planar tile fill, inline (stTile.h)
#define JL_HAS_TILE_COPY // st planar tile copy, inline (stTile.h)
#define JL_HAS_TILE_COPY_MASKED // st planar masked copy, inline (stTile.h)
#define JL_HAS_TILE_PASTE // st planar tile paste, inline (stTile.h)
#define JL_HAS_TILE_SNAP // st planar tile snap, inline (stTile.h)
#define JL_HAS_TILE_PASTE_MONO // st planar mono colorize+paste, inline (stTile.h)
#define JL_HAS_SPRITE_DRAW // st planar sprite draw, function
#define JL_HAS_SPRITE_SAVE // st planar sprite save, function
#define JL_HAS_SPRITE_RESTORE // st planar sprite restore, function
#define JL_HAS_FLOOD_WALK_PLANES // st planar flood walk-out, function
#define JL_HAS_FLOOD_SCAN_ROW_PLANES // st planar flood scan-row, function
#define JL_HAS_SURFACE_COPY_PLANES // st planar buffer memcpy, function
#define JL_HAS_SURFACE_COPY_RECT // st interleaved rect row memcpy, function
#define JL_HAS_SAMPLE_PIXEL // st planar nibble decode, function
#define JL_HAS_SURFACE_HASH // st planar hash, function
#define JL_HAS_SURFACE_LOAD_FILE // st planar load, function
#define JL_HAS_SURFACE_SAVE_FILE // st planar save, function
#define JL_HAS_STAGE_ALLOC_PIXELS // st: NULL (no chunky stage shadow), function
#define JL_HAS_SURFACE_ALLOC_PIXELS // st: NULL (planar storage), function
#define JL_HAS_SURFACE_ALLOC_PORT_DATA // st StPlanarT + interleaved buffer, function
#define JL_HAS_SURFACE_FREE_PORT_DATA // st free buffer, function
#define JL_HAS_FRAME_HZ // PAL 50, function
#define JL_HAS_FRAME_COUNT // VBL-ISR counter, function
#define JL_HAS_WAIT_VBL // frame-counter wait, function
#define JL_HAS_MILLIS_ELAPSED // Supexec 200 Hz tick, function
// audio: every real port implements the full engine
#define JL_HAS_AUDIO_INIT
#define JL_HAS_AUDIO_SHUTDOWN
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
#define JL_HAS_AUDIO_TONE
#define JL_HAS_AUDIO_VOICE
#define JL_HAS_AUDIO_NOISE
#define JL_HAS_AUDIO_TICK_REGISTER
#define JL_HAS_AUDIO_CRITICAL_ENTER
#define JL_HAS_AUDIO_CRITICAL_EXIT
#define JL_HAS_AUDIO_FRAME_TICK
// SAMPLE side (src/x68000/audioPcm.c): libxmp-lite + the shared 5-slot SFX
// overlay, encoded to MSM6258 ADPCM and played via _iocs_adpcmlot. Separate
// device from the OPM, so chip music and digital audio do not contend.
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
// lifecycle / present / input (every real port implements)
#define JL_HAS_INIT
#define JL_HAS_SHUTDOWN
#define JL_HAS_PRESENT
#define JL_HAS_INPUT_INIT
#define JL_HAS_INPUT_SHUTDOWN
#define JL_HAS_INPUT_POLL
#define JL_HAS_JOYSTICK_RESET
// serial add-on (optional; BIOS Aux / XBIOS Rsconf on the Modem port)
#define JL_HAS_SERIAL_OPEN
#define JL_HAS_SERIAL_CLOSE
#define JL_HAS_SERIAL_POLL
#define JL_HAS_SERIAL_READ
#define JL_HAS_SERIAL_WRITE
#define JL_HAS_SERIAL_AVAILABLE
#define JL_HAS_SERIAL_FLUSH
// save files + disk space (POSIX mkdir/remove + GEMDOS Dfree)
#define JL_HAS_SAVE_DIR_ENSURE
#define JL_HAS_SAVE_DELETE
#define JL_HAS_DISK_FREE
#elif defined(JOEYLIB_PLATFORM_DOS)
// chunky generics: surface clear, draw pixel/line/circle, fill circle/rect,
// tiles, surface readers, allocation -- DOS overrides the timing services
// plus the whole-map tile walker (src/dos/dosTile.h, dispatched via the
// jlpTileMapPaste alias from tile.c's shared whole-map arm like the ST
// engine; not a jlp op, so no JL_HAS flag).
// (The planar dual-write hooks are not linked to generics: every chunky port
// elides them to ((void)0) in port.h's shared chunky block, PERF-AUDIT #42.)
#define JL_HAS_FRAME_HZ // VGA ~70, function
#define JL_HAS_FRAME_COUNT // $3DA retrace edge counter, function
#define JL_HAS_WAIT_VBL // $3DA retrace poll, function
#define JL_HAS_MILLIS_ELAPSED // uclock / audio-ISR tick, function
// audio: every real port implements the full engine
#define JL_HAS_AUDIO_INIT
#define JL_HAS_AUDIO_SHUTDOWN
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
#define JL_HAS_AUDIO_TONE
#define JL_HAS_AUDIO_VOICE
#define JL_HAS_AUDIO_NOISE
#define JL_HAS_AUDIO_TICK_REGISTER
#define JL_HAS_AUDIO_CRITICAL_ENTER
#define JL_HAS_AUDIO_CRITICAL_EXIT
#define JL_HAS_AUDIO_FRAME_TICK
// SAMPLE side (src/x68000/audioPcm.c): libxmp-lite + the shared 5-slot SFX
// overlay, encoded to MSM6258 ADPCM and played via _iocs_adpcmlot. Separate
// device from the OPM, so chip music and digital audio do not contend.
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
// lifecycle / present / input (every real port implements)
#define JL_HAS_INIT
#define JL_HAS_SHUTDOWN
#define JL_HAS_PRESENT
#define JL_HAS_INPUT_INIT
#define JL_HAS_INPUT_SHUTDOWN
#define JL_HAS_INPUT_POLL
#define JL_HAS_JOYSTICK_RESET
// serial add-on (optional; 8250/16550 UART on a COM port, IRQ RX ring)
#define JL_HAS_SERIAL_OPEN
#define JL_HAS_SERIAL_CLOSE
#define JL_HAS_SERIAL_POLL
#define JL_HAS_SERIAL_READ
#define JL_HAS_SERIAL_WRITE
#define JL_HAS_SERIAL_AVAILABLE
#define JL_HAS_SERIAL_FLUSH
// save files + disk space (POSIX mkdir/remove + int21h/36h disk-free)
#define JL_HAS_SAVE_DIR_ENSURE
#define JL_HAS_SAVE_DELETE
#define JL_HAS_DISK_FREE
#elif defined(JOEYLIB_PLATFORM_X68000)
// Bring-up: platform SERVICES only (src/x68000/hal.c), plus the serial
// add-on (src/x68000/serial.c). Everything graphical comes from the portable
// generics, so the port renders correctly before any native primitive
// exists. Native ops arrive with the storage-model decision.
// Planar graphics, adapted from the Amiga (identical surface layout).
#define JL_HAS_SURFACE_CLEAR
#define JL_HAS_DRAW_PIXEL
#define JL_HAS_DRAW_LINE
#define JL_HAS_DRAW_CIRCLE
#define JL_HAS_FILL_CIRCLE
#define JL_HAS_FILL_RECT
#define JL_HAS_TILE_FILL
#define JL_HAS_TILE_COPY
#define JL_HAS_TILE_COPY_MASKED
#define JL_HAS_TILE_PASTE
#define JL_HAS_TILE_SNAP
#define JL_HAS_TILE_PASTE_MONO
#define JL_HAS_SPRITE_DRAW
#define JL_HAS_SPRITE_SAVE
#define JL_HAS_SPRITE_RESTORE
#define JL_HAS_FLOOD_WALK_PLANES
#define JL_HAS_FLOOD_SCAN_ROW_PLANES
#define JL_HAS_SURFACE_COPY_PLANES
#define JL_HAS_SURFACE_COPY_RECT
#define JL_HAS_SAMPLE_PIXEL
#define JL_HAS_SURFACE_HASH
#define JL_HAS_SURFACE_LOAD_FILE
#define JL_HAS_SURFACE_SAVE_FILE
#define JL_HAS_STAGE_ALLOC_PIXELS
#define JL_HAS_SURFACE_ALLOC_PIXELS
#define JL_HAS_SURFACE_ALLOC_PORT_DATA
#define JL_HAS_SURFACE_FREE_PORT_DATA
#define JL_HAS_INIT // _iocs_crtmod display bring-up
#define JL_HAS_SHUTDOWN // restore the previous CRT mode
#define JL_HAS_PRESENT // expand the chunky stage into GVRAM
#define JL_HAS_INPUT_INIT
#define JL_HAS_INPUT_SHUTDOWN
#define JL_HAS_INPUT_POLL // _iocs_bitsns key bitmaps -> gKeyState[]
#define JL_HAS_JOYSTICK_RESET
#define JL_HAS_WAIT_VBL // _iocs_vsync
#define JL_HAS_FRAME_COUNT
#define JL_HAS_FRAME_HZ // ~55 Hz in the 31 kHz modes
// Chains Human68k's MFP Timer C (~100 Hz). Without this the port fell back to
// the generic clock, which derives ms from the POLLED frame counter and
// undercounts exactly in proportion to how slow the op is.
#define JL_HAS_MILLIS_ELAPSED
// Save add-on: Human68k _dos_dskfre / _dos_mkdir, structurally the ST HAL.
#define JL_HAS_DISK_FREE
#define JL_HAS_SAVE_DELETE
#define JL_HAS_SAVE_DIR_ENSURE
// Serial add-on: IOCS polled RS-232C, structurally the ST HAL.
#define JL_HAS_SERIAL_OPEN
#define JL_HAS_SERIAL_CLOSE
#define JL_HAS_SERIAL_POLL
#define JL_HAS_SERIAL_AVAILABLE
#define JL_HAS_SERIAL_READ
#define JL_HAS_SERIAL_WRITE
#define JL_HAS_SERIAL_FLUSH
// Audio. CHIP side on the YM2151 (OPM): tone voices + noise, which is what
// the portable JYM1 tracker rides, with no CPU mixing.
#define JL_HAS_AUDIO_INIT
#define JL_HAS_AUDIO_SHUTDOWN
#define JL_HAS_AUDIO_TONE
#define JL_HAS_AUDIO_VOICE
#define JL_HAS_AUDIO_NOISE
#define JL_HAS_AUDIO_CRITICAL_ENTER
#define JL_HAS_AUDIO_CRITICAL_EXIT
#define JL_HAS_AUDIO_FRAME_TICK
// SAMPLE side (src/x68000/audioPcm.c): libxmp-lite + the shared 5-slot SFX
// overlay, encoded to MSM6258 ADPCM and played via _iocs_adpcmlot. Separate
// device from the OPM, so chip music and digital audio do not contend.
#define JL_HAS_AUDIO_PLAY_MOD
#define JL_HAS_AUDIO_STOP_MOD
#define JL_HAS_AUDIO_IS_PLAYING_MOD
#define JL_HAS_AUDIO_PLAY_SFX
#define JL_HAS_AUDIO_PLAY_SFX_STREAM
#define JL_HAS_AUDIO_STOP_SFX
#elif defined(JOEYLIB_PLATFORM_BLANK)
// Copy-to-start template. It overrides ONLY the platform SERVICES (TODO
// stubs in src/blank/blank.c). Everything graphical -- draw / tile / sprite
// primitives, surface readers, allocation, bigAlloc, millisElapsed -- comes
// from the portable-C generics for free, so a chunky port renders correctly
// before you write a line of graphics code. Add a JL_HAS_<OP> here + an
// override in blank.c only when you want to accelerate a specific op.
#define JL_HAS_INIT // bring up your display mode
#define JL_HAS_SHUTDOWN // restore it
#define JL_HAS_PRESENT // blit the chunky stage to your framebuffer
#define JL_HAS_INPUT_INIT
#define JL_HAS_INPUT_SHUTDOWN
#define JL_HAS_INPUT_POLL // read your keyboard into gKeyState[]
#define JL_HAS_JOYSTICK_RESET
#define JL_HAS_WAIT_VBL // pace to the display
#define JL_HAS_FRAME_COUNT // a monotonic frame/refresh counter
#define JL_HAS_FRAME_HZ // your refresh rate in Hz
// audio: left to the no-op generics (your port links + runs silent). Add
// JL_HAS_AUDIO_* + overrides in blank.c when you wire up sound.
#endif
// ----- Library version -----
#define JOEYLIB_VERSION_MAJOR 1
#define JOEYLIB_VERSION_MINOR 0
#define JOEYLIB_VERSION_PATCH 0
#define JOEYLIB_VERSION_STRING "1.0.0"
#endif