Omnimaga

Calculator Community => Casio Calculators => Topic started by: z80man on March 25, 2011, 02:50:05 am

Title: Prizm Getkey
Post by: z80man on March 25, 2011, 02:50:05 am
Many of us out here are Axe programmers. Many of us also don't want to code in SH3 asm (not me of course, SH3 asm is the best ;D). Many of us do not want to go through all of the difficult steps to set up a C compiler. So there is a solution for this. Make Axe for the Prizm.

Now this project hasn't even been started yet. I'm not even the one in charge of the language. But what I have here is an early development of the Getkey routine. So when the Axe port does come around someday, you will be able to interface with the keyboard. How this instruction works is that it returns the word length code through the stack. What is great about this routine is that the codes are easy to remember, it is extremely fast, and it supports multiple key presses.

So how to use it? Well the answer is you can't right now. unless of course you integrate it with a program you wrote in C or asm. but anyways it will function just like your standard BASIC or AXE getkey routine where you can say GetKey ->A. Before I can teach you how to use multiple key presses, I have to teach you how the instruction works internally. what is great about the SH3 is that the keyboard is memory mapped. How that works is that there are 10 bytes representing the state of the keyboard starting at 0xA44B0000. Basically each row of keys has its own byte and each key has its own bit within that byte. (On key has its own byte; 0101) So for a single key press, the routine returns the byte index of the key pressed in the MSB and the value of that byte in the LSB. An example the EXE key. Because exe it located in the first byte 00xx is the first part evaluated then because pressing the the exe key toggles bit 2 in relative address 00, 4 is loaded into the lower byte. That then yields a result of 0004. So for multiple key presses everything works just about the same way. for this example say you are pushing the shift key 0940 and the up arrow 0902. Normally you would add the 2 MSB's together, but not when they are the same. So in this case they are both 9 so do not add them. But you always add the LSB's of all the keys being pushed. So 02 + 40 = 42. Then your result would be 0942.

Sorry that this might be a bit vague. If you have a question on either the source or the routine usage, please ask.

(http://img.removedfromgame.com/imgs/prizm keypad.png)


Code: [Select]
Getkey:
MOVA  @($07,PC),R0    ;$A44B0000
MOV  $0A,R1
Loop:
DT R1
BT/S  $08             ;Exit
MOV.B  @(R0,R1),R2
CMP/PL  R2
BF/S  $FA             ;Loop
MOV  R1,R4
SHLL8  R4
ADD  R2,R3
BRA  $F6              ;Loop
ADD  R4,R3
Exit:
RTS
MOV.L  R3,@-R15
data.l  $A44B0000
Title: Re: Prizm Getkey
Post by: DJ Omnimaga on March 25, 2011, 03:04:20 am
There is also the people that tried learning C but just can,t get used to that type of language and prefer z80-TI-BASIC or Casio BASIC style syntax. I personally tried on 68K and couldn't get used to C, so I stuck to TI-BASIC for the 83+ using libs, then Axe arrived.

I'M happy to see the possibility that an Axe Casio port might happen in the future. I wish you good luck on it, however, as these projects are huge undertakings, although fortunately, you already have the language pretty much designed by Quigibo, so it would be a matter of coding it and finding equivalent for BASIC functions that are missing or different.
Title: Re: Prizm Getkey
Post by: AngelFish on March 25, 2011, 03:31:18 am
:)
Title: Re: Prizm Getkey
Post by: DJ Omnimaga on March 25, 2011, 03:37:16 am
Is there any difference other than the shape looking closer to a Prizm keypad?
Title: Re: Prizm Getkey
Post by: AngelFish on March 25, 2011, 03:38:05 am
I fixed a typo in one of the keys, so not really. But making that was better than homework and it gave me an excuse to play around with paint.net
Title: Re: Prizm Getkey
Post by: DJ Omnimaga on March 25, 2011, 03:43:50 am
Ok thanks for the info. These would be the final key codes, right? In the Casio Axe would we type the full 0020 for example? Or would 20 be fine?
Title: Re: Prizm Getkey
Post by: AngelFish on March 25, 2011, 03:45:21 am
It will probably use much shorter mnemonics such as 1, 2, 3, 4, etc and simply translate them into the keycodes.
Title: Re: Prizm Getkey
Post by: SimonLothar on March 25, 2011, 06:01:08 am
...what is great about the SH3 is that the keyboard is memory mapped. How that works is that there are 10 bytes representing the state of the keyboard starting at 0xA44B0000...
The 0xA44B0000 register set is not a standard feature of the SH3-group. If you program another SH3-based machine, you won't find the set. It is a special feature of the Prizm. The Prizm MPU is a 7705/7720/XXXX hybrid (the OS identifies the MPU as 7305, which is CASIO customized, t. i. a lot of registers are not documented).

