OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 11:28 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Bochs Keyboard Input
PostPosted: Thu May 25, 2017 1:45 pm 
Offline

Joined: Sun Feb 26, 2017 7:52 am
Posts: 9
Hello, i am trying to program 8259A in bochs. But there are problems that i cant solve by myself so i'd like to ask them here. My question is when we map Master 8259's interrupt vectors to 0x20-0x27 range, does it mean that i need correct IVT entries between the physical addresses 0x80-A0 (i am in real mode and ivt sits at 0x000-0x400 so i thought interrupt numbers 0x20-0x27 would map to 0x80-0xA0 physical address range)?

If i call int 0x21(i think this is keyboard interrupt after mapping?) from assembly it works(a string printed on screen). But when i press any key it doesn't work. I'd appreciate any help which enlightens my misunderstandings on subject.
Code:
cli
mov ax,0x7c0
mov ds,ax

mov ax,0x7000
mov sp,ax

xor ax,ax
mov es,ax
mov ax,0x84;0x21th interrupt address
mov di,ax

mov ax,[int_offset]
mov [es:di],ax
inc di
inc di

mov ax,[int_segment]
mov [es:di],ax

;ICW 1
mov   al, 0x11
out   0x20, al
out   0xA0, al
;ICW 2
mov   al, 0x20      
out   0x21, al
mov   al, 0x28      
out   0xA1, al
;ICW 3
mov   al, 0x4      
out   0x21, al
mov   al, 0x2      
out   0xA1, al   
;ICW 4
mov   al, 1      
out   0x21, al
out   0xA1, al

;OCW1 no mask
;mov   al, 0
;out   0x21, al
;out   0xa1, al

sti

int 0x21

end:
   jmp end

;prints string in [ds:si] to screen   
printStr:
   pusha;
   push di
   push es
   cld;inc si after lodsb
loadchr:
   lodsb;
   cmp al,0x00;
   je printStrFinish;
   cmp al,0x0A;
   je newline;
   mov ah,0x4e;
   mov di,[video_memory_index];
   mov es,[video_memory_base];
   mov [es:di],ax;
   inc di;
   inc di;
   mov [video_memory_index],di;
   jmp loadchr;
newline:
   push dx;
   push bx;
   push ax;
   mov bx,0x00A0;
   add [video_memory_index],bx;
   mov dx,0;
   mov ax,[video_memory_index];
   div bx;
   sub [video_memory_index],dx;
   pop ax;
   pop bx;
   pop dx;
   jmp loadchr;
printStrFinish:
   pop es
   pop di
   popa;
   ret;

video_memory_base dw 0xb800;
video_memory_index dw 0x0000;
disk_drive_number_str db 'DiskDriveNumber:',0x00;
int_offset dw 0x7d00
int_segment dw 0x0000
times 256-($-$$) db 0

mov ax,disk_drive_number_str;My interrupt handler which sits at 0x7d00
mov si,ax
call printStr
mov al, 0x20;send EOI
out 0x20, al
iret

times 510-($-$$) db 0
db 0x55
db 0xAA


Top
 Profile  
 
 Post subject: Re: Bochs Keyboard Input
PostPosted: Thu May 25, 2017 3:49 pm 
Offline
Member
Member
User avatar

Joined: Thu Aug 06, 2015 6:41 am
Posts: 97
Location: Netherlands
To get interrupts from the keyboard they first have to be enabled in the PS/2 controller configuration byte.
Also note that you should save and restore all registers you modify in an IRQ handler (in your case at least ax and si), because you don't know if the code that got interrupted was using any of those registers.


Top
 Profile  
 
 Post subject: Re: Bochs Keyboard Input
PostPosted: Thu May 25, 2017 4:11 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
I haven't reviewed your code to see if the PIC is being configured correctly, but sleephacker is right: you need to configure the keyboard itself as well and not just the PIC, because the keyboard can also be used in polling mode instead of IRQs, and you have no real way of knowing how the BIOS configured the keyboard. After reading sleephacker's link to configure the PS/2 controller itself, you also need to configure the PS/2 keyboard. Read the Wiki article on PS/2 keyboards. Your homework for today will be figuring out which commands you need to send to tell the keyboard to send IRQs. :)

Hint: You'll need to reset the keyboard, configure the auto-repeat delay/speed, and enable IRQs as well.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: Bochs Keyboard Input
PostPosted: Thu May 25, 2017 7:05 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
Although I wouldn't structure your code the way you did, I'll just identify where I think things have gone wrong.You seem to have remapped both PICS to 0x20and 0x28. The problem is that the entire BIOS Interrupt Vector Table is pointing all of its routines to the old locations. If any external interrupt comes in other than the keyboard (which you have set up an interrupt service routine for) they will no longer be going to the original interrupt routines.

Since you have only dealt with the keyboard ISR after remapping you can disable all the external interrupts besides the keyboard by updating the masks with an instruction sequence like:
Code:
;OCW1 no mask
mov   al, 0xFD
out   0x21, al
mov   al, 0xFF
out   0xa1, al

This should only enable the keyboard interrupt. One may ask why enabling the other interrupts will cause an issue. It is more than likely the BIOS originally installed default interrupt handlers for 0x20 to 0x2f. Usually it is to a BIOS function that simply does an IRET. The problem is that the default is almost certainly not sending an End of Interrupt (EOI) to the PICs. Effectively after the first timer tick occurs and IRET likely occurs without an EOI. Since IRQ0 is highest priority all future interrupts are effectively disabled so your system will appear to receive no further interrupts. This is why it is important to attach proper Interrupt service routines for any of the external interrupts that may be active.

As has been already mentioned your interrupt service routine clobbers registers. Your ISR should save and restore all the registers it will alter. This could easily be done with a `pusha` instruction at the beginning of your ISR and a `popa` before the `IRET`. PUSHA/POPA were only available on 80186 compatible processors and later. If you are targeting a real 8086 then you have to push each register individually and pop them individually.

On a side note. In real mode CS is the only general purpose (or segment) register that can be guaranteed to have a specific/known value when control is transferred to your ISR. This is because CS gets set to the value you placed into the Interrupt Vector Table for that ISR. You can't even rely on DS being what you expect.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 68 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group