[comp.sys.ibm.pc] 4 gigs in Real Mode

shurr@cbnews.ATT.COM (Larry A. Shurr) (02/01/90)

In article <7713@pt.cs.cmu.edu> ralf@b.gp.cs.cmu.edu (Ralf Brown) writes:
}In article <Jan.25.16.16.09.1990.13042@occlusal.rutgers.edu> koenig@occlusal.rutgers.edu (Evan M. Koenig) writes:
}}After playing with 386 protected mode, I finally got real mode to
}}work with a 4 gig linear address space. 

}}If you wan't the source code, I can email it.
            ^
            |
 Look out!  The apostrophe man's gonna get you! :-)

}Count me in!

All seriousness aside... I, too am interested in the code.  This may be
worth posting.  In any case, I would like to have it.  Please e-mail or
post.

regards, Larry
-- 
Signed: Larry A. Shurr (cbema!las@att.ATT.COM or att!cbema!las)
Clever signature, Wonderful wit, Outdo the others, Be a big hit! - Burma Shave
(With apologies to the real thing.  The above represents my views only.)
(You may now R'eply.  Forwarding from cbnews to my mail address now works!!!)

harlow@plains.UUCP (Jay B. Harlow) (02/02/90)

In article <40970040@hpindda.HP.COM> kmont@hpindda.HP.COM (Kevin Montgomery)
writes:
>> This is because your computer most probably does not decode address line
>> A20 (at least in real mode). If you want to access the addresses beyond
>> 1M you got to turn A20 ON implicitly. 
>
>Ahhhhhg!  I must be real confused- of what purpose is ignoring A20? 
  Certain Companies when they released thier NEW 286 Intel machine, for
a follow up to thier popular PC machine, decided they NEEDED to 
mimick it in EVERY aspect. Including the 1M limit wrap around
( i.e. address FFFF:0010 wraps to 0000:0000 ) at least being 'smart' and 
realizing that even 1M chunks (2nd M, 4th M, 6th M.... ) would be nice to
use in any upcoming PROTECTED mode systems they set up a special port
to toggle how the hardware sees A20, ( interesting enough the 486 has
direct support for this 'feature' )  Of course this same company chose
to ignore Intel warning about using INT 0 - INT 1F, any one try using
the BOUND inst on a AT ;-).

> What boxes do this?  
Nearly all of them, Must follow the leader ;-). who cares if it
is brain-dead..... ( from a reliable system point of view )
>


Of course ALL the clone makers, have to follow the leader to 
maintain compatibility ( or do they...... ;-)

			Jay

-- 
		Jay B. Harlow	<harlow@plains.nodak.edu>
	uunet!plains!harlow (UUCP)	harlow@plains (Bitnet)

Of course the above is personal opinion, And has no bearing on reality...

Ralf.Brown@B.GP.CS.CMU.EDU (02/02/90)

In article <3288@plains.UUCP>, harlow@plains.UUCP (Jay B. Harlow) wrote:
}In article <40970040@hpindda.HP.COM> kmont@hpindda.HP.COM (Kevin Montgomery)
}writes:
}>> This is because your computer most probably does not decode address line
}>> A20 (at least in real mode). If you want to access the addresses beyond
}>> 1M you got to turn A20 ON implicitly. 
}>
}  Certain Companies when they released thier NEW 286 Intel machine, for
}a follow up to thier popular PC machine, decided they NEEDED to 
}mimick it in EVERY aspect. Including the 1M limit wrap around
}( i.e. address FFFF:0010 wraps to 0000:0000 ) at least being 'smart' and 

Probably because a Certain OS Company actually *used* the 1M wraparound....
(the CP/M-compatible "CALL 5" entry point jumps to 000C0h, but is
constrained on HOW it jumps there by the need for PSP:0006h to be the
size of the first segment. That's how CP/M programs determined how much
space they had, since the jump instruction at location 5 on a CP/M
machine goes to the lowest byte of the OS, which is the next byte after
the last byte available to the program)

