Author Topic: Arrays  (Read 4358 times)

0 Members and 1 Guest are viewing this topic.

Offline z80man

  • Casio Traitor
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 977
  • Rating: +85/-3
    • View Profile
Arrays
« on: March 18, 2011, 02:11:27 am »
Sometimes I really miss programming in asm, but it can be difficult to do on x86 systems. So basically my problem is that I have an array of chars, but I need to read and write multiple types from it. Ranging from 32 bit longs, 16 bit words, and 8 bit bytes. Now the solution would be easy in asm, but this is C++ here which thinks that restricting a programmer from low-level access is a good thing.
Code: [Select]
char * memory = new char[0xFFFF];


int readmemory_long(int pointer)
{
unsigned int r_pointer = pointer - 0xA4000000;            //converts given pointer to the array address
if (r_pointer > 0x1FFFFF) return 0;
return ntohl(memory[r_pointer]);                    //ntohl(), converts data to little endian (I hope :P) issue here
                                                               // I want to get the 32 bit value at this address
}
void writememory_long(int pointer, int data)
{
unsigned int r_pointer = pointer - 0xA4000000;
if (r_pointer > 0x1FFFFF) return;
memory[r_pointer] = htonl(data);                //converts data to big endian: same issue
}
I was considering using for loops, but that could be kinda tricky. Any ideas/examples would be smiled upon  :)

List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)

Offline z80man

  • Casio Traitor
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 977
  • Rating: +85/-3
    • View Profile
Re: Arrays
« Reply #1 on: March 18, 2011, 10:51:26 pm »
bump

Well I tried this new code here which yields some results, but isn't perfect. The issue is that when I read the first index from the array, type short, I get a result of $3d44 which isn't contained anywhere in the file I used for the input.
Code: [Select]
char * memory = new char[0xFFFF];


int readmemory_long(int pointer)
{
unsigned int r_pointer = pointer - 0xA4000000;
if (r_pointer > 0x1FFFFF) return 0;
int temp = int(memory[r_pointer]) * 0x1000000;
temp |= int(memory[r_pointer + 1]) * 0x10000;
temp |= int(memory[r_pointer + 2]) * 0x100;
temp |= int(memory[r_pointer + 3]);
return ntohl(temp);
}

short readmemory_word(int pointer)
{
unsigned int r_pointer = pointer - 0xA4000000;
if (r_pointer > 0x1FFFFF) return 0;
short temp = short(memory[r_pointer]) * 0x100;
temp |= short(memory[r_pointer + 1]);
return ntohs(temp);
}
Code: (input file) [Select]
70 01 71 01 8B FD FF FE
Code: (input code) [Select]
PC = 0xA4000000;
ifstream program("spectrum.data", ios::in|ios::binary);
if(!program.is_open())
{
cout << "Error opening spectrum.data";
cin.get();
return -1;
}
program.seekg(0, ios::beg);
int program_counter;
char buffer;
program.read(&buffer, 1);
int prog_index;
while(program.good())
{
writememory_byte(prog_index + 0xA4000000, buffer);
prog_index++;
program.seekg(prog_index);
program.read(&buffer, 1);
}
So for the first instruction I should be getting a value of $7001, but I get the 3d44 instead. In the other code block I have the code for reading the input file, but I don't believe there is any error there.

List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)

Offline Goplat

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 289
  • Rating: +82/-0
    • View Profile
Re: Arrays
« Reply #2 on: March 19, 2011, 01:28:35 am »
First of all, this kind of code effectively byte-swaps the integer twice:
Quote
   int temp = int(memory[r_pointer]) * 0x1000000;
   temp |= int(memory[r_pointer + 1]) * 0x10000;
   temp |= int(memory[r_pointer + 2]) * 0x100;
   temp |= int(memory[r_pointer + 3]);
   return ntohl(temp);
If you read the integer byte-by-byte, with the multipliers being for big-endian, then it's already correct and you don't need to use ntohl.

If you want to read the integer all at once, use a pointer cast: *(int *)&memory[r_pointer]. If you do this, then the integer will have its bytes in the wrong order (because x86 is little-endian), and then you would need something like ntohl to fix it: ntohl(*(int *)&memory[r_pointer]).

As for your input loop: There are a couple of problems. First, prog_index needs to be initialized to some value (I assume you intended 0) - otherwise, you could be writing anywhere. Second, if the input file is in hex, then you need to parse the hex numbers. istream.read() just reads raw bytes, so if the file contains 70 01... then buffer will take on values of 0x37, 0x30, 0x20, 0x30, 0x31... In C++, you can instead use the >> operator. You'll have to set the stream to hex mode first though. You will also have to change buffer to be an int, not a char, because >> determines what to do based on the type of the variable on the right: if the variable is a char, >> just reads a character; if the variable is an int, >> reads a space-delimited number.

