// IIgs GS/OS file I/O wrappers.
//
// GS/OS calls dispatch through $E100A8 with X holding the call number
// and a 16-bit pointer to a class-1 parameter block pushed on the
// stack.  The parm block layout is per-call but always begins with a
// pCount field giving the number of parameters used.
//
// These wrappers are STUBS — they construct the parm blocks and call
// the dispatcher, but require the caller to have a real ProDOS volume
// mounted (or equivalent GS/OS volume) for the calls to succeed.
// Without that, the dispatcher returns an error code or hangs.
//
// To use these in MAME smoke tests you'd need:
//   - A 2img / po / dsk image containing a ProDOS volume
//   - MAME launched with the image as floppy or hard-disk
//   - Tool Locator + GS/OS init via iigsToolboxInit()
// None of which the current smoke harness provides — these wrappers
// are infrastructure for a future GS/OS-aware test rig.
//
// Class-1 GS/OS calls (pCount-prefixed):
//   $2010 Open
//   $2012 Read
//   $2013 Write
//   $2014 Close
//   $2016 SetMark
//   $2017 GetMark
//   $2018 SetEOF
//   $2019 GetEOF
//   $2029 Quit (special — no return)
// See "GS/OS Reference" for the full ~50 calls and parm-block layouts.

#ifndef IIGS_GSOS_H
#define IIGS_GSOS_H

#ifdef __cplusplus
extern "C" {
#endif

// GS/OS string descriptor: 2-byte length + char data (no NUL).
// Use with caller-allocated storage:
//   struct { unsigned short len; char text[14]; } pname = { 6, "MYFILE" };
typedef struct {
    unsigned short length;
    char           text[1];      // variable-length; total size = length + 2
} GSString;

// Class-1 Open parm block.
typedef struct {
    unsigned short pCount;       // 2 (or up to 12 for full options)
    unsigned short refNum;       // [out] file reference number
    void          *pathname;     // [in] GSString *
    // Optional fields (if pCount > 2): requestAccess, resourceNumber,
    // accessRequested, optionList, ... — left out for the basic open.
} OpenParm;

// Class-1 Read/Write parm block.
typedef struct {
    unsigned short pCount;       // 4
    unsigned short refNum;       // [in] file reference
    void          *dataBuffer;   // [in] in-bank pointer to buffer
    unsigned long  requestCount; // [in] bytes requested
    unsigned long  transferCount;// [out] bytes actually transferred
} IORecGS;

// Class-1 Close / GetEOF / SetEOF / etc. — simple refNum-only blocks.
typedef struct {
    unsigned short pCount;       // 1
    unsigned short refNum;
} RefNumRecGS;

typedef struct {
    unsigned short pCount;       // 2
    unsigned short refNum;
    unsigned long  eof;
} EOFRecGS;

// Class-1 SetMark/GetMark parm block — 32-bit position within file.
typedef struct {
    unsigned short pCount;       // 2
    unsigned short refNum;
    unsigned long  position;     // [in for SetMark, out for GetMark]
} MarkRecGS;

// Open / Read / Write / Close wrappers.  Each returns 0 on success or
// a non-zero GS/OS error code (see gsos.h reference for codes).  The
// parm block lives on the caller's stack; you set the input fields
// before the call and read output fields after.
//
// Implementation lives in runtime/src/iigsGsos.s — needed because the
// W65816 backend's inline asm can't take memory operands for the
// parm-block address.
extern unsigned short gsosOpen   (OpenParm    *p);
extern unsigned short gsosRead   (IORecGS     *p);
extern unsigned short gsosWrite  (IORecGS     *p);
extern unsigned short gsosClose  (RefNumRecGS *p);
extern unsigned short gsosGetEOF (EOFRecGS    *p);
extern unsigned short gsosSetEOF (EOFRecGS    *p);
extern unsigned short gsosSetMark(MarkRecGS   *p);
extern unsigned short gsosGetMark(MarkRecGS   *p);

#ifdef __cplusplus
}
#endif

#endif  // IIGS_GSOS_H
