Atari Logo
Atari Computer

Hauptseite -
Welches System? -
Hardware -
Software -
Emulatoren -
Internet
MausNet
Programmieren
Verweise
Über

MetaDOS Treiber

Home BOS Treiber Die verschiedenen Strukturen DOS Treiber

3.5 Beispiel für einen BOS Treiber

Das folgende Beispiel ist ein Minimalrumpf für einen BOS 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.

        .EXPORT bos_functions
        .IMPORT BosInit, BosDevInit
        .IMPORT BosOpen, BosClose, BosRead, BosWrite
        .IMPORT BosSeek, BosStatus, BosIoctl
        .IMPORT BosStartaudio, BosStopaudio, BosSetsongtime
        .IMPORT BosGettoc, BosDiscinfo

        TEXT
entry_point:
        ; Aktionen, die zur Initialisierung des Treibers noetig sind
        jsr     BosInit
        ; Liefere den Zeiger fuer die Initialisierung des Geraetes
        move.l  #init_device_p,d0
        rts

init_device:
        move.w  d1,-(sp)   ; DMA Kanal
        move.w  d0,-(sp)   ; physikalischen Laufwerksbuchstaben
        jsr     BosDevInit
        addq.l  #8,sp
        rts

        ; Fuer diese Functionen zeigt a0 auf den Bos Header des Geraetes
        ; Die Parameter liegen auf dem Stack ab 4(sp)
open:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosOpen
        addq.l  #4,sp
        rts

close:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosClose
        addq.l  #4,sp
        rts

read:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosRead
        addq.l  #4,sp
        rts

write:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosWrite
        addq.l  #4,sp
        rts

seek:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosSeek
        addq.l  #4,sp
        rts

status:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosStatus
        addq.l  #4,sp
        rts

ioctl:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosIoctl
        addq.l  #4,sp
        rts

startaudio:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosStartaudio
        addq.l  #4,sp
        rts

stopaudio:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosStopaudio
        addq.l  #4,sp
        rts

setsongtime:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosSetsongtime
        addq.l  #4,sp
        rts

gettoc:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosGettoc
        addq.l  #4,sp
        rts

discinfo:
        move.l  a0,-(sp)   ; META_BOS_HEADER *bosheader
        jsr     BosDiscinfo
        addq.l  #4,sp
        rts

        DATA
init_device_p:
        dc.l    init_device

bos_functions:
        dc.l    $ffffffff
        dc.l    open
        dc.l    close
        dc.l    read
        dc.l    write
        dc.l    seek
        dc.l    status
        dc.l    ioctl
        dc.l    $ffffffff
        dc.l    $ffffffff
        dc.l    $ffffffff
        dc.l    startaudio
        dc.l    stopaudio
        dc.l    setsongtime
        dc.l    gettoc
        dc.l    discinfo

        END

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 XBIOS Funktion aus dem Trap und die Rücksprungadresse dort vor. Damit hat jede C Funktion die Parameter bosheader (aus A0), die Rücksprungadresse ret für den XBIOS Trap und den XBIOS Opcode. Die Parameter ret und opcode sind deshalb ohne Bedeutung und müssen ignoriert werden.

xyz(META_BOS_HEADER *bosheader, long ret, int opcode,

Der Rumpf für eine C Implementierung würde damit wie folgt aussehen:

#include <string.h>
#include <metados.h>

extern META_BOS_FUNCTIONS bos_functions;

static META_BOS_HEADER BosHeader;

void BosInit(void)
{
}

long cdecl BosDevInit(unsigned int PhysDrive, unsigned int PhysChannel)
{
   memset(&BosHeader, 0, sizeof(BosHeader));
   BosHeader.phys_letter = PhysDrive;
   BosHeader.dma_channel = PhysChannel;
   BosHeader.functions = &bos_functions;
   strcpy(BosHeader.name, "DISKIMAGE");
   /* Liefere den BOS Header (oder einen negativen Fehlercode, falls noetig) */
   return((long)&BosHeader);
}

long cdecl BosOpen(META_BOS_HEADER *bosheader, long ret, int opcode,
                   META_DRVINFO *metaopen)
{
   metaopen->mdr_name = bosheader->name;
   metaopen->res[0] = 0;
   metaopen->res[1] = 0;
   metaopen->res[2] = 0;
   return(0);
}

long cdecl BosClose(META_BOS_HEADER *bosheader)
{
   return(0);
}

long cdecl BosRead(META_BOS_HEADER *bosheader, long ret, int opcode,
                   void *buffer, unsigned long first, unsigned short count)
{
   /* <count> Bloecke von <first> Block nach <buffer> lesen */
   return(-32);
}

long cdecl BosWrite(META_BOS_HEADER *bosheader, long ret, int opcode,
                    void *buffer, unsigned long first, unsigned short count)
{
   /* <count> Bloecke ab <first> Block von <buffer> schreiben */
   return(-32);
}

long cdecl BosSeek(META_BOS_HEADER *bosheader, long ret, int opcode,
                   unsigned long offset)
{
   /* Schreib-/Lesezeiger auf Block <offset> setzen */
   return(-32);
}

long cdecl BosStatus(META_BOS_HEADER *bosheader, long ret, int opcode,
                     META_BOS_STATUS *extended)
{
   /* Status des GEraewtss liefern. -1 = Fehler,
      bit 1: Device Busy
      bit 2: Medienwechsel
      bit 7: Timeout
      bit 15: Error
   */
   return(-32);
}

long cdecl BosIoctl(META_BOS_HEADER *bosheader, long ret, int opcode,
                    unsigned long magic, unsigned short ioctlopcode, void *buffer)
{
   /* Geraetespezifische Aktion ausfuehren */
   return(-32);
}

long cdecl BosStartaudio(META_BOS_HEADER *bosheader, long ret, int opcode,
                         unsigned short dummy, unsigned char *tracks)
{
   /* Abspielen von audio starten */
   return(-32);
}

long cdecl BosStopaudio(META_BOS_HEADER *bosheader)
{
   /* Abspielen von audio beenden */
   return(-32);
}

long cdecl BosSetsongtime(META_BOS_HEADER *bosheader, long ret, int opcode,
                          unsigned short dummy, unsigned long start, unsigned long end)
{
   /* Abspeielen von Audio starten */
   return(-32);
}

long cdecl BosGettoc(META_BOS_HEADER *bosheader, long ret, int opcode,
                     unsigned short dummy, CD_TOC_ENTRY *tocentry)
{
   /* Inhaltsverzeichnis lesen */
   return(-32);
}

long cdecl BosDiscinfo(META_BOS_HEADER *bosheader, long ret, int opcode,
                       CD_DISC_INFO *discinfo)
{
   /* Informationen ueber CD erfragen */
   return(-32);
}

Home BOS Treiber Die verschiedenen Strukturen DOS Treiber


Best viewed with any browser English version not yet available.

Änderungen und Irrtümer vorbehalten. Letzte Änderung:
14 September 2001.
Home - Mail an den Webmaster - Impressum