I was wondering what's the correct keyboard reading procedure without using
OS routines? I know that by reading CIAA-sdr register ($bfec01) i can get a
code of a key, the problem is that when i get back to the OS (ow, yes i
want to shut it off), the OS receives first 8 key codes - they stay in the
buffer (if you dunno what i am talking about, run some intro/demo, press
few keys there, exit and look what happens in CLI). Now i know i need to
play with CIAA-cra register ($bfee01), because it is associated with CIAA
Timer-A, which is used for keystrokes handshaking. Well, i disassembled ROM
a bit, where i found: or.b #$40,$bfee01. Hopefully someone knows how to
deal with this properly? I would also apreciate more in-depth CIA docs,
because HW-RM is almoust silent... Thanx in advance, later.
Boris.
Only the last code that turned up.
>the problem is that when i get back to the OS (ow, yes i want to shut
>it off),
Oh dear. If you 'shut the OS off' you cannot be sure of being able to
bring it back. So don't Disable() and don't Forbid(). There are ways
to get exclusive access to the hardware you want to bash without that.
>the OS receives first 8 key codes - they stay in the buffer (if you
>dunno what i am talking about, run some intro/demo, press few keys
>there, exit and look what happens in CLI).
Probably because the keyboard.device interrupt handler is still in
place and handling the key events.
>Now i know i need to play with CIAA-cra register ($bfee01), because
>it is associated with CIAA Timer-A, which is used for keystrokes
>handshaking. Well, i disassembled ROM a bit, where i found: or.b
>#$40,$bfee01. Hopefully someone knows how to deal with this properly?
>I would also apreciate more in-depth CIA docs, because HW-RM is
>almoust silent...
I think you can do something like this:
include "exec/exec_lib.i"
include "exec/nodes.i"
include "resources/cia.i"
include "resources/cia_lib.i"
...
move.l _SysBase,a6 ; you do cache the ExecBase pointer, I hope?
lea ciaa_name,a1
jsr (_LVOOpenResource,a6)
tst.l d0
beq kbd_panic ; should never happen
move.l d0,ciaa_base
move.l d0,a6
moveq.l #3,d0 ; serial port bit
lea kbd_int,a1
jsr (_LVOAddICRVector,a6)
...
move.l ciaa_base,a6
moveq.l #3,d0
lea kbd_int,a1
jsr (_LVORemIRCVector,a6)
kbd_panic
...
ciaa_base ds.l 1
kbd_int dc.l 0,0
dc.b NT_INTERRUPT,127
dc.l kbd_int_name
dc.l kbd_int_data ; gets passed to your routine in a1
dc.l kbd_int_code ; routine to be called
kbd_int_name dc.b "my hardware-bashing app",0
ciaa_name CIAANAME
...
However, I'm not entirely sure that this will work.
--
Ben Hutchings - should be revising | http://users.ox.ac.uk/~worc0223/ / IRC:
m95...@ecs.ox.ac.uk | Jay Miner Society: www.jms.org | Team *AMIGA* /Womble
> I was wondering what's the correct keyboard reading procedure without using
> OS routines? I know that by reading CIAA-sdr register ($bfec01) i can get a
The is no other "correct" keyboard reading routines besides using the OS.
> code of a key, the problem is that when i get back to the OS (ow, yes i
> want to shut it off), the OS receives first 8 key codes - they stay in the
> buffer (if you dunno what i am talking about, run some intro/demo, press
> few keys there, exit and look what happens in CLI). Now i know i need to
> play with CIAA-cra register ($bfee01), because it is associated with CIAA
> Timer-A, which is used for keystrokes handshaking. Well, i disassembled ROM
> a bit, where i found: or.b #$40,$bfee01. Hopefully someone knows how to
> deal with this properly? I would also apreciate more in-depth CIA docs,
> because HW-RM is almoust silent... Thanx in advance, later.
Okay.. here is a real ugly example of how you can do it.. I don`t recommend
using it :)
(this example below waits for the key "a" to be pressed five times)
x: move $dff01c,d0 ;Interrupts aus
ori #$8000,d0
move d0,intena
move #$7fff,$dff09a
move.l 104,vec2 ;Interruptvektoren ändern
move.l 108,vec3 ;*
move.l #inkey,104
move.l #rast,108 ;*
move #$c028,$dff09a ;Interrupts an
moveq #4,d1 ;Tastenzähler
x1: btst #0,keyfl ;Auf Taste warten
beq.s x1
move.b keyco,d0 ;Tastencode holen
bclr #0,keyfl ;keyfl löschen
cmpi.b #$20,d0 ;"A"-Code ?
bne.s x1 ;nein => zurück
dbra d1,x1 ;zum 5. Mal gedrückt ?
x2: move #$7fff,$dff09a ;Interrupts aus
move.l vec2,104 ;Alte Vektoren zurück
move.l vec3,108 ;*
move intena,$dff09a ;Interrupts an
rts
inkey: move.l d0,-(a7) ;Tastaturabfrage
move #8,$dff09c ;Interruptrequestbit löschen
btst #3,$bfed01
bne inkey2
bclr #0,repfl ;*Hilfsflag aus
move.b $bfec01,d0 ;Tastencode berechnen
ror.b #1,d0
eori.b #$ff,d0
bmi.s inkey1 ;Taste losgelassen ?
btst #0,keyfl ;Bereits ein Code gespeichert?
bne.s inkey1
move.b d0,keyco ;Code speichern
bset #0,keyfl ;keyfl setzen
move.b #20,repco ;*Verzögerungszähler starten
bset #0,repfl ;*Hilfsflag aktivieren
inkey1: move.b #$ff,$bfec01 ;Tastaturleitung auf 0
bset #6,$bfee01
bclr #6,$bfee01
inkey2: move.b $bfed01,d0
move.l (a7)+,d0
rte
rast: move.l d0,-(a7) ;*Rasterinterrupt
move #$0020,$dff09c ;*
btst #0,repfl ;*Hilfsflag gesetzt
beq.s rast2 ;*nein => kein Repeat
move.b repco,d0 ;*Zähler erniedrigen
subi.b #1,d0 ;*
bne.s rast1 ;*gleich 0 ?
move.b #4,d0 ;*Neue Verzögerung setzen
bset #0,keyfl ;*keyfl setzen
rast1: move.b d0,repco ;*
rast2: move.l (a7)+,d0 ;*
rte ;*
vec2: dc.l 0 ;alter Interruptvektor (Priotität 2)
vec3: dc.l 0 ;*alter Interruptvektor (Priorität 3)
intena: dc.w 0 ;altes Interruptkontrollregister
keyco: dc.b 0 ;Tastencode
keyfl: dc.b 0 ;Taste gedrückt ja/nein
repco: dc.b 0 ;*Verzögerungszähler
repfl: dc.b 0 ;*Hilfsflag für Tastenwiederholung
Cya, Nicholas
--
__
__/// Sn...@studbox.uni-stuttgart.de <*> Irc: Yagger (#amigacafe/undernet)
\XX/ http://home.pages.de/~Snowy/ <*> Too Lazy to Fail..
> I was wondering what's the correct keyboard reading procedure without using
^^^^^^^ ^^^^^^^
> OS routines?
^^
There is no such thing.
Christian
I stand corrected.
Let me put it another way. Always use the OS. :)
Boris Donko wrote in message
<01bd955b$b6ae9820$11ef...@litehouse.ppp.uni-mb.si>...
> Howdy all.
>
>I was wondering what's the correct keyboard reading procedure without using
>OS routines? I know that by reading CIAA-sdr register ($bfec01) i can get a
>code of a key, the problem is that when i get back to the OS (ow, yes i
>want to shut it off), the OS receives first 8 key codes - they stay in the
>buffer (if you dunno what i am talking about, run some intro/demo, press
>few keys there, exit and look what happens in CLI). Now i know i need to
>play with CIAA-cra register ($bfee01), because it is associated with CIAA
>Timer-A, which is used for keystrokes handshaking. Well, i disassembled ROM
>a bit, where i found: or.b #$40,$bfee01. Hopefully someone knows how to
>deal with this properly? I would also apreciate more in-depth CIA docs,
>because HW-RM is almoust silent... Thanx in advance, later.
>
>Boris.
>
The Following "Keyboard" code WORKS VERY WELL!!!
Its not mine and I've lost the original doc's, so it's
been cut out of a Car Game I'm working on. Hope nothing
vital's Missing.
???????????????????????????????????????????????????
H.E.L.P.
DOES ANYONE HAVE ANY GOOD NON/OS FAST MASKED BOB ROUTINES,
IS IT POSSIBLE TO CUT BACK ON THE BLITTER CHANNELS.
My code frag at eof.
While I'm at it, does anyone have a protacker player (Low cpu usage)
that can also support ingame sounds (priority on sfx).
???????????????????????????????????????????????????
;************************
;*** KeyBoard ***
;************************
rsreset
kb.qualifiers: rs.b 1
kb.keytmp: rs.b 1
kb.lastkeytmp: rs.b 1
kb.keydelaytmp: rs.b 1
kb.repspeedtmp: rs.b 1
kb.key: rs.b 1
kb.reserved: rs.w 1
kb.sizeof rs.b 0
rsreset
;--------------------------------------------------------
;Code Start
ENABLE_LEVEL2_INTERRUPT Level2
; Code Body
;--DO--
bsr ReadKeys
tst.b d0
ble .skip
;code here
.skip
;--LOOP--
;Code end
EVEN
OldLev2 dc.l 0
kb_temp: ds.b kb.sizeof
Qualifier_Table: dc.b "`abcdefg"
;--------------------------------------------------------
; *** KeyBoard ***
GetKeycodes lea Qualifier_Table(pc),a0
moveq #7,d7
moveq #0,d2
move.b (a1),d3 ;kb.Qualifiers(a1),d3
check_qual1 move.b (a0)+,d1
cmp.b d0,d1
bne.s checkqual2
bset d2,d3
move.b d3,(a1) ;kb.Qualifiers(a1)
rts
checkqual2 add.w #$80,d1
cmp.b d0,d1
bne.s checkqual4
bclr d2,d3
checkqual3 move.b d3,(a1) ;kb.Qualifiers(a1)
rts
checkqual4 addq.b #1,d2
dbra d7,check_qual1
tst.b d0
bpl.s KeyOk
move.b d0,d1
sub.b #$80,d1
cmp.b kb.KeyTMP(a1),d1
beq.s KeyOk
rts
KeyOk move.b d0,kb.KeyTMP(a1)
rts
;---
cnop 0,4
ReadKeys lea kb_temp(pc),a1
moveq #0,d0
move.b kb.KeyTMP(a1),d0
cmp.b kb.LastKeyTMP(a1),d0
beq.s Repeat
move.b d0,kb.LastKeyTMP(a1)
sf.b kb.KeyDelayTMP(a1)
bra.s DoKey3
Repeat tst.b kb.KeyDelayTMP(a1)
beq.s DoKey
subq.b #1,kb.KeyDelayTMP(a1)
bra.s No_Key
DoKey tst.b kb.RepSpeedTMP(a1)
beq.s DoKey2
subq.b #1,kb.RepSpeedTMP(a1)
bra.s No_Key
DoKey2 sf.b kb.RepSpeedTMP(a1)
DoKey3 tst.b d0
bpl.s DoKey4
No_Key st.b d0
DoKey4 move.b d0,kb.KEY(a1) * d0.b = keycode..
move.b (a1),d1 ;kb.Qualifiers(a1),d1 * d1.b = qualifiers..
rts
;--------------------------------------------------------
;###################
;Lev2"CIA-A"Interrupt:
;###################
Level2 movem.l d0-d7/a0-a6,-(sp) * preserve irq reg`s..
lea $DFF000.l,a6 * hardware base..
move.w $1E(a6),d0 * intreqr
and.w #8,d0 * level 2 request ?
beq.s Exit_Lev2
btst #3,$BFED01.l * from keyboard?
beq.s _Exit_Lev2
lea kb_temp(pc),a1
move.b $BFEC01,d0 * get key
bset #6,$BFEE01 * start ciaa
not.w d0
ror.b #1,d0
bsr GetKeycodes
lea $dff006,a1
moveq #4-1,d2
key6: move.b (a1),d3
key1: cmp.b (a1),d3 * wait 4 rasters... before ciaa
beq.b key1 * stop.. ack`ing keyboard
dbf d2,key6
bclr #6,$BFEE01.l * stop ciaa - acknowlege kb
_Exit_Lev2 move.w #8,$9C(a6) * clear irq bit..
Exit_Lev2 movem.l (sp)+,d0-d7/a0-a6 * restore irq reg`s..
nop * NB: these nop`s are here for 040/060
nop * cache compatibility! you should do
rte * the same for any other hardware irq`s
nop * like a Level3 that you setup to make
nop * sure your code works on MC680x0!
;--------------------------------------
ENABLE_LEVEL2_INTERRUPT MACRO
bsr GetVBR
move.l d0,a4
lea OldLev2(pc),a0 * our level2 save
move.l $68(a4),(a0)
move.l #\1,$68(a4) ; Lable Address
move.w #$8000+$4008,INTENA+CUSTOM ; Enable CIA-A interrupt
ENDM
;--------------------------------------
***********************************************************
* This function provides a method of obtaining a pointer to the base of the
* interrupt vector table on all Amigas. After getting this pointer, use
* the vector address as an offset. For example, to install a level three
* interrupt you would do the following:
*
* bsr _GetVBR
* move.l d0,a0
* move.l $6c(a0),OldIntSave
* move.l #MyIntCode,$6c(a0)
*
***********************************************************
* Inputs: none
* Output: d0 contains vbr.
GetVBR: move.l a5,-(sp) ; save it.
moveq #0,d0 ; clear
movea.l 4.w,a6 ; exec base
btst.b #AFB_68010,AttnFlags+1(a6); are we at least a 68010?
beq.b .1 ; nope.
lea.l vbr_exception(pc),a5 ; addr of function to get VBR
CALL Supervisor ; supervisor state
.1: move.l (sp)+,a5 ; restore it.
rts ; return
vbr_exception:
; movec vbr,Xn is a priv. instr. You must be supervisor to execute!
; movec vbr,d0
; many assemblers don't know the VBR, if yours doesn't, then use this
; line instead.
dc.l $4e7a0801
rte ; back to user state code
------ END OF EXAMPLE
; ***********************
; *** 32x32 PASTE BOB ***
; ***********************
;INPUT d3,d4,d5 = x,y,frame
;(bob size is taken as 32x32)
PasteBob32x32
tst.w d4
blt bob32x32_error
cmp.w #SCREENHEIGHT-32-1+OVERRUN*2,d4
bgt bob32x32_error
tst.w d3
blt bob32x32_error
cmp.w #SCREENWIDTH-32-1+OVERRUN*2,d3
bgt bob32x32_error
moveq #0,d1
move.w d4,d1 ;bob_ypos
mulu #((OVERRUN*2/8)+BYTEWIDTH)*4,d1
add.l LogicScreenBuffer,d1
move.w d3,d2
lsr.w #3,d2
and.l #$fffe,d2
add.l d2,d1
move.w d3,d2
move.l d1,A1 ;blitto
and.w #$0f,d2
ror.w #4,d2
moveq #0,d0
move.w d5,d0 ;Frame
mulu #(4*32*4)+(4*32),d0 ; *400 can be
; (<<2)*FastMul10
move.l BobGfxBuffer,a2 ; Image
add.l d0,a2
move.l BobGfxBuffer,a0 ; Mask
add.l #4*32*4,d0 ; new
add.l d0,a0
BLTWAIT
move.w d2,bltcon1+custom
add.w #$0fca,d2
move.w d2,bltcon0+custom
move.w #$0,bltalwm+custom
move.w #$ffff,bltafwm+custom
move.w #-2,bltamod+custom
move.w #-2,bltbmod+custom
move.w #(((OVERRUN*2/8)+BYTEWIDTH)*BITPLANES)-6,BLTCMOD+custom
move.w #(((OVERRUN*2/8)+BYTEWIDTH)*BITPLANES)-6,BLTDMOD+custom
move.l a0,bltapt+custom ;Mask
move.l a2,bltbpt+custom ;Bob Gfx Data
move.l a1,bltcpt+custom
move.l a1,bltdpt+custom ;blitto
FASTBLIT_ON
BLTSIZE 3,32
REPT (BITPLANES-1)
lea (OVERRUN*2/8)+BYTEWIDTH(a1),a1
BLTWAIT
move.l a0,bltapt+custom
move.l a1,bltcpt+custom
move.l a1,bltdpt+custom
BLTSIZE 3,32
ENDR
FASTBLIT_OFF
bob32x32_error:
rts
;-----------------------------------------------------------
>Boris Donko wrote in message
><01bd955b$b6ae9820$11ef...@litehouse.ppp.uni-mb.si>...
>> Howdy all.
>>
>>I was wondering what's the correct keyboard reading procedure without using
>>OS routines?
A nice program would install an input.device input handler which looks for
rawkeys and then gobbles all the input events. You can still get a reasonable
amount of CPU time for your program by doing this and raising the priority of
your task to about +4, LoadView(0) and OwnBlitter() and away you go.
[snip]
> H.E.L.P.
>does anyone have any good non/os fast masked bob routines,
>is it possible to cut back on the blitter channels.
[text converted to lowercase for much easier reading]
Have you considered using an interleaved bitmap for your display? This
would require a much larger mask (the mask would need the same amount of
memory as the image you want to blit) but you can get a GREAT speedup
by using 1 tall blit to copy your image rather than 6/8 separate small
ones. And you can run the processors in parallel then too.
Another solution is to use the blitter to draw half or 3/4 of the planes
of the image and use the CPU to draw the remaining. Like, start the blitter
doing plane #1 and use the CPU to do plane #8. Or you could have the
blitter do the top half of the image and the CPU start at the bottom and
work its way up.
Cheers,
-- ___ ___
| .| _____ __ __ _____/ \
.--' :|/ .Y || .Y -- _)-7_/
| -- ;| -- ;| `' ;| (_ _ Dave's not here man.
`------^----^-^------^-----'`-'
"Beware of yellow snow"
Hi !
----
boris...@uni-mb.si (Boris Donko) benutzte seine Tastatur am 11.06.1998 um 17:12:06 Uhr,
um folgenden Text unter dem Betreff "Low level key reading"
zu erzeugen:
> Howdy all.
>
> I was wondering what's the correct keyboard reading procedure without using
> OS routines? I know that by reading CIAA-sdr register ($bfec01) i can get a
> code of a key, the problem is that when i get back to the OS (ow, yes i
> want to shut it off), the OS receives first 8 key codes - they stay in the
> buffer (if you dunno what i am talking about, run some intro/demo, press
> few keys there, exit and look what happens in CLI). Now i know i need to
> play with CIAA-cra register ($bfee01), because it is associated with CIAA
> Timer-A, which is used for keystrokes handshaking. Well, i disassembled ROM
> a bit, where i found: or.b #$40,$bfee01. Hopefully someone knows how to
> deal with this properly? I would also apreciate more in-depth CIA docs,
> because HW-RM is almoust silent... Thanx in advance, later.
Without OS routines is very problematic. Using lowlevel.library would be
a very fast way to read the keyboard...
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) Roland Mainz C programmer
\__\/\/__/ gis...@w-specht.rhein-ruhr.de MPEG specialist
/O /==\ O\ Tel +49 (0) 2426901568 Sun and Amiga programmer
(;O/ \/ \O;) FAX +49 (0) 2426901569
Ofcourse there is! disassemble the os functions and check how :)
Rune Stensland Mc680x0 Democoder. Irc: Sp^Ctz Channel:#amycoders at Ircnet
Email: run...@ifi.uio.no Using a1200/030 50mhz Amiga power!
>> > I was wondering what's the correct keyboard reading procedure without
>> > using
>> ^^^^^^^ ^^^^^^^
>> > OS routines?
>> ^^
>> There is no such thing.
>Ofcourse there is! disassemble the os functions and check how :)
Note here: The OS is supposed to be a "black box" - that means; you are not
"allowed" to do that. ;)
Which gives the correct answer; "There is no such thing."
Peeking the hardware for keaystrokes means that you "disable" that a
window has to be "active" to send keystrokes to the related software.
If more than one program is receiving keystrokes at a time (which will be the
case if you peek the hardware - unless you have closed EVERYTHING down) then
you will be creating chaos.
/Hannu E K Nevalainen/
Personal rc5-stats: 5,569 2^28-key blks, i.e. 1,494,917+ Mkeys, M68K Amiga.
--
Amiga makes it possible, Mac makes it expensive and
Win95 just makes B. G. rich....
> > > I was wondering what's the correct keyboard reading procedure without using
> > ^^^^^^^ ^^^^^^^
> > > OS routines?
> > ^^
> > There is no such thing.
>
> Ofcourse there is! disassemble the os functions and check how :)
The CURRENT os code does not work with all imaginable types of keyboards
and/or keyboard chipsets that have been added in the past and/or will be
added in the future. As you're copying a snapshot of current OS code, your
resulting program will fail soon, or fail already on some machines.
For example it will already fail on computers equipped with an IBM type
keyboard, that works with a special driver device (installed at boot time).
Your OS copy does not include this code, and therefore can't talk to the
keyboard.
As future Amigas (if ever built) focus more on mainstream hardware, there
is an almost 100% chance that their keyboard chipset will not be CIAs with
custom keyboard PCB, but a serial keyboard port like in todays PCs. Your
driver will also not talk to the keyboard on this type of Amiga.
The conclusion is that a) your approach is NOT a "correct keyboard reading
procedure without using the OS routines", as well as b) there obiously
really "is no such thing".
>Ofcourse there is! disassemble the os functions and check how :)
For example:
I'm writing this on an Amiga with a cordless mouse and cordless keyboard.
If you don't use the OS, I have to walk across the room to my amiga kb/mouse
(and I won't unless your program is /really/ good )
Mike
--
Mike Redrobe - mailto:mi...@redrobe.demon.co.uk MikeRR on #Amiga
http://www.redrobe.demon.co.uk