Corrected input loop:
   program >> hex;
   int buffer;
   program >> buffer;
   int prog_index = 0;
   while(program.good())
   {
      writememory_byte(prog_index + 0xA4000000, buffer);
      prog_index++;
      program >> buffer;
   }
« Last Edit: March 19, 2011, 02:01:01 am by Goplat »
Numquam te deseram; numquam te deficiam; numquam circa curram et te desolabo
Numquam te plorare faciam; numquam valedicam; numquam mendacium dicam et te vulnerabo

Offline z80man

  • Casio Traitor
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 977
  • Rating: +85/-3
    • View Profile
Re: Arrays
« Reply #3 on: March 19, 2011, 01:53:32 am »
The hex I put in my previous post was just the output from a hex editor. Otherwise the data was already in a compiled format. I did debug my file input routine and that worked too. It just took a few edits to the memory routine to get it working. And the data was stored in memory in big endian format. When it was read from memory, it was then it was converted to little endian to be operated upon. Now it looks like just a few more things to debug, then the prog will be ready for its first official release.

List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)

Offline AngelFish

  • Is this my custom title?
  • Administrator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3242
  • Rating: +270/-27
  • I'm a Fishbot
    • View Profile
Re: Arrays
« Reply #4 on: March 19, 2011, 01:53:40 am »
Goplat, if it's parsing "70" to the ASCII codes 0x37 and 0x30, then "01" would read 0x3031, not 0x3001. 0x01 is a non-printable ASCII control character.
∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ

Offline Goplat

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 289
  • Rating: +82/-0
    • View Profile
Re: Arrays
« Reply #5 on: March 19, 2011, 02:00:37 am »
Goplat, if it's parsing "70" to the ASCII codes 0x37 and 0x30, then "01" would read 0x3031, not 0x3001. 0x01 is a non-printable ASCII control character.
Right, that was a typo, sorry :(
Numquam te deseram; numquam te deficiam; numquam circa curram et te desolabo
Numquam te plorare faciam; numquam valedicam; numquam mendacium dicam et te vulnerabo

Offline z80man

  • Casio Traitor
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 977
  • Rating: +85/-3
    • View Profile
Re: Arrays
« Reply #6 on: March 19, 2011, 02:12:04 am »
Well another error, but I bet it is the last difficult to fix one because everything else is easy to trace or has already been solved. I have one function in my program that takes the current instruction (type short) then runs through an else if block to find the corresponding instruction type. Because each instruction has several variations of its own type I preform an & to remove the dynamic bits of that instruction to leave only the static ones.
Code: [Select]
if (ADD_v == instruction & ADD_v) 
ADD();

else if (MOVi_v == instruction & MOVi_v)
MOVi();

else if (ADDi_v == instruction & ADDi_v)
ADDi();

else if (MOVLi_v == instruction & MOVLi_v) 
MOVLi();
You might recognize these as SH3 opcodes.(don't worry there are many more in my code) The first instruction in memory is $7001 aka ADD $01,R0. Now I have a debug statement right after data is loaded into instruction and that reads $7001 as expected. Now this instruction is represented by ADDi_v which is defined earlier as $7000. So if I do $7001 & $7000, I should get $7000 which would equal ADDi_v. But my program doesn't seem to respond to this for some reason.

Edit: changed MOVi_v to ADDi_v. Just a typo
« Last Edit: March 19, 2011, 02:18:03 am by z80man »

List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)

Offline Goplat

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 289
  • Rating: +82/-0
    • View Profile
Re: Arrays
« Reply #7 on: March 19, 2011, 02:33:13 am »
The & operator has lower precedence than ==. So "ADD_v == instruction & ADD_v" is equivalent to "(ADD_v == instruction) & ADD_v", rather than to the intended "ADD_v == (instruction & ADD_v)". This is just an annoying feature of C and C++ (it trips me up all the time...)

Also, the bit mask that you AND with should have all the bits identifying the instruction set to 1 - even the bits that must be 0 to match that instruction. For example:
0x7000 == (0x7001 & 0x7000) - this is true, as we want
0x7000 == (0xF001 & 0x7000) - but this is also true!
Numquam te deseram; numquam te deficiam; numquam circa curram et te desolabo
Numquam te plorare faciam; numquam valedicam; numquam mendacium dicam et te vulnerabo

Offline z80man

  • Casio Traitor
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 977
  • Rating: +85/-3
    • View Profile
Re: Arrays
« Reply #8 on: March 19, 2011, 03:34:31 am »
Thanks Goplat. Almost everything is working now. With a few more edits, optimizations, removal of debugs, documentation, and a better sample program, Spectrum should be ready for release tomorrow.

Side Note:
My eyes lit up with happiness when I saw R0 increment on the register screen. :angel:  I became crestfallen when my branching statement epically failed.  :P

List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)