-
Notifications
You must be signed in to change notification settings - Fork 1
/
dld.c
166 lines (135 loc) · 4.31 KB
/
dld.c
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
#if 0
/*===========================================================================
D L D . C
Declarations and definitions:
Rockwell 6502 format records.
The data is recorded as a series of ASCII records. The format of the
records is as follows:
;ccaaaadddd...chks
where ";" is the record sentinal, "cc" is the count of the number of binary
bytes of data in the record, "aaaa" is the 16 bit load address of byte 0
in the record, "dd" are bytes of data and "chks" is the 16-bit checksum
of the count, address, and data converted to bytes.
All binary bytes in the record are checksumed with 8-bit precision
including the count and each byte of the 2 byte load address, and the type
field. All values are expressed in hex and there is 1 ASCII character for
each 4 bit nibble.
Whitespace is ignored.
Copyright 1989 Atari Games. All rights reserved.
Author: Lyle Rains
---------------------------------------------------------------------------
Revision history:
---------------------------------------------------------------------------
Known bugs/features/limitations:
===========================================================================*/
#endif
/* #define SHOSTUFF */
#include "mixit.h"
/*==========================================================================*/
int GetRec_dld(InRecord *rec)
{
int cnt, datacnt, chk, c;
uchar *inbuf = rec->recBuf;
uchar * lookahead,*bufend,*data;
if ( fgets((char *)inbuf, rec->recBufLen, rec->recFile) == NULL )
{
rec->recLen = 0;
return (rec->recType = feof(rec->recFile) ? REC_EOF : REC_ERR);
}
/* Convert to 'pure' hexidecimal record: purge everything until a ';',
* squeeze out junk, and quit when you find end of record.
*/
lookahead = bufend = inbuf;
c = 0;
while ( *lookahead != 0 )
{
if ( c )
{
if ( isxdigit(*bufend = *lookahead) )
++bufend;
}
else if ( *lookahead == ';' )
c = 1;
++lookahead;
}
if ( (cnt = bufend - inbuf) == 0 )
{
rec->recLen = 0;
return (rec->recType = REC_UNKNOWN)/* empty line */;
}
cnt /= 2;
/* Convert to byte string. */
SHOW( *bufend = 0;
fputs((char *)inbuf, errFile);
putc('\n', errFile);
)
strtobytes(inbuf, cnt);
bufend = inbuf + cnt;
SHOW( for ( data = inbuf; data < bufend; ++data )
fprintf(errFile, "%.2X", *data);
putc('\n', errFile);
)
/* Get count, addr, and record type. */
datacnt = inbuf[0];
rec->recSAddr = bytestoaddr(&inbuf[1], 2);
SHOW( fprintf(errFile, "addr = %.4X\n", rec->recSAddr);
)
/* Verify record length and checksum. */
if ( datacnt > cnt - 5 /* 1-byte count, 2-byte addr, 2-bytes chksum */ )
{
moan("Record length error (sez %d, is %d)", datacnt, cnt - 5);
rec->recLen = 0;
return (rec->recType = REC_ERR);
}
chk = 0;
for ( data = inbuf; data < bufend - 2; ++data )
chk += *data;
SHOW( fprintf(errFile, "chk = 0x%.2X\n", chk);
)
if ( (LogicalAddr)(chk & 0xFFFF) != bytestoaddr(bufend - 2, 2) )
{
moan("Checksum error");
rec->recLen = 0;
return (rec->recType = REC_ERR);
}
rec->recLen = datacnt;
rec->recData = inbuf + 3 /* skip header */;
rec->recEAddr = rec->recSAddr+datacnt-1;
return (rec->recType = datacnt ? REC_DATA : REC_UNKNOWN /* EOF record */);
} /* end GetRec_dld */
/*==========================================================================*
* Outputs a single record in DLD format.
*==========================================================================*/
int PutRec_dld(FILE *file, uchar *data, int recsize, ulong recstart)
{
int j;
char *cp;
char outbuf[512];
uint cksum;
#if 0
int recbytes;
recbytes = recsize + 3;
#endif
cp = outbuf;
sprintf(cp, ";%02X%04lX", recsize, recstart & 0xFFFF);
cp += strlen(cp);
/* Append data to the record */
cksum = recsize + ((recstart >> 8) & 0xFF) + (recstart & 0xFF);
for ( j = 0; j < recsize; ++j )
{
cksum += *data;
cp = to_hex(*data++, cp);
} /* end each record */
/* Append the checksum */
sprintf(cp, "%04X\n", cksum & 0xFFFF);
fputs(outbuf, file); /* Output the record to the file */
return 1;
} /* end PutRec_dld */
/*==========================================================================*
* Outputs all footer information required by a DLD format file.
*==========================================================================*/
int PutFoot_dld(FILE *file)
{
fputs(";0000000000\n", file);
return 1;
} /* end PutFoot_dld */