OpenCores
URL https://opencores.org/ocsvn/i650/i650/trunk

Subversion Repositories i650

[/] [i650/] [trunk/] [utils/] [ibm650_soap2/] [ibm650_soap2/] [ibm_codec.cpp] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 29 eightycc
//////////////////////////////////////////////////////////////////////////////////
2
// IBM 650 Reconstruction in Verilog (i650)
3
// 
4
// This file is part of the IBM 650 Reconstruction in Verilog (i650) project
5
// http:////www.opencores.org/project,i650
6
//
7
// Description: An implementation of SOAP 2 for the IBM 650.
8
// 
9
// Additional Comments: .
10
//
11
// Copyright (c) 2015 Robert Abeles
12
//
13
// This source file is free software; you can redistribute it
14
// and/or modify it under the terms of the GNU Lesser General
15
// Public License as published by the Free Software Foundation;
16
// either version 2.1 of the License, or (at your option) any
17
// later version.
18
//
19
// This source is distributed in the hope that it will be
20
// useful, but WITHOUT ANY WARRANTY; without even the implied
21
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
22
// PURPOSE.  See the GNU Lesser General Public License for more
23
// details.
24
//
25
// You should have received a copy of the GNU Lesser General
26
// Public License along with this source; if not, download it
27
// from http://www.opencores.org/lgpl.shtml
28
//////////////////////////////////////////////////////////////////////////////////
29
 
30
#include "ibm_codec.h"
31
#include <iostream>
32
#include <iomanip>
33
 
34
using namespace std;
35
 
36
// -------------------------------------------------------------------------
37
// Hollerith zone and digit punches.
38
// -------------------------------------------------------------------------
39
enum holl_zn {
40
  holl_znone,
41
  holl_z0,
42
  holl_z11,     // aka X punch
43
  holl_z12      // aka Y punch
44
};
45
enum holl_dig {
46
  holl_dnone,
47
  holl_d0,
48
  holl_d1,
49
  holl_d2,
50
  holl_d3,
51
  holl_d4,
52
  holl_d5,
53
  holl_d6,
54
  holl_d7,
55
  holl_d8,
56
  holl_d9,
57
  holl_d8_2,
58
  holl_d8_3,
59
  holl_d8_4,
60
  holl_d8_5,
61
  holl_d8_6,
62
  holl_d8_7
63
};
64
 
65
// -------------------------------------------------------------------------
66
// Glyph specification.
67
// -------------------------------------------------------------------------
68
struct glyph_spec {
69
    holl_zn  zone;
70
    holl_dig digit;
71
    int      unicode;
72
    int      ascii;
73
    int      keycode; // Qt keycode
74
    int      code650;
75
    int      bcd704;
76
    int      bcd705;
77
    int      codeset;
78
};
79
 
80
// -------------------------------------------------------------------------
81
// Not all BCD characters have readily available keyboard equivalents.
82
// To these characters, we assign a modifier plus an alphabetic key.
83
// When the keycode field is not negative, it contains the unmodified
84
// keycode of the alphabetic key that when entered with a platform-
85
// pecific modifier key will enter the unavailable code. For example,
86
// pressing alt-R on a Mac will enter the unicode 'square root' character.
87
// Pressing the modifier key with a digit, '-', or '=' key will act
88
// as a multipunch, where '-' is an 11 punch and '=' is a 12 punch.
89
//
90
// The special characters in the final group, shown below, have
91
// several alternate encodings, designated by IBM as special character
92
// arrangements A through K. Encodings A, F and H are implemented above.
93
//
94
// A - &.^-$*,%/#@
95
// B - /.^-$*,%&#@
96
// C - &.^-$*,%0#@
97
// D - -.^-$*,%/#@
98
// E - -.<./*,%&#>
99
// F - +.)-$*,(/=-
100
// G - +.^-$*,%/+-
101
// H - +.)-$*,(/='
102
// J - +.^-$*,%/#@
103
// K - +.)-$*,(/=@
104
//
105
// In addition to the standard 48 BCD encodings shown above, the 705
106
// uses 6 additional encodings, 4 for marks (tape mark, record mark,
107
// group mark, storage and drum mark), and 2 encodings for signed zeroes
108
// (plus zero, minus zero).
109
//
110
// A word about marks. Some of the BCD character codes have special meaning to
111
// early IBM business computers. The 702 and its successor machines (705, 7070)
112
// were 'character oriented', i.e., they operated on variable length BCD character
113
// strings. Mark characters ('tape mark', 'record mark', 'group mark',
114
// 'segment mark', and 'word separator') served to delineate variable length
115
// objects on tape and in memory.
116
//
117
// In fact, a six bit character can have 64 unique values. The remaining
118
// unused BCD character codes were assigned by subsequent machines until
119
// all possible codes were accounted for. Mappings between BCD and Hollerith
120
// remain stable across the IBM product line, but glyph assignment differs
121
// between systems, options, and RPQs.
122
// -------------------------------------------------------------------------
123
#define A48 cs_bcd48_a
124
#define F48 cs_bcd48_f
125
#define H48 cs_bcd48_h
126
#define BCD48 cs_bcd48
127
#define BCD64 cs_bcd64
128
 
