|
Hauptseite - Welches System? - Hardware - Software - Emulatoren - |
Internet MausNet Programmieren Verweise Über |
Das folgende Beispiel ist ein Minimalrumpf für einen DOS Treiber, der für jede Funktion eine C Funktion aufruft und sämtliche Parameter auf den Stack legt. Damit könnte der Assemblerrumpf als Wrapper zu einer Implementierung in C dienen. Das Beispiel basiert auf den MetaDOS cookiefs.dos Treiber von Julian F. Reschke zum Artikel "ATARIUM Anatomie eines DOS-Treibers für MetaDOS" aus der Computer, Januar 1996.
.globl FunctionTable, DriverName, ShowBanner .globl InitDevice, DiskFree, SearchFirst, SearchNext .globl OpenFile, CloseFile, DateAndTime, WriteFile .globl ReadFile, FileAttributes, CreateFile, SeekFile, FCntl .globl DPathConf, FXAttr, DOpenDir, DReadDir, DXReadDir .globl DCloseDir, DRewindDir, DReadLabel, FDelete .globl initfun, wdfree, wfsfirst, wfsnext, wfopen .globl wfclose, wfdatime, wfwrite, wfread .globl wfattrib, wfcreate, wfseek, wfcntl .globl wdpathconf, wfxattr, wdopendir, wdreaddir .globl wdclosedir, wdxreaddir, wdrewinddir .globl wdreadlabel, wfdelete .text ; evtl. Meldung ausgeben move.l #FunctionTable+12,d0 move.l #DriverName,d1 rts initfun: movem.l a0-a6/d1-d7,-(sp) move.w d1,-(sp) move.w d0,-(sp) bsr InitDevice addq #4,sp movem.l (sp)+,a0-a6/d1-d7 moveq #5,d1 rts wdfree: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DiskFree lea 12(sp),sp rts wfsfirst: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr SearchFirst lea 12(sp),sp rts wfsnext: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr SearchNext lea 12(sp),sp rts wfopen: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr OpenFile lea 12(sp),sp rts wfclose: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr CloseFile lea 12(sp),sp rts wfdatime: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DateAndTime lea 12(sp),sp rts wfwrite: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr WriteFile lea 12(sp),sp rts wfread: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr ReadFile lea 12(sp),sp rts wfattrib: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr FileAttributes lea 12(sp),sp rts wfcreate: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr CreateFile lea 12(sp),sp rts wfseek: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr SeekFile lea 12(sp),sp rts wfcntl: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr FCntl lea 12(sp),sp rts wfdelete: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr FDelete lea 12(sp),sp rts wdpathconf: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DPathConf lea 12(sp),sp rts wfxattr: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr FXAttr lea 12(sp),sp rts wdopendir: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DOpenDir lea 12(sp),sp rts wdreaddir: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DReadDir lea 12(sp),sp rts wdxreaddir: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DXReadDir lea 12(sp),sp rts wdclosedir: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DCloseDir lea 12(sp),sp rts wdrewinddir: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DRewindDir lea 12(sp),sp rts wdreadlabel: move.l a5,-(sp) move.l a4,-(sp) move.l a3,-(sp) bsr DReadLabel lea 12(sp),sp rts
Diese Assemblerfunktionen speichern die zusätzlichen Parameter der Register auf dem Stack, ohne die schon vorhandene Parameter umzusortieren. Damit findet die C Funktionen auch den Opcode der GEMDOS Funktion aus dem Trap und die Rücksprungadresse dort vor. Damit hat jede C Funktion die Parameter ldp (aus A3), pathname (aus A4), drp (aus A5), die Rücksprungadresse ret für den GEMDOS Trap und den GEMDOS Opcode. Die Parameter ret und opcode sind deshalb ohne Bedeutung und müssen ignoriert werden.
xyz(void *ldp, char *pathname, void *drp, long ret, int opcode,
Der Rumpf für eine C Implementierung würde damit wie folgt aussehen:
#include <stddef.h> #include <tos.h> #include <mintbind.h> #include <metados.h> extern initfun(); extern wdfree(), wfsfirst(), wfsnext(); extern wfopen(), wfclose(), wfdatime(); extern wfread(), wfwrite(), wfattrib(); extern wfcreate(), wfseek(), wfcntl(); extern wdpathconf(), wdopendir(), wdreaddir(); extern wdxreaddir(), wdclosedir(), wdrewinddir(); extern wfxattr(), wdreadlabel(), wfdelete(); typedef struct { } PRIVATE_DATA; /* Funktionen */ long cdecl DiskFree(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, DISKINFO *buf, int drive) { } long cdecl CreateFile(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, char *pn, int mode) { } long cdecl OpenFile(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, char *pn, int mode) { } long cdecl CloseFile(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, int handle) { } long cdecl FDelete(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, char *pn) { } long cdecl ReadFile(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, int handle, long count, void *buffer) { } long cdecl WriteFile(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, int handle, long count, void *buffer) { } long cdecl SeekFile(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, long offset, int handle, int seekmode) { } long cdecl FileAttributes(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, char *pn, int wflag, int attr) { } long cdecl SearchFirst(void *ldp, char *pathname, DTA *dta, long ret, int opcode, const char *pn, int attribs) { } long cdecl SearchNext(void *ldp, char *pathname, DTA *dta, long ret, int opcode) { } long cdecl FXAttr(void *ldp, char *pathname, DTA *dta, long ret, int opcode, int flag, const char *name, XATTR *xap) { } long cdecl DateAndTime(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, DOSTIME *timeptr, int handle, int wflag) { } long cdecl FCntl(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, int handle, void *arg, int cmd) { } long cdecl DPathConf(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, const char *path, int cmd) { } long cdecl DOpenDir(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, const char *path, int flag) { } long cdecl DCloseDir(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, long handle) { } long cdecl DRewindDir(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, long handle) { } long cdecl DXReadDir(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, int len, long handle, long *buf, XATTR *xap, long *xret) { } long cdecl DReadDir(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, int len, long handle, long *buf) { } long cdecl DReadLabel(void *ldp, char *pathname, PRIVATE_DATA *p, long ret, int opcode, const char *path, char *name, int size) { } long FunctionTable[] = { 'MAGI', 'CMET', 349, (long) initfun, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 49 */ -1L, -1L, -1L, -1L, (long) wdfree, -1L, -1L, -1L, -1L, -1L, /* 59 */ (long)wfcreate, (long)wfopen, (long)wfclose, (long)wfread, (long)wfwrite, (long)wfdelete, (long)wfseek, (long)wfattrib, -1L, -1L, /* 69 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, (long)wfsfirst, (long)wfsnext, -1L, -1L, -1L, -1L, -1L, -1L, -1L, (long)wfdatime, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 99 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 109 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 119 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 129 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 139 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 149 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 159 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 169 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 179 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 189 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 199 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 209 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 219 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 229 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 239 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 249 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 259 */ (long)wfcntl, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 269 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 279 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 289 */ -1L, -1L, (long)wdpathconf, -1L, -1L, -1L, (long)wdopendir, (long)wdreaddir, (long)wdrewinddir, (long)wdclosedir, /* 299 */ (long)wfxattr, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 309 */ -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 319 */ -1L, -1L, (long)wdxreaddir, -1L, -1L, -1L, -1L, -1L, -1L, -1L, /* 329 */ -1L, -1L, -1L, -1L, -1L, /* 334 */ -1L, -1L, -1L, (long)wdreadlabel, -1, /* 339 */ -1L, -1L, -1L, -1L, -1L, /* 344 */ -1L, -1L, -1L, -1L, -1L, /* 349 */ }; char DriverName[]="DOS-BSP"; void * cdecl InitDevice(int deviceid, int drv) { /* PRIVATE_DATA initialisieren unf zurückliefern */ return(NULL); }
English version not yet available. |