--
UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=- 412-268-3053 (school) -=- FAX: ask
ARPA: ralf@cs.cmu.edu  BIT: ralf%cs.cmu.edu@CMUCCVMA  FIDO: Ralf Brown 1:129/46
"How to Prove It" by Dana Angluin              Disclaimer? I claimed something?
14. proof by importance:
    A large body of useful consequences all follow from the proposition in
    question.

feustel@well.UUCP (David Alan Feustel) (02/03/90)

Your problem is almost certainly that address line A20 is gated off.
A bios call is available to turn it on.
-- 
Phone:	219-482-9631	FAX: by arrangement
E-mail:	feustel@well.sf.ca.us		
{ucbvax,apple,hplabs,pacbell}!well!feustel	

kemp@umn-cs.cs.umn.edu (Stuart R. Kemp) (02/05/90)

I am posting this on behalf of Evan Koenig. Please direct
all replies to him.


From koenig@occlusal.rutgers.edu Sat Feb  3 13:14:39 1990

Hello to everyone and thanks for your responses. Since so many people
responded to question about the 386, I'm writing this rather generically.
In sum here's what has happened since I've posted my original question.

Addressing 4gigs in real mode works. I've been using it for over a week
now in my C programs. I load multiple images into expanded(extended?) memory
and do some edge detection work in the expanded memory. I am therefore
absolutely sure that my addressing scheme is good.

The problem as I stated was that I couldn't access the 1 to 2 meg range.
After some further investigation, I found I couldn't get to the 3 to 4
range. The problem? Address line A20 is gated off by the keyboard controller
as so many of you have told me.

R. Kirchner@informatik.uni-kl.de says that you have to write

d1h to port 64h
00h to port 60h

He says that there was a program in a german magazine in regards to this.
Can anyone send it to me? I can understand most of the german.

Any Way, here is the assembly code needed to access 4 gigs. Clip the
assembly portion and save to a file called 4gig.asm. Also included
is a small c program written for Turbo C 2.0 that will test the 32 bit
addressing. Save that file to peek32.c

If anyone gets the A20 addressing line problem solved post it to
comp.sys.ibm.pc and send me some mail.

Good Luck to all and enjoy!!

Evan Koenig koenig@occlusal.rutgers.edu


-------------------------Cut here 4gig.asm---------------------------------


; This program will go into protected mode, return but
; leave fs,gs pointing to a 32 bit descriptor.
; This will result in a 4 gigabyte real mode !!!!
; Just play back what's in memory
; 4 GIG .ASM


;*********************************************************
;Program by Neal Margulis -- Use Masm 5.0, OR TASM V1.0
;     This program was taken the article
;     80386 Protected Mode Initialization
;      Dr. Dobb's Journal, October 1988
;Note: Basically I deleted all the code that dumps some
;      test patterns to the screen in protected mode and
;      real mode. After returning from protected mode
;      CS,DS,ES point to a real mode descriptor (64k segments)
;      But, GS,FS are left pointing to the 4gig segment.
;
;      #### DONT EVER PLAY WITH GS OR FS, LEAVE THEM ALONE ####
;      #### IF YOU MESS WITH THEM, YOU WILL LOSE ACCESS TO ####
;      #### THE 4 GIG RANGE. IF YOU WANT TO LEARN MORE     ####
;      #### ABOUT THE DESCRIPTORS, I SUGGEST YOU PICK UP A ####
;      #### FEW BOOKS ON THE 80386!!! NO ONE PARTICULAR    ####
;      #### BOOK IS GOOD BY ITSELF. I SUGGEST YOU TRY TO   ####
;      #### FIGURE AS MUCH AS YOU CAN FROM THIS CODE AND   ####
;      #### THEN BUY A BOOK.                               ####
;
;      THIS PROGRAM SHOULD BE RUN FIRST. I SUGGEST YOU PUT
;      IT IN THE AUTOEXECFILE. AFTER THIS PROGRAM RUNS, YOUR
;      ASSEMBLY OR C PROGRAM CAN ACCESS ALL 4GIGS
;
;      -EVAN KOENIG koenig@occlusal.rutgers.edu
;
;*********************************************************