129
static glyph_spec glyph_codes[] = {
130
//   zone        digit      unicode ascii keycd 650 704  14xx codeset(s)
131
//                                              BCD BCD  BCD
132
    {holl_znone, holl_dnone, ' ',    ' ',  -1,  00, 060, 000, BCD48},
133
    {holl_znone, holl_d0,    '0',    '0',  -1,  90, 000, 012, BCD48},
134
    {holl_znone, holl_d1,    '1',    '1',  -1,  91, 001, 001, BCD48},
135
    {holl_znone, holl_d2,    '2',    '2',  -1,  92, 002, 002, BCD48},
136
    {holl_znone, holl_d3,    '3',    '3',  -1,  93, 003, 003, BCD48},
137
    {holl_znone, holl_d4,    '4',    '4',  -1,  94, 004, 004, BCD48},
138
    {holl_znone, holl_d5,    '5',    '5',  -1,  95, 005, 005, BCD48},
139
    {holl_znone, holl_d6,    '6',    '6',  -1,  96, 006, 006, BCD48},
140
    {holl_znone, holl_d7,    '7',    '7',  -1,  97, 007, 007, BCD48},
141
    {holl_znone, holl_d8,    '8',    '8',  -1,  98, 010, 010, BCD48},
142
    {holl_znone, holl_d9,    '9',    '9',  -1,  99, 011, 011, BCD48},
143
 
144
    {holl_z12,   holl_d0,    '?',    '?',  -1,  -1, 032, 072, BCD64},  // plus zero
145
    {holl_z12,   holl_d1,    'A',    'A',  -1,  61, 021, 061, BCD48},
146
    {holl_z12,   holl_d2,    'B',    'B',  -1,  62, 022, 062, BCD48},
147
    {holl_z12,   holl_d3,    'C',    'C',  -1,  63, 023, 063, BCD48},
148
    {holl_z12,   holl_d4,    'D',    'D',  -1,  64, 024, 064, BCD48},
149
    {holl_z12,   holl_d5,    'E',    'E',  -1,  65, 025, 065, BCD48},
150
    {holl_z12,   holl_d6,    'F',    'F',  -1,  66, 026, 066, BCD48},
151
    {holl_z12,   holl_d7,    'G',    'G',  -1,  67, 027, 067, BCD48},
152
    {holl_z12,   holl_d8,    'H',    'H',  -1,  68, 030, 070, BCD48},
153
    {holl_z12,   holl_d9,    'I',    'I',  -1,  69, 031, 071, BCD48},
154
 
155
    {holl_z11,   holl_d0,    '!',    '!',  -1,  -1, 052, 052, BCD64},  // minus zero
156
    {holl_z11,   holl_d1,    'J',    'J',  -1,  71, 041, 041, BCD48},
157
    {holl_z11,   holl_d2,    'K',    'K',  -1,  72, 042, 042, BCD48},
158
    {holl_z11,   holl_d3,    'L',    'L',  -1,  73, 043, 043, BCD48},
159
    {holl_z11,   holl_d4,    'M',    'M',  -1,  74, 044, 044, BCD48},
160
    {holl_z11,   holl_d5,    'N',    'N',  -1,  75, 045, 045, BCD48},
161
    {holl_z11,   holl_d6,    'O',    'O',  -1,  76, 046, 046, BCD48},
162
    {holl_z11,   holl_d7,    'P',    'P',  -1,  77, 047, 047, BCD48},
163
    {holl_z11,   holl_d8,    'Q',    'Q',  -1,  78, 050, 050, BCD48},
164
    {holl_z11,   holl_d9,    'R',    'R',  -1,  79, 051, 051, BCD48},
165
 
166
    {holl_z0,    holl_d1,    '/',    '/',  -1,  31, 061, 021, A48+F48+H48},
167
    {holl_z0,    holl_d2,    'S',    'S',  -1,  82, 062, 022, BCD48},
168
    {holl_z0,    holl_d3,    'T',    'T',  -1,  83, 063, 023, BCD48},
169
    {holl_z0,    holl_d4,    'U',    'U',  -1,  84, 064, 024, BCD48},
170
    {holl_z0,    holl_d5,    'V',    'V',  -1,  85, 065, 025, BCD48},
171
    {holl_z0,    holl_d6,    'W',    'W',  -1,  86, 066, 026, BCD48},
172
    {holl_z0,    holl_d7,    'X',    'X',  -1,  87, 067, 027, BCD48},
173
    {holl_z0,    holl_d8,    'Y',    'Y',  -1,  88, 070, 030, BCD48},
174
    {holl_z0,    holl_d9,    'Z',    'Z',  -1,  89, 071, 031, BCD48},
175
 
176
    {holl_z12,   holl_dnone, '&',    '&',  -1,  20, 020, 060, A48},
177
    {holl_z12,   holl_dnone, '+',    '+',  -1,  20, 020, 060, F48+H48},
178
    {holl_z12,   holl_d8_3,  '.',    '.',  -1,  18, 033, 073, A48+F48+H48},
179
    {holl_z12,   holl_d8_4, L'⌑',    '^', 'L',  19, 034, 074, A48},    // unicode 'square lozenge'
180
    {holl_z12,   holl_d8_4,  ')',    ')',  -1,  19, 034, 074, F48+H48},
181
    {holl_z12,   holl_d8_5,  '[',    '[',  -1,  -1, 035, 075, BCD64},
182
    {holl_z12,   holl_d8_6,  '<',    '<',  -1,  -1, 036, 076, BCD64},
183
    {holl_z12,   holl_d8_7,L'\uF000', -1, 'G',  -1, 037, 077, BCD64},  // group mark, use uF000 for triple dagger
184
 
185
    {holl_z11,   holl_dnone, '-',    '-',  -1,  30, 040, 040, A48+F48+H48},
186
    {holl_z11,   holl_d8_3,  '$',    '$',  -1,  28, 053, 053, A48+F48+H48},
187
    {holl_z11,   holl_d8_4,  '*',    '*',  -1,  29, 054, 054, A48+F48+H48},
188
    {holl_z11,   holl_d8_5,  ']',    ']',  -1,  29, 055, 055, BCD64},
189
    {holl_z11,   holl_d8_6,  ';',    ';',  -1,  29, 056, 056, BCD64},
190
    {holl_z11,   holl_d8_7,L'\uF004', -1, 'D',  29, 057, 057, BCD64},  // delta -> unicode uppercase delta
191
 
192
    {holl_z0,    holl_d8_2, L'‡',     -1, 'R',  -1, 073, 033, BCD64},  // record mark -> double dagger
193
    {holl_z0,    holl_d8_3,  ',',    ',',  -1,  38, 073, 033, A48+F48+H48},
194
    {holl_z0,    holl_d8_4,  '%',    '%',  -1,  39, 074, 034, A48},
195
    {holl_z0,    holl_d8_4,  '(',    '(',  -1,  39, 074, 034, F48+H48},
196
    {holl_z0,    holl_d8_5,L'\u2423', -1, 'W',  -1, 075, 035, BCD64},  // word separator -> open box
197
    {holl_z0,    holl_d8_6, '\\',    '\\', -1,  -1, 076, 036, BCD64},  // left oblique
198
    {holl_z0,    holl_d8_7,L'\u29FB', -1, 'S',  -1, 077, 037, BCD64},  // segment mark -> triple plus
199
 
200
    {holl_znone, holl_d8_2,L'\u2422',' ', ' ',  -1, 060, 020, BCD64},  // alternate blank
201
    {holl_znone, holl_d8_3,  '#',    '#',  -1,  48, 013, 013, A48},
202
    {holl_znone, holl_d8_3,  '=',    '=',  -1,  48, 013, 013, F48+H48},
203
    {holl_znone, holl_d8_4,  '@',    '@',  -1,  49, 014, 014, A48},
204
    {holl_znone, holl_d8_4,  '-',    '-',  -1,  49, 014, 014, F48},    // FORTRAN's other minus
205
    {holl_znone, holl_d8_4,  '\'',   '\'', -1,  49, 014, 014, H48},
206
    {holl_znone, holl_d8_5,  ':',    ':',  -1,  -1, 015, 015, BCD64},  // colon
207
    {holl_znone, holl_d8_6,  '>',    '>',  -1,  -1, 016, 016, BCD64},  // greater than
208
    {holl_znone, holl_d8_7, L'√',     -1, 'T',  -1, 017, 017, BCD64}   // radical
209
};
210
 