http://ourl.ca/8207/178228
Title: Re: Prizm Getkey
Post by: AngelFish on March 25, 2011, 06:34:45 am
/me facepalms

I don't know how I missed the capitalized text saying "RENESAS 730501" and "RENESAS 735501" in the OS.
Title: Re: Prizm Getkey
Post by: SimonLothar on March 25, 2011, 06:57:45 am
I don't know how I missed the capitalized text saying "RENESAS 730501" and "RENESAS 735501" in the OS.
The 7355 is the 7705 hybrid of the 9860GII-series
The 7337 is the 7705 hybrid of the 9860G-series
The string "RENESAS 735501" in the Prizm OS is debris from legacy GII-OSes.
Obviously they used some parts of the legacy source (of course  :)).
Title: Re: Prizm Getkey
Post by: AngelFish on March 25, 2011, 06:59:18 am
Yeah, I noticed the discussions from Casiocalc on Google talking about that.
Title: Re: Prizm Getkey
Post by: z80man on March 25, 2011, 11:21:35 pm
Here was what I was thinking about the mnemonics. Because identifying the keys as 0020 and 0101 is the fastest way to work with the keys, internally that will stay the same. The keys though will be identified using numbers in which we have several options: Axe keys (Keep the key codes as close as possible to the original Axe ones), Casio BASIC keys (Use the exact same keys as Casio BASIC), TI BASIC keys(TI BASIC layout format, my personal favorite), or just a numerical index (1,2,3,...). There are no technical benefits to anyone because the translation will be done at compile time. It is just whichever layout the community would prefer. We can make a poll for this sometime.

Now to use mnemonics in your code. Yo won't be able to just refer to the keys as 45 or 12, but instead as k(45) or k(12). That way the compiler knows to translate the values. The k() part could really be anything, it will probably be replaced with an unused token. Now if you want to have multiple key presses you would say k(45+12). When saying this the compiler will not just add 45 and 12, but add their translated values instead. Also the k() translation would be smart enough to evaluate 0220 + 0210 as 0230 while 0520 + 0220 as 0740. 
Title: Re: Prizm Getkey
Post by: DJ Omnimaga on March 25, 2011, 11:25:10 pm
Ah ok. How would it be if someone made a language like Axe? Would we be able to do stuff like Getkey(45) and the compiler would translate back to a machine code-compatible format?
Title: Re: Prizm Getkey
Post by: z80man on March 25, 2011, 11:48:08 pm
Ah ok. How would it be if someone made a language like Axe? Would we be able to do stuff like Getkey(45) and the compiler would translate back to a machine code-compatible format?
Now that you mention it, doing Getkey(45) should automatically translate the 45 value (but it would be a different, faster routine that only checks for that one key, unless it is a multiple key press test then it would be the original routine still). The k() instruction would be for more like if you used code like this.
Code: [Select]
:Getkey->A
:if A= k(45)
:blah
:if A= k(12)
:blah

