Omnimaga
General Discussion => Technology and Development => Computer Programming => Topic started by: Munchor on February 10, 2011, 04:05:52 pm
-
Assemblex has been stuck because of the 8xp file maker...
def ExporTo8xp(event):
def to_binary(hex_string):
ints = [int(hex_string[i:i+2], 16) for i in range(0,len(hex_string),2)]
return struct.pack('B' * len(ints), *ints)
dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "8XP Files (*.8xp)|*.8xp", \
wx.SAVE | wx.OVERWRITE_PROMPT)
if dlg.ShowModal() == wx.ID_OK:
programData = self.inputText.GetValue()
self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
filehandle=open(os.path.join(self.dirname, self.filename),'wb')
filehandle.write(to_binary(finalProgram))
filehandle.close()
self.SetTitle('Assemblex - '+self.filename)
dlg.Destroy()
This is the GUI code for it, the programData variable is the Hexadecimal code given by the user...
However, all I need to move on is to create a 8xp file:
programData = self.inputText.GetValue()
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
000000000029000D
0018000650524F47
52414D0000001800
1600BB6DCE0B
This is a sample code of an assembly program, I need to change the size of the program. I can count the length of it, so let's say it is 98 bytes:
> How can I make 98 bytes, what is the size of the program in the hex code of it?
I know this is very general, I'll try to give you more details when I can.
-
This is a sample code of an assembly program, I need to change the size of the program. I can count the length of it, so let's say it is 98 bytes:
> How can I make 98 bytes, what is the size of the program in the hex code of it?
I know this is very general, I'll try to give you more details when I can.
What do you mean by the size of the "program in the hex code"? Remember that two hex digits make up one byte.
-
I think he means: "How do I find the size of the file? And how do I get the checksum?"
-
I think he means: "How do I find the size of the file? And how do I get the checksum?"
No I don't. I mean I can get a size in bytes, I just can't make that size little endian...
53 (35h) 2 bytes Length, in bytes, of the data section of the file. This number should be 57 (39h) bytes less than the file size.
http://www.cemetech.net/forum/viewtopic.php?p=132898#132898 (http://www.cemetech.net/forum/viewtopic.php?p=132898#132898)
Just like Deep Thought says there, I need the size - 57 bytes in little endian.
So let's say the file is 98 bytes (I can get that value, no issues there), 98-57 is 41. Then 41 in little endian is 4100. That is easy, but with larger files I don't know how to.
It's a python question. Any ideas?
-
I think he means: "How do I find the size of the file? And how do I get the checksum?"
No I don't. I mean I can get a size in bytes, I just can't make that size little endian...
53 (35h) 2 bytes Length, in bytes, of the data section of the file. This number should be 57 (39h) bytes less than the file size.
http://www.cemetech.net/forum/viewtopic.php?p=132898#132898 (http://www.cemetech.net/forum/viewtopic.php?p=132898#132898)
Just like Deep Thought says there, I need the size - 57 bytes in little endian.
So let's say the file is 98 bytes (I can get that value, no issues there), 98-57 is 41. Then 41 in little endian is 4100. That is easy, but with larger files I don't know how to.
It's a python question. Any ideas?
Oh, that's easy. Take the number %256 (modulus), insert it as the first byte, then put the number /256 into the byte after it.
-
Oh, that's easy. Take the number %256 (modulus), insert it as the first byte, then put the number /256 into the byte after it.
Sorry, I can't understand.
Let's say the size, in bytes, is 98.
98-57=41
Then 41 in hex is 29.
29 in little endian is 2900.
I need a python code for that, the problem is the little endian/hex :S
-
Oh, that's easy. Take the number %256 (modulus), insert it as the first byte, then put the number /256 into the byte after it.
Sorry, I can't understand.
Let's say the size, in bytes, is 98.
98-57=41
Then 41 in hex is 29.
29 in little endian is 2900.
I need a python code for that, the problem is the little endian/hex :S
Why would you subtract 57? If 98 is the number of bytes in the program, you add 57 to account for the header and stuff when calculating the overall filesize for the .8xp program, a small portion of which is the actual TI program.
But anyway, let's just say you want to convert the number 8811 to little-endian. Big-endian is easy; it's just hex(8811), which is 0x226B. But if you want to find the little-endian number, remember that little-endian is basically just flipping the bytes, putting the least-significant byte in front. So you want it to be 6B22, or 27426.
Since you're just flipping the bytes, you need to find the two bytes individually. The least-significant byte (the one that you want to put in front) is just 8811 % 256 (what you get as a remainder when you divide 8811 by 256), and the most-significant byte is 8811 / 256. So to combine the two, multiply the least-significant byte by 256 (to "force" it to become the byte in front), and add the other byte on.
So here's the code:
le = be % 256 * 256 + (be / 256)
where be is the big-endian number and le is the little-endian number.
-
I got it Deep Thought.
However, when doing this:
littleEndian = dataLengthBigEndian% 256 * 256 + (dataLengthBigEndian / 256)
I got this error:
littleEndian = dataLengthBigEndian% 256 * 256 + (dataLengthBigEndian / 256)
TypeError: not all arguments converted during string formatting
I think I know why: hex(number) will return something like 0x2A.
Now, should I divide 2A by hex(256)? Is that what you mean?
Thanks.
EDIT, I tried:
littleEndian = dataLengthBigEndian% hex(256) * hex(256) + (dataLengthBigEndian / hex(256))
And I got the same error, not sure what I should do, though (concerning hexadecimal objects and integers).
-
No, never use hex(. hex( just converts a number into a hex string. Remember that a number is a number whether it's a decimal or a hex. 0x226B is exactly the same as 8811, so don't bother converting it to hex. To the computer it's all the same, anyway.
The only real time you'd ever use hex( would be if you wanted to display something that way.
Hope this helps?
-
No, never use hex(. hex( just converts a number into a hex string. Remember that a number is a number whether it's a decimal or a hex. 0x226B is exactly the same as 8811, so don't bother converting it to hex. To the computer it's all the same, anyway.
The only real time you'd ever use hex( would be if you wanted to display something that way.
Hope this helps?
I get it, then how do I get big-endian value?
dataLengthBigEndian = hex((len(programData)/2))
This is what I was doing :S
-
Yeah, but because of hex(, dataLengthBigEndian is now a string. You can't do operations on a string.
Just replace that with
dataLengthBigEndian = len(programData)/2
Remember, whether it's in hex or decimal does not matter. It's exactly the same number.
-
In Python, hex( will turn values into hex variables, so neither integers nor strings.
This makes it impossible to make calculus with it, I think, so you can use the integer values of hexadecimal variables for this type of calculus.
-
In Python, hex( will turn values into hex variables, so neither integers nor strings.
This makes it impossible to make calculus with it, I think, so you can use the integer values of hexadecimal variables for this type of calculus.
Yeah I've just noticed :P Thanks and it seems like you're new, welcome!
Now, I already got to the point where I don't get errors when making 8xp files but still not creating valid 8xp files.
210100C9 This is what I entered.
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
000000000010240D
0018000650524F47
52414D0000001800
1600BB6D210100C9
CE0B This is the 8xp file it created.
Now, the size in the 8xp file created is 1024, which is certainly wrong since my program data size, in bytes, is 2 (bytes). This would make the little endian code be 0200, so something in my code is wrong:
def to_binary(hex_string):
ints = [int(hex_string[i:i+2], 16) for i in range(0,len(hex_string),2)]
return struct.pack('B' * len(ints), *ints)
programData = self.inputText.GetValue()
dataLengthBigEndian = len(programData)/2
littleEndian = dataLengthBigEndian % 256 * 256 + (dataLengthBigEndian / 256)
sample8xp = "2A2A54493833462A1A0A0046696C652067656E657261746564206279205761626269745369676E0000000000000000000000000000"""+str(littleEndian)+"0D0018000650524F4752414D00000018001600BB6D"+programData+"CE0B"
self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
filehandle=open(os.path.join(self.dirname, self.filename),'wb')
filehandle.write(to_binary(sample8xp))
filehandle.close()
Note: The identation is correct, any idea what's wrong? Thanks.
-
In Python, hex( will turn values into hex variables, so neither integers nor strings.
It's actually a string, and that's why you can't do math: http://docs.python.org/library/functions.html#hex
Welcome to Omnimaga, by the way :)
Now, the size in the 8xp file created is 1024, which is certainly wrong since my program data size, in bytes, is 2 (bytes). This would make the little endian code be 0200, so something in my code is wrong:
Um, how is that two bytes?
210100C9 is four bytes (eight nibbles).
And replace str(littleEndian) with hex(littleEndian)[2:]. Since you're dealing with a hex string, you need that to be a hex string too. (The [2:] is because hex( converts it into '0xHH' form.)
-
1. Yeah, eight nibbles, 4 bytes, bad calculation XD
2. I know 1024 is the size, because:
...0010240D00180...
The 1024 is at the location where the size should be and I also added a print line to print the little endian value of the data section and it returned '1024'.
-
1. Yeah, eight nibbles, 4 bytes, bad calculation XD
2. I know 1024 is the size, because:
...0010240D00180...
The 1024 is at the location where the size should be and I also added a print line to print the little endian value of the data section and it returned '1024'.
See my edit above. Use hex(littleEndian)[2:] instead :)
EDIT: Dammit, new page >:(
So you don't have to click back, here's what I said:
And replace str(littleEndian) with hex(littleEndian)[2:]. Since you're dealing with a hex string, you need that to be a hex string too. (The [2:] is because hex( converts it into '0xHH' form.)
-
210100C9
It returned this:
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
00000000004000D0
018000650524F475
2414D00000018001
600BB6D210100C9C
E00B
4000 is the size, but it was supposed to be 0400. So, am I missing a switch in the code?
def to_binary(hex_string):
ints = [int(hex_string[i:i+2], 16) for i in range(0,len(hex_string),2)]
return struct.pack('B' * len(ints), *ints)
dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "8XP Files (*.8xp)|*.8xp", \
wx.SAVE | wx.OVERWRITE_PROMPT)
if dlg.ShowModal() == wx.ID_OK:
programData = self.inputText.GetValue()
dataLengthBigEndian = len(programData)/2
littleEndian = dataLengthBigEndian % 256 * 256 + (dataLengthBigEndian / 256)
sample8xp = "2A2A54493833462A1A0A0046696C652067656E657261746564206279205761626269745369676E0000000000000000000000000000"""+str(hex(littleEndian)[2:])+"0D0018000650524F4752414D00000018001600BB6D"+programData+"CE0B"
print littleEndian
print dataLengthBigEndian
self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
filehandle=open(os.path.join(self.dirname, self.filename),'wb')
filehandle.write(to_binary(sample8xp))
filehandle.close()
self.SetTitle('Assemblex - '+self.filename)
dlg.Destroy()
-
Don't bother doing str(hex(. hex( returns a string variable already. Try that, but I'm not sure if that's it...
EDIT: Hey, I figured it out!
Hold on...
EDIT2: Basically, it's this: When you do hex( when the length of data is 4, it returns '0x400'. See the problem? You slice it with [2:], and it becomes '400'. That's still not the value you want. You need to pad it so it's exactly 4 chars long.
A really crude (but simple) way to do it is to do something like
if len(le) == 3:
le = '0' + le
Then put it in the data.
EDIT3: How about this:
(le if len(le) == 4 else ('0' + le))
where le is the little-endian hex string as found by hex(littleEndian)[2:].
Nice and concise? ;D
-
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
000000000004000D
0018000650524F47
52414D0000001800
1600BB6D210100C9
CE0B
The size created seems perfect ;D