*** empty log message ***
[h316.git] / pc-tools / ldc2 / src / tape_block.cpp
1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <string.h>
4
5 #include "tape_block.hh"
6 #include "data_block.hh"
7
8 #include "silent_code.hh"
9 #include "hw_constants.hh"
10
11 tape_block::tape_block()
12 {
13 }
14
15 tape_block::tape_block(tape_block & org){
16 block_type=org.block_type;
17 init_state=org.init_state;
18 data_read=org.data_read;
19 raw_data=0;
20 raw_size=org.raw_size;
21 word_data=0;
22 word_size=org.word_size;
23 if (raw_size){
24 raw_data=(unsigned char *)malloc(raw_size);
25 memcpy(raw_data,org.raw_data,raw_size);
26 }
27 if (word_size){
28 word_data=(unsigned short *)malloc(word_size*sizeof(unsigned short));
29 memcpy(word_data,org.word_data,word_size*sizeof(unsigned short));
30 }
31 }
32
33 tape_block::tape_block (int fd,
34 void(*input_start)(void *),
35 void (*input_stop)(void *),
36 void * start_stop_arg
37 )
38 {
39 unsigned char buffer;
40 int retval;
41 int eot_needed=EOT_LENGTH;
42 int eob_needed=EOB_LENGTH;
43 int block_complete=0;
44
45 block_type= TBT_DISCARD;
46 init_state= TBS_DEFAULT;
47 data_read = 0;
48 raw_data = 0;
49 raw_size = 0;
50 word_data = 0;
51 word_size = 0;
52
53 if (input_start) input_start (start_stop_arg);
54
55 /* Look for block start in input stream */
56 do {
57 retval=read(fd, &buffer, 1);
58 if (retval == 0){ // End of file
59 block_type=TBT_DISCARD;
60 init_state=TBS_EOF_LEGAL;
61 return;
62 }
63 if (retval == -1){ // Error reading from fd
64 block_type=TBT_DISCARD;
65 init_state=TBS_IOERR;
66 return;
67 }
68 data_read++;
69
70 /* Look for end ot tape sequence */
71 switch(eot_needed){
72 case 3:
73 if (buffer==EOT_SEQ_1) eot_needed--;
74 else eot_needed=EOT_LENGTH;
75 break;
76 case 2:
77 if (buffer==EOT_SEQ_2) eot_needed--;
78 else eot_needed=EOT_LENGTH;
79 break;
80 case 1:
81 if (buffer==EOT_SEQ_3){
82 raw_data=(unsigned char*)malloc(3);
83 raw_size=3;
84 raw_data[0]=EOT_SEQ_1;
85 raw_data[1]=EOT_SEQ_2;
86 raw_data[2]=EOT_SEQ_3;
87 block_type =TBT_EOT;
88 init_state =TBS_OK;
89 return;
90 }
91 else eot_needed=EOT_LENGTH;
92 break;
93 }
94 } while (buffer != (unsigned char) BLOCK_START_DELIMITER);
95
96
97 /* Now input the block data */
98 block_complete = 0;
99 do {
100 retval = read (fd, &buffer, 1);
101
102 if (retval == 0){ // End of file
103 block_type=TBT_DISCARD;
104 init_state=TBS_EOF_ILLEGAL;
105 return;
106 }
107 if (retval == -1){ // Error reading from fd
108 block_type=TBT_DISCARD;
109 init_state=TBS_IOERR;
110 return;
111 }
112 data_read++; // We have consumed a byte
113
114 /* sort in the new byte */
115 raw_size++;
116 raw_data=(unsigned char*)realloc(raw_data,raw_size);
117 raw_data[raw_size-1]=buffer;
118
119 /* Look for end ot block sequence */
120 switch(eob_needed){
121 case 2:
122 if (buffer==BLOCK_END_DELIMITER_1) eob_needed--;
123 else eob_needed=EOB_LENGTH;
124 break;
125 case 1:
126 if (buffer==BLOCK_END_DELIMITER_2){
127 raw_size-=EOB_LENGTH; // Don't want the delimiter(s) in the data!
128 raw_data=(unsigned char*)realloc(raw_data,raw_size);
129 block_complete=1;
130 }
131 else eob_needed=EOB_LENGTH;
132 break;
133 }
134 }while (!block_complete);
135 if (input_stop) input_stop (start_stop_arg);
136
137 /* Now we have the data in. */
138
139 if (init_words()!=0){
140 init_state=TBS_CHECKSUM;
141 return;
142 }
143
144 if (test_checksum()!=0){
145 init_state=TBS_CHECKSUM;
146 return;
147 }
148
149 block_type=TBT_DATA;
150 init_state=TBS_OK;
151 }
152
153 tape_block::~tape_block(){
154 free(raw_data);
155 free(word_data);
156 }
157
158 tape_block::tb_state_t tape_block::get_state(){
159 return init_state;
160 }
161
162 int tape_block::get_raw_size(){
163 return raw_size;
164 }
165
166 unsigned char * tape_block::get_raw_data(){
167 return raw_data;
168 }
169
170 int tape_block::get_type(){
171 int result=block_type;
172 if (block_type==TBT_DATA){
173 data_block * mb=new data_block(*this);
174 result=mb->get_type();
175 }
176 return result;
177 }
178
179 int tape_block::get_subtype(){
180 int result=0;
181 if (block_type==TBT_DATA){
182 data_block * mb=new data_block(*this);
183 result=mb->get_subtype();
184 }
185 return result;
186 }
187
188 int tape_block::init_words(){
189 word_size=raw_size/3;
190 if (word_size<MINIMUM_DATA_BLOCK_WORDSIZE) return 1; // Block too short!
191 word_data=(unsigned short *)malloc(raw_size*sizeof(unsigned short));
192 for (int pos=0; pos<word_size; pos++)
193 word_data[pos]=combine466(raw_data+3*pos);
194 return 0;
195 }
196
197 int tape_block::test_checksum(){
198 unsigned short sum=0;
199 for (int pos=0; pos<word_size-1;pos++)
200 // sum^=word_data[pos];
201 sum+=word_data[pos];
202
203 // printf("cs:%04x\n",word_data[word_size-1]);
204 if (sum==word_data[word_size-1]) return 0;
205 else return 1;
206 }