Keybord interupt

[b][red]This message was edited by Grizant at 2003-12-1 19:53:31[/red][/b][hr]
How do i write a keyboard interrupt server that adds new characters from the keyboard to the keyboard buffer queue.

Characters are input and accessed by user programs asynchronously, and the first input should be the first accessed.
The interrupt server should get the next character input, output it, and add it to the queue.
That's about it. The code + data for this server can be less than twenty words.

heres the code using lc3, my interrupt need to go where in place of iserv.

;pa4_1.asm
;RDO fall 2003 for pa4, CS2318
; rev 20031108

.orig x3000
main
;initialize SP
ld r6,initSP
; Initialize queue
and r0,r0,#0
add r0,r0,#10 ; initialize size set to ten
ld r1,kbbufptr

ld r2,kbiptr
jsrr r2
; set up new server
ld r0,intvec
lea r1,isrv
str r1,r0,#0
; enable KB interrupt
ldi r0,kbsr
ld r1,iemsk
and r0,r0,r1 ; clear ie
not r1,r1
add r0,r0,r1 ; set ie

setie sti r0,kbsr ; doit!
;OK,
spin
lea r0,prompt1
PUTS
jsr getchar
lea r0,prompt2
PUTS
jsr getchar

lea r0,promptf
PUTS
isfull
ld r0,kbqunfptr
jsrr r0 ; test if buffer is full
brnp isfull

;; buffer is full
bffull
lea r0,bffmsg
PUTS
;flush
lea r3,mybuff
ld r0,kbqulshptr
jsrr r0

lea r0,mybuff
PUTS
;
br spin

bffmsg .fill x000A
.stringz "Keyboard buffer is full! Must flush..."
prompt1 .fill x000A ; NL
.stringz "1: "
prompt2 .fill x000A ; NL
.stringz "2: "
promptf .fill x000A ; NL
.stringz "Fill queue: "


;;;;;;;;;;;;;;;;;;;;;;;

;main static data
kbsr .fill xFE00
kbdr .fill xFE02
iemsk .fill b1011111111111111

intvec .fill x0180 ; fixed in hardware
initSP .fill x3000

;;;;;;;;;;;;;;;;;;;;;;;;;;;code
getchar
; trashes r0,r1 .
; On return the next character is in r0 .
st r7,gcr7
ld r1,kbquneptr
gcwait jsrr r1
brz gcwait

ld r1,kbqudptr
jsrr r1

ld r7,gcr7
ret
;getchar data
gcr7 .blkw 1
;***** Keyboard access functions ************
; "external" references
kbqunfptr .fill qunfull
kbquneptr .fill qunempty
kbqudptr .fill qudel
kbquiptr .fill quinit
kbquaptr .fill quadd
kbqulshptr .fill quflush
kbiptr .fill quinit

kbbufptr .fill xF000

;;;;;;; insert isrv here ;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;the big buffer
mybuff .blkw 1024
;
;************ Paste queue.asm here: ************

;queue.asm
; RDO fall 2003, FIFO lists

; .orig x4000 ; arbitrary
;*********** QUEUE PROCEDURES ***************
quinit ; initialize queue
; On entry r0 contains the size of the queue and r1 contains a pointer to the base.
; Trashes r0,r1
add r0,r0,#0
brp qui1
ret
qui1 st r1,qubfptr
add r1,r1,r0

not r0,r0
add r0,r0,#1
st r0,qunsize ; qunsize <-- -N

not r1,r1
add r1,r1,#1
st r1,qulimit

and r0,r0,#0
st r0,qucnt
st r0,quf
st r0,qur
ret

qunfull
; returns cc reset to Z iff queue is full
; trashes r0,r1 . On return r0 contains minus the size of the remaining space.
ld r0,qucnt
ld r1,qunsize
add r0,r0,r1
ret

qunempty
; returns cc reset to Z iff qu is empty
; On return r0 contains the number of items in the queue.
ld r0,qucnt
ret

quadd
; add the item in r0 to the queue
; returns with cc set to Z iff the queue is full
; trashes r0,r1,r2
ld r1,qucnt
ld r2,qunsize
add r2,r2,r1
brnp qua1
ret ; failed, queue is full
qua1 add r1,r1,#1
st r1,qucnt

ld r2,qubfptr
ld r1,qur
add r2,r2,r1

str r0,r2,#0 ; item added

