1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
10 ** 2. Redistributions in binary form must reproduce the above copyright
11 ** notice, this list of conditions and the following disclaimer in the
12 ** documentation and/or other materials provided with the distribution.
14 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 ** POSSIBILITY OF SUCH DAMAGE.
27 #define USED_PLUGIN_API_VERSION 8
28 #include <devices/diskimage.h>
29 #include <proto/exec.h>
30 #include <proto/dos.h>
34 # define Uncompress uncompress
36 # include <libraries/z.h>
41 #include "device_locale.h"
42 #include <SDI_compiler.h>
43 #include "rev/diskimage.device_rev.h"
47 extern struct DiskImagePlugin dax_plugin
;
49 PLUGIN_TABLE(&dax_plugin
)
59 UBYTE
*in_buf
, *out_buf
;
62 frame_t
*frame_in_buf
;
66 struct Library
*zbase
;
69 BOOL
DAX_Init (struct DiskImagePlugin
*Self
, const struct PluginData
*data
);
70 BOOL
DAX_CheckImage (struct DiskImagePlugin
*Self
, BPTR file
, CONST_STRPTR name
, QUAD file_size
,
71 const UBYTE
*test
, LONG testsize
);
72 APTR
DAX_OpenImage (struct DiskImagePlugin
*Self
, APTR unit
, BPTR file
, CONST_STRPTR name
);
73 void DAX_CloseImage (struct DiskImagePlugin
*Self
, APTR image_ptr
);
74 LONG
DAX_Geometry (struct DiskImagePlugin
*Self
, APTR image_ptr
, struct DriveGeometry
*dg
);
75 LONG
DAX_Read (struct DiskImagePlugin
*Self
, APTR image_ptr
, struct IOStdReq
*io
);
77 struct DiskImagePlugin dax_plugin
= {
78 PLUGIN_NODE(0, "DAX"),
97 struct Library
*SysBase
;
98 struct Library
*DOSBase
;
99 static struct DIPluginIFace
*IPlugin
;
101 #define ZBase image->zbase
103 struct Library
*Z1Base
;
106 BOOL
DAX_Init (struct DiskImagePlugin
*Self
, const struct PluginData
*data
) {
107 SysBase
= data
->SysBase
;
108 DOSBase
= data
->DOSBase
;
109 IPlugin
= data
->IPlugin
;
113 #define DAX_MAGIC MAKE_ID('D','A','X',0)
115 BOOL
DAX_CheckImage (struct DiskImagePlugin
*Self
, BPTR file
, CONST_STRPTR name
, QUAD file_size
,
116 const UBYTE
*test
, LONG testsize
)
118 return testsize
>= sizeof(ULONG
) && rbe32(test
) == DAX_MAGIC
;
123 #define DAX_FRAME_SIZE 8192
124 #define MAX_NCAREAS 192
141 static inline BOOL
IsNCArea (ncarea_t
*ncareas
, ULONG frame
, ULONG count
) {
143 for (i
= 0; i
< count
; i
++) {
144 if (frame
>= ncareas
->frame
&&
145 (frame
- ncareas
->frame
) < ncareas
->size
)
153 APTR
DAX_OpenImage (struct DiskImagePlugin
*Self
, APTR unit
, BPTR file
,
157 LONG error
= NO_ERROR
;
158 LONG error_string
= NO_ERROR_STRING
;
159 IPTR error_args
[4] = {0};
160 struct DAXImage
*image
= NULL
;
163 ULONG
*offsets
= NULL
;
164 UWORD
*lengths
= NULL
;
165 ncarea_t
*ncareas
= NULL
;
168 if (FRead(file
, &dax
, 1, sizeof(dax
)) != sizeof(dax
)) {
173 if (rle32(&dax
.version
) > 1) {
174 error
= ERROR_OBJECT_WRONG_TYPE
;
178 image
= AllocVec(sizeof(*image
), MEMF_CLEAR
);
180 error
= ERROR_NO_FREE_STORE
;
185 image
->total_bytes
= rle32(&dax
.isosize
);
186 image
->block_size
= 2048;
187 image
->total_blocks
= image
->total_bytes
>> 11;
190 image
->zbase
= OpenLibrary("z1.library", 1);
191 Z1Base
= image
->zbase
;
193 image
->zbase
= OpenLibrary("z.library", 1);
195 if (!image
->zbase
|| !CheckLib(image
->zbase
, 1, 6)) {
196 error
= ERROR_OBJECT_NOT_FOUND
;
197 error_string
= MSG_REQVER
;
198 error_args
[0] = (IPTR
)"z.library";
204 nframes
= image
->total_bytes
/ DAX_FRAME_SIZE
;
205 if (image
->total_bytes
% DAX_FRAME_SIZE
) nframes
++;
206 image
->nframes
= nframes
;
208 offsets
= AllocVec(nframes
<< 2, MEMF_ANY
);
209 lengths
= AllocVec(nframes
<< 1, MEMF_ANY
);
210 image
->frames
= AllocVec(nframes
<< 3, MEMF_ANY
);
211 if (!offsets
|| !lengths
|| !image
->frames
) {
212 error
= ERROR_NO_FREE_STORE
;
216 if (FRead(file
, offsets
, 4, nframes
) != nframes
||
217 FRead(file
, lengths
, 2, nframes
) != nframes
)
223 for (i
= 0; i
< nframes
; i
++) {
224 image
->frames
[i
].offset
= rle32(&offsets
[i
]);
225 image
->frames
[i
].size
= rle16(&lengths
[i
]);
226 image
->frames
[i
].comp
= 1;
236 nncareas
= rle32(&dax
.ncareas
);
237 ncareas
= AllocVec(MAX_NCAREAS
*sizeof(*ncareas
), MEMF_ANY
);
239 error
= ERROR_NO_FREE_STORE
;
242 if (FRead(file
, ncareas
, sizeof(*ncareas
), MAX_NCAREAS
) != MAX_NCAREAS
) {
246 for (i
= 0; i
< MAX_NCAREAS
; i
++) {
247 ncareas
[i
].frame
= rle32(&ncareas
[i
].frame
);
248 ncareas
[i
].size
= rle32(&ncareas
[i
].size
);
250 for (i
= 0; i
< nframes
; i
++) {
251 if (IsNCArea(ncareas
, i
, nncareas
)) {
252 image
->frames
[i
].comp
= 0;
259 image
->in_buf
= AllocVec(DAX_FRAME_SIZE
+1024, MEMF_ANY
);
260 image
->out_buf
= AllocVec(DAX_FRAME_SIZE
, MEMF_ANY
);
261 if (!image
->in_buf
|| !image
->out_buf
) {
262 error
= ERROR_NO_FREE_STORE
;
274 Plugin_CloseImage(Self
, image
);
279 if (error
== NO_ERROR
) {
280 error
= ERROR_OBJECT_WRONG_TYPE
;
281 error_string
= MSG_EOF
;
283 IPlugin_SetDiskImageErrorA(unit
, error
, error_string
, error_args
);
288 void DAX_CloseImage (struct DiskImagePlugin
*Self
, APTR image_ptr
) {
289 struct DAXImage
*image
= image_ptr
;
291 if (image
->zbase
) CloseLibrary(image
->zbase
);
292 FreeVec(image
->in_buf
);
293 FreeVec(image
->out_buf
);
294 FreeVec(image
->frames
);
300 LONG
DAX_Geometry (struct DiskImagePlugin
*Self
, APTR image_ptr
, struct DriveGeometry
*dg
) {
301 struct DAXImage
*image
= image_ptr
;
302 dg
->dg_SectorSize
= image
->block_size
;
304 dg
->dg_TrackSectors
=
305 dg
->dg_CylSectors
= 1;
307 dg
->dg_TotalSectors
= image
->total_blocks
;
308 return IOERR_SUCCESS
;
311 LONG
DAX_Read (struct DiskImagePlugin
*Self
, APTR image_ptr
, struct IOStdReq
*io
) {
312 struct DAXImage
*image
= image_ptr
;
313 BPTR file
= image
->file
;
318 ULONG to_skip
, to_read
;
321 offset
= io
->io_Offset
;
322 buffer
= io
->io_Data
;
323 size
= io
->io_Length
;
326 i
= offset
/ DAX_FRAME_SIZE
;
327 to_skip
= offset
% DAX_FRAME_SIZE
;
328 if (i
>= image
->nframes
) return IOERR_BADADDRESS
;
330 frame
= &image
->frames
[i
];
331 io
->io_Actual
= size
;
333 if (i
>= image
->nframes
) {
334 io
->io_Actual
-= size
;
335 return IOERR_BADLENGTH
;
338 to_read
= min(size
, DAX_FRAME_SIZE
- to_skip
);
340 if (image
->frame_in_buf
!= frame
) {
342 image
->frame_in_buf
= NULL
;
343 if (!ChangeFilePosition(file
, frame
->offset
, OFFSET_BEGINNING
) ||
344 Read(file
, image
->in_buf
, frame
->size
) != frame
->size
)
346 io
->io_Actual
-= size
;
347 return IPlugin_DOS2IOErr(IoErr());
349 bytes
= DAX_FRAME_SIZE
;
350 if (Uncompress(image
->out_buf
, &bytes
, image
->in_buf
, frame
->size
) != Z_OK
) {
351 io
->io_Actual
-= size
;
352 return TDERR_NotSpecified
;
354 image
->frame_in_buf
= frame
;
356 CopyMem(image
->out_buf
+ to_skip
, buffer
, to_read
);
358 if (!ChangeFilePosition(file
, frame
->offset
+ to_skip
, OFFSET_BEGINNING
) ||
359 Read(file
, buffer
, to_read
) != to_read
)
361 io
->io_Actual
-= size
;
362 return IPlugin_DOS2IOErr(IoErr());
372 return IOERR_SUCCESS
;