write large array to binary file

i have built a bread board computer and am currently at the point of programming the instruction logic. i have built an array to define all my instructions. this is very much based on Ben Eaters you tube series and i have adapted much of his code. however, the code was originally designed for an Arduino app and my modifications made it too large to program the eeproms using an Arduino. i then decided to order the TL866II eeprom programmer and load the eeproms that way, but i need tho have the data save on a binary file. so now i have transferred everything over to c++, i think i have all of the array data set up properly, but i cant quite figure out how to write the array to a binary file. i have tried a few things but i lack the general understanding of writing files and am having trouble fitting code to my application

i need to write the 4 byte array split up across 4 1 byte files, i know a bit-shift loop could be made but i am first just trying to get a write function working, in the past on the Arduino i just manually shifted the bytes and ran the program.

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
 #include <iostream>
#include <fstream>

using namespace std;


}
#define HALT      0b10000000000000000000000000000000 // HALT
#define MICRST    0b01000000000000000000000000000000 // MICRO COUNTER RST
#define INSRIN    0b00100000000000000000000000000000 // INST. REG. IN
#define SUMOUT    0b00010000000000000000000000000000 // SUM OUT
#define BLANK     0b00001000000000000000000000000000 //
#define BREGIN    0b00000100000000000000000000000000 // B REG IN
#define LDBSHU    0b00000010000000000000000000000000 // LOAD B SHIFT UP
#define LDBSHD    0b00000001000000000000000000000000 // LOAD B SHIFT DOWN
#define SUBINV    0b00000000100000000000000000000000 // SUBTRACT INVERT
#define AREGIN    0b00000000010000000000000000000000 // A REG IN
#define LDASHD    0b00000000001000000000000000000000 // LOAD A SHIFT DOWN
#define LDASHU    0b00000000000100000000000000000000 // LOAD A SHIFT UP
#define BLANK     0b00000000000010000000000000000000 //
#define BLANK     0b00000000000001000000000000000000 //
#define FLAGEN    0b00000000000000100000000000000000 // FLAGS ENABLE
#define ALUCIN    0b00000000000000010000000000000000 // ADDER CARRY IN
#define BLANK     0b00000000000000001000000000000000 //
#define DSPRIN    0b00000000000000000100000000000000 // DISPLAY REG IN
#define MEMCTI    0b00000000000000000010000000000000 // MEM COUNT IN
#define MEMCTO    0b00000000000000000001000000000000 // MEM COUNT OUT
#define MEMCTU    0b00000000000000000000100000000000 // MEM COUNT UP
#define MEMADI    0b00000000000000000000010000000000 // MEM ADDR. IN
#define MEMLD     0b00000000000000000000001000000000 // MEM LOAD
#define MEMWRT    0b00000000000000000000000100000000 // MEM WRITE
#define PSTPCT    0b00000000000000000000000010000000 // PGM STEP COUNT UP
#define SELPGM    0b00000000000000000000000001000000 // PGM NO. IN
#define PGMSTI    0b00000000000000000000000000100000 // PGM STEP IN
#define PINSTO    0b00000000000000000000000000010000 // PGM INSTR. OUT
#define UIHIOU    0b00000000000000000000000000001000 // USER INPUT UPPER OUT
#define UILOOU    0b00000000000000000000000000000100 // USER INPUT LOWER OUT

#define FLAGS_U0N0Z0C0 0  // NO FLAGS
#define FLAGS_U0N0Z0C1 1  // ALU CARRY OUT FLAG
#define FLAGS_U0N0Z1C0 2  // ALU ZERO FLAG
#define FLAGS_U0N0Z1C1 3  // NOT USED, ERROR
#define FLAGS_U0N1Z0C0 4  // ALU NEGATIVE FLAG
#define FLAGS_U0N1Z0C1 5  // NOT USED, ERROR
#define FLAGS_U0N1Z1C0 6  // NOT USED, ERROR
#define FLAGS_U0N1Z1C1 7  // NOT USED, ERROR
#define FLAGS_U1N0Z0C0 8  // UNDEFINED FLAG
#define FLAGS_U1N0Z0C1 9  // NOT USED, ERROR
#define FLAGS_U1N0Z1C0 10 // NOT USED, ERROR
#define FLAGS_U1N0Z1C1 11 // NOT USED, ERROR
#define FLAGS_U1N1Z0C0 12 // NOT USED, ERROR
#define FLAGS_U1N1Z0C1 13 // NOT USED, ERROR
#define FLAGS_U1N1Z1C0 14 // NOT USED, ERROR
#define FLAGS_U1N1Z1C1 15 // NOT USED, ERROR


