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 ... 87 88 [89] 90 91 ... 153
1321
« on: April 26, 2011, 04:47:07 pm »
Here's a request that shouldn't be hard to implement: adding If conditionals to sub and Goto.
I agree, that would be nice. I think Quigibo was contemplating adding this feature not long ago. Also, I would like For loops to work with negative numbers (as a seperate option). For example, For(I,-1,1) is a legitimate loop (check the positions to the left, center, and right, for instance) but would end immediately. So, I would like to specify For(I,-1,1)r to show that the indexes are signed.
Having For() loops work with negative numbers would be sort of tricky and larger than normal loops, because signed comparisons are harder than unsigned comparisons. To have a loop like For(I,⁻1,1), you could just use a loop like For(I,⁻1+256,1+256) and change every reference of I in the loop to I-256. Alternatively, you can make a custom While loop that would be smaller and faster: ⁻1-2 While 1 +2→I ;Your code goes here End!If I-1
Oh, and I would also like to specify custom steps in For loops, like we can in TI-BASIC.
I've been wondering why Quigibo hasn't added that as well. As an addition to the signed For Loop, Could there be a loop that automatically increments negatively or positively so that the loop always runs? Like, say, For(Q,A,B,C)rr where C>0, would increment by -C if A>B and C if A<B
This doesn't seem like a loop structure that would be widely used, especially since modern programming languages don't have loops like this. This is the kind of thing that you would best build a custom loop for.
1322
« on: April 25, 2011, 10:05:52 pm »
Some more Axiom feature requests: the ability to specify commands that must be followed by a store token, and the ability to specify that the Axiom should be searched before the internal commands.
I understand that you didn't make Axioms parsed first because it would slow down parsing of normal commands, which would probably account for most of the program. But having it as an option would be useful. That way if your Axiom didn't supplement/replace any built-in commands, you wouldn't specify this option and parsing speed would be normal. But if your Axiom was designed to replace internal commands, you could do so by specifying this option.
Also, if you're going to modifying the Axiom system with any feature additions (not necessarily the ones above), it would probably be a good idea to start adding more information to the Axiom header, namely version information. This would signal to the Axe application parsing the Axiom whether or not the application's version is compatible. Adding an expanded header would also allow for the addition of more information, like whether or not to parse with a higher priority than internal commands. Perhaps:
.db $C0,$DE ;Header bytes reversed so old Axe applications won't accept the Axiom .db Axiom_version ;Possibly additional header data
1323
« on: April 25, 2011, 09:18:01 pm »
Stolen borrowed from WikiTI:
#define FULLSPEED in a,2 \ rla \ sbc a,a \ out (20h),a
And this gives you the added bonus of the CPU operating approximately 25KHz faster at full speed mode!
Note: This has the side effect of out (0),0 on the TI-83+. Is that okay?
Since this is the current routine: #define FULLSPEED in a,(2) \ and 80h \ rlca \ out (20h),a
It shouldn't make 83+ compatibility any worse than it already is.
1324
« on: April 25, 2011, 02:50:35 pm »
Stolen borrowed from WikiTI: #define FULLSPEED in a,2 \ rla \ sbc a,a \ out (20h),a
And this gives you the added bonus of the CPU operating approximately 25KHz faster at full speed mode!
1325
« on: April 24, 2011, 10:04:37 am »
Runer, how do you suggest I do the token replacement? The first problem I had was that you have to know ahead of time what Axioms are being used in the program so it knows what to replace. That can easily be solved with your first suggestion of always requiring the Axioms to come first, but this does remove a possible convenience, however its probably worth it. The next problem is that for each token the Axioms have to be searched for in the symbol table to find their pointers, which could be costly with a large number of programs. Then, when finally found, each Axiom would have to be scanned completely to find if the token matches by transversing the offset list (again, for each token). So if you had 2 Axioms with 25 new commands each, and about 20 tokens on the screen, that's 40 symbol table searches + 1000 checks + the built in checks. I could definitely see this causing lag in the scrolling. There might be another way of caching the data in ram somewhere, and maybe setup a binary search, but this would greatly complicate things. The token hook is only called when tokens are being printed and I don't want to use other hooks so its difficult to have some sort of "pre-parsing". I am however still open to suggestions of what to name the rest of the custom override tokens.
If there's a way to only parse any #Axiom( tokens immediately when the program editor is opened, that seems like a good route to take. You could get their pointers from the symbol table and cache them at the start, and you'd only need 3 bytes * 5 Axioms of cache storage. If there isn't a specific event that can be triggered upon opening the program editor, you can always fake it by hooking into an event that periodically occurs, but only acting upon it the first time it is triggered. Your other suggestion, If I'm reading this correctly, is a static offset to optimize doing ld hl,dynamic_ptr; ld de,offset; add hl,de; correct? This might be an option in the future. There are other useful features I can think of too, like adding the ability to create Axioms that take a label as their first argument, like how the current interrupt setup command works.
Yeah, something like that. It would be more useful for doing offset calls though, like: OFS_NEXT(7) call sub_Axiom1
This is the sort of thing you often do with drawing commands so they can work with different buffers.
1326
« on: April 23, 2011, 10:08:29 pm »
I'm not sure how that's a bug, the parser throwing an error at erroneous code is a good thing. Axe doesn't support custom named variables. Axe's variables are A- Z, θ, r1-r 6, X1T- X3T, and Y1T- Y3T.
1327
« on: April 23, 2011, 09:49:50 pm »
I don't feel great about bumping my own suggestion because I don't want to make it seem like I think my suggestion is more important than others. But in reality, it sort of is. I know you (Quigibo) have been leaning away from adding new commands and instead implementing parser and general application improvements, leaving new commands for Axiom programmers. I think this is a great idea, leaving the deep down technical stuff to the person who knows it best and leaving the job of writing commands to the general assembly programming populous. But it would be useful if Axiom programmers had a programming tool that currently only you have. There are commands that I'm literally just waiting for this ability to finally implement. The Axiom system is great. Things like automatic jump and call replacements and manual 16-bit load replacements are great, which even the hard-coded Axe commands cannot do. But there's one thing that internal Axe commands can do whereas Axioms can't that I would love to be able to do. Would it be possible to add a new internal Axiom compiler feature that allows calls to be made with offsets? Perhaps a new macro like ld b,b \ .db BYTE \ .org $-2? Because this would be incredibly useful for calling a command in slightly different ways, like you often use with an optional buffer argument for drawing commands.
There are a few other command-adding abilities that only you have that would also be useful. For instance custom token replacements would be nice, even if they had limitations such as requiring Axioms to be at the very start of the program or only loading token replacements upon opening the program editor. The closer that Axiom programmers come to your ability to add new commands, the less we would have to bug you about adding commands.
1328
« on: April 23, 2011, 09:21:56 pm »
getkey(key1,key2...) This would check all of the keys with the corresponding getkey numbers and return the getkey number of the one that was pressed.
I can't really think of a use for that, it seems to me like plain old getKey would do what you want. Although perhaps I'm not quite understanding your suggestion. Could you give me an example of how it might be used?
1329
« on: April 23, 2011, 12:10:29 pm »
I haven't tested the code myself, but I'm guessing the problem you're experiencing is that the 'I' sometimes moves in a random direction in addition to the direction you pressed. This is happening because the cursor position adjusting routines destroy the key value in the a register, which possibly activates another key check if the value. For instance, if Ypos was 1 and you pressed the down key, Yinc would be called. This would load Ypos into a and increase it, leaving 2 in the a register. When the Yinc routine returns, because the a register still contains 2 from the routine, it will mistakenly activate Xdec as well. The "proper" way to fix this is to turn your key checks into a series of ElseIfs, so if one of them activates, none of the others do. The easiest way to form If and ElseIf statements is with jumps instead of calls, so I'm going to restructure your program a bit. Also note that, when forming If structures with jumps in assembly, the jumps are used to skip the portions of code you don't want, not to reach the portion of code you do want. I'm also going to add a bit of spacing, tabbing, and comments to make this a little easier to read. ...(insert header here)
Xpos .equ AppBackUpScreen Ypos .equ Xpos+1
ld A,0 ld (Xpos),A ld (Ypos),A
Loop: B_CALL _GetCSC cp 1 jr nz,Yincskip ;If key=1 ;Yinc: ;Then (the label is commented because it isn't actually used, it's just for clarity) ld A,(Ypos) cp 7 Call NZ,Ainc ld (Ypos),A jr EndKeys ;Else... Yincskip: cp 2 jr nz,Xdecskip ;...If key=2 ;Xdec: ;Then ld A,(Xpos) cp 0 Call NZ,Adec ld (Xpos),A jr EndKeys ;Else... Xdecskip: cp 3 jr nz,Xincskip ;...If key=3 ;Xinc: ;Then ld A,(Xpos) cp 15 Call NZ,Ainc ld (Xpos),A jr EndKeys ;Else... Xincskip: cp 4 jr nz,Ydecskip ;...If key=4 ;Ydec: ;Then ld A,(Ypos) cp 0 Call NZ,Adec ld (Ypos),A jr EndKeys ;Else... Ydecskip: cp 15 jr nz,Quitskip ;...If key=15 ;Quit: ;Then ret Quitskip: EndKeys: ;End (the above Else... ...If's are really ElseIfs, so one End handles them all) ld A,(Xpos) ld (CurCol),A ld A,(Ypos) ld (CurRow),A ld HL,Itx B_CALL _PutS jp Loop
Adec: dec A ret Ainc: inc A ret Itx: ;"I" text .db "I",0 Quit: ret
I hope that restructuring makes sense. If not, feel free to ask me about it more. But that code was just to correct the key problem that you were experiencing. Time to tear this code apart and make the most optimized version I can. I commented nearly every line with pseudocode that should hopefully make it easier to understand. The pseudocode is sort of a mix of TI-BASIC, Axe, and C. ...(insert header here)
ld de,0 ;We will designate e=curRow, d=curCol
Loop: ;While true B_CALL(_GetCSC) ; getKey->key cp 15 ; ret z ; ReturnIf key=15 dec a ; key-- jr nz,Yincskip ; If key=0 (if original getKey=1) ;Yinc ; Then inc e ; curRow++ bit 3,e ; jr z,EndKeys ; If curRow=8 dec e ; 7->curRow Yincskip: ; End dec a ; key-- jr nz,Xdecskip ; If key=0 (if original getKey=2) ;Xdec: ; Then dec d ; curCol-- jp p,EndKeys ; If curCol=-1 inc d ; 0->curCol Xdecskip: ; End dec a ; key-- jr nz,Xincskip ; If key=3 (if original getKey=3) ;Xinc: ; Then inc d ; curCol++ bit 4,d ; jr z,EndKeys ; If curCol=16 dec d ; 15->curCol Xincskip: ; End dec a ; key-- jr nz,Ydecskip ; If key=4 (if original getKey=1) ;Ydec: ; Then add a,e ; jr z,EndKeys ; If curRow!=0 dec e ; curRow-- Ydecskip: ; End EndKeys: ; ld (curRow),de ; e->(curRow) ;d->(curCol) ld a,'I' ; B_CALL(_PutMap) ; Disp 'I' jr Loop ;End
EDIT: Just came up with an even crazier, even more optimized version: ...(insert header here)
ld de,0 ;e=curRow, d=curCol
Loop: B_CALL(_GetCSC) cp 15 ret z dec a cp 4 jr nc,EndKeys dec a sra a jr nz,UpDown ;LeftRight: ld c,d adc a,a add a,a dec a add a,d ld d,a and %00010000 jr z,EndKeys ld d,c UpDown: ld c,e neg add a,e ld e,a and %11111000 jr z,EndKeys ld e,c EndKeys: ld (curRow),de ld a,'I' B_CALL(_PutMap) jr Loop
1330
« on: April 21, 2011, 12:09:28 am »
Here are the most optimized constant comparisons I could come up with. I'm not sure what optimized comparisons for powers of 2 you found, because I didn't really find any. The only individual special cases I found dealt with 0, 32768, and 65535. And I hope the parser can handle the fancy constant mangling operations necessary for some of these. p_GE0: .db 3 ld hl,1
p_GT65535: .db 3 ld hl,0
p_LE65535: .db 3 ld hl,1
p_LT0: .db 3 ld hl,0
p_GE1 =p_NE0 p_GT0 =p_NE0 p_LE0 =p_EQ0 p_LT1 =p_EQ0
p_GE32768 =p_Div32768 p_GT32767 =p_Div32768 p_LE32767 =p_SGE0 p_LT32768 =p_SGE0
p_GE65535 =p_EQN1 p_GT65534 =p_EQN1 p_LE65534 =p_NEN1 p_LT65535 =p_NEN1
p_GEconstMod256EQ0: .db 6 ld a,h sub const>>8 sbc hl,hl inc hl
p_GTconstMod256EQ255: .db 6 ld a,h sub const+1>>8 sbc hl,hl inc hl
p_LEconstMod256EQ255: .db 6 ld a,h add a,-(const+1>>8) sbc hl,hl inc hl
p_LTconstMod256EQ0: .db 6 ld a,h add a,-(const>>8) sbc hl,hl inc hl
p_GEconst: .db 8 xor a ld de,-const add hl,de ld h,a rla ld l,a
p_GTconst: .db 8 xor a ld de,-(const+1) add hl,de ld h,a rla ld l,a
p_LEconst: .db 7 ld de,-const add hl,de sbc hl,hl inc hl
p_LTconst: .db 7 ld de,-(const+1) add hl,de sbc hl,hl inc hl
1331
« on: April 20, 2011, 07:05:19 pm »
I may be wrong, but couldn't you get the exact number of cycles you wanted (up to 255 or maybe 256) by outputting the desired number of cycles to the counter port and setting the timer speed to the CPU clock speed?
1332
« on: April 20, 2011, 06:48:05 pm »
@Runer: I totally agree, I don't understand how the first option won.
Actually my post was vouching for the first option. It was explaining that giving the user manual control is in fact worse if their program is intended to run at 15MHz.
1333
« on: April 20, 2011, 06:10:56 pm »
If you post what you have so far, I can look at them and see if I can find any optimizations for them. I also might see if there are any other optimized comparisons you don't already have that I could contribute.
1334
« on: April 20, 2011, 04:37:29 pm »
By the way, I just want to clarify something about the second poll option because its text is somewhat misleading. Your code would only be smaller if you run your program at 6MHz. If your program runs at 15MHz, your program could actually be bigger by having to manually add the Normal and Full wrapper. Not to mention the added pain of having to add it.
1335
« on: April 19, 2011, 11:07:34 pm »
How does it compare to this one? I suggested it a while ago but Quigibo either didn't see it or didn't seem to be interested in it.
Pages: 1 ... 87 88 [89] 90 91 ... 153
|