.386p

descriptor STRUC
           limt_0_15     dw  0
           base_0_15     dw  0
           base_16_23    db  0
           access        db  0
           gran          db  0
           base_24_31    db  0
descriptor ENDS

code_seg_access  equ 09ah

data_seg_access  equ 092h


CSEG segment word use16 'code'
assume cs:CSEG,ds:CSEG

           mov ax,CSEG
           mov ds,ax         ; PUT Code Segment in DS

           mov ax,seg PMODE  ; Move PMode segment in ax
           and eax,0FFFFh    ; eax 0000 PMODE  Let eax = a040
           shl eax,4h        ; eax a040 0000
           mov ebx,eax       ; ebx a040 0000
           shr eax,16        ;

           mov gdt_PM_1.base_0_15,bx
           mov gdt_PM_2.base_0_15,bx
           mov gdt_PM_1.base_16_23,al
           mov gdt_PM_2.base_16_23,al

           mov ax,seg C3
           and eax,0ffffh
           shl eax,04h
           mov ebx,eax
           shr eax,16
           mov gdt_c3_5.base_0_15,bx
           mov gdt_c3_5.base_16_23,al

           mov ax,cs
           and eax,0ffffh
           shl eax,4h
           add eax,offset gdttbl
           mov dword ptr gdtaddr+2,eax



; NOW LOAD THE DESCRIPTOR TABLE


           lgdt gdtaddr


A20_ON:
           cld
           cli


           ; Enter Protected Mode
           mov eax,cr0
           or eax,1
           mov cr0,eax


           DB 0eah,0h,0h,08h,0h  ; jmp to PMODE use descriptor 1

gdtaddr    label  qword
           dw     48
           dd     ?
           dw     0



; global descriptor table

gdttbl     label  dword
gdt_null   descriptor <,,,,,>                               ; descrip 0
gdt_PM_1   descriptor <0ffffh,,,code_seg_access,0c0h,0>     ; descrip 1
gdt_PM_2   descriptor <0ffffh,,,data_seg_access,08fh,0>     ; descrip 2
gtd_3      descriptor <0ffffh,0,0,data_seg_access,08fh,0>   ; descrip 3
gdt_rm_4   descriptor <0ffffh,0,0,data_seg_access,08fh,0>   ; descrip 4
gdt_c3_5   descriptor <0ffffh,,,code_seg_access,080h,0>     ; descrip 5

CSEG ends

;//////////////////////////////////////////////////////////////////////////

; HERE IS OUR PROTECTED MODE PROGRAM


;/////////////////////////////////////////////////////////////////////////

PMODE segment para public use32 'code'


      assume cs:PMODE

        mov ax,18h            ; SELECTOR 3 (18h/8h = 3) IS A 4 GIG DATA SEGMENT
        mov es,ax             ; WITH BASE AT 0
        MOV fs,ax             ; Let ES and FS point to 4 GiG data segment
        mov gs,ax

        mov ax,10h            ; Set DS to selector 1, but we don't care       mov ds,ax             ;
                              ; It isn't my code


; JUMP BACK TO REAL MODE
; LEAVE GS POINTING TO A 32 BIT DESCRIPTOR
;


; MAKE A SHORT JUMP. CLEARS OUT PREFETCH QUEUE. JUMP BACK TO REAL MODE


     db 0eah ,0h,0h,0h,0h,28h,0h;

align 16

      pdat db 0ach

lastpm label dword
PMODE ends


c3 segment para public use16 'code'
assume cs:c3

       mov ax,20h      ; Selector #4 real mode
       mov es,ax       ; Set all segment registers back to the real
       mov ds,ax       ; mode descriptor
                       ; Notice!!! Leave Gs and FS pointing to the 4 gig
                       ; address space. NEVER NEVER NEVER CHANGE IN REAL
                       ; MODE, ELSE 4 GIGS GO BYE BYE


       mov eax,cr0     ; Clear protection mode bit

       and eax,07ffffffeh
       mov cr0,eax
       jmp far ptr flushr1
