// CoreMark porting layer for the W65816 / Apple IIgs target.
// Adapts the barebones template:
//   - clock() via VBL counter at 60 Hz (CLOCKS_PER_SEC=60)
//   - printf via our libc
//   - MEM_STATIC (heap-free)
//   - HAS_FLOAT=1 (soft-double; needed for the score calc)
//   - Single-threaded (MULTITHREAD=1)

#ifndef CORE_PORTME_H
#define CORE_PORTME_H

#define HAS_FLOAT      1
#define HAS_TIME_H     1
#define USE_CLOCK      1
#define HAS_STDIO      1
#define HAS_PRINTF     1

#define COMPILER_VERSION "llvm816"
#define COMPILER_FLAGS   "-O2 -ffunction-sections (W65816 backend)"
#define MEM_LOCATION     "STATIC"

typedef signed short   ee_s16;
typedef unsigned short ee_u16;
// On W65816, `int` is 16-bit and `long` is 32-bit.  CoreMark needs
// genuine 32-bit ee_s32/ee_u32 (CRCs, timings, iteration counts).
typedef signed long    ee_s32;
typedef double         ee_f32;
typedef unsigned char  ee_u8;
typedef unsigned long  ee_u32;
typedef ee_u32         ee_ptr_int;
typedef unsigned long  ee_size_t;
#define NULL ((void *)0)

#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3))

// ITERATIONS — keep small for the 1 MHz IIgs.  CoreMark spec wants
// >= 10 sec of runtime; at this clock that's order-of-magnitude
// 100 iterations.  Run with ITERATIONS=1 first to validate, then
// scale up.  The user can pass -DITERATIONS=N to override.
#ifndef ITERATIONS
#define ITERATIONS 1
#endif

// Timing.  CLOCKS_PER_SEC = 60 (VBL).  Use TIMER_RES_DIVIDER=1 since
// 60 Hz is already coarse.
#define CORETIMETYPE       ee_u32
typedef ee_u32             CORE_TICKS;
typedef double             secs_ret;
#define SECS_VAL_FMT       "%.2f"

// Seeds via volatile (default).
#ifndef SEED_METHOD
#define SEED_METHOD SEED_VOLATILE
#endif

// Memory: static block.  Heap-free, avoids dynamic alloc.
#ifndef MEM_METHOD
#define MEM_METHOD MEM_STATIC
#endif

#ifndef MULTITHREAD
#define MULTITHREAD 1
#define USE_PTHREAD 0
#define USE_FORK    0
#define USE_SOCKET  0
#endif

#ifndef MAIN_HAS_NOARGC
#define MAIN_HAS_NOARGC 1
#endif

#ifndef MAIN_HAS_NORETURN
#define MAIN_HAS_NORETURN 0
#endif

extern ee_u32 default_num_contexts;

typedef struct CORE_PORTABLE_S {
    ee_u8 portable_id;
} core_portable;

void portable_init(core_portable *p, int *argc, char *argv[]);
void portable_fini(core_portable *p);

#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \
    && !defined(VALIDATION_RUN)
#if (TOTAL_DATA_SIZE == 1200)
#define PROFILE_RUN 1
#elif (TOTAL_DATA_SIZE == 2000)
#define PERFORMANCE_RUN 1
#else
#define VALIDATION_RUN 1
#endif
#endif

#endif /* CORE_PORTME_H */
