forked from mheyer32/vasm
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoutput_pap.c
More file actions
166 lines (135 loc) · 3.62 KB
/
output_pap.c
File metadata and controls
166 lines (135 loc) · 3.62 KB
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
#include "vasm.h"
#ifdef OUTPAP
static char *copyright = "vasm MOS paper tape output module 0.1 (c) 2024 Dimitri Theulings";
static uint8_t *buffer; /* output buffer for data records */
static uint8_t buffer_s = 24; /* default buffer size */
static uint8_t buffer_i = 0; /* current index in buffer */
static uint32_t addr = 0; /* current output address */
static uint32_t lines = 0; /* number of lines in output file */
static int strict = 0; /* default not strict */
static void write_newline(FILE *f)
{
uint8_t i;
fw8(f,'\r');
fw8(f,'\n');
if(strict) /* pad file with 6 NULL chars */
for (i=0; i<6; i++)
fw8(f,0);
lines++;
}
static void write_eof_record(FILE *f)
{
uint16_t csum = (lines>>8 & 0xFF) + (lines & 0xFF);
fprintf(f, ";00%04X%04X", lines, csum);
write_newline(f);
if(strict) /* end file with XOFF */
fw8(f,19);
}
static void write_data_record(FILE *f)
{
uint32_t csum;
uint8_t i;
uint32_t start;
/* pre-flight checks */
if (buffer_i == 0)
return;
/* addr points to the next inserted byte
addr-1 is the last one written */
if (addr-1 > UINT16_MAX)
output_error(11, addr-1);
start = addr - buffer_i;
start &= 0xFFFF;
/* write data record */
fprintf(f, ";%02X%04X", buffer_i, start);
csum = buffer_i + (start>>8 & 0xFF) + (start &0xFF);
for (i = 0; i < buffer_i; i++) {
csum = (csum + buffer[i]) & 0xFFFF;
fprintf(f, "%02X", buffer[i]);
}
fprintf(f, "%04X", csum);
write_newline(f);
/* reset the buffer index */
buffer_i = 0;
}
static void buffer_data(FILE *f, uint8_t b)
{
buffer[buffer_i] = b;
buffer_i++;
addr++;
if (buffer_i == buffer_s)
write_data_record(f);
}
static void write_output(FILE *f, section *sec, symbol *sym)
{
uint32_t i, j;
section *s;
atom *a;
if (!sec)
return;
for (; sym; sym = sym->next)
if (sym->type == IMPORT)
output_error(6, sym->name); /* undefined symbol (sym->name) */
chk_sec_overlap(sec); /* fail on overlapping sections */
buffer = mymalloc(sizeof(uint8_t) * buffer_s);
for (s = sec; s; s = s->next) {
addr = s->org;
for (a = s->first; a; a = a->next) {
if (a->type == DATA) {
for (i = 0; i < a->content.db->size; i++) {
buffer_data(f, a->content.db->data[i]);
}
} else if (a->type == SPACE) {
for (i = 0; i < a->content.sb->space; i++) {
for (j = 0; j < a->content.sb->size; j++) {
buffer_data(f, a->content.sb->fill[j]);
}
}
}
}
/* flush buffer before moving on to next section */
write_data_record(f);
}
write_eof_record(f);
myfree(buffer);
}
static int parse_args(char *arg)
{
int size;
long long val;
if (!strcmp(arg, "-strict")) {
strict = 1;
return 1;
}
else if (!strncmp(arg, "-record-size=", 13)) {
size = atoi(arg + 13);
/* a PAP record (incl. header) cannot be longer than 0xFF bytes */
if (size < 1 || size > 249)
return 0;
buffer_s = size;
return 1;
}
else if (!strncmp(arg,"-start=",7)) {
sscanf(arg+7,"%lli",&val);
defsectorg = val; /* set start of default section */
return 1;
}
return 0;
}
int init_output_pap(char **cp, void (**wo)(FILE *, section *, symbol *), int (**oa)(char *))
{
if (sizeof(utaddr) > sizeof(uint32_t)) {
output_error(1, cpuname); /* output module doesn't support (cpuname) */
return 0;
}
*cp = copyright;
*wo = write_output;
*oa = parse_args;
defsecttype = emptystr; /* default section is "org 0" */
return 1;
}
#else
int init_output_pap(char **cp, void (**wo)(FILE *, section *, symbol *), int (**oa)(char *))
{
return 0;
}
#endif