fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/devices/device.c *
7 * Created: 2005-12-08 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2005-2009 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include <stdlib.h>
24#include <string.h>
25
26#include "device.h"
27
28
29void dev_init (device_t *dev, void *ext, const char *type)
30{
31 dev->next = NULL;
32 dev->refcnt = 1;
33 dev->type = type;
34
35 dev->free = NULL;
36 dev->del = NULL;
37
38 dev->clock = NULL;
39
40 dev->ext = ext;
41}
42
43void dev_free (device_t *dev)
44{
45 if ((dev != NULL) && (dev->free != NULL)) {
46 dev->free (dev);
47 }
48}
49
50device_t *dev_new (void *ext, const char *type)
51{
52 device_t *dev;
53
54 dev = malloc (sizeof (device_t));
55 if (dev == NULL) {
56 return (NULL);
57 }
58
59 dev_init (dev, ext, type);
60
61 return (dev);
62}
63
64void dev_del (device_t *dev)
65{
66 if (dev == NULL) {
67 return;
68 }
69
70 if (dev->del != NULL) {
71 dev->del (dev);
72 }
73 else {
74 dev_free (dev);
75 free (dev->ext);
76 free (dev);
77 }
78}
79
80void dev_ref (device_t *dev)
81{
82 dev->refcnt += 1;
83}
84
85void dev_unref (device_t *dev)
86{
87 dev->refcnt -= 1;
88
89 if (dev->refcnt == 0) {
90 dev_del (dev);
91 }
92}
93
94
95void dev_lst_init (dev_list_t *lst)
96{
97 lst->cnt = 0;
98 lst->head = 0;
99 lst->tail = 0;
100}
101
102void dev_lst_free (dev_list_t *lst)
103{
104 device_t *dev;
105
106 while (lst->head != NULL) {
107 dev = lst->head;
108 lst->head = lst->head->next;
109
110 dev_unref (dev);
111 }
112}
113
114void dev_lst_add (dev_list_t *lst, device_t *dev)
115{
116 if (lst->head == NULL) {
117 lst->head = dev;
118 }
119 else {
120 lst->tail->next = dev;
121 }
122
123 lst->tail = dev;
124
125 lst->cnt += 1;
126}
127
128void dev_lst_insert (dev_list_t *lst, device_t *dev)
129{
130 dev->next = lst->head;
131 lst->head = dev;
132
133 if (lst->tail == NULL) {
134 lst->tail = dev;
135 }
136}
137
138device_t *dev_lst_get (dev_list_t *lst, const char *type, unsigned idx)
139{
140 device_t *dev;
141
142 dev = lst->head;
143
144 while (dev != NULL) {
145 if (strcmp (dev->type, type) == 0) {
146 if (idx == 0) {
147 return (dev);
148 }
149 else {
150 idx -= 1;
151 }
152 }
153
154 dev = dev->next;
155 }
156
157 return (NULL);
158}
159
160void *dev_lst_get_ext (dev_list_t *lst, const char *type, unsigned idx)
161{
162 device_t *dev;
163
164 dev = dev_lst_get (lst, type, idx);
165
166 if (dev == NULL) {
167 return (NULL);
168 }
169
170 return (dev->ext);
171}
172
173void dev_lst_clock (dev_list_t *lst, unsigned n)
174{
175 device_t *dev;
176
177 dev = lst->head;
178
179 while (dev != NULL) {
180 if (dev->clock != NULL) {
181 dev->clock (dev->ext, n);
182 }
183
184 dev = dev->next;
185 }
186}