flushr1:

; WELCOME BACK TO REAL MODE
; YOU CAN CALL DOS TO PRINT OUT A MESSAGE HERE IF YOU WANT
; DON'T DO IT IN PROTECTED MODE. THE IDT TABLES AREN'T SET UP!

A20_off:
       mov ah,04ch
       mov al,01h
       int 21h
c3     ends
.8086
end

---------------------------Cut here peek32.c--------------------------------




/* 32 Bit peek and poke                                */
/* by Evan Koenig                                      */
/* Assumptions: gs and fs point to a 32 bit descriptor */
/*                                                     */
/* This code was written for Turbo C V2.0. This program*/
/* should be compiled with TCC and TASM. TCC will      */
/* automatically invoke TASM. I guess for other        */
/* compilers it might be similar.                      */



#pragma inline

#include <dos.h>

main()
{
   unsigned int segment,offset,ret,ret2;
   unsigned long address;

   unsigned long ret32,real32;

   printf("Enter a 32 bit address to at. Enter it in hex\n");
   scanf ("%lx",&address);


     asm .386;
     asm push esi;
     asm mov esi,dword ptr address;
     asm mov edx,gs:[esi];
     asm mov dword ptr ret32,edx;
     asm pop esi;
     asm .8086;

     printf("32 bit peek returned %lx\n",ret32);

}

tonyg@batserver.cs.uq.oz.au (Tony Gedge) (02/06/90)

Has anyone ever thought of doing a similar thing with a 286 processor ?
(Dives for cover to avoid the falme onslaught :-)

But seriously, would it be possible, or is the 286 too retarded ?

ant
(Believe it or not, this is not tonyg)
--
 -------------------------------------------------------------------------
| Computer Science Department,        | tonyg@batserver.cs.uq.oz.au       |
| University of Queensland, Australia.| "CC stands for Cryptic Crossword" |
 -------------------------------------------------------------------------

yip@ztivax.UUCP (Dr Yeung-Cho Ip) (02/12/90)

In article <1990Feb5.153408.15670@umn-cs.cs.umn.edu> kemp@umn-cs.cs.umn.edu (Stuart R. Kemp) writes:
>
>If anyone gets the A20 addressing line problem solved post it to
>comp.sys.ibm.pc and send me some mail.
>

Now here is a small program written in TURBO C, which toggels
the state of the A20 bit every time it is called. I can't
test it with Koenigs program, since I don't have a 386 box.
I hope it meets
your needs. If you want to set A20 to a constant value, you
only have to change the line before the last one in main().
(  put_dat((ea^0x02) | 0xD1); /* toggel a20 bit */)
(               ^                                 )
(               |                                 )
( This is the bit value of the a20 bit            )

Hope that helps

Michael Franzen, c/o yip@ztivax.uucp, Siemens AG, Munich

------------------------ cut here ---------------------------
#include <dos.h>

#define COMMAND 0x64
#define STATUS  0x64
#define DATA    0x60

put_com(c)
unsigned char c;
{
  if (inportb(STATUS)&0x1) inportb(DATA); /* Datenport loeschen */
  do ;
  while(inportb(STATUS)&0x3);
  outportb(COMMAND, c);
}

put_dat(d)
unsigned char d;
{
  do ;
  while(inportb(STATUS)&0x2);
  outportb(DATA, d);
}

unsigned char get_dat()
{
  while(!(inportb(STATUS)&0x1));
  return(inportb(DATA));
}

main()
{
unsigned char ea;

  disable();
  put_com(0xD0); /* Read EA Port */
  ea = get_dat();
  put_com(0xD1); /* Write EA Port */
  put_dat((ea^0x02) | 0xD1); /* toggel a20 bit */
  enable();
}