211
static uint16_t make_holl(int z, int d)
212
{
213
    uint16_t h = 0;
214
    switch (z) {
215
        case holl_znone:
216
            break;
217
        case holl_z0:
218
            h += (1 << 9);
219
            break;
220
        case holl_z11:
221
            h += (1 << 10);
222
            break;
223
        case holl_z12:
224
            h += (1 << 11);
225
            break;
226
        default:
227
            break;
228
    }
229
    switch (d) {
230
        case holl_dnone:
231
            break;
232
        case holl_d0:
233
            h += (1 << 9);
234
            break;
235
        case holl_d1:
236
            h += (1 << 8);
237
            break;
238
        case holl_d2:
239
            h += (1 << 7);
240
            break;
241
        case holl_d3:
242
            h += (1 << 6);
243
            break;
244
        case holl_d4:
245
            h += (1 << 5);
246
            break;
247
        case holl_d5:
248
            h += (1 << 4);
249
            break;
250
        case holl_d6:
251
            h += (1 << 3);
252
            break;
253
        case holl_d7:
254
            h += (1 << 2);
255
            break;
256
        case holl_d8:
257
            h += (1 << 1);
258
            break;
259
        case holl_d9:
260
            h += (1 << 0);
261
            break;
262
        case holl_d8_2:
263
            h += (1 << 1) + (1 << 7);
264
            break;
265
        case holl_d8_3:
266
            h += (1 << 1) + (1 << 6);
267
            break;
268
        case holl_d8_4:
269
            h += (1 << 1) + (1 << 5);
270
            break;
271
        case holl_d8_5:
272
            h += (1 << 1) + (1 << 4);
273
            break;
274
        case holl_d8_6:
275
            h += (1 << 1) + (1 << 3);
276
            break;
277
        case holl_d8_7:
278
            h += (1 << 1) + (1 << 2);
279
            break;
280
        default:
281
            break;
282
    }
283
    return h;
284
}
285
 
