30 November 2018, 18:36 | #41 |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
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. Last edited by litwr; 30 November 2018 at 19:23. |
30 November 2018, 20:10 | #42 | |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,085
|
Quote:
|
|
30 November 2018, 20:21 | #43 | |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,377
|
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 ? |
|
30 November 2018, 20:23 | #44 | |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
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. |
|
30 November 2018, 20:54 | #45 |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
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.
|
01 December 2018, 10:18 | #46 | |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,377
|
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. It's not missing, it's just to be accessed in some indirect way 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. |
|
01 December 2018, 11:16 | #47 |
Zone Friend
Join Date: May 2006
Location: France
Posts: 1,889
|
how about lowlevel.library (didn't checked)
|
01 December 2018, 12:04 | #48 | |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
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. I have tried to check ports but it work very poorly. I used the next code. Code:
btst #3,$dff01d beq .nkbdevent btst #3,$BFED01 beq .nkbdevent ;it gets there very seldom, I have to press a key many times to get there .nkbdevent: |
|
01 December 2018, 12:43 | #49 | |||
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,377
|
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 beq .nkbdevent move.b $bfec01,d0 ori.b #$40,$bfee01 .loop2 cmpi.b #$70,$dff007 bcc.s .loop2 moveq #1,d2 .loop1 move.b $dff006,d1 .loop0 cmp.b $dff006,d1 beq.s .loop0 dbf d2,.loop1 andi.b #$bf,$bfee01 not.b d0 ror.b #1,d0 ; here you have d0.b=keycode, b7 indicates key pressed/released |
|||
01 December 2018, 13:14 | #50 |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
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? |
01 December 2018, 14:17 | #51 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,377
|
Rather than Forbid(), try Disable(). Interrupts may read the port and so your code won't get anything meaningful out of it.
|
01 December 2018, 14:55 | #52 |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
If it was so then the interrupt effect can be noted when there was no Forbid call but without call to Forbid your code work. So it is a kind of a mystery. However you are right it works with Disable. Thank you very much again. But I think that the code with interrupts would be better. So I have to do some more study. Indeed, if somebody has a code to set a keyboard interrupt handler it would help.
|
01 December 2018, 16:20 | #53 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,569
|
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 lea _LinkerDB,a6 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. |
|
01 December 2018, 16:57 | #54 | |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
Quote:
I have just made my code for the kbd interrupt: Code:
LEVEL2IADDR = $68 move.l LEVEL2IADDR,level2ie+2 ;save and set intr vector move.l #level2i,LEVEL2IADDR ... move.l level2ie+2,LEVEL2IADDR ;restore intr vector ... level2i: ;intr handler btst #3,$bfed01 ;kbd intr? beq level2ie move.b #1,key_ready level2ie: jmp 0 ... tst.b key_ready(a3) ;is a key pressed? beq .nokey move.l 4,a6 lea dosname(a3),a1 ; points to dc.b "dos.library",0 jsr OldOpenLibrary(a6) move.l d0,a6 jsr Input(a6) ;get stdin move.l d0,d1 move.l #kbdbuf,d2 moveq.l #4,d3 jsr Read(a6) .nokey: Last edited by litwr; 01 December 2018 at 17:20. |
|
01 December 2018, 18:47 | #55 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,456
|
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. Last edited by roondar; 01 December 2018 at 18:58. |
01 December 2018, 20:04 | #56 | |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
Quote:
EDIT. As I know Read does input with echo. I need to suppress the echo. Maybe it is the cause of the problem. Last edited by litwr; 01 December 2018 at 21:51. |
|
02 December 2018, 00:56 | #57 | |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,456
|
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. ; It also probably won't work because it reads from the CIA ICR register, which can cause problems for the OS. LEVEL2IADDR EQU $68 lea.l LEVEL2IADDR,a0 move.l (a0),level2_vector move.l #level2i,(a0) ... move.l level2_vector,(a0) ... ; intr handler level2i btst #3,$bfed01 ; NOTE: this instruction does not work as intended (discussed below in post) beq level2ie move.b #1,key_ready level2ie: lea level2_vector,a2 jmp (a2) ... level2_vector dc.l 0 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(). Last edited by roondar; 02 December 2018 at 01:05. |
|
02 December 2018, 11:31 | #58 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,569
|
|
02 December 2018, 11:39 | #59 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,515
|
Well, this is the reason why, if I do not forget, I use brackets (and also a)
Code:
movea.l (level2_vector),a2 Kudos however to roondar for trying to untangle and correct that little skein of code. Last edited by ross; 02 December 2018 at 11:54. |
02 December 2018, 11:47 | #60 |
Registered User
Join Date: Mar 2016
Location: Ozherele
Posts: 229
|
@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) move.b $bfed01,d0 ;kbd ori.b #$80,d0 move.b d0,$bfed01 move.l (sp)+,d0 level2ie: jmp 0 |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Misc Amiga Assembler Source Code | copse | Coders. General | 14 | 20 October 2019 02:05 |
The 6502 assembler code in "The Terminator" (1984) | Shoonay | Nostalgia & memories | 2 | 15 May 2009 13:52 |
Assembler System Friendly code | redblade | Coders. General | 3 | 29 July 2008 12:15 |
Amiga Cross Assembler to code intros! - Help! | W4r3DeV1L | Amiga scene | 6 | 30 May 2008 16:53 |
3D code and/or internet code for Blitz Basic 2.1 | EdzUp | Retrogaming General Discussion | 0 | 10 February 2002 11:40 |
|
|