1 // license:BSD-3-Clause
2 // copyright-holders:Robbbert
3 /*********************************************************************
4 
5     formats/sorc_dsk.c
6 
7     Exidy Sorcerer floppy-disk images
8 
9 *********************************************************************/
10 
11 #include <cstring>
12 #include <cassert>
13 
14 #include "sorc_dsk.h"
15 #include "basicdsk.h"
16 
FLOPPY_IDENTIFY(sorc_dsk_identify)17 static FLOPPY_IDENTIFY(sorc_dsk_identify)
18 {
19 	*vote = (floppy_image_size(floppy) == 332640) ? 100 : 0;
20 	return FLOPPY_ERROR_SUCCESS;
21 }
22 
sorc_get_heads_per_disk(floppy_image_legacy * floppy)23 static int sorc_get_heads_per_disk(floppy_image_legacy *floppy)
24 {
25 	return 1;
26 }
27 
sorc_get_tracks_per_disk(floppy_image_legacy * floppy)28 static int sorc_get_tracks_per_disk(floppy_image_legacy *floppy)
29 {
30 	return 77;
31 }
32 
sorc_translate_offset(floppy_image_legacy * floppy,int track,int head,int sector)33 static uint64_t sorc_translate_offset(floppy_image_legacy *floppy, int track, int head, int sector)
34 {
35 	return 270*(16*track+sector);
36 }
37 
get_offset(floppy_image_legacy * floppy,int head,int track,int sector,bool sector_is_index,uint64_t * offset)38 static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, uint64_t *offset)
39 {
40 	uint64_t offs;
41 	/* translate the sector to a raw sector */
42 	if (!sector_is_index)
43 	{
44 		sector -= 1;
45 	}
46 	/* check to see if we are out of range */
47 	if ((head != 0) || (track < 0) || (track >= 77) || (sector < 0) || (sector >= 16))
48 		return FLOPPY_ERROR_SEEKERROR;
49 
50 	offs = sorc_translate_offset(floppy, track, head, sector);
51 	if (offset)
52 		*offset = offs;
53 	return FLOPPY_ERROR_SUCCESS;
54 }
55 
56 
57 
internal_sorc_read_sector(floppy_image_legacy * floppy,int head,int track,int sector,bool sector_is_index,void * buffer,size_t buflen)58 static floperr_t internal_sorc_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, void *buffer, size_t buflen)
59 {
60 	uint64_t offset;
61 	floperr_t err;
62 	err = get_offset(floppy, head, track, sector, sector_is_index, &offset);
63 	if (err)
64 		return err;
65 
66 	floppy_image_read(floppy, buffer, offset, buflen);
67 	return FLOPPY_ERROR_SUCCESS;
68 }
69 
70 
71 
internal_sorc_write_sector(floppy_image_legacy * floppy,int head,int track,int sector,bool sector_is_index,const void * buffer,size_t buflen,int ddam)72 static floperr_t internal_sorc_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, const void *buffer, size_t buflen, int ddam)
73 {
74 	uint64_t offset;
75 	floperr_t err;
76 
77 	err = get_offset(floppy, head, track, sector, sector_is_index, &offset);
78 	if (err)
79 		return err;
80 
81 	floppy_image_write(floppy, buffer, offset, buflen);
82 	return FLOPPY_ERROR_SUCCESS;
83 }
84 
85 
86 
sorc_read_sector(floppy_image_legacy * floppy,int head,int track,int sector,void * buffer,size_t buflen)87 static floperr_t sorc_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen)
88 {
89 	return internal_sorc_read_sector(floppy, head, track, sector, false, buffer, buflen);
90 }
91 
sorc_write_sector(floppy_image_legacy * floppy,int head,int track,int sector,const void * buffer,size_t buflen,int ddam)92 static floperr_t sorc_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
93 {
94 	return internal_sorc_write_sector(floppy, head, track, sector, false, buffer, buflen, ddam);
95 }
96 
sorc_read_indexed_sector(floppy_image_legacy * floppy,int head,int track,int sector,void * buffer,size_t buflen)97 static floperr_t sorc_read_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen)
98 {
99 	return internal_sorc_read_sector(floppy, head, track, sector, true, buffer, buflen);
100 }
101 
sorc_write_indexed_sector(floppy_image_legacy * floppy,int head,int track,int sector,const void * buffer,size_t buflen,int ddam)102 static floperr_t sorc_write_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
103 {
104 	return internal_sorc_write_sector(floppy, head, track, sector, true, buffer, buflen, ddam);
105 }
106 
sorc_get_sector_length(floppy_image_legacy * floppy,int head,int track,int sector,uint32_t * sector_length)107 static floperr_t sorc_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, uint32_t *sector_length)
108 {
109 	floperr_t err;
110 	err = get_offset(floppy, head, track, sector, false, nullptr);
111 	if (err)
112 		return err;
113 
114 	if (sector_length) {
115 		*sector_length = 270;
116 	}
117 	return FLOPPY_ERROR_SUCCESS;
118 }
119 
120 
121 
sorc_get_indexed_sector_info(floppy_image_legacy * floppy,int head,int track,int sector_index,int * cylinder,int * side,int * sector,uint32_t * sector_length,unsigned long * flags)122 static floperr_t sorc_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, uint32_t *sector_length, unsigned long *flags)
123 {
124 	sector_index += 1;
125 	if (cylinder)
126 		*cylinder = track;
127 	if (side)
128 		*side = head;
129 	if (sector)
130 		*sector = sector_index;
131 	if (flags)
132 		/* TODO: read DAM or DDAM and determine flags */
133 		*flags = 0;
134 	return sorc_get_sector_length(floppy, head, track, sector_index, sector_length);
135 }
136 
137 
FLOPPY_CONSTRUCT(sorc_dsk_construct)138 static FLOPPY_CONSTRUCT(sorc_dsk_construct)
139 {
140 	struct FloppyCallbacks *callbacks;
141 	callbacks = floppy_callbacks(floppy);
142 	callbacks->read_sector = sorc_read_sector;
143 	callbacks->write_sector = sorc_write_sector;
144 	callbacks->read_indexed_sector = sorc_read_indexed_sector;
145 	callbacks->write_indexed_sector = sorc_write_indexed_sector;
146 	callbacks->get_sector_length = sorc_get_sector_length;
147 	callbacks->get_heads_per_disk = sorc_get_heads_per_disk;
148 	callbacks->get_tracks_per_disk = sorc_get_tracks_per_disk;
149 	callbacks->get_indexed_sector_info = sorc_get_indexed_sector_info;
150 
151 	return FLOPPY_ERROR_SUCCESS;
152 }
153 
154 
155 
156 /* ----------------------------------------------------------------------- */
157 
158 LEGACY_FLOPPY_OPTIONS_START( sorcerer )
159 	LEGACY_FLOPPY_OPTION( sorc_dsk, "dsk", "Exidy Sorcerer floppy disk image", sorc_dsk_identify, sorc_dsk_construct, nullptr, nullptr)
160 LEGACY_FLOPPY_OPTIONS_END
161