Thanks. It is now not actual. However it sounds like another Moto's oddity for me. I needed to save C flag because every MOVE (it is yet another oddity) clears it! I could find a way to write my code without this saving. I don't know any other processor which works so unusually with arithmetic flags. x86 has PUSHF/POPF, LAHF/SAHF. They can be quite useful although rather rarely.
I have another actual problem. I need to get a key from a keyboard. I don't need to wait key if it is not pressed. So I need to check whether a key action happened and if it happened then to get the scan code. What is the easiest way to get such a functionality? EDIT. I am going to use WaitForChar, Input and Read. However I am not sure that it is the best way. It is better for me to use an interrupt handler with direct access to ports. |
Quote:
|
Quote:
Therefore any data move will change C (usually cleared, exactly like a cmp with zero would have done). But not X. Maybe you can use X in your code rather than C ? Why do you want to preserve the carry anyway ? |
Quote:
I have just found out that WaitForChar is buggy. :( It doesn't allow to set a delay to zero, with a delay equals 1 us it becomes slow and crashes after repeated calls. :( Please help to find another way. Is there any link to instructions about how to use kbd at the lower level? EDIT. @meynaf Thanks to you too but I have another problem. We can discuss the oddity with flags in other thread. Indeed, I am aware of X and C flag and even wrote about them several times as a minor non-significant oddity. |
I have just found an interesting thread - http://eab.abime.net/showthread.php?t=62322 - I will try to work with it. IMHO It is also unusual that Amiga misses a so ordinal function.
|
Quote:
- use input.device, - kill the OS and peek keyboard directly. But i am not sure if accessing the kbd at a low level is a good idea. Quote:
In a multitasking environment keyboard input has to come from some specific location : a window you opened yourself, or eventually a console window. And grabbing keyboard input that is targeted to another application isn't exactly a polite thing to do. The normal way of doing is using a window and ICDMP messages and this is now always what I do. |
how about lowlevel.library (didn't checked)
|
Quote:
There should be a kind of system routine that gets scan-codes and put them into system buffer where the applications can get them from. It looks like there is no such routine. :shocked I have tried to check ports but it work very poorly. I used the next code. Code:
btst #3,$dff01d |
Quote:
You need to first setup the screen (I use OpenScreenTagList for that), then setup the window (I use OpenWindowTagList). The window needs to be backdrop/borderless. Quote:
But, hey, there can not be a global queue for key presses : imagine what would happen if several programs attempt to read them ! Quote:
When i had to do this i used something like that : Code:
btst #3,$bfed01 |
Thank you very much! But, yes, I have trouble. It just doesn't work. Because my program (like mentioned at reaktor.com) uses Forbid call. I can't understand how it can prevent the port at $bfec01 from normal working. So your code doesn't work at all after the Forbid call. If I skip this call then your code works but my program crashes at exit.
IMHO it is better to intercept a keyboard interrupt. So I just need to intercept interrupts check it whether it from keyboard (BTW any help how to do this can greatly accelerate my programming) and if it is keyboard's then set a flag. I can check this flag from my code and later call to Input to get a keyboard's symbol. Is it a correct idea or there is some objections? |
Rather than Forbid(), try Disable(). Interrupts may read the port and so your code won't get anything meaningful out of it.
|
Quote:
|
Yes, I know I'm a bit late, but nobody posted a real answer to this question yet, just the workaround with BASEREG. :)
Quote:
But a base-relative addressing mode needs a base symbol to be defined, so the linker can calculate the 16-bit offsets from it. vlink looks for either of the following two symbols for that purpose: _SDA_BASE_ (Unix, SysVR4) or _LinkerDB (AmigaOS). The linker would even provide that symbol automatically, using the address of your small-data section + 32766 as default value. But all you have to do is to reference that symbol and initialize your base register with it. For example Code:
xref _LinkerDB ; from linker The advantage of real small-data relocations compared with BASEREG is that you are not restricted to a single source file, but you may link several object files together. Unlike absolute 32-bit relocs, all these small-data relocs will disappear in the final executable. |
Quote:
I have just made my code for the kbd interrupt: Code:
LEVEL2IADDR = $68 |
If you are running with the OS active, you are not allowed to set your own interrupt vectors like that. If you need interrupts while using the OS you have to add your handler to the OS interrupt chain. On the other hand, if you are running with the OS disabled then you can set interrupts however you like, but you can't reliably use OS functions.
I'd guess that changing the level 2 interrupt vector by yourself breaks part of the OS, as it also uses the level 2 interrupt (the level 2 interrupt is the PORTS interrupt, which is stated to be in use by Exec here: http://amigadev.elowar.com/read/ADCD.../node0306.html). I'm almost 100% certain that this interrupt is also in part used by AmigaDOS for reading/writing files and as such the Read() function will hang if you change the vector. Without meaning this in a negative way, perhaps it's best to learn a bit more about the environment you are using before mucking about with interrupts etc? AmigaOS is a fully multitasking operating system and you're simply not supposed to address the hardware directly if you wish to use it*. The idea is that you use the available libraries etc to get your desired results. If you do want to use the hardware in a more direct manner, perhaps disabling the OS fits your needs better (though this does mean file I/O becomes much more tricky or impossible unless you either use a trackloader or switch the OS in/out on demand)? *) Note that with OwnBlitter()/DisownBlitter()/WaitBlitter() you can kinda-maybe-more-or-less get away with your own Blitter programming, but even that is not recommended. |
Quote:
EDIT. As I know Read does input with echo. I need to suppress the echo. Maybe it is the cause of the problem. |
Allright, I'll try.
Let's start at the beginning - you use self modifying code to write an address to jump to in your interrupt handler. That is a very, very bad idea. It can easily crash any 68020+ system. Apart from that, it's also completely unnecessary. With this in mind, a cleaner version of the above would be: Code:
; Note that like your code, this is not 68020+ compatible. And even if it does happen to work by accident, I think it's not a good idea to ignore the OS. If you want to use the OS, use the OS for interrupts as well. It saves you mucking about with vectors and won't crash if someone decides to move the VBR to Fast RAM (and your code will crash in that case). Your actual interrupt handler also contains a flaw - it tests a single bit in the CIA ICR register. This read action clears the CIA interrupt for all flags, not just the one you read. In other words, your interrupt handler can cause other interrupts to be cleared and thus not be handled. Quote:
I can't give you a working example as I don't have one ready. There is an example for keyboard.device over at http://amigadev.elowar.com/read/ADCD.../node01A0.html but it notes potential problems if input.device is also in use. AFAIK the 'OS legal way' of reading the keyboard is supposedly to use input.device. Lastly, Read() does not cause character echo. If you see character echo in a shell/cli window that is because the OS is catching the keyboard and choosing to echo. It has nothing to do with Read(). |
Quote:
Code:
move.l level2_vector,a2 |
:p
Quote:
Code:
movea.l (level2_vector),a2 Kudos however to roondar for trying to untangle and correct that little skein of code. |
@roondar Thank your very much for your very useful information. Reading of $bfed01 actually disables Read. :( Thus I need to preserve the content of this register and restore it after the reading. I have made the next code for my interrupt handler.
Code:
level2i: move.l d0,-(sp) |
All times are GMT +2. The time now is 22:52. |
Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.