Simple way to *wait* for a key press, and get its martrix or PETSCII code? - 6502

I have found a few BASIC and KERNAL functions and memory addresses related to getting a key press/line, but how can I simply wait for a key press, and get its code? I want to pause execution, and resume once a key is pressed. I do not want them to be queued up during execution.

The principle is to use a non-blocking call, and keep calling it until you get a key.
In assembler you can use the KERNAL function GETIN at $FFE4
WAIT_KEY
jsr $FFE4 ; Calling KERNAL GETIN
beq WAIT_KEY ; If Z, no key was pressed, so try again.
; The key is in A
In BASIC you can use GET
10 GET A$:IF A$="" GOTO 10:REM WAIT FOR KEY
20 PRINT A$
Above I used spaces to make it more readable, but spaces are not necessary (they use memory and take time to process. It could be written as:
10 GETA$:IFA$=""GOTO10
20 PRINTA$

Related

Anylogic - Assembler should stop working for 2 hours after 10 assemblies done

The "Assembler" should stop working for 2 hours after 10 assemblies are done.
How can I achieve that?
There are so many ways to do this depending on what it means to stop working and what the implications are for the incoming parts.. but here's one option
create a resourcePool called Machine, this will be used along with the technicians:
on the "on exit" action of the assembler do this (I use 9 instead of 10 because the out.count() doesn't count until the agent is completely out, so when it counts 9, it means that you have produced 10)
if(self.out.count()==9){
machine.set_capacity(0);
create_MyDynamicEvent(2, HOUR);
}
In your dynamice event (that you have to create) you will add the following code:
machine.set_capacity(1);
A second option is to have a variable countAssembler count the number of items produced... then
on exit you write countAssembler++;
on enter delay you write the following:
if(countAssembler==10){
self.suspend(agent);
create_MyDynamicEvent(2, HOUR,agent);
}
on the dynamic event you write:
assembler.resume(agent);
Don't forget to add the parameter needed in the dynamic event:
Create a variable called countAssembler of type int. Increment this as agents pass through the assembler. Also create a variable called assemblerStopTime. You also record the assembler stop time with assemblerStopTime=time()
Place a selectOutputOut block before the and let them in if countAssembler value is less than 10. Otherwise send to a Wait block.
Now, to maintain the FIFO rule, in the first selectOutputOut condition, you need to check also if there is any agent in the wait block and if the current time - assemblerStopTime is greater than 2. If there is, you free it and send to the assembler with wait.free(0) function. And send the current agent to wait. You also need to reset the countAssembler to zero.

WindowKeyPressFcn stops being called

I am working on some modifications to EEGlab's eegplot function (things like vim-style navigation etc.) that need to work through WindowKeyPressFcn.
However, the callback is not being called for some reason. I have been debugging the issue for some time and am a bit lost. I am looking for suggestions on what might be wrong. Unfortunatelly the eegplot function is big, complex and somewhat convoluted and I was unable to reproduce the issue in a simple example. Therefore I am looking for general suggestions on why a function handle that is clearly present in WindowKeyPressFcn might stop being used at some point.
Here is what I have learned so far:
If I go to debug mode in eegplot (set a breakpoint near the end of the setup function [the first half of eegplot]) I am able to run the WindowKeyPressFcn at least once.
However - the function stops being called at some point during debug (sometimes even after being called only once).
If I run eegplot without debug (that is wait for it to finish and return control to me) I am unable to call WindowKeyPressFcn by pressing a key. The function handle is still present in WindowKeyPressFcn property of the figure.
Whener the WindowKeyPressFcn is not being used when I press a key, I can still call it with:
figh = gcf;
fun = get(figh, 'WindowKeyPressFcn');
ev.Key = 'rightarrow';
ev.Character = ' ';
ev.Modifier = [];
feval(fun, figh, ev);
So the function handle is 'healthy' so to speak, but for some reason it is not being used any more when a key is pressed and the figure has focus. When and why something like this could happen? Any ideas on things I should check to understand this issue?
Update:
I found out that WindowKeyPressFcn callback can sometimes be blocked by some window listeners, and tried out the following solution:
hManager = uigetmodemanager(gcf);
set(hManager.WindowListenerHandles,'Enable','off');
It doesn't work - WindowKeyPressFcn is still not called when I press a key. :(
Update 2:
Another thing that does not work:
chld = get(gcf, 'Children');
tp = get(chld, 'type');
chld = chld(strcmp(tp, 'uicontrol'));
set(chld, 'KeyPressFcn', #eegplot_readkey_new)
(eegplot_readkey_new is the function I use for reacting to keypresses)
Update 3:
And another one not working:
addlistener(gcf, 'WindowKeyPress', #eegplot_readkey_new);
Ok - I fiugred it out, although the solution is weird to say the least.
For some mysterious reason using linesmoothing undocummented property prevents WindowKeyPressFcn from being called. I have absolutely no idea why...

KbWait won't register key press

I'm trying to collect keyboard data, but I can't get KbWait to work. In the following code, I'm trying to wait for the participant to respond, check if their response is one of two acceptable answers, and then continue. It should only continue when the participant presses 'j' or 'f'.
response = [];
while isempty(response)&&(GetSecs - FlipTimestamp) < 10
[keyIsDown, RTsecs, RTkeyCode, deltaSecs] = KbWait;
if keyIsDown
r=find(RTkeyCode);%this should be the code for the key pressed
response=KbName(r);%Figure out what key was pressed
rt=num2str(RTsecs-time); %subtract off timestamp from when window was flipped
if response == 'f'
match_response= false;
end
if response == 'j'
match_response= true;
end
end
end
However, KbWait never returns. When I try to run it from the command line, it doesn't work either. It just hangs up and refuses to return, and I have to interrupt the program.
It's been nine months since you posted this, so I imagine you've already found some sort of solution. But I was also having this problem, and here's what I discovered:
I went through my entire HID list: devices = PsychHID('Devices')
As I examined each one's 'usageName' property, I found that multiple devices were considered to be 'Keyboard', even though I only have one actual keyboard connected.
I then tried each one's index as an argument for KbWait. When I got to the correct one, KbWait worked.
Hi there I think your problem is the KbWait function.
you used KbWait like ist KbCheck but the output of those functions is different
[secs, keyCode, deltaSecs] = KbWait([deviceNumber][, forWhat=0][, untilTime=inf])
[keyIsDown, secs, keyCode, deltaSecs] = KbCheck([deviceNumber])
Try KbCheck its more exact than KbWait, because KbWait checks the keyboard only every 5 ms
Here is a Function I wrote sometimes ago: working KbCheck

UPDATE and READKEY at the same time?

In my application I'm building, I'd like for the first screen to be an UPDATE to an integer, but I'd like to have an option to press F2 to access a different kind of functionality in the program.
When I try it the logical way, I get buzzed at since the UPDATE is expecting INTEGER only input, and I'm pressing F2.
Can you UPDATE and READKEY successfully at the same time?
You're trying to do it the old way with editing blocks - try reading up on event-driven programming, where the code describes events and what gets run when a certain event happens. The code would look something like this:
ON F2 of update-field
DO: /* something */
END.
UPDATE update-field.
Better yet, don't use "UPDATE", do a "WAIT-FOR" instead.

Why Seting the SetMode to orbit disables custom KeyPressFcn event handlers, the callback

1-The code below displays the properties of the pressed key.Try it by pressing a key and observe the results.
figure('Name','Press keys to put event data in Command Window',...
'KeyPressFcn',#(obj,evt)disp(evt));
you will see outputs like this( e.g upon pressing space bar)
Character: ' '
Modifier: {1x0 cell}
Key: 'space'
2-Now simply add the following line of code to above ( or simply execute it before clearing the workspace)
cameratoolbar('SetMode','orbit');
Now press any key and nothing happens! the control will no longer be transferred to your costume call back function! ( here:#(obj,evt)disp(evt)).
same thing happens for WindowButtonDownFcn, WindowButtonUpFcn too.
How can I get around this? I wanna be able to handle KeyPressFcn or WindowButtonDownFcn after executing cameratoolbar('SetMode','orbit').
I found the answer: Once the cameratoolbar('SetMode','orbit') is called one of these two happens:the handle to the figure is lost or the event handler gets its default value. I am not sure which one though. Therefore we can add the following code to re-assign the lost handler back to our own call back function:
set(gcf,'KeyPressFcn',#(obj,evt)disp(evt))