Show Posts

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 - MGOS

Pages: 1 [2] 3 4 ... 23
16
Axe / Re: [Tutorial] Key hooks in Axe
« on: December 27, 2013, 06:59:19 pm »
You forgot the End between these two lines of code in your example program:

Code: [Select]
:Asm(EF6F4F)    //Disable the hook
:!If K-142   //someone pressed  "0"
Fixed, was actually and Else

Also what do I do to disable the memory menu instead of the 0 key?
Check out the Wikipad by DT, it's very handy for this kind of stuff.

Haha... Well... to be honest that was my initial intention which lead me to explore this whole thing....
Not just blocking it, but rather open up a menu that looks and behaves visually the same but doesn't do anything... ehhhrmmm I better stop talking now... ;)

edit 2: Is there a way to chain hooks?
I'm not an assembly programmer, I just get by... What do you mean by chaining hooks?

17
Axe / Re: [Tutorial] Key hooks in Axe
« on: December 27, 2013, 06:18:05 pm »
How to make it work from RAM :

Replace Asm(CD50002740) by Return. As first instruction, copy your hook to a fixed RAM area and put that area in HL before enabling the hook.

Sure, you need to make sure that the memory area doesn't get corrupted by other programs (many programs and apps use it) and the function mustn't be to large. Otherwise that works fine!
Thanks for the addition!

18
Axe / [Tutorial] Key hooks in Axe
« on: December 24, 2013, 05:52:56 pm »
Disclaimer: The code discussed here can be used in completely save and harmless applications, but may also cause damage to your calc if used improperly or even viciously. I'm not responsible for any results in abuse or misuse of this code.


Note this tutorial can be adapted to work with other types of hooks - I find the key hook to be quite easy and still useful so I chose that one for this tutorial.

What is a key hook?
Key hooks are functions which are called on a certain key presses anywhere in the OS or TI-Basic program (or assembly/axe program that uses the OS key press functions). Key hooks thus can be used to add your own awesome functionality to the OS. Many shells use some kinds of key hooks such as zStart. What I'm going to show in this tutorial is how to set up your own key hooks in your Axe program. I'm not that great at assembly programming, so it might not be the cleanest code, but it works nicely and is probably easy to understand.

