This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Messages - Runer112
Pages: 1 ... 63 64 [65] 66 67 ... 153
961
« on: December 12, 2011, 01:48:13 am »
First, an optimization so simple, it doesn't even deserve a fancy side-by-side comparison. It's funny that nobody (including myself, until now) noticed this optimization, because it's something you wouldn't even think about optimizing. But anyways, getting to the optimization: remove the ld hl,0 at the start of p_Mul! Who would've thought, optimize code by simply deleting a line of it! Second, I actually thought of the above optimization while toying around with the multiplication routine attempting to optimize it in another manner. Although I know you generally like to optimize for size, I think that with a routine like multiplication that is so heavily used, a routine optimized more for speed would be worth it. Especially if the cost in size is a paltry two bytes! This optimization will get a fancy side-by-side comparison. Smaller routine: 14 bytes, ~836 cycles
p_Mul: .db __MulEnd-1-$ ld c,h ld a,l ld b,16 __MulNext: add hl,hl add a,a rl c jr nc,__MulSkip add hl,de __MulSkip: djnz __MulNext ret __MulEnd:
| | Faster routine: 16 bytes, ~741 cycles
p_Mul: .db __MulEnd-1-$ ld c,l ld a,h call __MulByte ld a,c __MulByte: ld b,8 __MulNext: add hl,hl add a,a jr nc,__MulSkip add hl,de __MulSkip: djnz __MulNext ret __MulEnd:
| EDIT: The division routine just gave me a great idea. For another paltry two bytes, if you'd like, you can cut the time for multiplying 8-bit numbers in half! Compared to Axe's current routine, you would get a speed increase anywhere from 12% to 120% for a total size increase of one byte! Not bad! Of the three routines I have provided, this routine is definitely my favorite. Even faster routine: 18 bytes, ~749 cycles for 16-bit inputs (h!=0), ~386 cycles for 8-bit inputs (h=0)
p_Mul: .db __MulEnd-1-$ ld c,l xor a ld l,a add a,h call nz,__MulByte ld a,c __MulByte: ld b,8 __MulNext: add hl,hl add a,a jr nc,__MulSkip add hl,de __MulSkip: djnz __MulNext ret __MulEnd:
| EDIT 2: Another thought: the same basic optimization I applied in the 16-byte routine (the faster routine before the 8-bit optimization) could be applied to p_MulFull to save a couple hundred cycles in each fixed-point multiplication. High-order multiplication and fixed-point multiplication could no longer share a routine, but it might be worth it considering the two multiplication techniques are (in my experience) not commonly used in the same scenario.
962
« on: December 11, 2011, 10:23:21 pm »
So many commands have changed since my last update of this, and now there are peephole optimizations to account for too. Although it would be a lot of work, I really should get this back up to date...
963
« on: December 11, 2011, 12:05:21 am »
Finally forced myself to update this thing for the past 2 months of activity! And as you can see in the changelog, Axe 1.1.0 was quite an impressive release; it resolved 25 issues. Phew, that took a while... EDIT: After multiple reports, compiling from archive is definitely confirmed to have problems.
964
« on: December 10, 2011, 10:42:46 pm »
No need for ...End, because ... already ends the comment block whether or not it's a conditional.
965
« on: December 10, 2011, 10:31:28 pm »
This can already be done in the form #-(^A).
966
« on: December 07, 2011, 09:30:09 pm »
Just throwing this out there, I had a very simple idea for a possible syntax for preprocessor conditionals. Pretty much, there would be no new syntax. It would just boil down to whether or not the condition of an If statement is a constant. And it can't get any simpler for beginners to understand than that.
967
« on: December 07, 2011, 01:58:50 pm »
I'm going to bump a feature request I've probably mentioned multiple times in the past: preprocessor conditionals. It is something that cannot be done in an Axiom and would be useful to every programmer, whether it's for building your program in a debug mode, testing different blocks of code to see which is better/faster/smaller, or (my personal favorite) making Axe libraries that programmers can very easily customize to their needs by changing a few defines. I'm sorry about bringing up this particular request multiple times, but this is the #1 feature I would like to see in Axe, and I'm sure many others would find it useful as well.
968
« on: December 06, 2011, 07:49:33 pm »
I believe that a frameskip would be better. The game would run at 100% speed, but every 30th frame or so would be skipped. I believe this is a better solution for a few reasons: - Accurately emulating the game itself is more important than accurately emulating the graphics.
- Skipping every 30th frame would be virtually unnoticeable, except maybe if you pay very close attention to graphical effects in which the game is trying to murder people with a history of seizures.
- If you were to implement a variable game speed limit (e.g. 50%, 200%, unlimited), you would need such a frameskipping method anyways.
969
« on: November 26, 2011, 06:06:48 pm »
Drawing text to the back buffer has been asked for multiple times, and has been rejected multiple times. Although it's a great idea, Axe uses the OS text drawing routine, which is only capable of drawing text either directly to the screen or to the front buffer.
970
« on: November 23, 2011, 09:29:31 am »
Here's a pretty minor bug brought to my attention by CoolioJazz, but a bug nonetheless. I thought this problem was fixed a while ago, but I guess it was only half fixed: [23:23:08] <+Runer112> I believe the documentation has fPart and iPart mixed uo [23:23:10] <+Runer112> up* [23:23:20] * Quits: +geekbozu ([email protected]) (Quit: i need sleep it what like sunrise or somthing X.x) [23:23:24] <+Runer112> it says nib{ is fPart( and it says float{ is iPart( [23:23:27] <+Runer112> but it's backwards [23:23:30] <+OmnomIRC> (#)<CoolioJazz> it says they are both iPart( [23:23:51] <+OmnomIRC> (#)<CoolioJazz> so maybe he fixed one and forgot the other was wrong? [23:24:30] <+OmnomIRC> (#)<CoolioJazz> regardless, nib{ is iPart( and float{ is fPart( then?
971
« on: November 16, 2011, 08:54:07 pm »
Ah, I guess that could do it. A very crazy bug indeed.
972
« on: November 16, 2011, 08:48:07 pm »
I know exactly what is causing that error. It is as runner said, the peephole optimizer. There is currently a bug where Axe confuses offsets with constants and is turning your code into exactly this:
Data(0,0,0,0,0,0,0,0,0,......)->A GetCalc("appvMTEMP",)->B Copy(A,B,48 The current offset in the code is 48 and you were using 48 at the same time to specify the size. It also happens to be in a pattern that normally peephole optimizes. So now its attempting to create an appvar with a size equal to the pointer which is a number around $9E00 which is over 40,000 bytes! You can fix this temporarily as Runer said by using zoom compile or adding one more zero to your data. Adding more code to the end wouldn't fix anything because there aren't any known bugs with ending code changing behavior to my knowledge.
Uhh... I don't think that explains the code I'm looking at: ld hl,Data000 ld (axv_A),hl ld hl,Data001 push hl ld hl,48 ;I'm still here call p_NewVar ld (axv_B),hl ld hl,(axv_A) push hl ld hl,(axv_B) push hl ld hl,48 pop de ;Note the abrupt end
p_NewVar: B_CALL(_EnoughMem) pop hl ex (sp),hl jr c,__NewVarFail push de push hl MOV9TOOP1() B_CALL(_ChkFindSym) jr c,__NewVarSkip B_CALL(_DelVarArc) __NewVarSkip: pop hl ld a,(hl) MOV9TOOP1() pop hl push af B_CALL(_CreateVar) pop af ex de,hl and %00011111 ret z cp CplxObj ret z inc hl inc hl ret __NewVarFail: ld hl,0 ret __NewVarEnd:
Data000: .block 48
Data001: .db AppVarObj,"MTEMP",0
973
« on: November 16, 2011, 03:18:44 pm »
Axe has problems when the last of the compiled code in a program is targeted by the peephole optimizer. In this case, Axe is producing erroneous code because Copy(A,B,48 is the last bit of code in the program and it's targeted by the peephole optimizer. This can be avoided easily enough until it is fixed by putting some other code after it or turning off the peephole optimizer altogether by pressing ZOOM to compile instead of ENTER.
974
« on: November 15, 2011, 08:06:53 pm »
Shame on both of you for not including a check that the variable is successfully found. !If GetCalc("appvPIC",Y₀) .Handle error End Copy(Y₀,L₆,768)
975
« on: November 13, 2011, 08:23:54 pm »
It's actually a lot simpler than it may sound. It's just a bit trickier in TI-BASIC because TI-BASIC has no binary data types. To use your number as an example, if you break down 854 into binary, you get:
512 64 4 | | | 00000011 01010110 | | | 256 16 2
This says that 854 = 512+256+64+16+4+2. And there's your answer, right in there. Each bit tells you whether 2^([bit position from right]) is a binary component of the number. The trick is isolating the bit that you care about. I do this by rotating the number to points where TI-BASIC is able to mask off the bits I don't want. The functions I have to work with are iPart() and fPart(), which mask on either side of the decimal point, so I have to shift the bit I want immediately next to the decimal point to be able to use these effectively. First I do this by dividing by 2^([bit position]+1), which effectively shifts the binary number right [bit position]+1 places:
00000000 00000001.10101011 0 | 256
Then I can mask off all the bits on the left with fPart() (in this case, just the bit representing 512):
00000000 00000000.10101011 0 | 256
I then multiply by 2 to shift the number back one place to the left:
00000000 00000001.01010110 | 256
And finally, I can use iPart() to mask off all the bits on the right:
00000000 00000001.00000000 | 256
So I'm left with the bit representing 256 in the one's place of my number and all other digits gone, thus giving me the boolean value 1, which tells me that 256 is a binary component of 854.
Pages: 1 ... 63 64 [65] 66 67 ... 153
|