#define Jumpifcarry     0b11111100 //
#define Jumpifzero      0b11111101
#define Jumpifneg       0b11111110
#define Jumpifundefined 0b11111111


first part of code
Last edited on

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



uint32_t BASE_TEMPLATE[256][16] = {
 { INSRIN|PSTPCT|PINSTO,          HALT|MICRST|SELPGM|PGMSTI|UIHIOU,                   0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0000 - 01 HALT + LOAD PGM
 { INSRIN|PSTPCT|PINST            HALT|AREGIN|LDASHD|LDASHU|UIHIOU,                   MICRST|BREGIN|LDBSHU|LDBSHD|UILOOU,         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0001 - 02 HALT + LOAD A+B
 { INSRIN|PSTPCT|PINSTO,          HALT|MICRST|BREGIN|LDBSHU|LDBSHD|UIHIOU,            0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0010 - 03 HALT + LOAD B ONLY
 { INSRIN|PSTPCT|PINSTO,          HALT|MEMADI|UIHIOU,                                 MICRST|MEMLD|MEMWRT|UILOOU,                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0011 - 04 HALT + LOAD MEM
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MICRST|AREGIN|LDASHD|LDASHU|MEMLD,                  0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0100 - 05 LOAD A FROM MEM
 { INSRIN|PSTPCT|PINSTO,          MEMADI|MEMCTO,                                      MICRST|MEMLD|AREGIN|LDASHD|LDASHU|MEMCTU,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0101 - 06 LOAD A FROM STACK
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MEMLD|BREGIN|LDBSHU|LDBSHD|MICRST,                  0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0110 - 07 LOAD B FROM MEM
 { INSRIN|PSTPCT|PINSTO,          MEMADI|MEMCTO,                                      MICRST|MEMLD|BREGIN|LDBSHU|LDBSHD|MEMCTU,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0111 - 08 LOAD B FROM STACK
 { INSRIN|PSTPCT|PINSTO,          MICRST|SUMOUT|AREGIN|LDASHD|LDASHU|DSPRIN,          0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 1000 - 09 DISPLAY SUM+LD TO A
 { INSRIN|PSTPCT|PINSTO,          MICRST|MEMLD|MEMCTI,                                0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 1001 - 10 SET RAM COUNTER
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MICRST|MEMLD|MEMWRT|SUMOUT,                         0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 1010 - 11 SAVE SUM TO MEM
 { INSRIN|PSTPCT|PINSTO,          MEMCTO|MEMADI,                                      MICRST|MEMLD|MEMWRT|MEMCTU|SUMOUT,          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 1011 - 12 SAVE SUM TO STACK
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MICRST|MEMLD|PGMSTI,                                0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 1100 - 13 JUMP FROM MEMORY
 { INSRIN|PSTPCT|PINSTO,          MICRST|PINSTO|PGMSTI,                               0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 1101 - 14 JUMP DIRECT
 { INSRIN|PSTPCT|PINSTO,          MICRST|MEMLD|SELPGM|PGMSTI,                         0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 1110 - 15 JUMP TO PGM+STEP
 { INSRIN|PSTPCT|PINSTO,          MICRST|SUMOUT|SUBINV|DSPRIN|AREGIN|LDASHD|LDASHU,   0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 1111 - 16 DISPLAY DIFF+LD TO A
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MICRST|SUMOUT|SUBINV|MEMLD|MEMWRT,                  0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0001 0000 - 17 SAVE DIFF. TO MEM
 { INSRIN|PSTPCT|PINSTO,          MEMCTO|MEMADI,                                      MICRST|MEMLD|MEMWRT|SUBINV|MEMCTU|SUMOUT,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0001 0001 - 18 SAVE DIFF. TO STACK
 { INSRIN|PSTPCT|PINSTO|MEMADI,   0,                                                  0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0001 0010 - 19

 //''       ''    ''    ''        ''                                                ''                                           ''  ''  ''  ''  ''  ''  ''  ''  ''  ''  ''  ''  '''  ' ' '

 { INSRIN|PSTPCT|PINSTO|MEMADI,  0,                                                   0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0000 - 255
 { INSRIN|PSTPCT|PINSTO|MEMADI,  0,                                                   0,                                          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // 0000 0000 - 256



};



uint32_t ucode [16][256][16];

void initucode() {  // Flag Conditions

  (ucode[FLAGS_U0N0Z0C0], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  //00. No Flags, No Modifications

  (ucode[FLAGS_U0N0Z0C1], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  //01. ALU Carry Flag Set, Jump If
  // Example code: ucode[FLAGS_U0N0Z0C1][jumpIfCarry][Step#] = MicIns1|MicIns2|Ect.

  (ucode[FLAGS_U0N0Z1C0], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  //02. ALU Zero Flag Set, Jump If

  (ucode[FLAGS_U0N0Z1C1], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  //03. No Configuration, Error

  (ucode[FLAGS_U0N1Z0C0], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  //04. Negative Flag Set, Jump If

  // "    "     "     "     "     "     "     "     "      " 

  (ucode[FLAGS_U1N1Z1C1], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  //15. No Configuration, Error


}






int main()
{
      //Program data bytes

   initucode();

    cout <<"Writing Binary File";




    fstream outputFile("Rom1.bin", ios::binary | ios::in | ios::out | ios::trunc);

    outputFile.open;

    if (outputFile.is_open()){

        for ( int address = 0; address < 65536; address += 1) {
              int flags      = (address & 0b1111000000000000) >> 12;
              int instr      = (address & 0b0000111111110000) >> 4;
              int step       = (address & 0b0000000000001111) >> 0;

            outputFile.write((int *)&address, ucode[flags][instr][step] >> 0);}   // set 24, 16, 8, 0 to shift bytes for rom order

        ouputFile.close();
    }
     else {
        cout << endl<< "Could not create file" + filename;
     }



    if (address % 64 ==0){
      cout << ".";
    }
  }
  cout << "done"<< endl;




    return 0;
}



i had to snip out a large chunk of the array to fit to this post, but i was all just repeat data
Thanks for the deep narrative but if the issue is the mechanics of reading/writing binary files then this tutorial with a section on binary files might help. It works.

http://www.cplusplus.com/doc/tutorial/files/
Last edited on
It's hard to understand what you want to do.

initucode doesn't do anything at all. What do you intend it to do?

You mention 4 1-byte files. What does that mean?

To write ucode as 32-bit values to a single file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() {
    initucode();
    std::ofstream fout("Rom1.bin", fout.binary|fout.out);
    if (!fout1) {
        std::cerr << "Error opening output file.\n";
        return 1;
    }
    for (uint32_t addr = 0; addr < 0x10000; ++addr) {
        uint16_t flag = (addr >> 12) & 0x0F,
                 inst = (addr >>  4) & 0xFF,
                 step = (addr      ) & 0x0F;
        fout.write((char*)&ucode[flag][inst][step], sizeof ucode[0][0][0]);
    }
}


To write each byte of the 32 bit ucode values to separate files (which I'm guessing is what you mean by 4 1-byte files):

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
int main() {
    initucode();
    std::ofstream fout1("Rom1.bin", fout1.binary|fout1.out),
                  fout2("Rom2.bin", fout2.binary|fout2.out),
                  fout3("Rom3.bin", fout3.binary|fout3.out),
                  fout4("Rom4.bin", fout4.binary|fout4.out);
    if (!fout1 || !fout2 || !fout3 || !fout4) {
        std::cerr << "Error opening output files.\n";
        return 1;
    }
    for (uint32_t addr = 0; addr < 0x10000; ++addr) {
        uint16_t flag = (addr >> 12) & 0x0F,
                 inst = (addr >>  4) & 0xFF,
                 step =  addr        & 0x0F;
        uint32_t u = ucode[flag][inst][step];
        uint8_t uc1 = (u >> 24),
                uc2 = (u >> 16),
                uc3 = (u >>  8),
                uc4 =  u;
        fout1.write((char*)&uc1, 1);
        fout2.write((char*)&uc2, 1);
        fout3.write((char*)&uc3, 1);
        fout4.write((char*)&uc4, 1);
    }
}

Depending on the endianness of your system, this may write the bytes in the opposite order that you intend, but you can just rename the files in that case.
Last edited on

It's hard to understand what you want to do.

initucode doesn't do anything at all. What do you intend it to do?

You mention 4 1-byte files. What does that mean?




you are correct, the initucode doesn't do much now, what the initucode will do eventually is make changes to steps in the base template based on the flags address inputs. but i am not that far along with my assembly code for the breadboard computer.

i commented out a small piece of demo code in the initucode function so ill remember how to use it later

file output format:

.................Rom4.........Rom3.........Rom2........Rom1(LSB)

0x0000 00000000 00000000 00000000 00000000
0x0001 00000000 00000000 00000000 00000000
0x0002 00000000 00000000 00000000 00000000
0x0003 00000000 00000000 00000000 00000000
0x0004 00000000 00000000 00000000 00000000

0xFFFF 00000000 00000000 00000000 00000000

sorry for not making that clearer

i am pretty sure it is all little endian, at least thats how i've coded it
Last edited on
the initucode doesn't do much now, other than make a 16 element array of the base template

No, it does absolutely nothing at all. If you mean it to copy the base template 16 times so that you can then you can modify it further, then you can do something like this:

1
2
3
4
5
6
#include <cstring> // for memcpy

void initucode() {
    for (int i = 0; i < 16; ++i)
        std::memcpy((char*)&ucode[i], BASE_TEMPLATE, sizeof BASE_TEMPLATE);
}


As for your rom files it looks like the second code snippet I've shown above will do what you want.
Very Cool!! i tried that code and it worked thank very much!

however the data files only contain zeros, it does not seem to be writing the array properly
My data files don't contain only zeros, although I'm obviously missing most of BASE_TEMPLATE. The missing part will contain zeros by default.

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
#include <iostream>
#include <fstream>
#include <cstring>

#define HALT      0b10000000000000000000000000000000 // HALT
#define MICRST    0b01000000000000000000000000000000 // MICRO COUNTER RST
#define INSRIN    0b00100000000000000000000000000000 // INST. REG. IN
#define SUMOUT    0b00010000000000000000000000000000 // SUM OUT
//#define BLANK     0b00001000000000000000000000000000 //
#define BREGIN    0b00000100000000000000000000000000 // B REG IN
#define LDBSHU    0b00000010000000000000000000000000 // LOAD B SHIFT UP
#define LDBSHD    0b00000001000000000000000000000000 // LOAD B SHIFT DOWN
#define SUBINV    0b00000000100000000000000000000000 // SUBTRACT INVERT
#define AREGIN    0b00000000010000000000000000000000 // A REG IN
#define LDASHD    0b00000000001000000000000000000000 // LOAD A SHIFT DOWN
#define LDASHU    0b00000000000100000000000000000000 // LOAD A SHIFT UP
//#define BLANK     0b00000000000010000000000000000000 //
//#define BLANK     0b00000000000001000000000000000000 //
#define FLAGEN    0b00000000000000100000000000000000 // FLAGS ENABLE
#define ALUCIN    0b00000000000000010000000000000000 // ADDER CARRY IN
//#define BLANK     0b00000000000000001000000000000000 //
#define DSPRIN    0b00000000000000000100000000000000 // DISPLAY REG IN
#define MEMCTI    0b00000000000000000010000000000000 // MEM COUNT IN
#define MEMCTO    0b00000000000000000001000000000000 // MEM COUNT OUT
#define MEMCTU    0b00000000000000000000100000000000 // MEM COUNT UP
#define MEMADI    0b00000000000000000000010000000000 // MEM ADDR. IN
#define MEMLD     0b00000000000000000000001000000000 // MEM LOAD
#define MEMWRT    0b00000000000000000000000100000000 // MEM WRITE
#define PSTPCT    0b00000000000000000000000010000000 // PGM STEP COUNT UP
#define SELPGM    0b00000000000000000000000001000000 // PGM NO. IN
#define PGMSTI    0b00000000000000000000000000100000 // PGM STEP IN
#define PINSTO    0b00000000000000000000000000010000 // PGM INSTR. OUT
#define UIHIOU    0b00000000000000000000000000001000 // USER INPUT UPPER OUT
#define UILOOU    0b00000000000000000000000000000100 // USER INPUT LOWER OUT

#define FLAGS_U0N0Z0C0 0  // NO FLAGS
#define FLAGS_U0N0Z0C1 1  // ALU CARRY OUT FLAG
#define FLAGS_U0N0Z1C0 2  // ALU ZERO FLAG
#define FLAGS_U0N0Z1C1 3  // NOT USED, ERROR
#define FLAGS_U0N1Z0C0 4  // ALU NEGATIVE FLAG
#define FLAGS_U0N1Z0C1 5  // NOT USED, ERROR
#define FLAGS_U0N1Z1C0 6  // NOT USED, ERROR
#define FLAGS_U0N1Z1C1 7  // NOT USED, ERROR
#define FLAGS_U1N0Z0C0 8  // UNDEFINED FLAG
#define FLAGS_U1N0Z0C1 9  // NOT USED, ERROR
#define FLAGS_U1N0Z1C0 10 // NOT USED, ERROR
#define FLAGS_U1N0Z1C1 11 // NOT USED, ERROR
#define FLAGS_U1N1Z0C0 12 // NOT USED, ERROR
#define FLAGS_U1N1Z0C1 13 // NOT USED, ERROR
#define FLAGS_U1N1Z1C0 14 // NOT USED, ERROR
#define FLAGS_U1N1Z1C1 15 // NOT USED, ERROR

#define Jumpifcarry     0b11111100
#define Jumpifzero      0b11111101
#define Jumpifneg       0b11111110
#define Jumpifundefined 0b11111111

uint32_t BASE_TEMPLATE[256][16] = {
 { INSRIN|PSTPCT|PINSTO,          HALT|MICRST|SELPGM|PGMSTI|UIHIOU,         },  // 0000 0000 - 01 HALT + LOAD PGM
 { INSRIN|PSTPCT|PINSTO,          HALT|AREGIN|LDASHD|LDASHU|UIHIOU,         MICRST|BREGIN|LDBSHU|LDBSHD|UILOOU, },  // 0000 0001 - 02 HALT + LOAD A+B
 { INSRIN|PSTPCT|PINSTO,          HALT|MICRST|BREGIN|LDBSHU|LDBSHD|UIHIOU,  },  // 0000 0010 - 03 HALT + LOAD B ONLY
 { INSRIN|PSTPCT|PINSTO,          HALT|MEMADI|UIHIOU,                       MICRST|MEMLD|MEMWRT|UILOOU, },  // 0000 0011 - 04 HALT + LOAD MEM
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MICRST|AREGIN|LDASHD|LDASHU|MEMLD,        },  // 0000 0100 - 05 LOAD A FROM MEM
 { INSRIN|PSTPCT|PINSTO,          MEMADI|MEMCTO,                            MICRST|MEMLD|AREGIN|LDASHD|LDASHU|MEMCTU, },  // 0000 0101 - 06 LOAD A FROM STACK
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MEMLD|BREGIN|LDBSHU|LDBSHD|MICRST,        },  // 0000 0110 - 07 LOAD B FROM MEM
 { INSRIN|PSTPCT|PINSTO,          MEMADI|MEMCTO,                            MICRST|MEMLD|BREGIN|LDBSHU|LDBSHD|MEMCTU, },  // 0000 0111 - 08 LOAD B FROM STACK
 { INSRIN|PSTPCT|PINSTO,          MICRST|SUMOUT|AREGIN|LDASHD|LDASHU|DSPRIN,},  // 0000 1000 - 09 DISPLAY SUM+LD TO A
 { INSRIN|PSTPCT|PINSTO,          MICRST|MEMLD|MEMCTI,                      },  // 0000 1001 - 10 SET RAM COUNTER
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MICRST|MEMLD|MEMWRT|SUMOUT,               },  // 0000 1010 - 11 SAVE SUM TO MEM
 { INSRIN|PSTPCT|PINSTO,          MEMCTO|MEMADI,                            MICRST|MEMLD|MEMWRT|MEMCTU|SUMOUT,  },  // 0000 1011 - 12 SAVE SUM TO STACK
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MICRST|MEMLD|PGMSTI,                      },  // 0000 1100 - 13 JUMP FROM MEMORY
 { INSRIN|PSTPCT|PINSTO,          MICRST|PINSTO|PGMSTI,                     },  // 0000 1101 - 14 JUMP DIRECT
 { INSRIN|PSTPCT|PINSTO,          MICRST|MEMLD|SELPGM|PGMSTI,               },  // 0000 1110 - 15 JUMP TO PGM+STEP
 { INSRIN|PSTPCT|PINSTO,          MICRST|SUMOUT|SUBINV|DSPRIN|AREGIN|LDASHD|LDASHU,},  // 0000 1111 - 16 DISPLAY DIFF+LD TO A
 { INSRIN|PSTPCT|PINSTO|MEMADI,   MICRST|SUMOUT|SUBINV|MEMLD|MEMWRT,        },  // 0001 0000 - 17 SAVE DIFF. TO MEM
 { INSRIN|PSTPCT|PINSTO,          MEMCTO|MEMADI,                            MICRST|MEMLD|MEMWRT|SUBINV|MEMCTU|SUMOUT, },  // 0001 0001 - 18 SAVE DIFF. TO STACK
 { INSRIN|PSTPCT|PINSTO|MEMADI, },  // 0001 0010 - 19
 // ...
 { INSRIN|PSTPCT|PINSTO|MEMADI, },  // 0000 0000 - 255
 { INSRIN|PSTPCT|PINSTO|MEMADI, },  // 0000 0000 - 256
};

uint32_t ucode[16][256][16];

void initucode() {
    for (int i = 0; i < 16; ++i)
        std::memcpy((char*)&ucode[i], BASE_TEMPLATE, sizeof BASE_TEMPLATE);
}

int main() {
    initucode();
    std::ofstream fout1("Rom1.bin", fout1.binary|fout1.out),
                  fout2("Rom2.bin", fout2.binary|fout2.out),
                  fout3("Rom3.bin", fout3.binary|fout3.out),
                  fout4("Rom4.bin", fout4.binary|fout4.out);
    if (!fout1 || !fout2 || !fout3 || !fout4) {
        std::cerr << "Error opening output files.\n";
        return 1;
    }
    for (uint32_t addr = 0; addr < 0x10000; ++addr) {
        uint16_t flag = (addr >> 12) & 0x0F,
                 inst = (addr >>  4) & 0xFF,
                 step =  addr        & 0x0F;
        uint32_t u = ucode[flag][inst][step];
        uint8_t uc1 = (u >> 24),
                uc2 = (u >> 16),
                uc3 = (u >>  8),
                uc4 =  u;
        fout1.write((char*)&uc1, 1);
        fout2.write((char*)&uc2, 1);
        fout3.write((char*)&uc3, 1);
        fout4.write((char*)&uc4, 1);
    }
}

Last edited on
i figured it out, the problem was in the initucode... (like you said).





1
2
3
4
5
6
void initUCode() {
  memcpy_P(ucode[FLAGS_U0N0Z0C0], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  
  memcpy_P(ucode[FLAGS_U0N0Z0C1], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  
  memcpy_P(ucode[FLAGS_U0N0Z1C0], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));

this is a snippet of my arduino code, when i transposed it to c++ i dropped the memcpy_p code thinking it only applied to arduino. but looking at your code i can see it needs a similar code to function. i also see a memory pointer.

i did not change that before i ran it.




will the new initucode for loop still allow me to make changes like i was expecting?

1
2
3
4
5
6
7
8
void initucode() {  // Flag Conditions

  (ucode[FLAGS_U0N0Z0C0], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  //00. No Flags, No Modifications

  (ucode[FLAGS_U0N0Z0C1], BASE_TEMPLATE, sizeof(BASE_TEMPLATE));
  //01. ALU Carry Flag Set, Jump If
  // Example code: ucode[FLAGS_U0N0Z0C1][jumpIfCarry][Step#] = MicIns1|MicIns2|Ect. 


or should i modify your code to work without the for loop like my original?


thank you so much!! this has been a major road block for me!
will the new initucode for loop still allow me to make changes like i was expecting?

I think so, if you mean something like this:

1
2
3
4
5
6
7
8
9
10
void initucode() {

    // Fill ucode with the base template
    for (int i = 0; i < 16; ++i)
        memcpy((void*)&ucode[i], BASE_TEMPLATE, sizeof BASE_TEMPLATE);

    // Make the modifications
//  ucode[FLAGS_U0N0Z0C1][jumpIfCarry][Step] = MicIns1|MicIns2|Ect. 
//  etc
}

ok, then i would only need to write for the flags that need it and not all 16 variations?
That seems right, but again I'm not privy to the deets.
This is bizarre - very much like the proverbial xy problem.

Anyone who knows a smidgin about the Arduino and microcontrollers knows a couple of things:
1) They receive data from a (serial) port that enables it to bootstrap & program itself.
2) They have to receive the info in an acceptable (to the device) way. How that data is prepared doesn't matter.

This problem as originally described seems to be taking the "0b ... 0" string and converting it to 4 8bit values which in turn get sent as a stream to the device. They probably don't have to be bytes, an ordered stream of 0 and 1 ASCII characters more likely.

Unlike the Arduino, C++ has only had a byte type since C++17 and how applicable that is, who knows without trying. C++ has a bitset<> type that also may or may not be useful.

Arduino is open source so I would find out what they do in handling their 'B' prefix.

But the bottom line is to break up the 34 character string into 4 8 long strings and take it from there.

Memory isn't an issue for the small number of instruction bytes listed. (It's trivial as anyone programming an Arduino with a complex character set to display knows.)

Another aspect is the device manufacturers specification will show the form of the instruction data to be received and therefore handled at the device end.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

int main()
{
    // SPLIT z INTO 4 8 BIT BYTES
    int z = 0b01010000000000000001000000000101;
    //        123456789 123456789 123456789 12
    
    std::cout
    << "bitset<32>: " << std::bitset<32>(z) << '\n'
    << "       hex: " << std::hex << z << '\n'
    << "   decimal: " << std::dec << z << "\n\n";
    
    
    std::cout
    << "1): " << std::bitset<8> ((0xff000000 & z) >> 24) << '\n'
    << "2): " << std::bitset<8> ((0x00ff0000 & z) >> 16) << '\n'
    << "3): " << std::bitset<8> ((0x0000ff00 & z) >> 8)  << '\n'
    << "4): " << std::bitset<8>  (0x000000ff & z)        << '\n';
    
    return 0;
}


bitset<32>: 01010000000000000001000000000101
hex: 50001005
decimal: 1342181381

1): 01010000
2): 00000000
3): 00010000
4): 00000101
Program ended with exit code: 0
So, continuing along on that theme we get:

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
#include <iostream>
#include <fstream>

int main()
{
    // SPLIT z INTO 4 8 BIT BYTES
    int z = 0b01010000000000010001000000000101;
    //        123456789 123456789 123456789 12
    
    std::cout
    << "bitset<32>: " << std::bitset<32>(z) << '\n'
    << "       hex: " << std::hex << z << '\n'
    << "   decimal: " << std::dec << z << "\n\n";
    
    std::bitset<8> byte_out[4];
    byte_out[0] = ((0xff000000 & z) >> 24);
    byte_out[1] = ((0x00ff0000 & z) >> 16);
    byte_out[2] = ((0x0000ff00 & z) >> 8);
    byte_out[3] = (0x000000ff & z);
    
    
    int chksum = 0;
    std::cout << "OUTPUT TO FILE\n";
    std::ofstream out_file;
    out_file.open("bits_and_bytes.txt");
    if( out_file )
    {
        chksum = 0;
        for(int i = 0; i < 4; i++)
        {
            out_file << byte_out[i] << ' ';
            std::cout << i << "): " << byte_out[i] << ' ' << std::dec << byte_out[i].to_ulong() << '\n';
            chksum += byte_out[i].to_ulong();
        }
        out_file << '\n';
        std::cout << "Sum: " << chksum << "\n\n";
        
        out_file.close();
    }
    else
        return  -1;
    
    
    
    std::cout << "INPUT FROM FILE\n";
    std::bitset<8> byte_in[4];
    
    std::ifstream in_file;
    in_file.open("bits_and_bytes.txt");
    if(in_file)
    {
        in_file >> byte_in[0] >> byte_in[1] >> byte_in[2] >> byte_in[3];
        
        chksum = 0;
        for(int i = 0; i < 4; i++)
        {
            std::cout
            << i << "): " << byte_in[i] << ' '
            << std::dec << byte_in[i].to_ulong() << '\n';
            
            chksum += byte_in[i].to_ulong();
        }
        std::cout << "Sum: " << chksum << "\n\n";
        
        in_file.close();
    }
    else
        return -1;
    
    return 0;
}


bitset<32>: 01010000000000010001000000000101
       hex: 50011005
   decimal: 1342246917

OUTPUT TO FILE
0): 01010000 80
1): 00000001 1
2): 00010000 16
3): 00000101 5
Sum: 102

INPUT FROM FILE
0): 01010000 80
1): 00000001 1
2): 00010000 16
3): 00000101 5
Sum: 102

Program ended with exit code: 0


i.e. FWIW I can transfer 32 bit data as 4 8 bit bytes
Topic archived. No new replies allowed.