Author Topic: [Axiom] Menu( using OS's bcalls (finished !)  (Read 19413 times)

0 Members and 3 Guests are viewing this topic.

Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
[Axiom] Menu( using OS's bcalls (finished !)
« on: August 02, 2014, 12:34:44 pm »
Good news, everyone !

I found a way, which is in my opinion reliable, to use the system DIALOG bcalls to make custom menus, like in TI-Basic. And it may be added to Axe ! Currently, if you want to use it, download it here  ;)



The OS does not expose a very simple way to generate menus, which is why the feature does not exist. But if any assembly wizards want to provide the majority of a solution, I'll happily include it! That is, if I can fit it.  :P



If you want to see how it works :

Spoiler For Asm code:
Here's the main part of the source code. Most of it comes from the program of Brandonw.

;Note : If the users presses [2nd] and [quit], the number returned will be the choice highlighted.

;It'd be great to find a way to backup the text screen and restore it later.
;There are other things this routine changes and doesn't restore, see the end of the code.

;The following lines backup the current "rawKeyHookPtr", which will be replaced.
;It uses the stack... it could use any RAM safe area, but they may be already used.
ld hl, rawKeyHookPtr - 1
ld b, 4
hookBackup:
inc hl
ld a, (hl)
push af
djnz hookBackup
;Backups some settings, still using the stack
ld a, (flags+34h) ;rawKeyHook active flag
push af

ld a, (cxCurApp) ;what kind of app is currently running
push af
ld a, 58h
ld (cxCurApp), a  ;Sets value to 58h=kExtApps="External Applications."

;Copy menu structure
ld hl, structStart
ld de, ramCode
ld bc, structEnd-structStart
ldir

;Prepares dialog :

ld hl, dialogCallback
in a, (6) ;Does any of the following bcalls changes the flash page mapped ?
bcall(_DialogInit)
bcall(_runIndicOff)

;Starts dialog
bcall(_StartDialog)

;End of dialog
bcall(_cursorOff)
bcall(_clrLCDFull)

;I discovered that the choice's index is located into RAM, at $8006. I conjecture it is always stored here.

ld hl, ($8006)
bcall(_DispHL) ;Show the chosen item's index


;Restores previous settings
res appCurWord, (iy+appFlags)pop afld (cxCurApp),a
pop af
ld (flags+34h), a
;Restores previous rawKeyHook
ld hl, rawKeyHookPtr+5
ld b, 4
hookRestore:
dec hl
pop af
ld (hl), a
djnz hookRestore

;Some changes are not restored :

;- the indicator and the cursor are set off
;- "ramCode" and the text screen have been modified
;- appCurWord flag is reset

;Dialog's callback :
dialogCallback:
xor a
ret


;Is it compatible with all shells (some shells might use ramCode) ?
Spoiler For Menu structure:
The menu structure is enough easy to be written by hand, but I've made a script to generate it automatically (see the download link at the beginning of this message). Here's how it works :


structStart:
;To make the title, there are three $01 bytes, followed by a pointer to the string.
;Note : you can add other titles anywhere in the menu, by using the same structure.
.db 1 \ .db 1 \ .db 1 \ .dw sTitle-structStart
;Then, for the first choice, put the bytes $05, $01, $01 again, and the pointer to the string.
.db 5 \ .db 1 \ .db 1 \ .dw sChoice1-structStart
;To add other items inside the menu, continue adding the $05 and $01 bytes, but increment the third byte for each new item, as it corresponds to the choice's index. Note : You can use numbers (from 0 to 9) randomly, and use the same number twice, but the number returned by the Menu( function will be the choice's row's index.
.db 5 \ .db 1 \ .db 2 \ .dw sChoice2-structStart
.db 5 \ .db 1 \ .db 3 \ .dw sChoice3-structStart
.db 5 \ .db 1 \ .db 4 \ .dw sChoice4-structStart
;Note : You can't put more than 8 items (including the title).
;When it's done, add $00.
.db 0
;The strings must be added after the structure, and preceded by their length.
;Note : you can write them in the order you want ; you may not respect the menu's choices order.
sTitle:   .db 7, "COMPILE"
sChoice1: .db 6, "Cancel"
sChoice2: .db 7, "Noshell"
sChoice3: .db 3, "Ion"
sChoice4: .db 8, "MirageOS"
structEnd:
;The menu is made.

« Last Edit: August 09, 2014, 12:45:12 pm by Zemmargorp »
I'm french, that's the reason why my English can be a bit approximate.

Offline Matrefeytontias

  • Axe roxxor (kinda)
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1982
  • Rating: +310/-12
  • Axe roxxor
    • View Profile
    • RMV Pixel Engineers
Re: Menu( command using OS's bcalls - need help
« Reply #1 on: August 02, 2014, 09:04:46 pm »
Quote
;Does anyone knows why it's actually required to change these flags for a menu ?
The OS's all-input routines use the raw key scanning commands along with raw key hooks, so those latters must be saved before and restored after calling such BCALLs.

Quote
;<-- What does this line exactly does ?
Port 6 controls the flash page currently mapped to $4000-$7FFF. I guess the BCALL maps another page to this zone, so the current page (retrieved with in a, (6)) must be saved in A for future restore. That's only supposition though.

Quote
;Is it always the case ? Does anyone know why ?
As I said above, the BCALL may map a specific flash page to $4000-$7FFF, so there's no reason why it wouldn't write the answer to an equally specific page. Also, page 1 is not flash but RAM, actually the only memory allowing for write.

Quote
;What does this line does ?
According to WikiTI :
Quote from: WikiTI
Official Name: appCurWord

Set to have the text cursor cover the entire token.

Quote
;There must be an easier way to do this.
textShadow is $8508 and only 128 bytes large, so :
Code: [Select]
  ld hl, $8508
  ld de, $8509
  ld (hl), 0
  ld bc, 127
  ldir
Actually, this only erases the screen's backup. The job of textShadow is to hold a copy of the large-font chars that were on your screen before you changed context (by entering a menu for example).


Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #2 on: August 03, 2014, 09:06:35 am »
The OS's all-input routines use the raw key scanning commands along with raw key hooks, so those latters must be saved before and restored after calling such BCALLs.
Ok. I don't know if it's that useful, because this hook isn't probably changed all the time, but I'll let it.

Port 6 controls the flash page currently mapped to $4000-$7FFF. I guess the BCALL maps another page to this zone, so the current page (retrieved with in a, (6)) must be saved in A for future restore. That's only supposition though.
Thanks, so that's the reason why the selection's index is stored there.

As I said above, the BCALL may map a specific flash page to $4000-$7FFF, so there's no reason why it wouldn't write the answer to an equally specific page. Also, page 1 is not flash but RAM, actually the only memory allowing for write.
I thought RAM was page 0 ?... A lot of bcalls, like "FindSym", returns B=0 if the value is in RAM, and else the page's number the variable is in. In fact, you mean they return B=0 if it's in the current flash page mapped, and B>0 otherwise ? But then I should be able to get this value without using bcall(_LoadCIndPaged) ? I didn't achieved to do it...

The job of textShadow is to hold a copy of the large-font chars that were on your screen before you changed context (by entering a menu for example).
So we should use it to backup the screen before the menu is set, and restore it later.

Thanks for your help. I'll update the source as soon as I can.
I'm french, that's the reason why my English can be a bit approximate.

Offline Matrefeytontias

  • Axe roxxor (kinda)
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1982
  • Rating: +310/-12
  • Axe roxxor
    • View Profile
    • RMV Pixel Engineers
Re: Menu( command using OS's bcalls - need help
« Reply #3 on: August 03, 2014, 12:22:32 pm »
There are two RAM pages ; page 0 is mapped in $8000-$BFFF and page 1 is mapped in $C000-$FFFF. Else you would have 16kb of RAM, not 32kb ! (although only 24 are usable). It's just that ChkFindSym returns DE > $BFFF and B = 0 if the variable is in page 1. That's why it says B=0 is RAM.

Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #4 on: August 03, 2014, 12:54:52 pm »
There are two RAM pages ; page 0 is mapped in $8000-$BFFF and page 1 is mapped in $C000-$FFFF. Else you would have 16kb of RAM, not 32kb ! (although only 24 are usable). It's just that ChkFindSym returns DE > $BFFF and B = 0 if the variable is in page 1. That's why it says B=0 is RAM.
Thanks for this explanation...  So the instruction "in a, (6)" is here to make sure the page needed is mapped before making the bcall. But then, how could we restore the previous page mapped ? because the command should restore it before returning !

And the following code can be optimized into "ld hl, ($8006)"... Indeed, it works !
Great optimization  ;D  ! Good old Zemmargorp, using bcalls to read from RAM...  ::)
Code: (Very bad code) [Select]
ld b, 1
ld hl, $8006
bcall(_LoadCIndPaged)
ld h, 0
ld l, c
« Last Edit: August 03, 2014, 01:12:54 pm by Zemmargorp »
I'm french, that's the reason why my English can be a bit approximate.

Offline Runer112

  • Project Author
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2289
  • Rating: +639/-31
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #5 on: August 03, 2014, 09:10:12 pm »
I've been playing with this for a while now. It seems that, at least for simple menus, this should be totally capable. But one problem I've run into so far is that, if I move the cursor into and then out of the number entry field, the dialog glitches out. Does this happen for you too, and/or do you have any idea why this would be happening?

EDIT: A bit of testing seems to suggest that it's some compatibility issue with Omnicalc and/or zStart. My guess would be a hook; probably the parser hook, which parses things like numerical input.
« Last Edit: August 03, 2014, 09:19:29 pm by Runer112 »

Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #6 on: August 04, 2014, 10:27:14 am »
I've been playing with this for a while now. It seems that, at least for simple menus, this should be totally capable. But one problem I've run into so far is that, if I move the cursor into and then out of the number entry field, the dialog glitches out. Does this happen for you too, and/or do you have any idea why this would be happening?
Yes, it works very good for simple menus. We just need to create a function which will create automatically the menu structure into ramCode. I've not currently tested the number input (I'll do it later), and I don't know why this happens... I'm trying to make a MENU Axiom, but I have got a problem (see the spoiler). Also, it would be great to increase the maximum arguments for a command to 8 instead of 6 ! By the way, in the code I posted above, I've noted all the things the routine changes and doesn't restore. Do you think some of them can be annoying, and we should find a way (even if it takes some more bytes) to restore them ?

Spoiler For Problem:
EDIT : I don't know why, but I'm not able to create an Axiom using the Menu( token (and also using any other token) ! I tried the following simple code, and when I include this Axiom into an Axe source, I get the error "INVALID TOKEN" on the token "Menu(".
Code: (Axiom source) [Select]
.dw $C0DE
.dw routineStop-routineBegin ;size of the command
.db $CF ;compatibility = all
.db $E6, $00 ;token to match = menu
.db $00 ;command type = inline
.db $00 ;arguments count = zero
.org $0000
routineBegin:
    ex de, hl ;this is just for testing
routineStop:
.dw $0000 ;no more commands
Code: (Axe source) [Select]
.ERROR
#Axiom(TEST)
Menu(
Spoiler For Problem solved !:
EDIT 2 : I don't know why, but I used TASM as compiler, and changing to SPASM solved the problem.
EDIT 3 : In fact, you can't use any Axiom called "AXIOM". If you call it "AXIOM2" though, it's fine.
« Last Edit: August 05, 2014, 10:59:58 am by Zemmargorp »
I'm french, that's the reason why my English can be a bit approximate.

Offline Runer112

  • Project Author
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2289
  • Rating: +639/-31
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #7 on: August 04, 2014, 03:53:45 pm »
I'm not sure what shell you're trying to compile this for, but right now your shell compatibility byte is 0xCF = 0b11001111. That means that it's incompatible with applications and Axe fusion. If that isn't the issue, I can't say what the issue is by looking at that.

As for increasing the number of arguments allowed, I'll look into it. Although I had a quick glance at the Axiom parsing code and was absolutely clueless about how it even checks the number of arguments, so it might not be easy for me to figure out.

Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #8 on: August 05, 2014, 08:37:54 am »
I'm not sure what shell you're trying to compile this for, but right now your shell compatibility byte is 0xCF = 0b11001111. That means that it's incompatible with applications and Axe fusion. If that isn't the issue, I can't say what the issue is by looking at that.
I'm trying to compile it to "No shell", as I always do - I never compile either to apps or to Axe Fusion (as it's buggy). I also tried other values : 0xFF for compatibility, and 0x01 for arguments, but it doesn't work, and I can't figure out why. I'll disassemble some Axioms to see how it works... But right now, I don't understand why I get the error "INVALID TOKEN".


As for increasing the number of arguments allowed, I'll look into it. Although I had a quick glance at the Axiom parsing code and was absolutely clueless about how it even checks the number of arguments, so it might not be easy for me to figure out.
Thanks. And it seems that Axe Parser doesn't recognize Axioms which starts with the header of compiled programs, even if then follows the Axiom header. It would be great to allow it.
I'm french, that's the reason why my English can be a bit approximate.

Offline Matrefeytontias

  • Axe roxxor (kinda)
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1982
  • Rating: +310/-12
  • Axe roxxor
    • View Profile
    • RMV Pixel Engineers
Re: Menu( command using OS's bcalls - need help
« Reply #9 on: August 05, 2014, 08:52:55 am »
What assembler are you using ? The .org preprocessor instruction have different behaviors depending on assemblers.

Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #10 on: August 05, 2014, 09:10:58 am »
What assembler are you using ? The .org preprocessor instruction have different behaviors depending on assemblers.
I'm using TASM. I know it has issues with the org directive, but I don't think it's the cause of my problem... I removed it, and I still have the same "INVALID TOKEN" error.
I'm french, that's the reason why my English can be a bit approximate.

Offline Matrefeytontias

  • Axe roxxor (kinda)
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1982
  • Rating: +310/-12
  • Axe roxxor
    • View Profile
    • RMV Pixel Engineers
Re: Menu( command using OS's bcalls - need help
« Reply #11 on: August 05, 2014, 09:24:17 am »
.org physically moves PC, as in, if you do .org $+8, the final compiled program will effectively have 8 zero bytes in the middle. I don't think TASM can do anything else related to PC, so I strongly recommend you using another assembler. I use SPASM, whose .org directive works the way you intend it to.

Download SPASM : http://wabbit.codeplex.com/releases/view/45088

Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #12 on: August 05, 2014, 09:56:59 am »
.org physically moves PC, as in, if you do .org $+8, the final compiled program will effectively have 8 zero bytes in the middle. I don't think TASM can do anything else related to PC, so I strongly recommend you using another assembler. I use SPASM, whose .org directive works the way you intend it to.

Download SPASM : http://wabbit.codeplex.com/releases/view/45088
Downloading... Editing the "compile.bat" file... Compiling... Adding the file "AXIOM.8XP" generated to TI-Flash debugger... Wait !  :o  It works ! There's no more "INVALID TOKEN" error ! I don't know what it changed, but thanks !  :thumbsup:  Now I can really start writing the Axiom...
I'm french, that's the reason why my English can be a bit approximate.

Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #13 on: August 05, 2014, 10:55:27 am »
Wait !  :o  It works ! I don't know what it changed, but thanks !  :thumbsup: 
I take back what I said ! (I'm kidding, of course I thank you : without you I would still have this error.)


No, the error didn't come from the compiler ! It was strange to me, because the two compilers generated the same output in the ".bin" file. In fact, when I compiled the source for the second time, I renamed the file "AXIOM2", instead of "AXIOM". And it made the difference ! There's a bug in Axe Parser I'm gonna immediately add to the bugs report list : you can't use Axioms if their name is "AXIOM", and this doesn't generate the error "INVALID AXIOM", but "INVALID TOKEN" wherever you use a command of the Axiom.
I'm french, that's the reason why my English can be a bit approximate.

Offline Zemmargorp

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 115
  • Rating: +7/-2
  • Either programming or thinking of it.
    • View Profile
Re: Menu( command using OS's bcalls - need help
« Reply #14 on: August 06, 2014, 09:15:20 am »
*Currently working hard on an Axiom that doesn't work very well...*

EDIT : Finally, I've solved the big problems I had ! First, I wrote somewhere ".db" instead of ".dw", (which is, for the compiler, unforgivable) and then, it seems that Axe Parser doesn't like when you put data (and not code) inside an appvar. I'm happy that's done. Now, well, let's code !
« Last Edit: August 06, 2014, 10:01:25 am by Zemmargorp »
I'm french, that's the reason why my English can be a bit approximate.