From 9fd2f28ec3429712316acb58e8ccd5df05409059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Fri, 3 May 2013 05:52:08 +0000 Subject: [PATCH] started implementation of XHDI caller interface --- sd-emutos/Makefile | 6 +- sd-emutos/xhdi.c | 324 +++++++++++++++++++++++++++++++++++++++++++++ sd-emutos/xhdi.h | 155 ++++++++++++++++++++++ 3 files changed, 483 insertions(+), 2 deletions(-) create mode 100644 sd-emutos/xhdi.c create mode 100644 sd-emutos/xhdi.h diff --git a/sd-emutos/Makefile b/sd-emutos/Makefile index 692c330..0fd577a 100644 --- a/sd-emutos/Makefile +++ b/sd-emutos/Makefile @@ -14,11 +14,13 @@ APP=$(EMUSD).prg all: $(APP) -SOURCES=$(EMUSD).c +SOURCES=$(EMUSD).c \ + xhdi.c + OBJECTS=$(SOURCES:.c=.o) $(APP): $(OBJECTS) - $(CC) $(CFLAGS) $< -o $(APP) + $(CC) $(CFLAGS) $(OBJECTS) -o $(APP) .PHONY clean: - rm -rf *.o $(APP) \ No newline at end of file diff --git a/sd-emutos/xhdi.c b/sd-emutos/xhdi.c new file mode 100644 index 0000000..9a40e89 --- /dev/null +++ b/sd-emutos/xhdi.c @@ -0,0 +1,324 @@ +/* + * xhdi.c + * + * Created on: 03.05.2013 + * Author: mfro + */ + +#include +#include +#include + +#include "xhdi.h" + + +uint32_t xhdi_call(int xhdi_fun, ...) +{ + va_list arguments; + va_start(arguments, xhdi_fun); + + switch (xhdi_fun) + { + case XHDI_VERSION: + return xhdi_version(); + break; + + case XHDI_INQUIRE_TARGET: + { + uint16_t major; + uint16_t minor; + uint32_t *block_size; + uint32_t *flags; + char *product_name; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + block_size = va_arg(arguments, uint32_t *); + flags = va_arg(arguments, uint32_t *); + product_name = va_arg(arguments, char *); + return xhdi_inquire_target(major, minor, + block_size, flags, product_name); + } + break; + + case XHDI_RESERVE: + { + uint16_t major; + uint16_t minor; + uint16_t do_reserve; + uint16_t key; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + do_reserve = va_arg(arguments, unsigned int); + key = va_arg(arguments, unsigned int); + + return xhdi_reserve(major, minor, do_reserve, key); + } + break; + + case XHDI_LOCK: + { + uint16_t major; + uint16_t minor; + uint16_t do_lock; + uint16_t key; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + do_lock = va_arg(arguments, unsigned int); + key = va_arg(arguments, unsigned int); + + return xhdi_lock(major, minor, do_lock, key); + } + break; + + case XHDI_STOP: + { + uint16_t major; + uint16_t minor; + uint16_t do_stop; + uint16_t key; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + do_stop = va_arg(arguments, unsigned int); + key = va_arg(arguments, unsigned int); + + return xhdi_stop(major, minor, do_stop, key); + } + break; + + case XHDI_EJECT: + { + uint16_t major; + uint16_t minor; + uint16_t do_eject; + uint16_t key; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + do_eject = va_arg(arguments, unsigned int); + key = va_arg(arguments, unsigned int); + + return xhdi_eject(major, minor, do_eject, key); + } + break; + + case XHDI_DRIVEMAP: + return xhdi_drivemap(); + break; + + case XHDI_INQUIRE_DEVICE: + { + uint16_t bios_device; + uint16_t *major; + uint16_t *minor; + uint32_t *start_sector; + void *bpb; + + bios_device = va_arg(arguments, unsigned int); + major = va_arg(arguments, uint16_t *); + minor = va_arg(arguments, uint16_t *); + start_sector = va_arg(arguments, uint32_t *); + bpb = va_arg(arguments, void *); + + return xhdi_inquire_device(bios_device, major, minor, start_sector, bpb); + } + break; + + case XHDI_INQUIRE_DRIVER: + { + uint16_t bios_device; + char *name; + char *version; + char *company; + uint16_t *ahdi_version; + uint16_t *maxIPL; + + bios_device = va_arg(arguments, unsigned int); + name = va_arg(arguments, char *); + version = va_arg(arguments, char *); + company = va_arg(arguments, char *); + ahdi_version = va_arg(arguments, uint16_t *); + maxIPL = va_arg(arguments, uint16_t *); + + return xhdi_inquire_driver(bios_device, name, version, company, + ahdi_version, maxIPL); + } + break; + + case XHDI_NEW_COOKIE: + { + void *new_cookie; + + new_cookie = va_arg(arguments, void *); + + return xhdi_new_cookie(new_cookie); + } + break; + + case XHDI_READ_WRITE: + { + uint16_t major; + uint16_t minor; + uint16_t rwflag; + uint32_t recno; + uint16_t count; + void *buf; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + rwflag = va_arg(arguments, unsigned int); + recno = va_arg(arguments, uint32_t); + count = va_arg(arguments, unsigned int); + buf = va_arg(arguments, void *); + + return xhdi_read_write(major, minor, rwflag, recno, count, buf); + } + break; + + case XHDI_INQUIRE_TARGET2: + { + uint16_t major; + uint16_t minor; + uint32_t *block_size; + uint32_t *device_flags; + char *product_name; + uint16_t strlen; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + block_size = va_arg(arguments, uint32_t *); + device_flags = va_arg(arguments, uint32_t *); + product_name = va_arg(arguments, char *); + strlen = va_arg(arguments, unsigned int); + + return xhdi_inquire_target2(major, minor, block_size, device_flags, + product_name, strlen); + } + break; + + case XHDI_INQUIRE_DEVICE2: + { + uint16_t bios_device; + uint16_t *major; + uint16_t *minor; + uint16_t *start_sector; + void *bpb; + uint32_t *blocks; + char *partid; + + bios_device = va_arg(arguments, unsigned int); + major = va_arg(arguments, uint16_t *); + minor = va_arg(arguments, uint16_t *); + start_sector = va_arg(arguments, uint16_t *); + bpb = va_arg(arguments, void *); + blocks = va_arg(arguments, uint32_t *); + partid = va_arg(arguments, char *); + + return xhdi_inquire_device2(bios_device, major, minor, start_sector, + bpb, blocks, partid); + } + break; + + case XHDI_DRIVER_SPECIAL: + { + uint32_t key1; + uint32_t key2; + uint16_t subopcode; + void *data; + + key1 = va_arg(arguments, uint32_t); + key2 = va_arg(arguments, uint32_t); + subopcode = va_arg(arguments, unsigned int); + data = va_arg(arguments, void *); + + return xhdi_driver_special(key1, key2, subopcode, data); + } + break; + + case XHDI_GET_CAPACITY: + { + uint16_t major; + uint16_t minor; + uint32_t *blocks; + uint32_t *bs; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + blocks = va_arg(arguments, uint32_t *); + bs = va_arg(arguments, uint32_t *); + + return xhdi_get_capacity(major, minor, blocks, bs); + } + break; + + case XHDI_MEDIUM_CHANGED: + { + uint16_t major; + uint16_t minor; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + return xhdi_medium_changed(major, minor); + } + break; + + case XHDI_MINT_INFO: + { + uint16_t opcode; + void *data; + + opcode = va_arg(arguments, unsigned int); + data = va_arg(arguments, void *); + + return xhdi_mint_info(opcode, data); + } + break; + + case XHDI_DOS_LIMITS: + { + uint16_t which; + uint32_t limit; + + which = va_arg(arguments, unsigned int); + limit = va_arg(arguments, uint32_t); + + return xhdi_dos_limits(which, limit); + } + break; + + case XHDI_LAST_ACCESS: + { + uint16_t major; + uint16_t minor; + uint32_t *ms; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + ms = va_arg(arguments, uint32_t *); + + return xhdi_last_access(major, minor, ms); + } + break; + + case XHDI_REACCESS: + { + uint16_t major; + uint16_t minor; + + major = va_arg(arguments, unsigned int); + minor = va_arg(arguments, unsigned int); + + return xhdi_reaccess(major, minor); + } + break; + + default: + break; + } + xprintf("unknown XHDI function %d\r\n"); + return EINVFN; +} + diff --git a/sd-emutos/xhdi.h b/sd-emutos/xhdi.h new file mode 100644 index 0000000..3a78cda --- /dev/null +++ b/sd-emutos/xhdi.h @@ -0,0 +1,155 @@ +/* + * xhdi.h + * + * Created on: 03.05.2013 + * Author: mfro + */ + +#ifndef XHDI_H_ +#define XHDI_H_ + +/* + * xhdi_sd.h + * + * This file is part of BaS_gcc. + * + * BaS_gcc is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BaS_gcc is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BaS_gcc. If not, see . + * + * Created on: 01.05.2013 + * Copyright 2012 M. Fršschle + */ +#ifndef _XHDI_SD_H_ +#define _XHDI_SD_H_ + +#ifdef __MSHORT__ +#error this include file is not suitable for -mshort compilation +#endif /* __MSHORT__ */ + +/* XHDI function numbers */ + +#define XHDI_VERSION 0 +#define XHDI_INQUIRE_TARGET 1 +#define XHDI_RESERVE 2 +#define XHDI_LOCK 3 +#define XHDI_STOP 4 +#define XHDI_EJECT 5 +#define XHDI_DRIVEMAP 6 +#define XHDI_INQUIRE_DEVICE 7 +#define XHDI_INQUIRE_DRIVER 8 +#define XHDI_NEW_COOKIE 9 +#define XHDI_READ_WRITE 10 +#define XHDI_INQUIRE_TARGET2 11 +#define XHDI_INQUIRE_DEVICE2 12 +#define XHDI_DRIVER_SPECIAL 13 +#define XHDI_GET_CAPACITY 14 +#define XHDI_MEDIUM_CHANGED 15 +#define XHDI_MINT_INFO 16 +#define XHDI_DOS_LIMITS 17 +#define XHDI_LAST_ACCESS 18 +#define XHDI_REACCESS 19 + +/* XHDI error codes */ + +#define E_OK 0 /* OK */ +#define ERROR -1 /* unspecified error */ +#define EDRVNR -2 /* drive not ready */ +#define EUNDEV -15 /* invalid device/target number */ +#define EINVFN -32 /* invalid function number */ +#define EACCDN -36 /* access denied (device currently reserved) */ +#define EDRIVE -46 /* BIOS device not served by driver */ + +/* XHDI device capabilities */ + +#define XH_TARGET_STOPPABLE (1 << 0) +#define XH_TARGET_REMOVABLE (1 << 1) +#define XH_TARGET_LOCKABLE (1 << 2) +#define XH_TARGET_EJECTABLE (1 << 3) +#define XH_TARGET_LOCKED (1 << 29) +#define XH_TARGET_STOPPED (1 << 30) +#define XH_TARGET_RESERVED (1 << 31) + +/* + * FIXME: dangerous TRAP here! + * + * all of these functions get compiled into BaS with "normal" GCC integers (32 bit). However, since they will be called + * from code compiled with -mshort, integers must be declared uint32_t for those compilation units to adhere + * to "normal" GCC calling conventions. + * + * This is ugly and slow (all stack frames from -mshort compiled code need to be rearranged for "normal" + * calling conventions), but that's the way it currently is... + * + */ +#ifdef __MSHORT__ +#define UINT16_T uint32_t +#else +#define UINT16_T uint16_t +#endif + +/* a riddle: how do you typedef a function pointer to a function that returns its own type? ;) */ +typedef void* (*xhdi_call_fun)(int xhdi_fun, ...); + +extern uint32_t xhdi_call(int xhdi_fun, ...); + +extern xhdi_call_fun xhdi_sd_install(xhdi_call_fun old_vector) __attribute__((__interrupt__)); + +extern uint32_t xhdi_version(void); /* XHDI 0 */ + +extern uint32_t xhdi_inquire_target(UINT16_T major, UINT16_T minor, uint32_t *block_size, uint32_t *flags, + char *product_name); /* XHDI 1 */ + +extern uint32_t xhdi_reserve(UINT16_T major, UINT16_T minor, UINT16_T do_reserve, UINT16_T key); /* XHDI 2 */ + +extern uint32_t xhdi_lock(UINT16_T major, UINT16_T minor, UINT16_T do_lock, UINT16_T key); /* XHDI 3 */ + +extern uint32_t xhdi_stop(UINT16_T major, UINT16_T minor, UINT16_T do_stop, UINT16_T key); /* XHDI 4 */ + +extern uint32_t xhdi_eject(UINT16_T major, UINT16_T minor, UINT16_T do_eject, UINT16_T key); /* XHDI 5 */ + +extern uint32_t xhdi_drivemap(void); /* XHDI 6 */ + +extern uint32_t xhdi_inquire_device(UINT16_T bios_device, UINT16_T *major, UINT16_T *minor, + uint32_t *start_sector, /* BPB */ void *bpb); /* XHDI 7 */ + +extern uint32_t xhdi_inquire_driver(UINT16_T bios_device, char *name, char *version, + char *company, UINT16_T *ahdi_version, UINT16_T *maxIPL); /* XHDI 8 */ + +extern uint32_t xhdi_new_cookie(void *newcookie); /* XHDI 9 */ + +extern uint32_t xhdi_read_write(UINT16_T major, UINT16_T minor, UINT16_T rwflag, + uint32_t recno, UINT16_T count, void *buf); /* XHDI 10 */ + +extern uint32_t xhdi_inquire_target2(UINT16_T major, UINT16_T minor, uint32_t *block_size, + uint32_t *device_flags, char *product_name, UINT16_T stringlen); /* XHDI 11 */ + +extern uint32_t xhdi_inquire_device2(UINT16_T bios_device, UINT16_T *major, UINT16_T *minor, + UINT16_T *start_sector, /* BPB */ void *bpb, uint32_t *blocks, char *partid); /* XHDI 12 */ + +extern uint32_t xhdi_driver_special(uint32_t key1, uint32_t key2, UINT16_T subopcode, void *data); /* XHDI 13 */ + +extern uint32_t xhdi_get_capacity(UINT16_T major, UINT16_T minor, uint32_t *blocks, uint32_t *bs); /* XHDI 14 */ + +extern uint32_t xhdi_medium_changed(UINT16_T major, UINT16_T minor); /* XHDI 15 */ + +extern uint32_t xhdi_mint_info(UINT16_T opcode, void *data); /* XHDI 16 */ + +extern uint32_t xhdi_dos_limits(UINT16_T which, uint32_t limit); /* XHDI 17 */ + +extern uint32_t xhdi_last_access(UINT16_T major, UINT16_T minor, uint32_t *ms); /* XHDI 18 */ + +extern uint32_t xhdi_reaccess(UINT16_T major, UINT16_T minor); /* XHDI 19 */ + +#endif /* _XHDI_SD_H_ */ + + +#endif /* XHDI_H_ */