/ sbt.c
sbt.c
  1  #include <string.h>
  2  #include <stdio.h>
  3  #include <stdint.h>
  4  #include <stdarg.h>
  5  #include "sbt.h"
  6  
  7  // Addresses
  8  // 0x25 [8] copy of LFSR/cryptovariable
  9  //     0x25 is set to 0x9c at the beginning of the mainloop.
 10  // 0x2d [8] LFSR/crypto variable
 11  // 0x35 [7] effective crypto variable
 12  // 0x3f [1] index into cipherblock for next byte to xor with, 0x2c..0x34
 13  // 0x7f41 [8] = cryptovariable/state
 14  // 0x72d7 [15] crypto key - keyed in via keyboard
 15  
 16  static const uint8_t SBOX[128] = {0xF4, 0xAF, 0x8A, 0xD1, 0x3B, 0x02, 0xE8, 0x20,
 17                                    0xCD, 0x65, 0x96, 0x1C, 0x47, 0xB3, 0x79, 0x5E,
 18                                    0x18, 0x8B, 0xE3, 0xAE, 0x7D, 0x4A, 0x94, 0xDF,
 19                                    0x69, 0x30, 0xBC, 0x56, 0xF5, 0x07, 0x21, 0xC2,
 20                                    0xBD, 0x72, 0x9C, 0x59, 0xAE, 0x17, 0xF3, 0x61,
 21                                    0x24, 0xC8, 0x40, 0xDF, 0xE6, 0x8A, 0x35, 0x0B,
 22                                    0x27, 0x4D, 0x56, 0xC8, 0x91, 0xB3, 0x70, 0x84,
 23                                    0xF5, 0xEF, 0xD2, 0xAE, 0x3A, 0x1C, 0x0B, 0x69,
 24                                    0x47, 0x9F, 0x80, 0x5C, 0x0A, 0x68, 0xA1, 0xEB,
 25                                    0xB9, 0x2D, 0x75, 0xF3, 0x1E, 0x32, 0xD6, 0xC4,
 26                                    0xB3, 0xAE, 0xED, 0x09, 0x91, 0xD4, 0x38, 0x26,
 27                                    0x6A, 0xC0, 0xFB, 0x75, 0x82, 0x5F, 0x4C, 0x17,
 28                                    0x59, 0x27, 0x16, 0x4D, 0xDB, 0xEF, 0x04, 0x9C,
 29                                    0xF0, 0xB8, 0x62, 0xCE, 0x3A, 0xA1, 0x73, 0x85,
 30                                    0x18, 0x5D, 0x47, 0x6E, 0xC5, 0xA0, 0x9B, 0xFA,
 31                                    0x32, 0xE3, 0x8C, 0x01, 0xDF, 0x74, 0x29, 0xB6};
 32  
 33  #define BITv(B,n) ((B >> n) & 1)
 34  #define BYTE(B7,B6,B5,B4,B3,B2,B1,B0) ((B7 << 7) | (B6 << 6) | (B5 << 5) | (B4 << 4) | (B3 << 3) | (B2 << 2) | (B1 << 1) | B0)
 35  
 36  #ifdef DO_TRACE
 37  #define TRACE(pc) if(trace) {                                        \
 38    printf("PC: %04x ", pc);                                           \
 39    for(int iter=0;iter<8;iter++) {                                    \
 40      if(iter>0 && iter%4==0)                                          \
 41        printf(" ");                                                   \
 42      printf("%02x", ctx->state[iter]); }                              \
 43    printf(" ");                                                       \
 44    for(int iter=0;iter<8;iter++) {                                    \
 45      if(iter>0 && iter%4==0)                                          \
 46        printf(" ");                                                   \
 47      printf("%02x", ctx->cipherblock[iter]); }                        \
 48    printf(" ");                                                       \
 49    for(int iter=0;iter<7;iter++) {                                    \
 50      if(iter>0 && iter%4==0)                                          \
 51        printf(" ");                                                   \
 52      printf("%02x", ctx->ctrlvar[iter]); }                            \
 53    printf("\n");}
 54  #else
 55  #define TRACE(pc) ;
 56  #endif // DO_TRACE
 57  
 58  static uint8_t assign_bit(const uint8_t dst, const int bit, const int pos) {
 59    return (dst & ~(1U << pos)) | (bit << pos);
 60  }
 61  
 62  static inline uint8_t map_sbox(const int i, const uint8_t in, const uint8_t hi_nibble) {
 63    return SBOX[(i*16) + (in & 0xf)] & (0xf << (4 * hi_nibble));
 64  }
 65  
 66  static inline uint8_t rrc(const uint8_t val, const uint8_t cf_in, uint8_t *cf_out) {
 67    *cf_out = val & 1;
 68    return (cf_in << 7) | (val >> 1);
 69  }
 70  
 71  void sbt_core(uint8_t state[8], uint8_t msgkey[7], uint8_t cipherblock[8]) { // fn_1d20
 72    // main function doing the dance called only from sbt_full() and sbt_short()
 73    // short: sbt(0x7f44, 0x30);
 74    // full:  sbt(0x7f41, 0x2d);
 75  
 76    uint8_t cf = 0;
 77    uint8_t tmp, tmp1;
 78  
 79    // step 1 - initial fill  - LFSR (1 + x^32 + x^63) 64 steps
 80    for(int i = 0; i<8; i++) {
 81      tmp = (state[0] ^ state[4]) >> 1 | (state[1] ^ state[5]) << 7;
 82      memmove(state,state+1, 7);
 83      state[7]=tmp;
 84    } // 1d3c
 85  
 86    // step 2 - fixed bit permutation
 87    cipherblock[0] = BYTE(BITv(state[4],4),BITv(state[1],5),BITv(state[3],1),BITv(state[7],6),BITv(state[0],5),BITv(state[6],0),BITv(state[5],7),BITv(state[2],3));
 88    cipherblock[1] = BYTE(BITv(state[3],2),BITv(state[0],7),BITv(state[7],1),BITv(state[1],0),BITv(state[6],3),BITv(state[4],5),BITv(state[5],4),BITv(state[2],0));
 89    cipherblock[2] = BYTE(BITv(state[7],5),BITv(state[3],3),BITv(state[1],3),BITv(state[5],1),BITv(state[0],3),BITv(state[2],4),BITv(state[6],2),BITv(state[4],1));
 90    cipherblock[3] = BYTE(BITv(state[5],5),BITv(state[3],0),BITv(state[0],1),BITv(state[4],3),BITv(state[1],6),BITv(state[6],7),BITv(state[2],2),BITv(state[7],3));
 91    cipherblock[4] = BYTE(BITv(state[2],5),BITv(state[6],4),BITv(state[4],7),BITv(state[0],6),BITv(state[5],6),BITv(state[7],7),BITv(state[3],5),BITv(state[1],2));
 92    cipherblock[5] = BYTE(BITv(state[6],5),BITv(state[4],2),BITv(state[3],6),BITv(state[5],2),BITv(state[1],7),BITv(state[2],6),BITv(state[7],4),BITv(state[0],2));
 93    cipherblock[6] = BYTE(BITv(state[5],0),BITv(state[7],2),BITv(state[1],4),BITv(state[3],4),BITv(state[4],6),BITv(state[6],1),BITv(state[0],0),BITv(state[2],1));
 94    cipherblock[7] = BYTE(BITv(state[6],6),BITv(state[0],4),BITv(state[1],1),BITv(state[7],0),BITv(state[3],7),BITv(state[2],7),BITv(state[4],0),BITv(state[5],3));
 95  
 96    // 1e30
 97    // main loop
 98    uint8_t msgkey_iter_ctrl = 0x9c; // 1e32
 99    for(int round = 0; round < 8; round++) {
100      // update control variable
101      for(int i=(msgkey_iter_ctrl & 0x80)?5:2;i!=0; i--) { // 1e35, 1e3b, 1e59
102        // msgkey_iter_ctrl has this binary value: 10011100 so 4x2
103        // and 4x5 iterations
104        cf = BITv(msgkey[3],4); // 1e44
105        for(int j=0; j<7; j++) {
106          msgkey[j] = rrc(msgkey[j], cf, &cf); // 1e4a
107        } // 1e4e
108        msgkey[3] = assign_bit(msgkey[3],cf,3); // 1e57
109      }
110      // rotate msgkey_iter_ctrl left
111      msgkey_iter_ctrl = msgkey_iter_ctrl << 1; // 1e5c .. 1e5f
112  
113      // 1e61 .. 1e8e
114      uint8_t box_perm_ctrl_words[4];
115      for(int i=0;i<4;i++) box_perm_ctrl_words[i] = state[3-i];
116      // rotate state right 8x
117      tmp = state[7];
118      memmove(state+1,state,7);
119      state[0]=tmp;
120  
121      // 1f1c
122      box_perm_ctrl_words[0] ^= BYTE(BITv(msgkey[1], 5), BITv(msgkey[4], 1), BITv(msgkey[1], 2), BITv(msgkey[5], 6), BITv(msgkey[2], 7), BITv(msgkey[5], 3), BITv(msgkey[2], 4), BITv(msgkey[5], 0));
123      box_perm_ctrl_words[1] ^= BYTE(BITv(msgkey[2], 1), BITv(msgkey[6], 5), BITv(msgkey[3], 6), BITv(msgkey[6], 2), BITv(msgkey[0], 7), BITv(msgkey[3], 3), BITv(msgkey[0], 4), BITv(msgkey[3], 0));
124      box_perm_ctrl_words[2] ^= BYTE(BITv(msgkey[0], 1), BITv(msgkey[4], 5), BITv(msgkey[1], 6), BITv(msgkey[4], 2), BITv(msgkey[1], 3), BITv(msgkey[5], 7), BITv(msgkey[1], 0), BITv(msgkey[5], 4));
125      box_perm_ctrl_words[3] ^= BYTE(BITv(msgkey[2], 5), BITv(msgkey[5], 1), BITv(msgkey[2], 2), BITv(msgkey[6], 6), BITv(msgkey[3], 7), BITv(msgkey[6], 3), BITv(msgkey[3], 4), BITv(msgkey[6], 0)); // 1f2c
126      int box_perm_index = 0; // INTMEM[0x28]
127  
128      uint8_t nib, nib2;
129      for(int i = 0; i < 4; i++) {  // 1f34
130        uint8_t box_perm_ctrl = box_perm_ctrl_words[i]; // 1f36
131        do {
132          nib = cipherblock[box_perm_index >> 1];
133          if(!(box_perm_index & 1)) {
134            nib >>= 4;
135          }
136          nib &= 0xf;
137  
138          switch(box_perm_ctrl >> 6) {
139          case(0): {
140            if((nib & 0xc) == 0) {  // 1f52
141              nib2 = cipherblock[(box_perm_index ^ 8) >> 1]; // 1f60 .. 1f64
142              if(!(box_perm_index & 1)) {
143                // swap nibbles
144                nib2 >>= 4;                                  // 1f6b
145              }
146              nib2 &= 0xf;                                   // 1f6c
147  
148              nib =   nib + (nib2  & 3);                     // 1f6f
149              nib = ((nib + (nib2 >> 2)) & 3) | 0xc;         // 1f78 .. 1f7e
150            } else {
151              nib -= 4;
152            }
153            break;
154          }
155          case(1): {
156            if((nib & 0x3) == 0) {                           // 1f94 .. 1f96
157              nib2 = cipherblock[(box_perm_index ^ 2) >> 1];
158              if(!(box_perm_index & 1)) {
159                  nib2 >>= 4;                                // 1fb3
160              }
161              nib2 &= 0xf;                                   // 1fb4
162  
163              nib >>= 2;                                     // 1fa2 .. 1fa6
164              nib =    nib + (nib2 & 3);                     // 1fb7, 1fbb
165              nib = (((nib + (nib2>>2)) & 3) << 2) | 3;      // .. 1fc8
166            } else {
167              nib-=1;                                        // 1f98 .. 1f9d
168            }
169            break;
170          }
171          case(2): {
172            if((nib & 0xc) == 0xc) {                         // 1fde .. 1fe0
173              nib2 = cipherblock[(box_perm_index ^ 4) >> 1]; // 1fe9 .. 1ff1
174              if(!(box_perm_index & 1)) {
175                nib2 >>= 4;                                  // 1ff4
176              }
177              nib2 &= 0xf;                                   // 1ff5
178  
179              nib &= 3;                                      // 1fe3 .. 1fe7
180              nib =    nib + (nib2 & 3);                     // 1ff8, 1fbb
181              nib = (((nib + (nib2>> 2))) & 3);              // 1ffe .. 2005
182            } else {
183              nib += 4;                                      // 200a .. 200e
184            }
185            break;
186          }
187          default: {
188            if((nib & 3) == 3) {                             // 2021 .. 2023
189              nib2 = cipherblock[(box_perm_index ^ 1) >> 1]; // .. 202e..2036
190              if(box_perm_index & 1) {
191                nib2 >>= 4;                                  // 2039
192              }
193              nib2 &= 0xf;                                   // 203a
194  
195              nib >>= 2;                                     // 202c
196              nib =   nib + (nib2 & 3);                      // 203d, 2041
197              nib = ((nib + (nib2>>2)) & 3) << 2;            // 2043 .. 204c
198            } else {
199              nib++;
200            }
201            break;
202          }
203          }
204          tmp = cipherblock[box_perm_index >> 1];            // 2058
205          if(!(box_perm_index & 1)) {
206            tmp &= 0xf;
207            nib <<= 4;
208          } else {
209            tmp &= 0xf0;                                     // 2063 ..
210          }
211          tmp |= nib;
212          cipherblock[box_perm_index >> 1] = tmp;            // 2068 .. 2069
213          box_perm_ctrl = (box_perm_ctrl << 2) | (box_perm_ctrl >> 6); // 2072 .. 2076
214        } while((++box_perm_index & 3) != 0);
215      }
216  
217      // step 6. fix byte permutation
218      tmp = cipherblock[0];           // 2087 ..
219      cipherblock[0] = cipherblock[3];
220      cipherblock[3] = cipherblock[4];
221      cipherblock[4] = cipherblock[6];
222      cipherblock[6] = cipherblock[7];
223      cipherblock[7] = cipherblock[2];
224      cipherblock[2] = cipherblock[1];
225      cipherblock[1] = cipherblock[5];
226      cipherblock[5] = tmp;              // .. 2097
227  
228      // step 8 nibble switch
229      tmp = BYTE(BITv(msgkey[3], 5), BITv(msgkey[6], 1), BITv(msgkey[0], 6), BITv(msgkey[3], 2),
230                 BITv(msgkey[0], 3), BITv(msgkey[4], 7), BITv(msgkey[0], 0), BITv(msgkey[4], 4));
231      for(int i = 0; i < 8; i++, tmp >>= 1) {                // 20c3, 20cc, 20cb
232        if(tmp & 1) {
233          // swap nibbles
234          cipherblock[i] = (cipherblock[i] << 4) | (cipherblock[i] >> 4); // 20c9
235        }
236      }
237      // step 10. SBOXes
238      for(int i = 0; i < 8; i++) {
239        tmp1 = map_sbox(i,cipherblock[i],0);
240        tmp = cipherblock[i];
241        cipherblock[i] = tmp1;                               // 20da
242        cipherblock[i] |= map_sbox(i,tmp >> 4,1);
243      }
244    }
245  }
246  
247  uint8_t sbt_crypt_byte(sbt_ctx *ctx, uint8_t res) { // 1cf5
248    // entry point
249    // called from: 1b77 1bea 2368 247a 261b 2731
250    //printf("\t%02x ^ %02x(%d) = %02x\n", res, cipherblock[cipherblock_idx], cipherblock_idx, res ^ cipherblock[/*r1*/cipherblock_idx]);
251    res ^= ctx->cipherblock[/*r1*/ctx->cipherblock_idx++];
252    if(ctx->cipherblock_idx == 8) {
253      sbt_core(ctx->state, ctx->ctrlvar, ctx->cipherblock);
254      //dump(ctx->cipherblock, sizeof(ctx->cipherblock), "cb: ");
255      ctx->cipherblock_idx=0;
256    }
257    return res;
258  }
259  
260  static void sbt_init(sbt_ctx *ctx, const uint8_t *nonce, const uint8_t *key) {
261    // only called from sbt_set_key()
262    // preliminary fill = key[:8] ^ intmem[0x2d:0x30]
263    //for(i=0x2d;i<0x35;i++, ptr++) {
264    for(int i=0;i<8;i++) {
265      if(i<3) {
266        ctx->cipherblock[i] ^= key[i]; // 1c91
267      } else {
268        ctx->cipherblock[i]= key[i];
269      }
270    } // 1c98
271  
272    // preliminary control (56 bits) = key[8:]
273    memcpy(ctx->ctrlvar, key+8, 7); // 1c9f
274    TRACE(0x1ca2);
275  
276    // preserve preliminary fill
277    memcpy(ctx->state, ctx->cipherblock, 8); // 1cab
278    TRACE(0x1cae);
279  
280    sbt_core(ctx->state, ctx->ctrlvar, ctx->cipherblock);
281    TRACE(0x1cb1);
282  
283    // hard coded fixed fill at 0x2c5c
284    uint8_t fixed_fill[8] = { 0xf5, 0xc0, 0x7a, 0x10, 0x8a, 0xaf, 0x17, 0xcf };
285  
286    // output of sbt_full becomes control variable
287    memcpy(ctx->ctrlvar, ctx->cipherblock, 7);
288    // initial fill becomes fixed_fill
289    memcpy(ctx->cipherblock, fixed_fill, 8); // 1cbf, 1cc4
290    TRACE(0x1cc2);
291  
292    // 0x7f41 also becomes fixed fill
293    memcpy(ctx->state, ctx->cipherblock, 8);
294    TRACE(0x1cd1)
295  
296    //dump(ctx->ctrlvar, sizeof(ctx->ctrlvar), "cv: ");
297    sbt_core(ctx->state, ctx->ctrlvar, ctx->cipherblock);
298    //dump(ctx->cipherblock, sizeof(ctx->cipherblock), "cb: ");
299    TRACE(0x1cd4);
300  
301    //memcpy(INTMEM + 0x25, nonce,3);
302    ctx->cipherblock_idx=0;
303    memcpy(ctx->state + 5, nonce, 3);
304    TRACE(0x1cf4)
305  }
306  
307  void sbt_set_key(sbt_ctx *ctx, uint8_t *nonce, const uint8_t *key) { // 1c6f
308    // entry point
309    // called from 1b42, 1bc3, 2362, 25d6
310    // input is dptr, flag is passed in the carry flag of the psw
311    // push input // 1c6f .. 1c71
312    memcpy(ctx->cipherblock, nonce, 3);
313    sbt_init(ctx, nonce, key);
314  }
315  
316  void sbt_decrypt(uint8_t *ct, const uint8_t *key) {
317    sbt_ctx ctx;
318  
319    uint8_t tmp, r2, r3;
320    uint8_t tbit, CY;
321    int dptr = 0;
322    do {
323      for(int i=6;i>0;i--) {
324        tmp = ct[dptr];
325        if(tmp == 0xfe) continue;
326        dptr++;
327        if(i==1 && tmp!=' ') {
328          printf("ERROR IN TEXT, PRESS LEFT ARROW!\n");
329          printf("dptr: %x, %c (%02x)\n", dptr, 0x40 | tmp, tmp);
330          return;
331        }
332      }
333    } while(ct[dptr]!=0xfe);
334  
335    sbt_set_key(&ctx, ct, key);
336  
337    dptr = 6; // skip first block which is a nonce
338    // see scramble.py for how the bits of *dptr and *intmem[4a..4c] are processed before output
339    // unscrambles bits
340    uint8_t buf[3];
341    do {
342      uint8_t r0 = 0;
343      for(r2 = 5; r2>0; r2--) {
344        tmp = ct[dptr];            // 1b58
345        CY=tmp<0xfe;               // set carry due to CJNE at 1b59
346        if(tmp!=0xfe) dptr++;
347        tmp--; // 1b5f dec a
348        tmp = (tmp << 4) | (tmp >> 4); // 1b60 swap a
349        for(r3 = 4;r3>0;r3--) {
350          // 1b61 rlc a
351          tbit=CY;
352          CY=tmp & 0x80;
353          tmp=(tmp<<1) | tbit;
354          // 1b62 xchg A, INTMEM[r0]
355          uint8_t tmp1 = tmp;
356          tmp=buf[r0];
357          buf[r0]=tmp1;
358          // 1b63 rrc a
359          tbit = CY;
360          CY = tmp & 1;
361          tmp = tbit | (tmp >> 1);
362          // 1b64 xchg a, intmem[r0]
363          tmp1 = tmp;
364          tmp=buf[r0];
365          buf[r0]=tmp1;
366          r0++;
367          CY=r0<3;
368          if(r0==3) r0=0;
369        }
370      }
371      for(r0 = 0;r0!=3;r0++) {
372        tmp = buf[r0]; // 1b71
373        CY=r0<2;
374        if(r0==2) {
375          // 1b75 rrc a
376          tbit=CY;
377          CY=tmp&1;
378          tmp = (tbit << 7) | (tmp >> 1);
379        }
380  
381        // 1b76 rrc a
382        tbit=CY;
383        CY=tmp&1;
384        tmp = (tbit << 7) | (tmp >> 1);
385        //printf("%d, ", tmp & 0x3f);
386        tmp = sbt_crypt_byte(&ctx, tmp);
387  
388        tmp &= 0x3f; // 1b7a
389        printf("%c", (tmp<32)?(0x40|tmp):tmp);
390      }
391    } while (ct[dptr++]!=0xfe && ct[dptr]!=' ' && ct[dptr]!=0xfe);
392    printf("\n");
393  }
394  
395  void sbt_encrypt(const uint8_t *plaintext, const uint8_t *key, const uint8_t prevcb0[5], uint8_t *output) {
396    sbt_ctx ctx;
397    // skip_print = print_output_query();
398    uint8_t tmp;
399    int optr=0;
400  
401    // get 5 values [1..16] by xoring what is in ram
402    // with the value of the 8bit reloading TL0 timer
403    // this is like a "nonce/iv" but quite predictable
404    // since this loop is static, if there are no interrupts
405    // then TL0 increases by 11 in each iteration.
406    // unless there are interrupts...
407    // see also emu-timer-1ba8.py
408  
409    // the following are "nonces" from original hw
410    // BAMLK HCAMM EGLLA LEEIC JDMNJ
411    // only the bottom nibble is "random" the top nibble is all zero
412  
413    uint8_t nonce[5]={0};
414    uint16_t dptr = 0;
415    uint8_t TL0 = 0;
416    if(prevcb0 != NULL) {
417      memcpy(nonce, prevcb0, 5);
418    }
419    for(int i = 0; i < 5; i++, dptr++, TL0+=15) {
420      tmp = TL0;
421      tmp = (nonce[dptr] ^ tmp) & 0xf;
422      tmp = tmp + 1;
423      nonce[dptr] = tmp;
424      //printf("%c", 0x40|tmp); //putc_maybe_print(tmp,skip_print);
425      output[optr++]=0x40|tmp;
426    }
427    //printf(" "); //putc_maybe_print(' ',skip_print);
428    output[optr++]=' ';
429    sbt_set_key(&ctx, nonce,key);
430    //dump(ctx.cipherblock, 8, "cb0");
431  
432    //copy result of sbt_set_key to 0x72d2
433    memcpy(nonce, ctx.cipherblock, 5); //1bc6..1bcf
434  
435    uint8_t tbit, CY;
436    dptr = 0;
437    // see sketchy.py for how the bits of *dptr and *intmem[4a..4c] are processed before ouptut
438    uint8_t buf[3]={0};
439    while(plaintext[dptr]!=0xfe) {
440      for(uint8_t r0 = 0;r0<3;r0++) {
441        tmp = plaintext[dptr];
442        if(tmp == 0xfe) {
443          tmp = 0x5f;
444        } else {
445          dptr++;
446        }
447        tmp = sbt_crypt_byte(&ctx,tmp);
448        buf[r0] = tmp;
449      }
450      // scramble output for transmission
451      // expands every 3 "bytes" - really only the lower 6 bits / byte
452      // into 5 char groups also using only 6 bits
453      uint8_t r0 = 0;
454      CY = 0; // the cjne at 1bef clears CY due to r0==0x4d
455      for(uint8_t r2 = 5; r2>0; r2--) {
456        tmp = 0; // 1bf8
457        for(uint8_t r3 = 4;r3>0;r3--) {
458          // 1bf9 xchg a, intmem[r0]
459          uint8_t tmp1 = tmp;
460          tmp=buf[r0];
461          buf[r0]=tmp1;
462  
463          // 1bfa rrc a
464          tbit = CY;
465          CY = tmp & 1;
466          tmp = tbit | (tmp >> 1);
467  
468          // 1bfb xchg a, intmem[r0]
469          tmp1 = tmp;
470          tmp=buf[r0];
471          buf[r0]=tmp1;
472  
473          // 1bfc rlc a
474          tbit=CY;
475          CY=tmp & 0x80;
476          tmp=(tmp<<1) | tbit;
477  
478          if(++r0 == 3) r0 = 0;
479        }
480        tmp++;
481        //printf("%c", 0x40|tmp); // really putc_maybe_print()
482        output[optr++]=0x40|tmp;
483        //output[optr++]=tmp;
484      }
485      //printf(" "); // really putc_maybe_print(' ')
486      output[optr++]=' ';
487    }
488    output[optr++]=0xfe;
489  }