-
Notifications
You must be signed in to change notification settings - Fork 1
/
cpcemu.h
95 lines (76 loc) · 3.44 KB
/
cpcemu.h
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
#ifndef CPCEMU_H
#define CPCEMU_H
#include <stdio.h>
#include "types.h"
#define CPCEMU_INFO_OFFSET 0x100
#define CPCEMU_TRACK_OFFSET 0x100
#define NUM_TRACK 40
#define NUM_SECTOR 9
#define SIZ_SECTOR 512
#define SIZ_TRACK (CPCEMU_TRACK_OFFSET + NUM_SECTOR * SIZ_SECTOR)
#define SIZ_TOTAL (NUM_TRACK * SIZ_TRACK)
extern const char *CPCEMU_HEADER_STD;
extern const char *CPCEMU_HEADER_EX;
extern const char *CPCEMU_CREATOR;
extern const char *CPCEMU_TRACK_HEADER;
/* Tightly packed disc data structures */
#pragma pack(push)
#pragma pack(1)
struct cpcemu_disc_info_s {
char header[34]; /* CPCEMU_HEADER_STD or
CPCEMU_HEADER_EX */
char creator[14]; /* Extended only */
u8 num_tracks; /* 40, 42, 80 */
u8 num_heads; /* 1, 2 */
u16 track_size; /* Standard only */
u8 track_size_table[NUM_TRACK * 2]; /* Extended only. High bytes
of track sizes */
u8 _unused1[204 - NUM_TRACK * 2];
/* - For single sided formats the table contains track sizes of just one
side, otherwise for two alternating sides.
- A size of value 0 indicates an unformatted track.
- Actual track data length = table value * 256.
- Keep in mind that the image contains additional 256 bytes for each
track info. */
};
struct cpcemu_sector_info_s {
u8 track;
u8 head;
u8 sector_id;
u8 sector_size; /* BPS (sector ID information) */
u8 FDC_status_reg1; /* state 1 error code (0) */
u8 FDC_status_reg2; /* state 2 error code (0) */
u8 _notused[2]; /* Extended only. sector data length in bytes (little
endian notation). This allows different sector
sizes in a track. It is computed as (0x0080 <<
real_BPS). */
};
struct cpcemu_track_info_s {
char header[13]; /* CPCEMU_TRACK_HEADER */
u8 _unused0[3];
u8 track_num; /* track number (0 to number of tracks-1) */
u8 head_num; /* head number (0 or 1) */
u8 _unused1[2];
/* Format track parameters */
u8 sector_size; /* BPS (bytes per sector) (2 for 0x200 bytes) */
u8 num_sectors; /* SPT (sectors per track) (9, at the most 18) */
u8 GAP3_length; /* GAP#3 format (gap for formatting; 0x4E) */
u8 filler_byte; /* Filling byte (filling byte for formatting; 0xE5) */
struct cpcemu_sector_info_s sector_info_table[29];
/* - The sector data must follow the track information block in the order of
the sector IDs. No track or sector may be omitted.
- With double sided formats, the tracks are alternating, e.g. track 0
head 0, track 0 head 1, track 1 ...
*/
};
#pragma pack(pop)
extern u8 g_sector_skew_table[NUM_SECTOR];
void read_disc_info(FILE *fp, struct cpcemu_disc_info_s *info);
void write_disc_info(FILE *fp, struct cpcemu_disc_info_s *info);
void read_track_info(FILE *fp, u8 track, struct cpcemu_track_info_s *track_info);
void write_track_info(FILE *fp, u8 track, struct cpcemu_track_info_s *track_info);
int check_disk_type(FILE *fp, u8 sector_id);
int check_extended(FILE *fp);
void read_logical_sector(FILE *fp, u8 track, u8 sector, u8 buffer[SIZ_SECTOR]);
void write_logical_sector(FILE *fp, u8 track, u8 sector, u8 buffer[SIZ_SECTOR]);
#endif