fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 186 lines 3.6 kB view raw
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}