Important note: To make this work properly and not create memory leaks, you need to compile the program as an APPLICATION! Other keyhooks (such as zStart's) have to be turned OFF to cause no interference!


The key hook function:
That is the routine that runs when any of the keys or combinations (like 2nd+[ ] or Alpha+[ ]) are pressed. You then need to check which one it was and decide what functionality to execute (similar to TI-Basic's getkey-function).
First we need to create a label with the name of the function (like any Axe subroutine). Because I am that creative I call it "HOOK":
Code: [Select]
: Header
:...  //Some other parts of your program
:
:Lbl HOOK
:
:
:Return

When the function is called we get the code of the key pressed last in the registers a. However, we have to add a,e as the first instruction so the OS recognizes our function as a hook. Because we don't want to mess up the registers in our function, we push them on the stack to back up.
Code: [Select]
add a,e
 push HL
 push BC
 push DE
 push AF

 ld l,a     ; load a to l to make it usable in axe
 ld h,00

 ;function goes here

 pop AF   ; restore the registers we might have messed up
 pop DE
 pop BC
 pop HL

Now the key code is prepared to be used in axe, since it is stored in axe's "ans", the HL register.
I already translated that assembly to Hex, so you can simply add it to your program:

Code: [Select]
: Header
... Some other parts of your program
:
:Lbl HOOK
:Asm(83E5C5D5F56F2600)
:->K     //store ans in axe variable K to use in your compare statements
:
:Asm(F1D1C1E1)
:Return

That's the first part done. No feel free to run any instruction according to your needs, as long as you don't jump out of the function. You find a list with the key codes (they differ from the getKey(x) ones) on DeepThought's WikiPad here under "_GetKey (Axe getKeyr)".


Installing your key hook:
Before we can use the key hook function, we need to tell the OS that it should run a key hook and where it is.
These few assembly instructions will set the current HL as the key hook address. In our case, that is the address of the function "HOOK", and we get that using the little "L" you find in the List-OPS menu. So "LHOOK" will return the address of that label.
Code: [Select]
in a,(6)   ;current ROM page to A
 _bcall(_EnableRawKeyHook)
 ; Usually we now quit the program using
 _bjump(_JForceCmdNoChar)
Now in Axe:
Code: [Select]
:LHOOK
:Asm(DB06EF664F)
:
: // return to OS
:Asm(CD50002740)


You can put this in any position of your code - I usually put it right to the beginning of the program, so it will be always installed when you run it. But you can also create a menu with an option to turn it on that will then run this code etc.

Now you are basically set to work with your hook.


Disabling the hook:
Usually there is at some point the need to disable the hook again, so there is this simple line of Hex to do that job:
Code: [Select]
:Asm(EF6F4F)  // = _bcall(_ClrRawKeyHook)

You can disable the hook when a certain key is pressed (put in the hook routine) or at some other point (e. g. using again some kind of menu).


Manipulating key code data:
You can manipulate the return value of the getKey function inside your hook routine - a really mighty feature, e. g. you can block a certain key.
Since the key code is stored in register A which is on top of the stack we need to pop it off, manipulate it and push it back on the stack.
This only works at the end of the hook routine, since there the stack is like we left it and we don't want to mess things up.
This stores the value of the "ans" register HL as the return value of our routine.
Code: [Select]
pop AF
 ld a,h
 push AF
In Axe it looks like this:
Code: [Select]
:9    //this now replaces the key pressed with the code for "CLEAR" (example)
:Asm(F17CF5)
:...  //use only ends of if statements here - that doesn't mess anything up.
:Asm(F1D1C1E1)  //usual restore routine
:
Storing 0 will make the OS ignore the key press, that way you can block certain keys.

Now you should be ready to setup your own routines!


Example:
This example will disable the functionality of the "0" key. No idea why someone would do that ;). Pressing "STO->" makes it normal again.
Code: [Select]
:.KeyHook  //name of my app
:LHOOK
:Asm(DB06EF664F) //enable Hook
:Asm(CD50002740) //return
:Lbl HOOK
:Asm(83E5C5D5F56F2600)
:->K
:!If K-138   //someone pressed "STO->"
:Asm(EF6F4F)    //Disable the hook
:Else!If K-142   //someone pressed  "0"
:0
:Asm(F17CF5)  //write 0 so the keypress is being ignored
:End   //only an end of an "if"-statement, that's ok
:Asm(F1D1C1E1)
:Return

Have fun - and be careful not to mess things up - that happens quite easily.... :)

