]> git.sesse.net Git - pistorm/blob - a314/a314device/device.c
Add A314 emulation
[pistorm] / a314 / a314device / device.c
1 #include <exec/types.h>
2 #include <exec/execbase.h>
3 #include <exec/devices.h>
4 #include <exec/errors.h>
5 #include <exec/ports.h>
6 #include <libraries/dos.h>
7 #include <proto/exec.h>
8
9 #include "device.h"
10 #include "a314.h"
11 #include "startup.h"
12 #include "fix_mem_region.h"
13
14 char device_name[] = A314_NAME;
15 char id_string[] = A314_NAME " 1.1 (28 Nov 2020)";
16
17 struct ExecBase *SysBase;
18 BPTR saved_seg_list;
19 BOOL running = FALSE;
20
21 static struct Library *init_device(__reg("a6") struct ExecBase *sys_base, __reg("a0") BPTR seg_list, __reg("d0") struct Library *dev)
22 {
23         SysBase = *(struct ExecBase **)4;
24         saved_seg_list = seg_list;
25
26         // We are being called from InitResident() in initializers.asm.
27         // MakeLibrary() was executed before we got here.
28
29         dev->lib_Node.ln_Type = NT_DEVICE;
30         dev->lib_Node.ln_Name = device_name;
31         dev->lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
32         dev->lib_Version = 1;
33         dev->lib_Revision = 0;
34         dev->lib_IdString = (APTR)id_string;
35
36         // AddDevice() is executed after we return.
37         return dev;
38 }
39
40 static BPTR expunge(__reg("a6") struct Library *dev)
41 {
42         // There is currently no support for unloading a314.device.
43
44         if (TRUE) //dev->lib_OpenCnt != 0)
45         {
46                 dev->lib_Flags |= LIBF_DELEXP;
47                 return 0;
48         }
49
50         /*
51         BPTR seg_list = saved_seg_list;
52         Remove(&dev->lib_Node);
53         FreeMem((char *)dev - dev->lib_NegSize, dev->lib_NegSize + dev->lib_PosSize);
54         return seg_list;
55         */
56 }
57
58 static void open(__reg("a6") struct Library *dev, __reg("a1") struct A314_IORequest *ior, __reg("d0") ULONG unitnum, __reg("d1") ULONG flags)
59 {
60         dev->lib_OpenCnt++;
61
62         if (dev->lib_OpenCnt == 1 && !running)
63         {
64                 if (!task_start())
65                 {
66                         ior->a314_Request.io_Error = IOERR_OPENFAIL;
67                         ior->a314_Request.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
68                         dev->lib_OpenCnt--;
69                         return;
70                 }
71                 running = TRUE;
72         }
73
74         ior->a314_Request.io_Error = 0;
75         ior->a314_Request.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
76 }
77
78 static BPTR close(__reg("a6") struct Library *dev, __reg("a1") struct A314_IORequest *ior)
79 {
80         ior->a314_Request.io_Device = NULL;
81         ior->a314_Request.io_Unit = NULL;
82
83         dev->lib_OpenCnt--;
84
85         if (dev->lib_OpenCnt == 0 && (dev->lib_Flags & LIBF_DELEXP))
86                 return expunge(dev);
87
88         return 0;
89 }
90
91 static void begin_io(__reg("a6") struct Library *dev, __reg("a1") struct A314_IORequest *ior)
92 {
93         PutMsg(&task_mp, (struct Message *)ior);
94         ior->a314_Request.io_Flags &= ~IOF_QUICK;
95 }
96
97 static ULONG abort_io(__reg("a6") struct Library *dev, __reg("a1") struct A314_IORequest *ior)
98 {
99         // There is currently no support for aborting an IORequest.
100         return IOERR_NOCMD;
101 }
102
103 static ULONG device_vectors[] =
104 {
105         (ULONG)open,
106         (ULONG)close,
107         (ULONG)expunge,
108         0,
109         (ULONG)begin_io,
110         (ULONG)abort_io,
111         (ULONG)translate_address_a314,
112         -1,
113 };
114
115 ULONG auto_init_tables[] =
116 {
117         sizeof(struct Library),
118         (ULONG)device_vectors,
119         0,
120         (ULONG)init_device,
121 };