text/html; charset=UTF-8 Last-Modified: Fri, 02 May 2025 16:15:24 GMT Expires: Mon, 30 Apr 2035 16:15:24 GMT vegas.c « drivers « mame « src - mame - MAME - Multiple Arcade Machine Emulator
summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/vegas.c
blob: 8c8df8f57d22855dbf39c82330fc631b6ab84e19 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888 } /* Comment */
.highlight .err { color: #A61717; background-color: #E3D2D2 } /* Error */
.highlight .k { color: #080; font-weight: bold } /* Keyword */
.highlight .ch { color: #888 } /* Comment.Hashbang */
.highlight .cm { color: #888 } /* Comment.Multiline */
.highlight .cp { color: #C00; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888 } /* Comment.Single */
.highlight .cs { color: #C00; font-weight: bold; background-color: #FFF0F0 } /* Comment.Special */
.highlight .gd { color: #000; background-color: #FDD } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #A00 } /* Generic.Error */
.highlight .gh { color: #333 } /* Generic.Heading */
.highlight .gi { color: #000; background-color: #DFD } /* Generic.Inserted */
.highlight .go { color: #888 } /* Generic.Output */
.highlight .gp { color: #555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666 } /* Generic.Subheading */
.highlight .gt { color: #A00 } /* Generic.Traceback */
.highlight .kc { color: #080; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #080; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #080; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #080 } /* Keyword.Pseudo */
.highlight .kr { color: #080; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #00D; font-weight: bold } /* Literal.Number */
.highlight .s { color: #D20; background-color: #FFF0F0 } /* Literal.String */
.highlight .na { color: #369 } /* Name.Attribute */
.highlight .nb { color: #038 } /* Name.Builtin */
.highlight .nc { color: #B06; font-weight: bold } /* Name.Class */
.highlight .no { color: #036; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555 } /* Name.Decorator */
.highlight .ne { color: #B06; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #06B; font-weight: bold } /* Name.Function */
.highlight .nl { color: #369; font-style: italic } /* Name.Label */
.highlight .nn { color: #B06; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #369; font-weight: bold } /* Name.Property */
.highlight .nt { color: #B06; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #369 } /* Name.Variable */
.highlight .ow { color: #080 } /* Operator.Word */
.highlight .w { color: #BBB } /* Text.Whitespace */
.highlight .mb { color: #00D; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #00D; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #00D; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #00D; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #00D; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #D20; background-color: #FFF0F0 } /* Literal.String.Affix */
.highlight .sb { color: #D20; background-color: #FFF0F0 } /* Literal.String.Backtick */
.highlight .sc { color: #D20; background-color: #FFF0F0 } /* Literal.String.Char */
.highlight .dl { color: #D20; background-color: #FFF0F0 } /* Literal.String.Delimiter */
.highlight .sd { color: #D20; background-color: #FFF0F0 } /* Literal.String.Doc */
.highlight .s2 { color: #D20; background-color: #FFF0F0 } /* Literal.String.Double */
.highlight .se { color: #04D; background-color: #FFF0F0 } /* Literal.String.Escape */
.highlight .sh { color: #D20; background-color: #FFF0F0 } /* Literal.String.Heredoc */
.highlight .si { color: #33B; background-color: #FFF0F0 } /* Literal.String.Interpol */
.highlight .sx { color: #2B2; background-color: #F0FFF0 } /* Literal.String.Other */
.highlight .sr { color: #080; background-color: #FFF0FF } /* Literal.String.Regex */
.highlight .s1 { color: #D20; background-color: #FFF0F0 } /* Literal.String.Single */
.highlight .ss { color: #A60; background-color: #FFF0F0 } /* Literal.String.Symbol */
.highlight .bp { color: #038 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #06B; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #369 } /* Name.Variable.Class */
.highlight .vg { color: #D70 } /* Name.Variable.Global */
.highlight .vi { color: #33B } /* Name.Variable.Instance */
.highlight .vm { color: #369 } /* Name.Variable.Magic */
.highlight .il { color: #00D; font-weight: bold } /* Literal.Number.Integer.Long */
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
/*********************************************************************

    formats/st_dsk.c

    All usual Atari ST formats

*********************************************************************/

#include <cassert>

#include "formats/st_dsk.h"

st_format::st_format()
{
}

const char *st_format::name() const
{
	return "st";
}

const char *st_format::description() const
{
	return "Atari ST floppy disk image";
}

const char *st_format::extensions() const
{
	return "st";
}

bool st_format::supports_save() const
{
	return true;
}

void st_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
	uint64_t size = io_generic_size(io);
	for(track_count=80; track_count <= 82; track_count++)
		for(head_count=1; head_count <= 2; head_count++)
			for(sector_count=9; sector_count <= 11; sector_count++)
				if(size == (uint32_t)512*track_count*head_count*sector_count)
					return;
	track_count = head_count = sector_count = 0;
}

int st_format::identify(io_generic *io, uint32_t form_factor)
{
	uint8_t track_count, head_count, sector_count;
	find_size(io, track_count, head_count, sector_count);

	if(track_count)
		return 50;
	return 0;
}

bool st_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
{
	uint8_t track_count, head_count, sector_count;
	find_size(io, track_count, head_count, sector_count);

	uint8_t sectdata[11*512];
	desc_s sectors[11];
	for(int i=0; i<sector_count; i++) {
		sectors[i].data = sectdata + 512*i;
		sectors[i].size = 512;
		sectors[i].sector_id = i + 1;
	}

	int track_size = sector_count*512;
	for(int track=0; track < track_count; track++) {
		for(int head=0; head < head_count; head++) {
			io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size);
			generate_track(atari_st_fcp_get_desc(track, head, head_count, sector_count),
							track, head, sectors, sector_count, 100000, image);
		}
	}

	image->set_variant(floppy_image::DSDD);

	return true;
}

bool st_format::save(io_generic *io, floppy_image *image)
{
	int track_count, head_count, sector_count;
	get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);

	if(track_count < 80)
		track_count = 80;
	else if(track_count > 82)
		track_count = 82;

	// Happens for a fully unformatted floppy
	if(!head_count)
		head_count = 1;

	if(sector_count > 11)
		sector_count = 11;
	else if(sector_count < 9)
		sector_count = 9;

	uint8_t sectdata[11*512];
	int track_size = sector_count*512;

	for(int track=0; track < track_count; track++) {
		for(int head=0; head < head_count; head++) {
			get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
			io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
		}
	}

	return true;
}


msa_format::msa_format()
{
}

const char *msa_format::name() const
{
	return "msa";
}

const char *msa_format::description() const
{
	return "Atari MSA floppy disk image";
}

const char *msa_format::extensions() const
{
	return "msa";
}

bool msa_format::supports_save() const
{
	return true;
}

void msa_format::read_header(io_generic *io, uint16_t &sign, uint16_t &sect, uint16_t &head, uint16_t &strack, uint16_t &etrack)
{
	uint8_t h[10];
	io_generic_read(io, h, 0, 10);
	sign = (h[0] << 8) | h[1];
	sect = (h[2] << 8) | h[3];
	head = (h[4] << 8) | h[5];
	strack = (h[6] << 8) | h[7];
	etrack = (h[8] << 8) | h[9];
}

bool msa_format::uncompress(uint8_t *buffer, int csize, int usize)
{
	uint8_t sectdata[11*512];
	int src=0, dst=0;
	while(src<csize && dst<usize) {
		unsigned char c = buffer[src++];
		if(c == 0xe5) {
			if(csize-src < 3)
				return false;
			c = buffer[src++];
			int count = (buffer[src] << 8) | buffer[src+1];
			src += 2;
			if(usize-dst < count)
				return false;
			for(int i=0; i<count; i++)
				sectdata[dst++] = c;
		} else
			sectdata[dst++] = c;
	}

	if(src != csize || dst != usize)
		return false;
	memcpy(buffer, sectdata, usize);
	return true;
}

bool msa_format::compress(const uint8_t *buffer, int usize, uint8_t *dest, int &csize)
{
	int src=0, dst=0;
	while(src<usize && dst<usize) {
		unsigned char c = buffer[src++];
		int ncopy = 1;
		while(src < usize && buffer[src] == c) {
			src++;
			ncopy++;
		}
		if(ncopy > 4 || c == 0xe5) {
			if(dst+3 > usize)
				return false;
			dest[dst++] = 0xe5;
			dest[dst++] = c;
			dest[dst++] = ncopy >> 8;
			dest[dst++] = ncopy;
		} else {
			src -= ncopy-1;
			dest[dst++] = c;
		}
	}

	csize = dst;

	return dst < usize;
}

int msa_format::identify(io_generic *io, uint32_t form_factor)
{
	uint16_t sign, sect, head, strack, etrack;
	read_header(io, sign, sect, head, strack, etrack);

	if(sign == 0x0e0f &&
		(sect >= 9 && sect <= 11) &&
		(head == 0 || head == 1) &&
		strack <= etrack &&
		etrack < 82)
		return 100;
	return 0;
}

bool msa_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
{
	uint16_t sign, sect, heads, strack, etrack;
	read_header(io, sign, sect, heads, strack, etrack);

	uint8_t sectdata[11*512];
	desc_s sectors[11];
	for(int i=0; i<sect; i++) {
		sectors[i].data = sectdata + 512*1;
		sectors[i].size = 512;
		sectors[i].sector_id = i + 1;
	}

	int pos = 10;
	int track_size = sect*512;

	for(int track=strack; track <= etrack; track++) {
		for(int head=0; head <= heads; head++) {
			uint8_t th[2];
			io_generic_read(io, th, pos, 2);
			pos += 2;
			int tsize = (th[0] << 8) | th[1];
			io_generic_read(io, sectdata, pos, tsize);
			pos += tsize;
			if(tsize < track_size) {
				if(!uncompress(sectdata, tsize, track_size))
					return false;
			}
			generate_track(atari_st_fcp_get_desc(track, head, head+1, sect),
							track, head, sectors, sect, 100000, image);
		}
	}

	image->set_variant(floppy_image::DSDD);
	return true;
}


bool msa_format::save(io_generic *io, floppy_image *image)
{
	int track_count, head_count, sector_count;
	get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);

	if(track_count < 80)
		track_count = 80;
	else if(track_count > 82)
		track_count = 82;

	// Happens for a fully unformatted floppy
	if(!head_count)
		head_count = 1;

	if(sector_count > 11)
		sector_count = 11;
	else if(sector_count < 9)
		sector_count = 9;

	uint8_t header[10];
	header[0] = 0x0e;
	header[1] = 0x0f;
	header[2] = 0;
	header[3] = sector_count;
	header[4] = 0;
	header[5] = head_count-1;
	header[6] = 0;
	header[7] = 0;
	header[8] = 0;
	header[9] = track_count-1;

	io_generic_write(io, header, 0, 10);

	int pos = 10;

	uint8_t sectdata[11*512];
	uint8_t compdata[11*512];
	int track_size = sector_count*512;

	for(int track=0; track < track_count; track++) {
		for(int head=0; head < head_count; head++) {
			get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
			int csize;
			if(compress(sectdata, track_size, compdata, csize)) {
				uint8_t th[2];
				th[0] = csize >> 8;
				th[1] = csize;
				io_generic_write(io, th, pos, 2);
				io_generic_write(io, compdata, pos+2, csize);
				pos += 2+csize;
			} else {
				uint8_t th[2];
				th[0] = track_size >> 8;
				th[1] = track_size;
				io_generic_write(io, th, pos, 2);
				io_generic_write(io, sectdata, pos+2, track_size);
				pos += 2+track_size;
			}
		}
	}

	return true;
}

const floppy_format_type FLOPPY_ST_FORMAT = &floppy_image_format_creator<st_format>;
const floppy_format_type FLOPPY_MSA_FORMAT = &floppy_image_format_creator<msa_format>;
a id='n2359' href='#n2359'>2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601