I decided to create a whole new thread for this, since I'm restarting my code so I can finally release Assemblex 1.0.0 (I mean the 8xp making code).

The first change I decided to make in the code is to make it all in bytearrays.


Code:

programData = self.inputText.GetValue() #This gets the hex code
myByteArray = bytearray()
for i in range(0, len(programData), 2):
    myByteArray.append( chr( int (programData[i:i+2], 16 ) ) ) #This loops converts the hex code string to bytes and appends it to the bytearray
filehandle.write(myByteArray) #This writes the file


So I have a working code for writing files in binary and it works just perfectly.

Then I decided to add header to the code:


Code:
programData = self.inputText.GetValue() #Gets the hex code typed by the user

strHeader = "2A2A54493833462A1A0A0046696c652067656e65726174656420627920417373656d626c6578202d20446176696420476f6d657300" #This is a fixed header that never changes

programData = strHeader + programData #Add the header before the program data

myByteArray = bytearray()  #Initialize bytearray
for i in range(0, len(programData), 2): #Loop to convert string to bytes
   myByteArray.append( chr( int (programData[i:i+2], 16 ) ) ) #Loop to convert string to bytes

filehandle.write(myByteArray) #Writing the file


I'm also commenting everything to make it easier for you to understand it and help me with it.



Now I'm going to start coding the code to get the size of the program data.

This used to be my code:


Code:
dataLengthBigEndian = len(programData)/2 #Gets the code from the user (TYPED CODE, WITHOUT HEADER) and divides its length by 2
         
littleEndian = hex(dataLengthBigEndian % 256 * 256 + (dataLengthBigEndian / 256))[2:] #Converts its length to little endian
         
if len(littleEndian) == 3:  #If the little endian code length is 3..
   littleEndian= '0' + littleEndian  #... add a 0 before it


I was given this code by Deep Thought and I don't fully get it, so I want to know what you think of it and if it okay in all circumstances.
Here's some absurdly well commented code for making an 8xp file in C# (look for the Save8XP method):
http://tidenv.codeplex.com/SourceControl/changeset/view/6935#50417
From that page what I most enjoyed was this:


Code:
private static byte[] GetChecksum()
        {
            short chk = 0;
            unchecked
            {
                for (int i = 36; i < AllBytes.Count; i++)
                    chk += (short)AllBytes[i];
            }
            return BitConverter.GetBytes(chk);
        }


I am going to convert it to python right away and have my checksum maker ready.

I couldn't figure out what the code to get the little endian size was though, but thanks that sounds helpful.


EDIT:

I think I have finished the 8xp writing CODE! I really think it is good, I have a doubt however.

Is BB6D part of the data section and variable data? Thanks.

I just need to fix this BB6D thing and the checksum.
Your code probably shouldn't handle BB6D, the assembler should do that for you.
SirCmpwn wrote:
Your code probably shouldn't handle BB6D, the assembler should do that for you.


My program is like an assembler, except it uses hex code instead of getting assembly code and converting assembly code to hexadecimal code so I do need to handle BB6D.

Is it part of the data section? So, should I count BB6D for the length of bytes and stuff?
Well, BB6D is put there by the programmer, and isn't actually required (KnightOS, for instance, doesn't use it). It's part of the data.
Thanks much SirCmpwn Smile


Code:
programData = self.inputText.GetValue()
programData = 'BB6D' + programData

dataLengthBigEndian = len(programData)/2
littleEndianSize = hex(dataLengthBigEndian % 256 * 256 + (dataLengthBigEndian / 256))[2:]
    
if len(littleEndianSize) == 3:
   littleEndianSize= '0' + littleEndianSize

varDataSize = 2+dataLengthBigEndian
littleEndianVarDataSize = hex(varDataSize % 256 * 256 + (varDataSize/256))[2:]

if len(littleEndianVarDataSize) == 3:
   littleEndianVarDataSize= '0' + littleEndianVarDataSize

strHeader = "2A2A54493833462A1A0A0046696c652067656e65726174656420627920417373656d626c6578202d20446176696420476f6d657300"

strVarHeader = "0D00"+littleEndianVarDataSize+"06"+"50524F4752414D00"+"00"+"00"+littleEndianVarDataSize

programData = strHeader + littleEndianSize + strVarHeader + programData

print littleEndianSize+"\n"
print programData

myByteArray = bytearray()
for i in range(0, len(programData), 2):
   myByteArray.append( chr( int (programData[i:i+2], 16 ) ) )

self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
filehandle=open(os.path.join(self.dirname, self.filename),'wb')
filehandle.write(myByteArray) #Writes the file
filehandle.close()
self.SetTitle('Assemblex - '+self.filename)


By the way, decided to post the code here.
Isn't this a duplicate of an existing topic? SirCmpwn, you seem to have an awfully optimistic view of your code. Smile Scout, can you explain this code to me? I understand it, but I think there's a few things you omitted.


Code:
if len(littleEndianSize) == 3:
   littleEndianSize= '0' + littleEndianSize
What do you mean by "optimistic?"
This part:
Quote:

Here's some absurdly well commented code
I took a look through the code, and the commenting was fairly inconsistent, in my opinion. But that's neither here nor there; let's get back to the topic at hand.
Most of the code is only moderately commented, but the relevant code is well commented.

Did you have any more questions, Scout?
KermMartian wrote:
Isn't this a duplicate of an existing topic? SirCmpwn, you seem to have an awfully optimistic view of your code. Smile Scout, can you explain this code to me? I understand it, but I think there's a few things you omitted.


Code:
if len(littleEndianSize) == 3:
   littleEndianSize= '0' + littleEndianSize


If I calculate the size of the data section, let's say it is very small, the size can be 0800. However, Python will make it 800 because 0 is useless, so I have to add it manually because the calculator requires it.


I have another question, is the checksum part of the variable data?
No, we went through this in your other topic, I defined it very clearly for you. Let me link and quote my previous post.

From the Structure of 8xp Files thread:

KermMartian wrote:
Don't look at that screenshot, it's wrong. Alberthro was trying to make a file from scratch, I think, and did so incorrectly. Anyway, let's call the size of the whole .8xp file S. We know that the checksum is two bytes, and the main header (comment etc) is 55 bytes. We'll call the "variable/data" part therefore of size S-(55+2) = S-57.

55 bytes: header
S-57 bytes: variable/data
2 bytes: checksum

At offset 53, we have the little-endian, two byte value (S-57). Then, we have the actual variable/data itself, which starts at offset 55. At offset 2 and offset 15 into that, in other words offset (55+2) and (55+15) = 57 and 70 overall, we have two copies of just the size of the contents of the actual program (/ picture / string / list / etc). Incidentally, because the variable's header is 17 bytes, the value of those two size fields is S-57-17 = S-74.


Edit: And I think you're missing the point that it would shorten 08 00 to 8 0, not 8 00, and something like 23 00 to 23 0. You need to do a second correction for a missing zero. I'd strongly recommended you do it in the function that generates those little-endian sizes.
KermMartian wrote:

Edit: And I think you're missing the point that it would shorten 08 00 to 8 0, not 8 00, and something like 23 00 to 23 0. You need to do a second correction for a missing zero. I'd strongly recommended you do it in the function that generates those little-endian sizes.


What do you mean by the function that generates them?
I really don't get what the problem is, 230 would be converted to 0230.

Also, I changed my code to make the data section contain BB6D, but I don't think it is right. Let's have a look at this program:

2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
000000000029000D
0018000650524F47
52414D0000001800
1600BB6DEF40453E
01C60526006FEF07
45EF7249EF4045C9

CE0B //The checksum

I used the Spasm to make it, and the size of the data section is: 2900.

This is correct, but when, using Assemblex I create this program, I get, as the length of the data section: 1700 (and I am adding BB6D before the data section in the program).

I thought my code for getting the size was OK because:


Code:

210100C9


It's size is:

Code:

0400


Is this 0400 correct? I'm pretty sure it is (as in 4 bytes).


Code:

programData = self.inputText.GetValue() #Gets hex code
programData = 'BB6D' + programData #Adds BB6D before it
         
dataLengthBigEndian = len(programData)/2 #Gets number of bytes
littleEndianSize = hex(dataLengthBigEndian % 256 * 256 +(dataLengthBigEndian / 256))[2:] #Converts it to little endian
             
if len(littleEndianSize) == 3: #If it requires a 0 before...
    littleEndianSize= '0' + littleEndianSize #... add it


Once again, this is my commented code, and I'll try and make 210100C9 using Spasm and see what the size is.

EDIT2:

I assembled the following program using SPASM:


Code:
#include "ti83plus.inc"
.org 40339
.db t2ByteTok, tAsmCmp

  ld hl,1
  ret


And got:


Code:
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
000000000019000D
00080006434C5248
4C00000000000800
0600BB6D210100C9
B103


The size of 210100C9 seems to be 1900 :S Where does that come from? The file size is 82bytes, 82-57=25, and 25 has nothing to do with 1900.

Phew....

Oh wait! 25 in hexadecimal is 19! This changes things... my program is calculating things wrong :S
You don't see why 23,00 -> 230 - >0230 is wrong??
KermMartian wrote:
You don't see why 23,00 -> 230 - >0230 is wrong??


1. What kind of comma is that?
2. Secondly, the minimum size of a program is 1byte (0100), so it'd never create something like 01.
3. I'm talking about little endian, which I am getting, according to what DThought toldme, from this:


Code:
littleEndianSize = hex(dataLengthBigEndian % 256 * 256 + (dataLengthBigEndian / 256))[2:]
Tell me exactly what that would output for dataLengthBigEndian=1.
Why manually zero-pad when you can make the language do it for you?

Code:
>>> i = 1025
>>> s = "%04X" %i
>>> print s
'0401'


Pretty easy to manually flip the endianness, then..

Code:
>>> s = s[2:] + s[:2]
>>> print s
'0104'


Seems like a much cleaner (and reliable) approach to me.
KermMartian wrote:
Tell me exactly what that would output for dataLengthBigEndian=1.



Code:
>>> dataLengthBigEndian = 1
>>> littleEndianSize = hex(dataLengthBigEndian % 256 * 256 + (dataLengthBigEndian / 256))[2:]
>>> print littleEndianSize
100
>>> if len(littleEndianSize)==3:
   littleEndianSize = '0' + littleEndianSize

   
>>> print littleEndianSize
0100
>>>



Tari, thanks much, that seems much easier and simple than this!!! Very HappyVery Happy




EDIT:

Also, what do you think of this code for the var header?


Code:
strVarHeader = "0D00"+littleEndianVarDataSize+"06"+"50524F4752414D00"+"00"+"00"+littleEndianVarDataSize
Looks fine to me. I'd say a better judge would be to try to generate the .8xp of a program you already have a .8xp for, and make sure they match.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
» Goto page 1, 2, 3, 4, 5, 6  Next
» View previous topic :: View next topic  
Page 1 of 6
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement