fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/drivers/block/blkram.c *
7 * Created: 2004-09-17 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2004-2011 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 "blkram.h"
24
25#include <stdlib.h>
26#include <string.h>
27
28
29static
30int dsk_ram_load (disk_ram_t *ram, const char *fname)
31{
32 int r;
33 FILE *fp;
34
35 fp = fopen (fname, "rb");
36 if (fp == NULL) {
37 return (1);
38 }
39
40 r = dsk_read (fp, ram->data, 0, 512 * (uint64_t) ram->dsk.blocks);
41
42 fclose (fp);
43
44 return (r);
45}
46
47static
48int dsk_ram_read (disk_t *dsk, void *buf, uint32_t i, uint32_t n)
49{
50 disk_ram_t *ram;
51
52 ram = dsk->ext;
53
54 if ((i + n) > dsk->blocks) {
55 return (1);
56 }
57
58 memcpy (buf, ram->data + 512 * i, 512 * n);
59
60 return (0);
61}
62
63static
64int dsk_ram_write (disk_t *dsk, const void *buf, uint32_t i, uint32_t n)
65{
66 disk_ram_t *ram;
67
68 if (dsk->readonly) {
69 return (1);
70 }
71
72 ram = dsk->ext;
73
74 if ((i + n) > dsk->blocks) {
75 return (1);
76 }
77
78 memcpy (ram->data + 512 * i, buf, 512 * n);
79
80 return (0);
81}
82
83static
84void dsk_ram_del (disk_t *dsk)
85{
86 disk_ram_t *ram;
87
88 ram = dsk->ext;
89
90 free (ram->data);
91 free (ram);
92}
93
94disk_t *dsk_ram_open (const char *fname, uint32_t n, uint32_t c, uint32_t h, uint32_t s, int ro)
95{
96 disk_ram_t *ram;
97
98 ram = malloc (sizeof (disk_ram_t));
99 if (ram == NULL) {
100 return (NULL);
101 }
102
103 dsk_init (&ram->dsk, ram, n, c, h, s);
104
105 dsk_set_type (&ram->dsk, PCE_DISK_RAM);
106
107 dsk_set_readonly (&ram->dsk, ro);
108
109 ram->dsk.del = dsk_ram_del;
110 ram->dsk.read = dsk_ram_read;
111 ram->dsk.write = dsk_ram_write;
112
113 ram->data = malloc (512 * ram->dsk.blocks);
114 if (ram->data == NULL) {
115 free (ram);
116 return (NULL);
117 }
118
119 memset (ram->data, 0, 512 * ram->dsk.blocks);
120
121 if (fname != NULL) {
122 if (dsk_ram_load (ram, fname)) {
123 free (ram->data);
124 free (ram);
125 return (NULL);
126 }
127
128 dsk_set_fname (&ram->dsk, fname);
129 }
130
131 return (&ram->dsk);
132}