add r1,r1,#1 ; make room for another
ld r2,qunsize
add r2,r2,r1
brnp qua2
and r1,r1,#0
qua2 st r1,qur
and r2,r2,#-1 ; make cc not Z
ret

qudel ; delete an item from queue
; If the queue is non-empty the itemat the front is removed
; is in r0 upon return.
; trashes r0,r1,r2
ld r1,qucnt
brp qud1
ret ; queue empty
qud1 add r1,r1,#-1
st r1,qucnt ; count decrements
ld r1,quf
ld r2,qubfptr
add r2,r2,r1
ldr r0,r2,#0
add r1,r1,#1
ld r2,qunsize
add r2,r2,r1
brnp qud2
and r1,r1,#0 ; wrap-around
qud2 st r1,quf ; update
ret

quflush ; flush the queue
; on entry r3 contains a pointer to the start of the array
; to which the queue will be moved.
; On return r0 contains the number of items moved.
; r0,r1,r2,r3 trashed.
ld r1,qucnt
brp quf1
ret ; queue empty,
quf1 ld r2,qubfptr
ld r0,quf
add r2,r2,r0 ; r2 now points to 1st item
qufloop ldr r0,r2,#0
add r2,r2,#1
str r0,r3,#0
add r3,r3,#1
;
ld r0,qulimit
add r0,r2,r0
brnp quf2
ld r2,qubfptr ; start over
quf2 add r1,r1,#-1
brp qufloop
qufx ld r0,qucnt
st r1,qucnt ; reset cnt to 0
st r1,quf
st r1,qur
ret



;data
qubfptr .fill xf000 ;pointer to base of queue
qucnt .fill #0 ; number of items currently in queue
qur .fill #0 ; index of rear of queue
quf .fill #0 ; index of front of queue
qunsize .fill #-10 ; replace with -256
qulimit .fill x0ff6 ; test for buffer overflow
; .end


.end


Comments

  • Hello, I don't have a real answer for you, but
    IN AL,60h
    gets key board presses from port 60h (its a bit complicated to get working right, but when it does it's fast tight code.)
    You would need Ralf Browns interrupt list with PORTS.A A-D?
    files and look into port 64h
    which bit indicates a key is waiting?

    Then an understanding of how the key board buffer works is the next step.
    I made a program, ViewMem.com and it dumps memory to the screen
    in char or hex form, 16x16=256 per page
    and you can watch the key board buffer work as you press keys.
    it's head & tail pointer change and the keys you press show up in
    char and scan code (er something)
    Any way, you can make a simple dump mem to screen .com file
    and watch the KBD buffer in action, which will show you how to add keys
    to the buffer and how to increment the buff pointers
    and what the buf max is, so you can change the pointers to buff head.
    bla bla bla etc
    Hopefully somebody will give you a real answer soon ?
    So till then, gud luck !
    Bitdog

  • [b][red]This message was edited by xkgdiam at 2003-12-7 21:19:25[/red][/b][hr]
    [code]
    First of all, i dont know your assemler,
    and i dont know if your code is going to use under Dos.
    if you use Dos,
    the Bios have a 32byte buffer to keep the keys pressed but,
    teh most recent key is at the end of buffer
    if you want so much little code+data size :
    1-i suppose your buffer will be less than 32 bytes
    2-you can let Dos handler do the job for you, and then just copy

    Well bios have to memory locations that points
    0040:001A ;word, points to offset of buffer start in 0040 seg
    0040:001C ;word points to the buffer tail offset (seg=0040)
    0040:001E ;the buffer (32 bytes size == 16 keys)
    Here what it happens :
    buffer tail tells you the location where the NEXT pressed key
    is going to store.If the buffer is full then tail points to head.
    So,
    mov ax,40h
    mov es,ax
    mov al,es:[1ch];get the tail
    cmp al,1eh ;the buffer's start
    jz buffer_full
    sub al,2 ;the previus key
    jmp get_key
    buffer_full:
    mov al,3ch ;the buffer's end
    get_key:
    mov di,ax ;ah=0
    mov ax,[di]

    then you can copy the bytes you want into your buffer
    from last to first, so in your buffer last key will be first
    so when you install your TSR ,
    first call old int9h handler (dos keyb handler) to do the job
    then go and copy bytes in your buffer
    That my idea,...











    [/code]






Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories