Y_Less Posted December 21, 2005 Share Posted December 21, 2005 (edited) IMPORTANT UPDATE - DWORD restriction bypassed! Note: this is for advanced coders only, if you don't know what I'm on about it's probably not for you. I have finally found a way round the defined memory size limitations in MB (0.22). Currently you can't write (using DMA) to an area outside the defined memory, if you do, even if you use a DMA variable, it will change it to one inside the memory area. This was very annoying for code rewriting (I used all sorts of wierd hacks to get round it before) as it restricted you to one area (I had to write code in there instead, which caused its own memory reservation problems). But I found a way round. If you set a variable in VICESCM.INI to a memory address the builder will complain about it but will still compile it with the correct address (as now defined in VICESCM.INI) e.g: Under '[variables]' in the ini add: 0104=alex_test Now in a stripped script (this may even work in later versions, not tested yet) set the defined memory to 50 and add this line: 0004: $ALEX_TEST = 5? Note: MUST be upper case. At the end of the compilation it will complain (once for the highest value out of memory) that undefined memory has been accessed, but will still have written it (decompile and see - you may want to comment out the ini line first so you can see the DMA address, not '$alex_test' which it will say as that is in the ini. This does NOT bypass the multiple of 4 restriction. Edit: this does work with later versions, but you must make sure that the variable in the ini is lowercase and the variable in the scm is upper case. Later versions also don't complain about the out of bounds access using this method. Edit 2: OK, my bad, case doesn't matter, but in later versions you must reload the builder every time you change the ini, this doesn't seem to apply to 0.22. Edit 3: WOW! In later versions you can assign the variable to non-DWORD boundaries and it still works! This means you can easilly use ANY address between 0?? and FFFF?? Edited December 21, 2005 by Y_Less Link to comment Share on other sites More sharing options...
Y_Less Posted December 21, 2005 Author Share Posted December 21, 2005 Right, I have used this hack to produce a new version of my array code, this version is alot more compact and easier to see what is going on (though stands no chance of being decompiled as it uses pre-4th-segment code and variable labels, there are ways round these but they make the code much harder to write). Directly under your "DEFINE MEMORY" line insert the following code: ;; Put your array code here.;; The first index should be set to the define memory ammount + 7;; Subsequent ones are that + size of previous arrays (in bytes);; Note: All numbers should be converted to HEX ;; [email protected] is the return/set value variable;; [email protected] is the current array index;; [email protected] is the current array offset (££labelarrayx - easy way to set it) :labelarrayget 008A: $arrayindex1 = [email protected];; Set the current array index (start from 0) 0010: $arrayindex1 *= 4;; Create byte offset from DWORD offset (aka 4-byte array position)005E: $arrayindex1 += [email protected];; Add the current arrays start position, for array 0: [email protected] = 57 (in this case)0010: $arrayindex1 *= 256;; Shift 1 byte left (or right due to little-endian ordering) 0008: $arrayindex1 += 1358954498;; Add 0x51000002 to create OpCode data 008B: [email protected] = $arrayindex1;; This line will be altered by the above code, $arrayindex1 points to here0051: return :labelarrayset008A: $arrayindex2 = [email protected];; Set the current array index0010: $arrayindex2 *= 4;; Create byte offset from DWORD offset (aka 4-byte array position)005E: $arrayindex2 += [email protected];; Add the current arrays start position, for array 0: [email protected] = 57 (in this case)0010: $arrayindex2 *= 65536;; Shift 2 bytes left (or right due to little-endian ordering) 0008: $arrayindex2 += 512;; Add 0x200 to create OpCode data 008A: $arrayindex2 = [email protected];; This line will be altered by the above code, $arrayindex2 points to here0051: return:labelarray0 ;; Add 2 "0000: nop"s for every array position you want.;; Array size 5, needs 10 nops:0000: nop0000: nop0000: nop0000: nop0000: nop0000: nop0000: nop0000: nop0000: nop0000: nop:labelarray1 Then under [variables] in your VICESCM.INI add the two following lines: 002E=arrayindex1005D=arrayindex2 Note: you have to change this number based on your DEFINE MEMORY size, the final number should be: define memory size + 7 + decimal number represented above (in hex), e.g. for a memory size of 50, the final ini code will be: 0067=arrayindex10096=arrayindex2 Finally, to use this in your code, you don't need alot. To write to the array use: 0050: gosub ££labelarrayset And to read from the array use: 0050: gosub ££labelarrayget The array value will be returned/read from [email protected], [email protected] is your array index and [email protected] is the start address of the current array (so you can use lots of arrays with the same code). These must be set BEFORE you set/get the array value, which will just be the data stored at (([email protected] * 4) + [email protected])?? copied to [email protected] This version is far more compact and easy to use than previous versions so should be actually usable. Link to comment Share on other sites More sharing options...
Demarest Posted December 21, 2005 Share Posted December 21, 2005 Wow. So easy and yet... here we are you only now finding it. Good for all of us. Link to comment Share on other sites More sharing options...