-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrelocate.c
122 lines (109 loc) · 2.53 KB
/
relocate.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
#include <stdio.h>
#include <stdbool.h>
#include "cpmimage.h"
unsigned int cksum;
const unsigned char *dataptr;
unsigned char databit;
#define TOPBIT 128
bool relocate_nextbit(void);
unsigned char relocate_nextbyte(void);
/*
* relocate2.s contains faster assembler implementations of these two functions.
*
* bool relocate_nextbit(void)
* {
* bool r;
*
* r = *dataptr & databit;
* databit = databit >> 1;
* if(databit == 0){
* databit=TOPBIT;
* dataptr++;
* }
*
* return r;
* }
*
* unsigned char relocate_nextbyte(void)
* {
* unsigned char out = 0;
* unsigned char bits = 8;
*
* while(1){
* if(relocate_nextbit())
* out |= 1;
* if(--bits == 0){
* cksum += out;
* return out;
* }
* out = out << 1;
* }
* }
*/
unsigned int relocate_read_int(unsigned char bits)
{
unsigned int out = 0;
while(1){
if(relocate_nextbit())
out |= 1;
if(--bits == 0)
return out;
out = out << 1;
}
}
unsigned int relocate_read_length(void)
{
unsigned char i;
unsigned int l;
i = 0;
while(true){
l = relocate_read_int(cpm_image_encoding[i]);
if(l){
return (l + cpm_image_offsets[i]);
}
i++;
// check for end of stream
if(cpm_image_encoding[i] == 0)
return 0;
}
}
bool relocate_cpm(unsigned char *dest)
{
unsigned char *target;
unsigned int length;
unsigned int reloc_offset;
unsigned int *r;
bool first;
reloc_offset = (unsigned int)dest;
target = dest;
dataptr = cpm_image_data;
databit = TOPBIT;
cksum = 0;
first = true;
while(length = relocate_read_length()){
if(first){
// do not relocate the first run
first = false;
}else{
// we wrote the low byte in the previous pass
// now we write the high byte;
*(target++) = relocate_nextbyte();
// then we relocate the value just written;
r = (unsigned int*)(target - 2);
*r += reloc_offset;
length--;
}
while(length--)
*(target++) = relocate_nextbyte();
}
if((unsigned int)(target - dest) != cpm_image_length){
printf("length mismatch\n");
return false;
}
if(cksum != cpm_image_cksum){
printf("checksum mismatch\n");
return false;
}
// looks OK!
return true;
}