GE-115 Emulator
An Emulator of the General Electrics GE-115 computer
binimage.c
Go to the documentation of this file.
1/*
2 * binimage.c — read/write the GE-120 unified binary format.
3 *
4 * See binimage.h for the header layout. All multi-byte header fields are
5 * big-endian (machine-native order). Standalone: no gemu/gasm/gdis headers.
6 */
7
8#include "binimage.h"
9
10int binimage_write(FILE *fp, uint16_t origin, uint16_t entry,
11 const uint8_t *img, uint16_t len)
12{
13 uint8_t hdr[BINIMAGE_HDR_SIZE];
14
15 if (!fp)
16 return BINIMAGE_E_IO;
17 if ((uint32_t)origin + (uint32_t)len > 0x10000u)
18 return BINIMAGE_E_RANGE;
19
20 hdr[0] = BINIMAGE_MAGIC0;
21 hdr[1] = BINIMAGE_MAGIC1;
22 hdr[2] = BINIMAGE_MAGIC2;
23 hdr[3] = BINIMAGE_MAGIC3;
24 hdr[4] = BINIMAGE_VERSION;
25 hdr[5] = 0x00; /* flags */
26 hdr[6] = (uint8_t)(origin >> 8);
27 hdr[7] = (uint8_t)(origin & 0xff);
28 hdr[8] = (uint8_t)(entry >> 8);
29 hdr[9] = (uint8_t)(entry & 0xff);
30 hdr[10] = (uint8_t)(len >> 8);
31 hdr[11] = (uint8_t)(len & 0xff);
32
33 if (fwrite(hdr, 1, sizeof(hdr), fp) != sizeof(hdr))
34 return BINIMAGE_E_IO;
35 if (len && fwrite(img, 1, len, fp) != (size_t)len)
36 return BINIMAGE_E_IO;
37
38 return BINIMAGE_OK;
39}
40
41int binimage_read(FILE *fp, uint16_t *origin, uint16_t *entry,
42 uint8_t *buf, size_t bufcap, uint16_t *len)
43{
44 uint8_t hdr[BINIMAGE_HDR_SIZE];
45 uint16_t o, e, n;
46
47 if (!fp)
48 return BINIMAGE_E_IO;
49
50 if (fread(hdr, 1, sizeof(hdr), fp) != sizeof(hdr))
52
53 if (hdr[0] != BINIMAGE_MAGIC0 || hdr[1] != BINIMAGE_MAGIC1 ||
54 hdr[2] != BINIMAGE_MAGIC2 || hdr[3] != BINIMAGE_MAGIC3)
55 return BINIMAGE_E_MAGIC;
56
57 if (hdr[4] != BINIMAGE_VERSION)
58 return BINIMAGE_E_VERSION;
59
60 o = (uint16_t)((hdr[6] << 8) | hdr[7]);
61 e = (uint16_t)((hdr[8] << 8) | hdr[9]);
62 n = (uint16_t)((hdr[10] << 8) | hdr[11]);
63
64 if ((uint32_t)o + (uint32_t)n > 0x10000u)
65 return BINIMAGE_E_RANGE;
66 if ((size_t)n > bufcap)
67 return BINIMAGE_E_TOOBIG;
68
69 if (n && fread(buf, 1, n, fp) != (size_t)n)
71
72 if (origin) *origin = o;
73 if (entry) *entry = e;
74 if (len) *len = n;
75
76 return BINIMAGE_OK;
77}
78
79const char *binimage_strerror(int code)
80{
81 switch (code) {
82 case BINIMAGE_OK:
83 return "ok";
84 case BINIMAGE_E_IO:
85 return "I/O error";
87 return "bad magic (not a GE12 unified image)";
89 return "unsupported format version";
91 return "truncated header or image";
93 return "image larger than buffer";
95 return "origin + length exceeds 64 KiB";
96 default:
97 return "unknown error";
98 }
99}
int binimage_write(FILE *fp, uint16_t origin, uint16_t entry, const uint8_t *img, uint16_t len)
Definition binimage.c:10
const char * binimage_strerror(int code)
Definition binimage.c:79
int binimage_read(FILE *fp, uint16_t *origin, uint16_t *entry, uint8_t *buf, size_t bufcap, uint16_t *len)
Definition binimage.c:41
@ BINIMAGE_E_VERSION
Definition binimage.h:50
@ BINIMAGE_OK
Definition binimage.h:47
@ BINIMAGE_E_IO
Definition binimage.h:48
@ BINIMAGE_E_RANGE
Definition binimage.h:53
@ BINIMAGE_E_MAGIC
Definition binimage.h:49
@ BINIMAGE_E_TRUNCATED
Definition binimage.h:51
@ BINIMAGE_E_TOOBIG
Definition binimage.h:52
#define BINIMAGE_MAGIC2
Definition binimage.h:40
#define BINIMAGE_VERSION
Definition binimage.h:42
#define BINIMAGE_HDR_SIZE
Definition binimage.h:43
#define BINIMAGE_MAGIC0
Definition binimage.h:38
#define BINIMAGE_MAGIC1
Definition binimage.h:39
#define BINIMAGE_MAGIC3
Definition binimage.h:41