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