Page 1 of 2

A20 and IDT

Posted: Tue Oct 22, 2002 12:03 pm
by Tom
Hello, I've searched the internet for A20 code, but only found stuff for TC.

So, I need some A20 enabling code.
And I need a IDT that doesn't reboot my computer.
I bet the IDT would work if I could stop the BIOS from interfering when I use sti...
Thank you...( and i'm still looking for a scroll function. If any one has a gettextxy() function or just a gettext function, or whatever you call it, I would like that too. Thank you )...

Re:A20 and IDT

Posted: Tue Oct 22, 2002 12:51 pm
by .bdjames
#include "a20.h"
#include "io.h"

__inline__ static unsigned char KeyboardRead(unsigned char p){
while(inb(0x64)&1==0);
return inb(p);
}

__inline__ static void KeyboardWrite(unsigned char c, unsigned char p){
while(inb(0x64)&2!=0);
outb(c,p);
}

void A20(){
unsigned char a;
do{
KeyboardWrite(0xD0,0x64);
a = KeyboardRead(0x60);
KeyboardWrite(0xD1,0x64);
KeyboardWrite(a|2,0x60);
KeyboardWrite(0xD0,0x64);
} while(KeyboardRead(0x60)&2==0);
}

Re:A20 and IDT

Posted: Tue Oct 22, 2002 4:33 pm
by grey wolf

Re:A20 and IDT

Posted: Tue Oct 22, 2002 5:35 pm
by Curufir
Here's what I use, got bored of typing it for every interrupt so I just made a macro. They're all the same type, but right now I'm not too concerned.

Code: Select all

IDT_Start:

%macro IDT_Entry 1
    DW ISR_%1           ;Bits 0-15 of entry point offset
    DW Kernel_Code_Sel ;Valid code selector
    DB 0x00
    DB 0x8E             ;32-bit Ring 0 interrupt gate
    DW 0x0000           ;Bits 31->16 of entry point offset
%endmacro

%assign i 0 
%rep    256
    IDT_Entry i
%assign i i+1 
%endrep

IDT_End:

IDTR:
    DW IDT_End-IDT_Start-1
    DD IDT_Start
That gives you a full 256 entry IDT, it's up to you to define the ISR_0 -> ISR_255 labels.

Load using:

Code: Select all

    LIDT [IDTR]       ;Load the IDT register
Hope that helps.

Curufir

Re:A20 and IDT

Posted: Tue Oct 22, 2002 5:54 pm
by Tom
Ty for the IDT Curufir, I'll try it.
I have a a20 code that I think loads the a20.
I need to test to see if the a20 is loaded.
Greywolf - the link you gave me had a a20 test, but it did't work.

As for the space for my kernel bug, I found the prob.

My kernel got to over 5 sectors big. My bootsector only loaded 5 sectors - so I changed that to 10 and it worked.

Thank you,

Re:A20 and IDT

Posted: Tue Oct 22, 2002 6:07 pm
by Curufir
Don't thank me until it works ;D

If you're gonna use that then this might come in handy:

Code: Select all

<Some real ISR routines>
.
.
.
.
%macro ISR_ 1
???ISR_%1:
%endmacro

%assign i 0
%rep    255
???ISR_ i
%assign i i+1 
%endrep

    IRET
Alter the start value of i to wherever your last interrupt is. This should save you time typing in labels yourself, and let you keep the IDT a constant size. You can always trim it off to taste later.

**

This isn't mine, it's part of Tran's A20 enabling routine.

Code: Select all

Enable_A20_Test:              ;test for enabled A20
      XOR AX, AX              ;set A20 test segments 0 and 0ffffh
      MOV FS, AX              ;fs=0000h
      DEC AX
      MOV GS, AX              ;gs=0ffffh
      MOV AL, BYTE [FS:0x00]] ;get byte from 0:0
      MOV AH, AL              ;preserve old byte
      NOT AL                  ;modify byte
      XCHG AL, BYTE [GS:0x10] ;put modified byte to 0ffffh:10h
                              ;which is either 0h or 100000h depending on the a20 state
      CMP AH, BYTE [FS:0x00]  ;set zero if byte at 0:0 equals preserved value
      MOV [GS:0x10], AL       ;put back old byte at 0ffffh:10h
      RET                     ;return, zeroflag is set if A20 is enabled
Curufir

Re:A20 and IDT

Posted: Tue Oct 22, 2002 6:24 pm
by Tom
How can I check what's in the ZF register?

Re:A20 and IDT

Posted: Tue Oct 22, 2002 6:34 pm
by Tom
Hello, I need a IDT that's all defined, your code didn't compile - I don't know a thing about IDT's.

Thank you,

Re:A20 and IDT

Posted: Tue Oct 22, 2002 6:44 pm
by Tom
Curufir ...
where is Kernel_code_sel defined?

Re:A20 and IDT

Posted: Tue Oct 22, 2002 6:46 pm
by Curufir
Sorry, kinda made an assumption you were working in NASM there (I don't work in anything else atm, so I don't know how you would head into this from C or something else). Simplest way to test the zero flag would be to call that routine, then directly after the call do a JZ to whatever part of your code deals with the a20 having been set correctly.

Eg Tran does this:

Code: Select all

CALL Enable_A20_Test    ;is A20 enabled?
JZ SHORT Enable_A20_Done;if yes (zf is set), done
I suppose if you wanted to test it manually you could push the eflags register, then pop and test the zero flag bit, but that seems a weird way of doing things. At least I think you could.

**

Just caught that last message. Kernel_Code_Sel is a VALID descriptor in the GDT. For me that's a single 4gb ring 0 segment, but all it has to be is a valid descriptor that contains your interrupt code.

Curufir

Re:A20 and IDT

Posted: Tue Oct 22, 2002 7:46 pm
by Tom
oh so CODESEL is my kernel _sel thing
and I am in NASM - I'll try it again...

Re:A20 and IDT

Posted: Wed Oct 23, 2002 6:46 am
by Whatever5k
Tom, I suggest you better *learn* something about IDT, interrupts and so on. It makes absolutely no sense if you just copy/paste from other's sources without knowing what it means...

Re:A20 and IDT

Posted: Wed Oct 23, 2002 6:48 am
by Tom
I will do that, for some reason, I need to see working code, compare that to the info/tutorial, and that's how I learn.

Re:A20 and IDT

Posted: Thu Oct 24, 2002 11:29 am
by Tom
can I load the IDT while in PMode?
also, I get a error saying that "ISR_255 not defined"

Hey, i'm 5 stars :o :o :o.

Re:A20 and IDT

Posted: Thu Oct 24, 2002 2:15 pm
by Ozguxxx
I do not know if you have solved your problem but I think there is a A20 enabling BIOS int. So before gonig into pmode you can call it to enable A20 line. I did not use it, (in fact I tried but for some reason it did not work :)) You can find info on interrupt from:
http://www.ctyme.com/intr/int-15.htm
Also: Is this way a comvenient way to turn on a20? I mean is it alright if we enable it via bios int and then jump to pmode?