feat: add AmigaOS support
This commit is contained in:
parent
52a8446ffb
commit
aaa28a5688
|
@ -175,6 +175,20 @@ Link management related function declarations
|
|||
|
||||
In case of error, the value of ``*linkp`` mustn't be used nor freed.
|
||||
|
||||
The format of the device name or path will vary depending on the platform:
|
||||
|
||||
* On Microsoft Windows, it will either be the DOS COM device name (e.g.
|
||||
``COM3``) or the path to the device.
|
||||
* On other POSIX-compatible platforms, it will be the path to the device,
|
||||
usually ``/dev/cu*`` or ``/dev/tty*`` (e.g. ``/dev/ttyUSB0`` for a
|
||||
serial link over a USB-serial cable);
|
||||
* On AmigaOS, it will be the serial unit number with the case-insensitive
|
||||
``U=`` or ``UNIT=`` keyword parameter, e.g. ``unit=0`` for the
|
||||
built-in serial device.
|
||||
|
||||
Available device names can be probed using :c:func:`cahute_detect_serial`,
|
||||
although the list may be incomplete and other devices may be used.
|
||||
|
||||
Since serial links do not offer any metadata, the protocol to use on the
|
||||
serial link is selected manually, amongst the following:
|
||||
|
||||
|
|
|
@ -210,6 +210,18 @@ Available mediums are the following:
|
|||
* :c:macro:`CAHUTE_LINK_PROTOCOL_SERIAL_SEVEN`;
|
||||
* :c:macro:`CAHUTE_LINK_PROTOCOL_SERIAL_SEVEN_OHP`.
|
||||
|
||||
.. c:macro:: CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL
|
||||
|
||||
Serial medium using AmigaOS serial I/O, as described in the
|
||||
`AmigaOS Serial Device Guide`_.
|
||||
|
||||
Available protocols on this medium are the following:
|
||||
|
||||
* :c:macro:`CAHUTE_LINK_PROTOCOL_SERIAL_AUTO`;
|
||||
* :c:macro:`CAHUTE_LINK_PROTOCOL_SERIAL_CASIOLINK`;
|
||||
* :c:macro:`CAHUTE_LINK_PROTOCOL_SERIAL_SEVEN`;
|
||||
* :c:macro:`CAHUTE_LINK_PROTOCOL_SERIAL_SEVEN_OHP`.
|
||||
|
||||
.. c:macro:: CAHUTE_LINK_MEDIUM_WIN32_SERIAL
|
||||
|
||||
Serial medium using the Windows API, with a |HANDLE|_ and
|
||||
|
@ -679,5 +691,7 @@ of the original function).
|
|||
https://libusb.sourceforge.io/api-1.0/group__libusb__syncio.html
|
||||
#ga2f90957ccc1285475ae96ad2ceb1f58c
|
||||
|
||||
.. _AmigaOS Serial Device Guide:
|
||||
https://wiki.amigaos.net/wiki/Serial_Device
|
||||
.. _USB Mass Storage Class, Bulk-Only Transport:
|
||||
https://www.usb.org/sites/default/files/usbmassbulk_10.pdf
|
||||
|
|
|
@ -245,6 +245,21 @@ end:
|
|||
return err;
|
||||
#endif
|
||||
|
||||
#if AMIGAOS_ENABLED
|
||||
cahute_serial_detection_entry entry;
|
||||
|
||||
/* When opening a serial port on the AmigaOS, we systematically use
|
||||
* the serial device, but allow selecting the unit number using the
|
||||
* name. */
|
||||
entry.cahute_serial_detection_entry_name = "UNIT=0";
|
||||
if (func(cookie, &entry))
|
||||
return CAHUTE_ERROR_INT;
|
||||
|
||||
/* TODO: How to detect multiple serial devices? */
|
||||
|
||||
return CAHUTE_OK;
|
||||
#endif
|
||||
|
||||
CAHUTE_RETURN_IMPL("No serial device detection method available.");
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,12 @@
|
|||
# define POSIX_ENABLED 0
|
||||
#endif
|
||||
|
||||
#if defined(AMIGA) || defined(__amigaos__)
|
||||
# define AMIGAOS_ENABLED 1
|
||||
#else
|
||||
# define AMIGAOS_ENABLED 0
|
||||
#endif
|
||||
|
||||
#if POSIX_ENABLED
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
|
@ -62,6 +68,17 @@
|
|||
# include <libusb.h>
|
||||
#endif
|
||||
|
||||
#if AMIGAOS_ENABLED
|
||||
# include <exec/io.h>
|
||||
# include <devices/serial.h>
|
||||
|
||||
CAHUTE_EXTERN(int)
|
||||
cahute_get_amiga_timer(
|
||||
struct MsgPort **msg_portp,
|
||||
struct TimeRequest **timerp
|
||||
);
|
||||
#endif
|
||||
|
||||
/* ---
|
||||
* Logging internals.
|
||||
* --- */
|
||||
|
@ -197,6 +214,9 @@ cahute__log_win_error(
|
|||
# define CAHUTE_LINK_MEDIUM_LIBUSB 5
|
||||
# define CAHUTE_LINK_MEDIUM_LIBUSB_UMS 6
|
||||
#endif
|
||||
#if AMIGAOS_ENABLED
|
||||
# define CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL 7
|
||||
#endif
|
||||
|
||||
/* Protocol selection for 'initialize_link_protocol()'. */
|
||||
#define CAHUTE_LINK_PROTOCOL_SERIAL_AUTO 0
|
||||
|
@ -266,6 +286,19 @@ struct cahute_link_libusb_medium_state {
|
|||
};
|
||||
#endif
|
||||
|
||||
#if defined(CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL)
|
||||
/**
|
||||
* AmigaOS serial device medium state.
|
||||
*
|
||||
* @property msg_port Message port with which the device was opened.
|
||||
* @property io IO structure of the device.
|
||||
*/
|
||||
struct cahute_link_amigaos_serial_medium_state {
|
||||
struct MsgPort *msg_port;
|
||||
struct IOExtSer *io;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Medium state, to be used depending on the link flags regarding the medium.
|
||||
*
|
||||
|
@ -290,6 +323,9 @@ union cahute_link_medium_state {
|
|||
#if defined(CAHUTE_LINK_MEDIUM_LIBUSB)
|
||||
struct cahute_link_libusb_medium_state libusb;
|
||||
#endif
|
||||
#if defined(CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL)
|
||||
struct cahute_link_amigaos_serial_medium_state amigaos_serial;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Absolute minimum buffer size for CASIOLINK. */
|
||||
|
|
115
lib/linkopen.c
115
lib/linkopen.c
|
@ -959,6 +959,45 @@ fail:
|
|||
}
|
||||
#endif
|
||||
|
||||
#if AMIGAOS_ENABLED
|
||||
/**
|
||||
* Get the AmigaOS serial port from the raw device name.
|
||||
*
|
||||
* This function expects a format such as "U=<unit>" or "UNIT=<unit>",
|
||||
* case-insensitive;
|
||||
*
|
||||
* @param raw Raw device name.
|
||||
* @param unitp Pointer to the unit number to set.
|
||||
* @return Cahute error, or 0 if successful.
|
||||
*/
|
||||
CAHUTE_LOCAL(int) get_amigaos_serial_port(char const *raw, int *unitp) {
|
||||
int unit;
|
||||
|
||||
if (tolower(raw[0]) == 'u' && raw[1] == '=')
|
||||
raw += 2;
|
||||
else if (tolower(raw[0]) == 'u' && tolower(raw[1]) == 'n' && tolower(raw[2]) == 'i' && tolower(raw[3]) == 't' && raw[4] == '=')
|
||||
raw += 5;
|
||||
else {
|
||||
/* Unknown port format. */
|
||||
return CAHUTE_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!isdigit(raw[0]))
|
||||
return CAHUTE_ERROR_NOT_FOUND;
|
||||
|
||||
unit = raw[0] - '0';
|
||||
while (*++raw) {
|
||||
if (!isdigit(*raw))
|
||||
return CAHUTE_ERROR_NOT_FOUND;
|
||||
|
||||
unit = unit * 10 + (raw[0] - '0');
|
||||
}
|
||||
|
||||
*unitp = unit;
|
||||
return CAHUTE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Open a link over a serial medium.
|
||||
*
|
||||
|
@ -1231,6 +1270,54 @@ cahute_open_serial_link(
|
|||
CloseHandle(handle);
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
#elif defined(CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL)
|
||||
struct MsgPort *msg_port;
|
||||
struct IOExtSer *io;
|
||||
int ret, unit;
|
||||
|
||||
/* The serial device name is the unit number for the serial device. */
|
||||
ret = get_amigaos_serial_port(name_or_path, &unit);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msg_port = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END);
|
||||
if (!msg_port) {
|
||||
msg(ll_error, "Could not open message port.");
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
io = IExec->AllocSysObjectTags(
|
||||
ASOT_IOREQUEST,
|
||||
ASOIOR_ReplyPort,
|
||||
msg_port,
|
||||
ASOIOR_Size,
|
||||
sizeof(struct IOExtSer),
|
||||
TAG_END
|
||||
);
|
||||
if (!io) {
|
||||
msg(ll_error, "Could not create IORequest.");
|
||||
IExec->FreeSysObject(ASOT_PORT, msg_port);
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
ret = IExec->OpenDevice(SERIALNAME, unit, (struct IORequest *)io, 0L);
|
||||
if (ret) {
|
||||
msg(ll_error,
|
||||
"Error %d has occurred while opening device \"%s\".",
|
||||
ret,
|
||||
name_or_path);
|
||||
|
||||
if (ret == IOERR_BADADDRESS)
|
||||
ret = CAHUTE_ERROR_NOT_FOUND;
|
||||
else if (ret == IOERR_UNITBUSY)
|
||||
ret = CAHUTE_ERROR_PRIV;
|
||||
else
|
||||
ret = CAHUTE_ERROR_UNKNOWN;
|
||||
|
||||
IExec->FreeSysObject(ASOT_IOREQUEST, io);
|
||||
IExec->FreeSysObject(ASOT_PORT, msg_port);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
CAHUTE_RETURN_IMPL("No serial device opening method available.");
|
||||
#endif
|
||||
|
@ -1266,6 +1353,18 @@ cahute_open_serial_link(
|
|||
sizeof(OVERLAPPED)
|
||||
);
|
||||
link->medium_state.windows.overlapped.hEvent = overlapped_event_handle;
|
||||
#elif defined(CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL)
|
||||
if (err) {
|
||||
IExec->CloseDevice((struct IORequest *)io);
|
||||
IExec->FreeSysObject(ASOT_IOREQUEST, io);
|
||||
IExec->FreeSysObject(ASOT_PORT, msg_port);
|
||||
return err;
|
||||
}
|
||||
|
||||
link->flags = CAHUTE_LINK_FLAG_CLOSE_MEDIUM;
|
||||
link->medium = CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL;
|
||||
link->medium_state.amigaos_serial.msg_port = msg_port;
|
||||
link->medium_state.amigaos_serial.io = io;
|
||||
#endif
|
||||
|
||||
link->serial_flags = 0;
|
||||
|
@ -1927,6 +2026,22 @@ CAHUTE_EXTERN(void) cahute_close_link(cahute_link *link) {
|
|||
libusb_exit(link->medium_state.libusb.context);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL
|
||||
case CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL:
|
||||
IExec->CloseDevice(
|
||||
(struct IORequest *)link->medium_state.amigaos_serial.io
|
||||
);
|
||||
IExec->FreeSysObject(
|
||||
ASOT_IOREQUEST,
|
||||
link->medium_state.amigaos_serial.io
|
||||
);
|
||||
IExec->FreeSysObject(
|
||||
ASOT_PORT,
|
||||
link->medium_state.amigaos_serial.msg_port
|
||||
);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
142
lib/medium.c
142
lib/medium.c
|
@ -478,6 +478,82 @@ cahute_read_from_link(
|
|||
} break;
|
||||
#endif
|
||||
|
||||
#if defined(CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL)
|
||||
case CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL: {
|
||||
struct TimeRequest *timer;
|
||||
struct IOExtSer *io = link->medium_state.amigaos_serial.io;
|
||||
struct MsgPort *timer_msgport,
|
||||
*serial_msgport = link->medium_state.amigaos_serial.msg_port;
|
||||
int err;
|
||||
|
||||
err = cahute_get_amiga_timer(&timer_msgport, &timer);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Run two operations at once:
|
||||
* - Read into the buffer.
|
||||
* - Start a timer to the currently requested timeout. */
|
||||
io->IOSer.io_Length = target_size;
|
||||
io->IOSer.io_Data = dest;
|
||||
io->IOSer.io_Command = CMD_READ;
|
||||
|
||||
IExec->SendIO((struct IORequest *)io);
|
||||
|
||||
if (IExec->CheckIO((struct IORequest *)io)) {
|
||||
/* Request is already complete, no need to wait for the
|
||||
* timer! */
|
||||
if (io->IOSer.io_Error) {
|
||||
msg(ll_error,
|
||||
"Error %d occurred while reading from device.",
|
||||
io->IOSer.io_Error);
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
bytes_read = io->IOSer.io_Actual;
|
||||
break;
|
||||
}
|
||||
|
||||
if (timeout > 0) {
|
||||
cahute_u32 signals;
|
||||
|
||||
/* Request did not complete immediately, we want to start the
|
||||
* timer and wait for the first event between serial and
|
||||
* timer. */
|
||||
timer->Time.tv_secs = timeout / 1000;
|
||||
timer->Time.tv_micro = timeout % 1000 * 1000;
|
||||
timer->Request.io_Command = TR_ADDREQUEST;
|
||||
|
||||
IExec->SendIO((struct IORequest *)timer);
|
||||
|
||||
signals = Wait(
|
||||
(1L << serial_msgport->mp_SigBit)
|
||||
| (1L << timer_msgport->mp_SigBit)
|
||||
);
|
||||
if (~signals & (1L << timer_msgport->mp_SigBit))
|
||||
IExec->AbortIO((struct IORequest *)timer);
|
||||
|
||||
if (~signals & (1L << serial_msgport->mp_SigBit)) {
|
||||
IExec->AbortIO((struct IORequest *)io);
|
||||
goto time_out;
|
||||
}
|
||||
} else {
|
||||
/* Infinite timeout, we can just wait for the I/O to be
|
||||
* completed on the request. */
|
||||
IExec->WaitIO((struct IORequest *)io);
|
||||
}
|
||||
|
||||
/* I/O request was completed, we want to read the contents. */
|
||||
if (io->IOSer.io_Error) {
|
||||
msg(ll_error,
|
||||
"Error %d occurred while reading from device.",
|
||||
io->IOSer.io_Error);
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
bytes_read = io->IOSer.io_Actual;
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
CAHUTE_RETURN_IMPL("No method available for reading.");
|
||||
}
|
||||
|
@ -750,6 +826,22 @@ cahute_write_to_link(cahute_link *link, cahute_u8 const *buf, size_t size) {
|
|||
} break;
|
||||
#endif
|
||||
|
||||
#if defined(CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL)
|
||||
case CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL: {
|
||||
struct IOExtSer *io = link->medium_state.amigaos_serial.io;
|
||||
|
||||
io->IOSer.io_Length = size;
|
||||
io->IOSer.io_Data = buf;
|
||||
io->IOSer.io_Command = CMD_WRITE;
|
||||
if (IExec->DoIO((struct IORequest *)io)) {
|
||||
msg(ll_error, "Unable to set the serial parameters!");
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
bytes_written = size;
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
CAHUTE_RETURN_IMPL("No method available for writing.");
|
||||
}
|
||||
|
@ -1071,6 +1163,56 @@ cahute_set_serial_params_to_link(
|
|||
} break;
|
||||
#endif
|
||||
|
||||
#if defined(CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL)
|
||||
case CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL: {
|
||||
struct IOReq *io = link->medium_state.amigaos_serial.io;
|
||||
|
||||
io->io_CtlChar = (0x13 << 24) | (0x11 << 16); /* XON, XOFF, INQ, ACK */
|
||||
io->io_Baud = speed;
|
||||
io->io_ReadLen = 8;
|
||||
io->io_WriteLen = 8;
|
||||
|
||||
io->io_SerFlags &=
|
||||
~(SERF_XDISABLED | SERF_EOFMODE | SERF_RAD_BOOGIE | SERF_QUEUEDBRK
|
||||
| SERF_7WIRE | SERF_PARTY_ODD | SERF_PARTY_ON);
|
||||
|
||||
switch (flags & CAHUTE_SERIAL_XONXOFF_MASK) {
|
||||
case CAHUTE_SERIAL_XONXOFF_ENABLE:
|
||||
io->io_SerFlags |= SERF_XDISABLED;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (flags & CAHUTE_SERIAL_STOP_MASK) {
|
||||
case CAHUTE_SERIAL_STOP_ONE:
|
||||
io->io_StopBits = 1;
|
||||
break;
|
||||
|
||||
case CAHUTE_SERIAL_STOP_TWO:
|
||||
io->io_StopBits = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (flags & CAHUTE_SERIAL_PARITY_MASK) {
|
||||
case CAHUTE_SERIAL_PARITY_EVEN:
|
||||
io->io_SerFlags |= SERF_PARTY_ON;
|
||||
break;
|
||||
|
||||
case CAHUTE_SERIAL_PARITY_ODD:
|
||||
io->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: AmigaOS doesn't manage DTR/RTS directly, which means we
|
||||
* may have to manage it here manually! */
|
||||
|
||||
io->IOSer.io_Command = SDCMD_SETPARAMS;
|
||||
if (IExec->DoIO((struct IORequest *)io)) {
|
||||
msg(ll_error, "Unable to set the serial parameters!");
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
CAHUTE_RETURN_IMPL("No method available for setting serial params.");
|
||||
}
|
||||
|
|
104
lib/misc.c
104
lib/misc.c
|
@ -130,6 +130,110 @@ CAHUTE_EXTERN(int) cahute_monotonic(unsigned long *msp) {
|
|||
return CAHUTE_OK;
|
||||
}
|
||||
|
||||
#elif AMIGAOS_ENABLED
|
||||
|
||||
struct cahute_amiga_timer {
|
||||
struct MsgPort *msg_port;
|
||||
struct TimeRequest *timer_io;
|
||||
};
|
||||
|
||||
CAHUTE_LOCAL_DATA(struct cahute_amiga_timer) cahute_amiga_timer = {0};
|
||||
|
||||
CAHUTE_LOCAL(void) close_amiga_timer() {
|
||||
IExec->CloseDevice(cahute_amiga_timer.timer_io);
|
||||
IExec->FreeSysObject(ASOT_IOREQUEST, cahute_amiga_timer.timer_io);
|
||||
IExec->FreeSysObject(ASOT_PORT, cahute_amiga_timer.msg_port);
|
||||
}
|
||||
|
||||
CAHUTE_EXTERN(int)
|
||||
cahute_get_amiga_timer(
|
||||
struct MsgPort **msg_portp,
|
||||
struct TimeRequest **timerp
|
||||
) {
|
||||
struct MsgPort *msg_port;
|
||||
struct TimeRequest *timer_io;
|
||||
|
||||
if (cahute_amiga_vblank_timer.timer_io)
|
||||
goto end;
|
||||
|
||||
msg_port = IExec->AllocSysObjectTags(ASOT_PORT, 0);
|
||||
if (!msg_port) {
|
||||
msg(ll_error,
|
||||
"An error has occurred while creating the port for the timer.");
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
timer_io = IExec->AllocSysObjectTags(
|
||||
ASOT_IOREQUEST,
|
||||
ASOIOR_Size,
|
||||
sizeof(struct TimeRequest),
|
||||
ASOIOR_ReplyPort,
|
||||
msg_port,
|
||||
TAG_END
|
||||
);
|
||||
if (!timer_io) {
|
||||
msg(ll_error, "An error has occurred while creating the timer I/O.");
|
||||
IExec->FreeSysObject(ASOT_PORT, msg_port);
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
ret = IExec->OpenDevice(
|
||||
TIMERNAME,
|
||||
UNIT_VBLANK,
|
||||
(struct IORequest *)timer_io,
|
||||
0L
|
||||
);
|
||||
if (ret) {
|
||||
msg(ll_error, "An error has occurred while creating the timer I/O.");
|
||||
IExec->FreeSysObject(ASOT_IOREQUEST, timer_io);
|
||||
IExec->FreeSysObject(ASOT_PORT, msg_port);
|
||||
return CAHUTE_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
atexit(close_amiga_timer);
|
||||
|
||||
cahute_amiga_timer.msg_port = msg_port;
|
||||
cahute_amiga_timer.timer_io = timer_io;
|
||||
|
||||
end:
|
||||
if (msg_portp)
|
||||
*msg_portp = cahute_amiga_timer.msg_port;
|
||||
if (timerp)
|
||||
*timerp = cahute_amiga_timer.timer_io;
|
||||
return CAHUTE_OK;
|
||||
}
|
||||
|
||||
CAHUTE_EXTERN(int) cahute_sleep(unsigned long ms) {
|
||||
struct TimeRequest *timer;
|
||||
int err;
|
||||
|
||||
err = cahute_get_amiga_timer(NULL, &timer);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
timer->Time.tv_secs = ms / 1000;
|
||||
timer->Time.tv_micro = ms % 1000 * 1000;
|
||||
timer->Request.io_Command = TR_ADDREQUEST;
|
||||
|
||||
IExec->DoIO((struct IORequest *)timer);
|
||||
return CAHUTE_OK;
|
||||
}
|
||||
|
||||
CAHUTE_EXTERN(int) cahute_monotonic(unsigned long *msp) {
|
||||
struct TimeRequest *timer;
|
||||
int err;
|
||||
|
||||
err = cahute_get_amiga_timer(NULL, &timer);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
timer->Request.io_Command = TR_GETSYSTIME;
|
||||
IExec->DoIO((struct IORequest *)timer);
|
||||
|
||||
*msp = timer->Time.tv_secs * 1000 + timer->Time.tv_micro / 1000;
|
||||
return CAHUTE_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CAHUTE_EXTERN(int) cahute_sleep(unsigned long ms) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
Short: Communication tools for CASIO calculators
|
||||
Author: Thomas Touhey
|
||||
Uploader: thomas@touhey.fr (Thomas Touhey)
|
||||
Type: comm/misc
|
||||
Architecture: m68k-amigaos
|
||||
Version: @PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@
|
||||
Distribution: Aminet
|
||||
|
||||
Cahute is a library and set of command-line utilities to handle serial
|
||||
and USB communication protocols and file formats related to CASIO calculators,
|
||||
dating from the 1990s to today.
|
||||
|
||||
For guides, topics and references, see the following website:
|
||||
|
||||
https://cahuteproject.org/
|
Loading…
Reference in New Issue