19
TI-BASIC / Re: Why aren't there so many programs using the dcs gui lib?
« on: December 23, 2013, 03:16:00 pm »
Actually in DCS's defense, you can also run programs from the home screen too.
True - I don't want to do DCS down - it's only my opinion. Why would someone put a 49k app (compared to zStart's 16k) on his calc when he doesn't come close to needing all the functionality. The idea of having a single app that combines the functionality of many other libs and shells - and adding more, like a GUI - is great as such, but I simply find memory more valuable when I think of all the stuff I don't need. Therefore I simply don't have DCS on my calc and thus I don't program anything that uses its libraries.
There might be people out there for who DSC is just the right thing, but I don't belong to those.

20
TI-BASIC / Re: Why aren't there so many programs using the dcs gui lib?
« on: December 23, 2013, 02:44:20 pm »
Many of the GUI functions DCS provides are quite awesome indeed - but like Hayleia pointed out, you can simply code those yourself depending on your needs. And I still don't like to use any shell at all - imho I think that a mouse/cursor system and a calc don't fit together. I don't see any advantage if having a mousecursor when you don't have a mouse or a touchpad attached (unless you own Kerm's ultimate calc). It is rather annoying and slow.
Other shells still have to be launched as an app to work - and when you run them on power on, you need to exit them when you want to do some calculations. I might be a fusspot but every button click you can save is worth saving it. So the only shell to fulfill these needs is zStart:: you can still use the good old program menu and run your asm programs without fiddling around in the catalog - and it provides other developers features I can't imagine things without.
I know we're talking about two different things right here - but DCS and its GUI belong together imo and needing multiple apps (a shell for executing and organizing - and a library for your graphics stuff) simply take a lot of your valuable memory.
On the other hand, since Axe became that popular, the number of TI-Basic programmers dropped and therefore TI-Basic libs cease with them.

21
News / Re: Many new amazing games for all calculators
« on: December 22, 2013, 07:23:21 am »
Thanks for highlighting my Templerun :)

22
General Calculator Help / Re: Graph X= Equations on the TI-83+ Series
« on: December 20, 2013, 05:10:02 pm »
A simple way:
Type your equations as Yn = (Yn being any of the ten equations) - and in the homescreen enter "DrawInv Yn". That swaps X and Y axis around.

23
Axe / Re: Support Request - How Does One Rotate a Tilemap?
« on: December 12, 2013, 12:16:45 pm »
This is the way I did it for my version of TempleRun (it's a 16x16 tilemap at L1):

clockwise:
Code: [Select]
:For(r1,0,7)
:For(r2,0,7)
:{r2*16+r1+L1}?r3
:{r1*16+15-r2+L1}?{r2*16+r1+L1}
:{15-r2*16+15-r1+L1}?{r1*16+15-r2+L1}
:{15-r1*16+r2+L1}?{15-r2*16+15-r1+L1}
:r3?{15-r1*16+r2+L1}
:End
:End

Edit: You may need to add some code to change the sprite rotation data

24
Other / Re: Calc + TV remote = ???
« on: December 10, 2013, 12:56:33 am »
I remembered that one, but my idea is quite a bit different - you load a single program to the AVR which makes it act like a slave and does everything for thr calc. The main program is running on the calc and giving Low level commands to the AVR - instead of just a linking protocol for bytes.

25
Other / Re: Calc + TV remote = ???
« on: December 06, 2013, 11:42:40 am »
Now you got me thinking about a calculator controlled microwave
*Hexatron runs
I'd love that! :D


I was actually thinking of something more versatile, kinda an Axe-to-Arduino interface - giving you all the major Arduino functions (pinMode, digitalRead/Write, analogRead/Write, Serial interface, etc) in the axiom and a slave program running on the arduino/atmega/attiny. Maybe that will lead more people to include their calc into their hardware hacking projects and create more awesomeness :)

26
Other / Re: Calc + TV remote = ???
« on: December 06, 2013, 01:01:35 am »
I only have an 83+, that's why I only post these projects for this platform. And isn't it the tinkering with a limited platform what we enjoy and doesn't the fun come from the challenge?

27
Other / Re: Calc + TV remote = ???
« on: December 04, 2013, 02:15:15 pm »
MGOS, 33 KHz isn't that fast for a 6 MHz processor. You can do port writes at least 1 MHz, assuming you have what you need to transmit.
Yeah, I misestimated... 33 kHz should work, but 1 MHz isn't doable for the z80: OUT(C),r takes 12 T states, meaning at 6 MHz you can achieve at maximum 500 kHz by putting dozens of OUT instructions after each other - and you need to divide that by two to make up a whole period (high -> low -> high). Having a loop and a nice ending condition and a duty cycle of 10% (which is better than 50% for these applications) you probably come close to the limits even in straight asm.

The IC demodulates the data, so it´s not 33kHz anymore. It´s just the carrier that is 33kHz.
For the receiver yes, but were talking about a sending LED here!

28
Other / Re: Calc + TV remote = ???
« on: December 04, 2013, 11:41:06 am »
If you add an emitter to it you can make an universal remote control. :D A small circuit can do the modulation for the calc.

That's a nice idea - you could then program each key by recording the sequence with the receiver.
I don't really want to use another circuit to do modulation - when you use e.g. an ATtiny (which I love by the way!) everything is possible and often much simpler. But the beauty of this project is, that it doesn't use any other hardware than the receiver, which is only one little IC with three leads.

When you let the micro controller do all the work for you you don't even need to program the calc anymore, since the OS has already a key emulation function built in!

29
Other / Re: Calc + TV remote = ???
« on: December 04, 2013, 11:22:05 am »
WOAH DOOD  *.* How do I build this???
The receivers cost about a dollar each and a 2.5 mm jack everyone has lying around somewhere - and that's all you need.

I just wanted to show that it can be done, and probably adapted easily to work with any TV remote.

Maybe you can use this for things like a wireless link to a laptop or phone.
Probably not, since those types of communication are two-way. But If you invent your own one-way protocol, it might work.
I might try to add an IR LED to send something, but I think I will have trouble to get a frequency that high. 33 kHz is quite a lot for a 6 MHz *damn inefficient* z80.

30
Other / Calc + TV remote = ???
« on: December 04, 2013, 09:23:33 am »
I was working an a completely different project, an infrared light barrier for outside and I needed some way to filter out the IR light of the LED from the sunlight. A common way to do this is modulation. Instead of just having a LED constantly on, you flash it really fast, e.g. with 33 kHz. The receiver filters out all other frequencies and gives a steady signal. We had a TSOP31233 (datasheet) lying around. This one connects the output pin over a transistor to ground when a 33 kHz signal is applied. The modulation worked fantastically, but the receiver is that sensitive that you cannot simply block the light with a simply object, you have to completely cover the receiver with a black box. That isn't really surprising, since those receivers where made for IR control systems and have to work under every condition. So I took the TV remote and looked what I can get out of it. Strangely enough it works with the same frequency, and it also uses a really simple protocol.

Schematic:

As you can see, there are no other electronic components needed!

I hooked up the sensor to my trusty 83+ and made a simple program that plots the state of the sensor over time. I figured out that the protocol starts with a rather long HIGH pulse, then a short LOW. The bits are coded in the length of the HIGH pulses (long pulse = 1, short one = 0), the LOW pulses are all the same time; the LSB arrives first, then a sequence of up to 15 bits. On this Sony remote, newer functions have more bits (such as enable surround sound or the Bravia sync system) where as functions that have been there forever (numbers, volume, power) have only 8 bits. I figured I only need the lower 8 bits so the following code ignores the upper bits. The program is written in pure Axe:
Code: [Select]
Lbl READ
While 1
EndIf port    //wait for the start bit to end
For(r1,0,7)
  If EAT()  //return if Stop bit reached or abort
    Goto END
  End
  GET()->{L1+r1}   //buffer the input
End
Lbl END
0->r2     //result
For(r1,0,7)
  r2*2->r2   //shift left
  {7-r1+L1}+r2->r2   //reverse and "or" together
End
r2
Return

Lbl EAT   //"eats" the Low state
For(r3,0,100)
  For(20):End  //some delay
End!If port  //wait until HIGH again
r3>100  // time out exceeded = Stop bit
Return

Lbl GET   //measures the length of a HIGH pulse and returns the result as a bit
For(r3,0,100)
  For(25):End
EndIf port   //wait until LOW again
r3 > 8    //8 seemed to be the threshold that worked best
Return

You can now write programs which use this function. For example move a sprite around the screen:
Code: [Select]
[3C7EFFFFFFFF7E3C]->Pic1
FnOff  //disable the nasty OS interrupts
44->X
28->Y
While 1
  !If port   //check for a keypress
    READ()->K
    K-244??Y--   //up
    K-245??Y++   //down
    K-180??X--   //left
    K-179??X++   //right
    Pt-On(X,Y,Pic1)
    DispGraphClrDraw
  End
EndIf getKey(15)
LnReg   //turn interrupts back on
Return

--- Subroutines from above ---

The video is probably the thing you are interested in the most:



Currently it works at around 10 key presses per second and I haven't got much hope that this will increase, since the speed is defined by the remote control, so I guess real time games are quite hard to accomplish.



Going further

What I have shown you is only a proof of concept. You can include remote control to any Axe or Asm program.

What you then could do is place the routine into a link port hook (IIRC there is one to transmit programs "silently") which enables when a key code is incoming. The code is then translated to "real" TI 83+ keycodes via a LUT and then given to the OS as a regular keypress - making it possible to enter your calculations with a freakin' TV remote....

The question one might ask is "What's the point of this?".
I'll ask instead:
Where will this lead?

Pages: 1 [2] 3 4 ... 23