I did realize one conflict if you said something like Locate 1,1,A and A happens to hold a keycode. In that case the internal keycode would be displayed instead of the mnemonic. So if you do k() on a non-constant variable, it will be a run time translation instead of a compile time one. If you do k() on a variable that contains a multiple keypress code, unfortunately null will be returned because it is impossible to translate that on variable data.
Title: Re: Prizm Getkey
Post by: DJ Omnimaga on March 27, 2011, 09:18:02 pm
Hmm I see, thanks for the info.

Would we also have a direct input routine like Getkey(keycode)? Basically in the following code:

If Getkey(45)
Do stuff
End

It will do stuff if the key 45 is pressed. This one allowed for multiple keypresses.
Title: Re: Prizm Getkey
Post by: AngelFish on March 27, 2011, 09:57:55 pm
That would indeed be possible. It could probably be done very efficiently if you used the barrel shifter in the CPU to rotate the proper bit in the register into the T bit.

EDIT: Looking it over with the keyboard matrix from Insight, you can actually optimize GetKey at run-time if some information can be computed beforehand (presumably at compile-time):

Code: [Select]
Returns 1 in T bit if the current key is being pressed. Returns 0 in T bit otherwise.
R1= -1*Number of shifts (two's complement notation)
R2= Specific longword of keyboard matrix (A44B0000, A44B0004, or A44B0008)
MOV.L @R2,R3
SHLD R1,R3
Title: Re: Prizm Getkey
Post by: z80man on August 19, 2011, 01:26:47 am
I've been working a making a getkey library that is OS independent for my contest entry and this is what I have so far. Currently it supports reading the key matrix then converting it into a short length identifier. Multi key support is not added yet but is coming soon. Here is the library along with an example program. To use just send a 12 byte array pointer to CustomKey() which will fill the array with the key buffer. Then use BufferConvert() to convert the buffer into a usable identifier. The key identifiers can be found in the #define section of CustomKey.h. Standby for full documentation

Code: (CustomKey.h) [Select]
#define KEY_EXE 0x0004
#define KEY_RETURN 0x0004
#define KEY_NEGATIVE 0x0008
#define KEY_ANS 0x0008
#define KEY_EXP 0x0010
#define KEY_PI 0x0010
#define KEY_QUOTE 0x0010
#define KEY_POINT 0x0020
#define KEY_EQUAL 0x0020
#define KEY_SPACE 0x0020
#define KEY_NUM_ZERO 0x0040
#define KEY_IMAGINARY 0x0040
#define KEY_ALPHA_Z 0x0040
#define KEY_AC_ON 0x0101
#define KEY_OFF 0x0101
#define KEY_DIV 0x0204
#define KEY_CURLY_RIGHT 0x0204
#define KEY_ALPHA_T 0x0204
#define KEY_MULT 0x0208
#define KEY_CURLY_LEFT 0x0208
#define KEY_ALPHA_S 0x0208
#define KEY_NUM_SIX 0x0210
#define KEY_ALPHA_R 0x0210
#define KEY_NUM_FIVE 0x0220
#define KEY_FORMAT 0x0220
#define KEY_ALPHA_Q 0x0220
#define KEY_NUM_FOUR 0x0240
#define KEY_CATALOG 0x0240
#define KEY_ALPHA_P 0x0240
#define KEY_MINUS 0x0304
#define KEY_BRACKET_RIGHT 0x0304
#define KEY_ALPHA_Y 0x0304
#define KEY_PLUS 0x0308
#define KEY_BRACKET_LEFT 0x0308
#define KEY_ALPHA_X 0x0308
#define KEY_NUM_THREE 0x0310
#define KEY_ALPHA_W 0x0310
#define KEY_NUM_TWO 0x0320
#define KEY_MAT 0x0320
#define KEY_ALPHA_V 0x0320
#define KEY_NUM_ONE 0x0340
#define KEY_LIST 0x0340
#define KEY_ALPHA_U 0x0340
#define KEY_ARROW 0x0402
#define KEY_SWAP 0x0402
#define KEY_ALPHA_L 0x0402
#define KEY_COMMA 0x0404
#define KEY_MOVE 0x0404
#define KEY_ALPHA_K 0x0404
#define KEY_PARA_RIGHT 0x0408
#define KEY_RECIPROCAL 0x0408
#define KEY_ALPHA_J 0x0408
#define KEY_PARA_LEFT 0x0410
#define KEY_CUBIC_ROOT 0x0410
#define KEY_ALPHA_I 0x0410
#define KEY_FRAC_DEC 0x0420
#define KEY_MIXED_IMPROPER 0x0420
#define KEY_ALPHA_H 0x0420
#define KEY_FRAC 0x0440
#define KEY_MIXED 0x0440
#define KEY_ALPHA_G 0x0440
#define KEY_DEL 0x0508
#define KEY_INS 0x0508
#define KEY_UNDO 0x0508
#define KEY_NUM_NINE 0x0510
#define KEY_PASTE 0x0510
#define KEY_ALPHA_O 0x0510
#define KEY_NUM_EIGHT 0x0520
#define KEY_CLIP 0x0520
#define KEY_ALPHA_N 0x0520
#define KEY_NUM_SEVEN 0x0540
#define KEY_CAPTURE 0x0540
#define KEY_ALPHA_M 0x0540
#define KEY_RIGHT 0x0602
#define KEY_DOWN 0x0604
#define KEY_EXIT 0x0608
#define KEY_QUIT 0x0608
#define KEY_RAISE 0x0610
#define KEY_X_ROOT 0x0610
#define KEY_THETA 0x0610
#define KEY_SQUARE 0x0620
#define KEY_SQUARE_ROOT 0x0620
#define KEY_RADIAN 0x0620
#define KEY_ALPHA 0x0640
#define KEY_ALPHA_LOCK 0x0640
#define KEY_TAN 0x0702
#define KEY_REVERSE_TAN 0x0702
#define KEY_ALPHA_F 0x0702
#define KEY_COS 0x0704
#define KEY_REVERSE_COS 0x0704
#define KEY_ALPHA_E 0x0704
#define KEY_SIN 0x0708
#define KEY_REVERSE_SIN 0x0708
#define KEY_ALPHA_D 0x0708
#define KEY_LN 0x0710
#define KEY_E_X 0x0710
#define KEY_ALPHA_C 0x0710
#define KEY_LOG 0x0720
#define KEY_TEN_X 0x0720
#define KEY_ALPHA_B 0x0720
#define KEY_X 0x0740
#define KEY_ANGLE 0x0740
#define KEY_ALPHA_A 0x0740
#define KEY_F_SIX 0x0802
#define KEY_G_T 0x0802
#define KEY_F_FIVE 0x0804
#define KEY_G_SOLVE 0x0804
#define KEY_F_FOUR 0x0808
#define KEY_SKETCH 0x0808
#define KEY_F_THREE 0x0810
#define KEY_V_WINDOW 0x0810
#define KEY_F_TWO 0x0820
#define KEY_ZOOM 0x0820
#define KEY_F_ONE 0x0840
#define KEY_TRACE 0x0840
#define KEY_UP 0x0902
#define KEY_LEFT 0x0904
#define KEY_MENU 0x0908
#define KEY_SETUP 0x0908
#define KEY_VARS 0x0910
#define KEY_PRGM 0x0910
#define KEY_OPTN 0x0920
#define KEY_SHIFT 0x0940



void CustomKey( char * buffer);
short BufferConvert( char * buffer);

void CustomKey( char * buffer)
{
const char * keyaddress = 0xa44b0000;

for (int index = 0; index < 12; index++)
{
buffer[index] = keyaddress[index];
}
}

short BufferConvert( char * buffer)
{
short KeyResult;
for(short index = 0; index < 12; index++)
{
if(buffer[index] != 0)
KeyResult = (index << 8) | ((short) buffer[index]);
}
return KeyResult;
}
Code: (example) [Select]
#include <display.h>
#include <SYSTEM_syscalls.h>
#include <CustomKey.h>
#include <keyboard.h>

//
void main(void) {
int x = 1;
int y = 1;
int color = 0;
int mode = 0;
char keybuffer[12];
short key;
int iContinue = 1;

char* heart = "    ";
heart[2] = 0xE5;
heart[3] = 0xE2;
Bdisp_AllCr_VRAM();

while (iContinue) {
key = 0;
Bdisp_AllCr_VRAM();
PrintXY(x, y, heart, mode, color);
Bdisp_PutDisp_DD();
while (key == 0)
{
CustomKey( keybuffer );
key = BufferConvert(keybuffer);
}
switch (key) {
case KEY_EXIT:
iContinue = 0;
break;
case KEY_UP:
y = y == 1 ? 8 : y-1;
break;
case KEY_DOWN:
y = y == 8 ? 1 : y+1;
break;
case KEY_LEFT:
x = x == 0 ? 21 : x-1;
break;
case KEY_RIGHT:
x = x == 21 ? x=1 : x+1;
break;
case KEY_PLUS:
color = color == 7 ? 0 : color+1;
break;
case KEY_MINUS:
color = color == 0 ? 7 : color-1;
break;
case KEY_MULT:
mode = !mode;
break;
case KEY_DIV:
mode = !mode;
break;
}
}

return;
}




Title: Re: Prizm Getkey
Post by: DJ Omnimaga on September 05, 2011, 04:07:00 pm
I wonder if adding multi key support will be easy? Does the Prizm allows direct input like on TI calcs? (where instead of returning the keycode, it checks if a specific key was pressed or not)
Title: Re: Prizm Getkey
Post by: z80man on September 05, 2011, 08:43:35 pm
I wonder if adding multi key support will be easy? Does the Prizm allows direct input like on TI calcs? (where instead of returning the keycode, it checks if a specific key was pressed or not)
Yes the entire keyboard is hardware memory mapped so you can if any key is currently up or down without any difficulty. On the matter of multi key support that is easily done but I'm still working on the best way to implement the function in C that would be very simple for another Prizm coder to use.
Title: Re: Prizm Getkey
Post by: JosJuice on September 06, 2011, 10:14:45 am
I wonder if adding multi key support will be easy? Does the Prizm allows direct input like on TI calcs? (where instead of returning the keycode, it checks if a specific key was pressed or not)
Yep. Insight has an example of it (the "keyboard ports" option).
Title: Re: Prizm Getkey
Post by: Ashbad on September 06, 2011, 08:28:17 pm
I wonder if adding multi key support will be easy? Does the Prizm allows direct input like on TI calcs? (where instead of returning the keycode, it checks if a specific key was pressed or not)
Yes the entire keyboard is hardware memory mapped so you can if any key is currently up or down without any difficulty. On the matter of multi key support that is easily done but I'm still working on the best way to implement the function in C that would be very simple for another Prizm coder to use.

Personally, passing and returning a key[] matrix by reference and checking like key[KEY_PRGM_F1] I think would be my favorite way.
Title: Re: Prizm Getkey
Post by: calc84maniac on September 07, 2011, 12:44:08 pm
It would be pretty easy to make an isKeyPressed macro like the Ndless library has.
Title: Re: Prizm Getkey
Post by: fb39ca4 on September 07, 2011, 04:49:22 pm
Does the prizm have a grid for the keys or can all keys be detected independent of each other?
Title: Re: Prizm Getkey
Post by: PierrotLL on November 28, 2011, 08:01:30 pm
Old topic but it's done : keydown function (http://ourl.ca/11160/266595)