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 ... 60 61 [62] 63 64 ... 153
916
« on: January 10, 2012, 08:23:47 pm »
Sorry for the double post, but technically, this is a project update!I fixed everything that I knew was bad about the previous version of the token hook that I posted. The updated hook is now: - DoorsCS compatible!
- zStart compatible!
- Compatible with any Axiom name length!
- Faster!
- Smaller!
And stronger, too!
.nolist #include "ti83plus.inc" .list
#define cxPrevApp cxPrev+cxCurApp-cxMain
#define p_GetArc $55E7 #define p_ReadArcApp $5658 #define p_CopyArc $568D
#define TokenHook_Temp appRawKeyHandle #define AxiomTokens statVars #define AxiomTokens_End curGStyle
.org $71E0
TokenHook: .db $83 ld a,(cxCurApp) cp kPrgmEd ret nz ld bc,(EditTop) ld a,(bc) cp tDecPt ret nz inc bc ld a,(bc) cp tDecPt jr z,TokenHook_IsAxe sub tA cp tTheta-tA+1 ret nc TokenHook_IsAxe: push hl ld hl,cxPrevApp ld a,kPrgmEd cp (hl) jr z,TokenHook_SkipAxiomSearch TokenHook_AxiomSearch: ld (hl),a push de ld hl,AxiomTokens ld (iy+statFlags),h B_CALL(_BufClr) ld hl,AxiomTokens-AxiomTokens_End ld (TokenHook_Temp),hl B_CALL(_IsAtTop) push de push hl B_CALL(_BufToBtm) B_CALL(_IsAtTop) sbc hl,de ld b,h ld c,l ex de,hl call TokenHook_AxiomSearch_Loop pop hl ld (editTop),hl B_CALL(_BufToTop) pop hl ld (editTop),hl pop de TokenHook_SkipAxiomSearch: ld hl,AxeTokens ld b,0 jr TokenHook_CompareLoop_Start TokenHook_CompareLoop: cp e inc hl jr z,TokenHook_LowByteMatch TokenHook_NoMatch: inc hl ld c,(hl) inc c add hl,bc TokenHook_CompareLoop_Start: ld a,(hl) or a jr nz,TokenHook_CompareLoop TokenHook_DoneNoMatch: add hl,hl ld hl,AxiomTokens jr nc,TokenHook_CompareLoop_Start pop hl ret TokenHook_LowByteMatch: ld a,(hl) cp d jr nz,TokenHook_NoMatch TokenHook_Match: ld de,localTokStr push de ld c,17 ldir pop hl pop bc ret
TokenHook_AxiomSearch_CheckHeader: call ReadArc inc de add a,c ld bc,$C0DE sbc hl,bc ld c,a ret z pop bc TokenHook_AxiomSearch_Loop__: pop bc TokenHook_AxiomSearch_Loop_: pop hl TokenHook_AxiomSearch_Loop: ld a,tAsmComp cpir ret po push hl dec hl dec hl ld a,(hl) cp t2ByteTok jr nz,TokenHook_AxiomSearch_Loop_ TokenHook_AxiomSearch_Backtrack: dec hl ld a,(hl) cp tSpace jr z,TokenHook_AxiomSearch_Backtrack sub tColon cp tEnter-tColon+1 jr nc,TokenHook_AxiomSearch_Loop_ TokenHook_AxiomSearch_FindAxiom: pop hl push hl push bc dec hl rst 20h ld hl,OP1 ld (hl),AppVarObj ld a,tRParen ld bc,10 cpir dec hl ld (hl),b ld l,OP1&$FF call p_GetArc+1 jr c,TokenHook_AxiomSearch_Loop__ TokenHook_AxiomSearch_FoundAxiom: ex de,hl ld c,b call TokenHook_AxiomSearch_CheckHeader ld b,32+1 TokenHook_AxiomSearch_ScanAxiom: call ReadArc inc de ld a,h or l jr z,TokenHook_AxiomSearch_EndOfAxiom add hl,de ld de,5 add hl,de ex de,hl djnz TokenHook_AxiomSearch_ScanAxiom TokenHook_AxiomSearch_EndOfAxiom: call TokenHook_AxiomSearch_CheckHeader call ReadArc inc de ld a,c ld b,h ld c,l ld hl,(TokenHook_Temp) add hl,bc jr c,TokenHook_AxiomSearch_Loop__ ld (TokenHook_Temp),hl sbc hl,bc push bc ld bc,curGStyle add hl,bc pop bc ex de,hl call p_CopyArc+5 jr TokenHook_AxiomSearch_Loop__
ReadArc: ex de,hl xor a cp c jr z,ReadArc_RAM push bc push hl call p_ReadArcApp+11 pop de inc de pop bc ret ReadArc_RAM: ld e,(hl) inc hl ld d,(hl) ex de,hl ret
AxeTokens: .db $F4,$03,5,"Copy(" .db $FE,$03,5,"Exch(" .db $0E,$04,5,"Freq(" .db $66,$01,5,"Buff(" .db $62,$01,5,"sign{" .db $06,$00,5,Lconvert,"Char" .db $08,$04,4,Lconvert,"Hex" .db $02,$04,5,"Data(" .db $4E,$01,7,"Bitmap(" .db $02,$00,4,Lconvert,"Tok" .db $80,$04,7,"#Axiom(" .db $04,$04,5,"Rect(" .db $06,$04,6,"RectI(" .db $58,$02,3,LrecurV,"ar" .db $5A,$02,4,"app",LrecurV .db $5C,$02,3,"grp" .db $F6,$01,4,"port" .db $52,$01,5,"Text " .db $D8,$01,8,"Pt-Mask(" .db $DA,$01,7,"pt-Get(" .db $D0,$01,3,"Get" .db $14,$04,5,"rotC(" .db $16,$04,6,"rotCC(" .db $18,$04,6,"flipV(" .db $1A,$04,6,"flipH(" .db $C8,$03,7,"inData(" .db $B8,$01,5,"input" .db $74,$01,6,"float{" .db $72,$01,4,"nib{" .db $F6,$03,9,"#Realloc(" .db $68,$01,6,"#Icon(" .db $80,$01,2,Llambda,"(" .db $38,$03,5,"Load(" .db $3A,$03,5,"Next(" .db $14,$03,7,"Render(" .db $3C,$03,6,"DrawL(" .db $3E,$03,6,"DrawR(" .db $16,$03,6,"DrawS(" .db $82,$03,6,"Print(" .db $44,$03,3,"Up(" .db $46,$03,5,"Down(" .db $5C,$03,5,"Left(" .db $40,$03,6,"Right(" .db $42,$03,4,"New(" .db $5E,$03,7,"Delete(" .db 0
917
« on: January 10, 2012, 07:23:40 pm »
I figured that you weren't referring to the method I was. Your method is the size-optimized method, mine is the speed-optimized method. Your method would take n+1 bytes of storage for each entry and lookups would run in linear time, whereas my method would take n+2 bytes of storage for each entry and lookups would run in constant time. Unfortunately, my method doesn't work because Axe won't let me put static data inside of Data(). EDIT: Just read your edit, and I guess that's true. Unless there's some way to get around it by determining the Data() pointer in the first pass and the anonymous data entry pointers in the second pass, but if there was, you would know better than I.
918
« on: January 10, 2012, 07:04:39 pm »
Why add a whole new command for it? Just make Data() not barf when you put static data inside of it, and making speedy data LUTs with anonymous entries would be a piece of cake. Data("Hello"r,"there!"r,"I"r,"am"r,"a"r,"LUT"r,"of"r,"strings."r)→Str0
919
« on: January 10, 2012, 03:41:19 am »
Code vomit: .nolist #include "ti83plus.inc" .list
#define p_GetArc $55E7 #define p_ReadArcApp $5658 #define p_CopyArc $568D
#define TokenHook_Temp appBackUpScreen-2 #define AxiomTokens appBackUpScreen
.org $71E0
TokenHook_NotAxe: ld bc,('A'<<8)+(StrPROGRAM&$FF) TokenHook_CheckIfChanged: ld de,textShadow ld a,(de) xor b ret nz push hl ld h,StrPROGRAM>>8 ld l,c B_CALL(_Mov7B) B_CALL(_saveShadow) B_CALL(_rstrShadow) pop hl xor a ret
TokenHook: .db $83 ld a,(cxCurApp) cp kPrgmEd ret nz ld bc,(EditTop) ld a,(bc) cp tDecPt jr nz,TokenHook_NotAxe TokenHook_MaybeAxe: inc bc ld a,(bc) cp tDecPt jr z,TokenHook_IsAxe sub tA cp tTheta-tA+1 jr nc,TokenHook_NotAxe TokenHook_IsAxe: push hl push de ld bc,('P'<<8)+(StrAXESRC&$FF) call TokenHook_CheckIfChanged call z,TokenHook_AxiomSearch pop de ld hl,AxeTokens ld b,0 jr TokenHook_CompareLoop_Start TokenHook_CompareLoop: cp e inc hl jr z,TokenHook_LowByteMatch TokenHook_NoMatch: inc hl ld c,(hl) inc c add hl,bc TokenHook_CompareLoop_Start: ld a,(hl) or a jr nz,TokenHook_CompareLoop TokenHook_DoneNoMatch: add hl,hl ld hl,AxiomTokens jr nc,TokenHook_CompareLoop_Start pop hl ret TokenHook_LowByteMatch: ld a,(hl) cp d jr nz,TokenHook_NoMatch TokenHook_Match: ld de,localTokStr push de ld c,17 ldir pop hl pop bc ret
TokenHook_AxiomSearch: ld hl,AxiomTokens B_CALL(_BufClr) ld hl,-768 ld (TokenHook_Temp),hl ld de,(editTop) push de ld hl,(editCursor) push hl push de B_CALL(_BufToBtm) ld hl,(editCursor) pop de or a sbc hl,de inc hl ld b,h ld c,l ex de,hl call TokenHook_AxiomSearch_Loop TokenHook_AxiomSearch_Done: pop hl ld (editTop),hl B_CALL(_BufToTop) pop hl ld (editTop),hl ret
TokenHook_AxiomSearch_CheckHeader: call ReadArc inc de add a,c ld bc,$C0DE sbc hl,bc ld c,a ret z pop bc TokenHook_AxiomSearch_Loop__: pop bc TokenHook_AxiomSearch_Loop_: pop hl TokenHook_AxiomSearch_Loop: ld a,tAsmComp cpir ret po push hl dec hl dec hl ld a,(hl) cp t2ByteTok jr nz,TokenHook_AxiomSearch_Loop_ TokenHook_AxiomSearch_Backtrack: dec hl ld a,(hl) cp tSpace jr z,TokenHook_AxiomSearch_Backtrack sub tColon cp tEnter-tColon+1 jr nc,TokenHook_AxiomSearch_Loop_ TokenHook_AxiomSearch_FindAxiom: pop hl push hl push bc dec hl rst 20h ld hl,OP1 ld d,AppVarObj ld (hl),d call p_GetArc+1 jr c,TokenHook_AxiomSearch_Loop__ TokenHook_AxiomSearch_FoundAxiom: ex de,hl ld c,b call TokenHook_AxiomSearch_CheckHeader ld b,32+1 TokenHook_AxiomSearch_ScanAxiom: call ReadArc inc de ld a,h or l jr z,TokenHook_AxiomSearch_EndOfAxiom add hl,de ld de,5 add hl,de ex de,hl djnz TokenHook_AxiomSearch_ScanAxiom TokenHook_AxiomSearch_EndOfAxiom: call TokenHook_AxiomSearch_CheckHeader call ReadArc inc de ld a,c ld b,h ld c,l ld hl,(TokenHook_Temp) add hl,bc jr c,TokenHook_AxiomSearch_Loop__ ld (TokenHook_Temp),hl sbc hl,bc push bc ld bc,appBackUpScreen+768 add hl,bc pop bc ex de,hl call p_CopyArc+5 jr TokenHook_AxiomSearch_Loop__
ReadArc: ex de,hl xor a cp c jr z,ReadArc_RAM push bc push hl call p_ReadArcApp+11 pop de inc de pop bc ret ReadArc_RAM: ld e,(hl) inc hl ld d,(hl) ex de,hl ret
AxeTokens: .db $F4,$03,5,"Copy(" .db $FE,$03,5,"Exch(" .db $0E,$04,5,"Freq(" .db $66,$01,5,"Buff(" .db $62,$01,5,"sign{" .db $06,$00,5,Lconvert,"Char" .db $08,$04,4,Lconvert,"Hex" .db $02,$04,5,"Data(" .db $4E,$01,7,"Bitmap(" .db $02,$00,4,Lconvert,"Tok" .db $80,$04,7,"#Axiom(" .db $04,$04,5,"Rect(" .db $06,$04,6,"RectI(" .db $58,$02,3,LrecurV,"ar" .db $5A,$02,4,"app",LrecurV .db $5C,$02,3,"grp" .db $F6,$01,4,"port" .db $52,$01,5,"Text " .db $D8,$01,8,"Pt-Mask(" .db $DA,$01,7,"pt-Get(" .db $D0,$01,3,"Get" .db $14,$04,5,"rotC(" .db $16,$04,6,"rotCC(" .db $18,$04,6,"flipV(" .db $1A,$04,6,"flipH(" .db $C8,$03,7,"inData(" .db $B8,$01,5,"input" .db $74,$01,6,"float{" .db $72,$01,4,"nib{" .db $F6,$03,9,"#Realloc(" .db $68,$01,6,"#Icon(" .db $80,$01,2,Llambda,"(" .db $38,$03,5,"Load(" .db $3A,$03,5,"Next(" .db $14,$03,7,"Render(" .db $3C,$03,6,"DrawL(" .db $3E,$03,6,"DrawR(" .db $16,$03,6,"DrawS(" .db $82,$03,6,"Print(" .db $44,$03,3,"Up(" .db $46,$03,5,"Down(" .db $5C,$03,5,"Left(" .db $40,$03,6,"Right(" .db $42,$03,4,"New(" .db $5E,$03,7,"Delete(" .db 0
StrPROGRAM: .db "PROGRAM" StrAXESRC: .db "AXE SRC" #if (StrPROGRAM>>8) != (StrAXESRC>>8) .error "StrPROGRAM and StrAXESRC must have the same MSB" #endif
Answers to your questions: - This is probably the trickiest, hackiest thing I had to do. And it turns out that the way I did it doesn't actually work with DoorsCS, but not because of its instant scroll. In the screenshot, I demonstrate changing the title of the program editor to "AXE SRC" when an Axe program is detected. However, this is more of an accident than a feature. To determine if the program editor was just opened and the file needs to be scanned for Axioms, I check if the program has a valid Axe header and (textShadow) equals 'P'. Whenever this is true, I change the title string so this condition does not occur again, scan for Axioms, and then continue the hook as usual. So this does work with instant scrolling, but it doesn't work with DoorsCS, only because it removes the top row of the program editor. It might be possible to use another RAM area that is written to upon opening a program for editing and thereafter not read or written to, which would allow for Axiom tokens to work in DoorsCS (Axe tokens still work fine), but I couldn't think of any.
- When token replacements no longer fit, I just ignore them. But frankly, most Axioms only have a couple of commands so I'm not too worried about anyone going over the limit.
- When no Axioms are detected, only a trivial amount of cycles for checking Axiom tokens is added to the token comparing stage. Scrolling in an Axe program with less than a dozen of so Axiom token replacements will actually be faster because I optimized the comparison loop.
- I didn't find it too difficult to make my own token hook comparison values. As long as the programmer has access to resources like this and this, it shouldn't be too difficult to calculate them.
EDIT: Oh, and if you plan on using this, it's probably a good idea to move TokenHook_Temp and AxiomTokens, since I recently figured out that zStart uses appBackUpScreen, and I know a lot of Axe users use zStart. statVars seems like a good alternative. EDIT 2: Now that I think about it, I think I realized the much simpler way to determine if the program editor was just opened... If the saved previous value of cxCurApp isn't equal to kPrgmEd, set it to kPrgmEd, scan for Axioms, and then resume the token hook as usual. EDIT 3: I knew this would happen, as soon as I release my code I think of improvements and bugs. Anyways, I forgot to make this properly find Axioms with names of less than 8 characters. Maybe later I'll just post a new version with all these edits taken into account.
920
« on: January 09, 2012, 04:09:00 pm »
Axe doesn't have this functionality yet, which is why I spent the time to make a prototype version that does. I haven't released it anywhere, since I think Quigibo would rather I give it to him and let him possibly tinker with it a bit and then release it officially. And existing Axioms don't have any token replacement data, so even with this new system, they will act just like they do currently. Only Axioms designed with this new system in mind will have token replacements. However, it is possible to tack on token replacement data to old Axioms if you properly resize the appvar and add in token replacement data.
921
« on: January 09, 2012, 03:57:18 pm »
Oh sorry, I misread your post. Basically, your standard Axiom looks like this: .dw $C0DE ;Axiom commands go here .dw 0
If you don't want any token replacements, you don't have to change a thing. This keeps backwards compatibility, which is always nice. If you want token replacements, the layout extends to something like this: .dw $C0DE ;Axiom commands go here .dw 0 .dw $C0DE .dw Tokens_End-Tokens Tokens: ;For as many token replacements as you want: .db HookLowByte, HookHighByte, StringLength, "String" .db HookLowByte, HookHighByte, StringLength, "String" Tokens_End: HookLowByte and HookHighByte are different from the usual token values. To figure them out, I use a mix of this in combination with this. And StringLength is the length of the replacement ASCII string, which should not include a null terminator. EDIT: Here's an example, taken from the Axiom I showed in the screenshot. It replaces GridOn with GrayOn, X₃ᴛ with Buf1, and Y₃ᴛ with Buf2. .dw $C0DE ;Axiom commands go here .dw 0 .dw $C0DE .dw Tokens_End-Tokens Tokens: .dw 10*2+$0384 .db 6,"GrayOn" .dw 14*2+$0220 .db 4,"Buf1" .dw 15*2+$0220 .db 4,"Buf2" Tokens_End:
922
« on: January 09, 2012, 03:44:43 pm »
Currently, I'm putting cached Axiom token replacements in appBackUpScreen, because I know that the OS will not touch this. Except for when you run an app, as the name suggests, but at that point you've exited the program editor. I still need to ask thepenguin77 if zStart wants this area of RAM when editing programs, in which case I should probably find another spot.
923
« on: January 09, 2012, 03:37:23 pm »
Axe gets first priority for token replacements. This is partially for speed reasons, and partially because there's not much sense in overriding an Axe token since you cannot (yet) override the Axe command. After that, Axioms get priority in order of appearance in the source code.
924
« on: January 09, 2012, 03:25:49 pm »
Pretty much, I detect whenever the source code open in the program editor has changed to become an Axe program (this mainly applies to the action of opening an Axe program). I then scan the entire program for any AsmComp( tokens (that's #Axiom( in Axe). For each one found, I check that it's in a valid position (e.g. not in the middle of a line, in a string, etc.) and then attempt to locate the appvar. If found, I skip to the end of the Axiom and check for a second header after the standard Axiom footer that signals that the Axiom includes token replacements, and if so, these token replacements are cached in RAM. Then, it's just the simple matter of running the token hook as usual, but checking this area of RAM in addition to Axe's built-in token replacements. Although to be fair, the whole process wasn't a simple matter. Every time I wanted to test a change, I had to hex-edit my hook into the Axe application. And I tried to do the whole thing in a very optimized manner, which means trying multiple code possibilities every step of the way. I must've spent over a dozen hours on this thing. One thing that this upgraded hook does not do is dynamically check for Axioms while the program is being edited. Adding such a feature would be a bit of a pain and probably add at least 50 bytes and slow down the hook, so I figured it's just best to leave it out. If you want to reload Axioms, it's easy enough to do so by closing and reopening the program.
925
« on: January 09, 2012, 12:24:01 am »
Well it took countless hours of work to get it working right, but it works! What works? Take a look at the screenshot. (If you'd rather just read what it is)
926
« on: January 08, 2012, 04:09:18 am »
That is a great approach, FloppusMaximus! The best part is that your solution perfectly fits my more general goal, though I didn't even tell you what it was: - While the program editor is open, save the edit buffer's state
- Move all the edit buffer data to one end
- Parse the (now gapless) data
- Restore the program editor to its original state like nothing ever happened
The B_CALL(_BufToBtm) at the start of your routine perfectly takes care of step two. And since the position I'm jumping to is just a saved (editCursor), calculating and validating the jump point can be completely cut out! So for my purposes, everything I need to do boils down to just this: ld hl,(editTop) push hl ld hl,(editCursor) push hl B_CALL(_BufToBtm) call ParseProgram pop hl ld (editTop),hl B_CALL(_BufToTop) pop hl ld (editTop),hl
Excellent thinking, FloppusMaximus. I may end up just trying to parse the data without removing the edit gap if if the code to do so is smaller overall, but for the question I asked, you've given what must surely be the best answer.
927
« on: January 08, 2012, 01:05:53 am »
I know Axe has a method of doing it for errors at least. I believe this is how Axe currently instantly scrolls to errors, and it does no manual copying or edit pointer updating. So that makes me think there's something similar that I can do for my purpose of simply adjusting the edit buffer.
928
« on: January 08, 2012, 12:59:58 am »
That works, but I feel that there's some OS routine that will do it for me and save me 10 or 20 bytes.
929
« on: January 08, 2012, 12:55:40 am »
The subject line mostly explains what I want to do. Inside of the OS program editor, I'm wondering what the easiest way is to "jump" to a point in the edit buffer. I don't want any scrolling, any adjusting of the cursor position on the screen, really any noticeable changes to the user. I just need the edit pointers to be adjusted and for the data in the edit buffer to be moved around properly. I probably explained that awfully, so let me sketch it out. I want to be able to start with a program in the edit buffer like it was just loaded:
X............... ................ .........XXXXXXX XXXXXXXXXXXXXXXX
And "scroll" to a certain byte:
XXXXXXXXXXXXXXXX XXX............ ................ ...........XXXXX
I feel like there's some easy way to do this involving a bcall or two instead of having to do the copying and pointer updating myself, but I don't know what it is. Sort of like an instant goto, but without any actual displaying. If you can only think of a way to do it with the displaying, that might be acceptable as well, so feel free to suggest whatever comes to mind.
930
« on: January 05, 2012, 04:54:43 pm »
I've been fantasizing about such a system as this for a long time, as it can be used both to conserve executable size and to allow for the use of larger but faster routines. However, your post wasn't very clear to me regarding one important matter: Will the old compilation style remain? One thing that always turned me off about some programs is their dependency on a shell, especially when they hardly needed any of the routines in it. Although I always have Axe on my calculator, others may not, and they may not want it. And if you're compiling your code as an app and not right up against the size limit, you can afford to have the routines included in your app. I think it would be best for Axe users to be able to control exactly how Axe compiles their program: with size-optimized included routines, with speed-optimized included routines, or with speed-optimized external routines. I would then advise programmers to follow logic somewhat like this as a guideline to compile and release their work: - If you are compiling your code to a program
- If you use one or no large routines (e.g. DispGraph, Pt-On())
- Compile with included routines; optimization style is up to you
- If you use large routines
- Compile for both included routines (optimization style is up to you) and external routines; include a readme explaining how the two are different and let the user choose
- If you are compiling your code to an application
- Compile with speed-optimized included routines
- If the application is too large
- If speed is important
- Compile with external routines
- Compile with size-optimized included routines
- If the application is too large
- Compile with external routines
Pages: 1 ... 60 61 [62] 63 64 ... 153
|