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 ... 73 74 [75] 76 77 ... 153
1111
« on: July 16, 2011, 02:28:37 pm »
This is a very extensive and well-written tutorial. But I have some questions/concerns about some of these topics and code structures. - Lambdas in Axe are, for all intents and purposes, slightly bloated subroutines (due to the jump past the routine). I realize that lambdas have other qualifying features like ease of inserting inline, but I feel that the fact that they produce slightly larger code than a standard subroutine is worth being mentioned.
- Regarding closures and currying, as far as I can tell, code would be more optimized simply without these techniques. I think code also looks cleaner without the unnecessary nesting. If you can give me a counter-example, I would love to see it. But regarding the examples you used, compare these:
Lbl CAT r₁+r₂→r₄ DOG(r₁,r₂,r₃,r₄) Goto DOGE Lbl DOG r₄+r₃ Return Lbl DOGE →r₁ Return Lbl CATE
| | Lbl CAT r₁+r₂→r₄ DOG(r₁,r₂,r₃,r₄) →r₁ Return Lbl CATE
Lbl DOG r₄+r₃ Return Lbl DOGE
| λ(r₁*(λ(r₁+r₂)(r₁,r₂)))(r₁,r₂)
| | λ((r₁+r₂)*r₁)(r₁,r₂)
|
- A big reason why the example above without currying is so much smaller is because it omitted an argument list due to one of the functions being eliminated. This is something that you should do in multiple other places as well. Calling a function with the r-vars as arguments is redundant, because all it does is load the r-vars and then save them back where they already were. For example, λ((r₁+r₂)*r₁)(r₁,r₂) could be λ((r₁+r₂)*r₁)() to save 12 bytes, and DOG(r₁,r₂,r₃,r₄) could simply be DOG() to save a massive 24 bytes.
VIII - Returning multiple values
WARNING -- THE FOLLOWING PROCEDURE IS POSSIBLY DANGEROUS IF USED INCORRECTLY.
|
- (Ninja'd by calcdude84se) Your procedure is dangerous if used at all. You push the second value to return on top of the return address, so the Return will read the wrong value and almost certainly crash or otherwise negatively affect your calculator. You need to keep the return address at the top of the stack and push extra return values under it:
Lbl HACK r₁+r₂ Asm(E3E5) . ex (sp),hl \ push hl r₂*r₁ Return
|
Also, a suggestion to make code look cleaner. Fish around in this for special characters on the calculator:
1112
« on: July 15, 2011, 10:13:44 pm »
'appv' is not parsed as 15h, unlike it is when in a string. This should probably be changed to return the same ASCII value it would represent in a string. The same probably goes for 'var' and 'grp'.
EDIT: Also, an entirely unrelated bug. B_CALL(_DelVarArc) apparently trashes (OP1) if the variable was archived, so attempting to create a variable that already exists in the archive deletes the old one and then fails to create the new one. Luckily, this is easily fixable. I found a solution that I think is as good as it gets, but I could be wrong. It only costs a single byte.
p_NewVar: .db __NewVarEnd-1-$ 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:
1113
« on: July 14, 2011, 11:34:17 pm »
Also, I found it a bit annoying that when I did something like If E<(96*256), the part in the parentheses wasn't reduced to a constant before doing the less-than operation. Could the look-ahead parsing be able to detect constants in parentheses?
This times a million.
1114
« on: July 14, 2011, 08:12:37 pm »
In addition to structs, another nice feature would be expression continuation over multiple lines. Take this for example:
lambda(Pt-on(r1,r2,r3):Pt-on(r1,r2+8,r3+8)) -> A It would be nice if when a line ends with a colon, the expression isn't closed at the end of the line, but rather continued on the next one:
lambda(Pt-on(r1,r2,r3): Pt-on(r1,r2+8,r3+8)) ->A I'm finding myself writing long lambdas ATM for TaN (don't yell at me for making it Axe based again, I only did it because the new functional features make life so much easier considering enemies), some of which take dozens of lines. This addition would be very helpful
You could just write the function as a subroutine and then deference the pointer to the subroutine.
1115
« on: July 13, 2011, 12:31:44 pm »
The reason why code and data are separated is because these recent developments you speak of require either a dedicated program to enforce this setting or an OS/boot code mod. I think most calculator gamers are just students who learned from other students that you can put cool games on your calculator. They probably have no knowledge of these recent developments regarding the execution limit, and will be complaining upon discovering that the game he put on his calculator causes a crash.
EDIT: Oh, I forgot. Or you can add ~50 bytes of code to do this in large programs, which may be completely unnecessary if the code is just moved around a bit.
1116
« on: July 13, 2011, 11:33:47 am »
Not all of what follows are bug reports, but I figured it's just easier to make one post here instead of 3 posts across multiple topics. Some errors in the command list: - Returnrr should be Returnr
- The description of the new Fill() command says "Ptr1" although it should say "Ptr"
- The grayscale DispGraphClrDraw commands are not as fast as their non-clearing counterparts. The 3-level variant is about 4,000 cycles slower and the 4-level variant is about 11,000 cycles slower. You probably don't want to be technical and cite these numbers in the command list, but you shouldn't say that they're just as fast.
Some actual errors: - Inline if statements (and I mean actual inline If:.true:End statements) seem to cause problems if they are inside of the argument list for Axe commands.
- Shade() does not load a 0 into the h register. I'm guessing you left this out because in most uses, it wouldn't matter. But it could still matter in some, like testing if the value is greater than, less than, or equal to a certain value.
An optimization: - Operations on big-endian values at constant pointers (e.g. +{°A}rr) would be better as: ld bc,(ptr) \ ld d,c \ ld e,b
A suggestion: - A checksum routine that's more than a simple checksum. Here's a CRC-CCITT implementation I wrote. And no, I actually didn't realize z80 bits had one just like this until after I had written it.
p_CheckSum: ld b,h ld c,l pop af pop de push af ld hl,$FFFF __CheckSumNext: ld a,(de) xor h ld h,a push bc ld bc,8<<8+$10 __CheckSumLoop: add hl,hl jr nc,__CheckSumSkip ld a,h xor c ld h,a ld a,l xor $21 ld l,a __CheckSumSkip: djnz __CheckSumLoop pop bc ex de,hl cpi ex de,hl ret po jr __CheckSumNext
1117
« on: July 13, 2011, 10:45:43 am »
To make the string "123@456", you would do something like the following. 40 is the hexadecimal character code for @.
"123"[40]"456"
1118
« on: July 12, 2011, 08:48:57 am »
Just checking, have you actually tested the routines out? Because I didn't actually test those routines I gave you, I just modeled them after some routines I knew worked and hoped these would still work as well.
1119
« on: July 12, 2011, 01:05:00 am »
Wow, I just did something I didn't think was even possible. I found a good use for a forward djnz. The following is the part of p_Disp4Lvl that initializes the mask: ld a,%11011011 or a ld hl,flags+asm_flag2 inc (hl) jr z,__Disp4Lvlskip rra ld b,(hl) inc b jr z,__Disp4Lvlskip rra ld (hl),-2
| | ld a,%11011011 or a ld hl,flags+asm_flag2 inc (hl) jr z,__Disp4Lvlskip rra ld b,(hl) djnz __Disp4Lvlskip rra ld (hl),-2
|
1120
« on: July 11, 2011, 08:55:55 pm »
That, and my independent documentation of Axe's commands. These are the optimized signed divisions that will round down instead of to zero: - //2
- //64
- //128
- //256
- //512
- //16384
- //32768
1121
« on: July 11, 2011, 08:31:07 pm »
In Axe, calculations that would generate decimals, such as division, will always be truncated. When dealing with positive numbers, this means results are rounded down. However, with negative numbers, the story changes slightly depending upon how the math is performed. With something like ⁻10//3, the signed division routine converts any negative inputs to positives and then corrects the sign later. So it actually calculates the result of 10/3 which gives 3 due to truncation, but then negating the final answer to correct for the signs results in the answer actually having been rounded to zero from -3.333... However, with optimized divisions like ⁻7//2, the inputs are not first converted to positive numbers and then operated on, resulting in the truncation actually rounding down to ⁻4. In summary: - Normal division: rounds to zero (down)
- Signed division: rounds to zero (not always down)
- Signed disivion by optimized constants: rounds down
1122
« on: July 11, 2011, 08:18:49 pm »
Ah! Now it works better! But there a new problem If I go up or left, I'm on the other side... Do you understand me?
Oh sorry, I found the problem and corrected it. I needed to check if the position became negative one before performing the min function. Check the code again, hopefully it should work now.
1123
« on: July 11, 2011, 02:10:40 pm »
Really!?
1124
« on: July 11, 2011, 11:22:21 am »
I don't get it work
Oh sorry, I typoed when copying that code from my calculator to here. +getKey(4) and +getKey(2) should be -getKey(4) and -getKey(2). Wait, so +{const}r isn't optimized automatically? :O
Nope. It bugs me a bit that Axe doesn't recognize those and parse them just like variables. I'm guessing Quigibo hasn't included them because he would need some sort of look-ahead parsing for that, which he hasn't implemented.
1125
« on: July 11, 2011, 11:16:52 am »
My calculator does not have a ViewScreen port. Otherwise, it seems to be pretty much the same.
Pages: 1 ... 73 74 [75] 76 77 ... 153
|