286
void ibm_codec::setup_tables(int c) {
287
    hollerith_to_code650_.resize(4096);
288
    code650_to_hollerith_.resize(100);
289
    hollerith_to_unicode_.resize(4096);
290
    unicode_to_hollerith_.resize(65536);
291
    hollerith_to_ascii_  .resize(4096);
292
    ascii_to_hollerith_  .resize(256);
293
    ascii_to_code650_    .resize(256);
294
    code650_to_ascii_    .resize(100);
295
    keycode_to_unicode_  .resize(256);
296
 
297
    // mark all translations invalid (-1)
298
    for (int i = 0; i < 65536; i++) {
299
        unicode_to_hollerith_[i] = -1;
300
        if (i < 4096) {
301
            hollerith_to_code650_[i] = -1;
302
            hollerith_to_unicode_[i] = -1;
303
            hollerith_to_ascii_[i]   = -1;
304
        }
305
        if (i < 256) {
306
            ascii_to_code650_[i]     = -1;
307
            ascii_to_hollerith_[i]   = -1;
308
            keycode_to_unicode_[i]   = -1;
309
        }
310
        if (i < 100) {
311
            code650_to_hollerith_[i] = -1;
312
            code650_to_ascii_[i]     = -1;
313
        }
314
    }
315
 
316
    // Fill in glyphs from table that are in the specified codeset(s).
317
    // When multiple glyphs map to the same codepoint, the first
318
    // glyph encoutered in the table occupying a codepoint takes
319
    // precedence.
320
    for (auto glyph : glyph_codes) {
321
        if (!(glyph.codeset & c)) continue;
322
        uint16_t hcode = make_holl(glyph.zone, glyph.digit);
323
        if (hollerith_to_code650_[hcode] < 0)
324
            hollerith_to_code650_[hcode] = glyph.code650;
325
        if (code650_to_hollerith_[glyph.code650] < 0)
326
            code650_to_hollerith_[glyph.code650] = hcode;
327
        if (hollerith_to_unicode_[hcode] < 0)
328
            hollerith_to_unicode_[hcode] = glyph.unicode;
329
        if (unicode_to_hollerith_[glyph.unicode] < 0)
330
            unicode_to_hollerith_[glyph.unicode] = hcode;
331
        if (keycode_to_unicode_[glyph.keycode] < 0)
332
            keycode_to_unicode_[glyph.keycode] = glyph.unicode;
333
        if (hollerith_to_ascii_[hcode] < 0)
334
            hollerith_to_ascii_[hcode] = glyph.ascii;
335
        if (ascii_to_hollerith_[glyph.ascii] < 0)
336
            ascii_to_hollerith_[glyph.ascii] = hcode;
337
        if (ascii_to_code650_[glyph.ascii] < 0)
338
            ascii_to_code650_[glyph.ascii] = glyph.code650;
339
        if (code650_to_ascii_[glyph.code650] < 0)
340
            code650_to_ascii_[glyph.code650] = glyph.ascii;
341
    }
342
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.