Accessing memory at 0xb800

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • lupher cypher

    Accessing memory at 0xb800

    Hi,

    I'm trying to access memory directly at 0xb800 (text screen). I tried this:

    char far* screen = (char far*)0xb8000000 ;

    but apparently c++ compiler doesn't know "far" (says "syntax error
    before *"). I've tried using __far, _far, FAR, _FAR, and __FAR, all with
    the same result. So, then I tried this:

    char* screen = (char*)0xb8000;

    This compiles fine, but when I try to access it with screen[0]='a', it
    gives me segmentation fault. Anyone knows what's wrong with it?
    I'm using c++ v3.2.2 that came with my linux box.

    Thanks
    luph

  • Rob Williscroft

    #2
    Re: Accessing memory at 0xb800

    lupher cypher wrote in news:wwrGb.217$ lt.121@nwrdny02 .gnilink.net:
    [color=blue]
    > Hi,
    >
    > I'm trying to access memory directly at 0xb800 (text screen). I tried
    > this:[/color]

    Don't do this use a library that comes with your system to write to
    the screen.
    [color=blue]
    >
    > char far* screen = (char far*)0xb8000000 ;[/color]

    Well if you were running ms-dos and had a sutible compiler then this
    would work.
    [color=blue]
    >
    > but apparently c++ compiler doesn't know "far" (says "syntax error
    > before *"). I've tried using __far, _far, FAR, _FAR, and __FAR, all
    > with the same result. So, then I tried this:
    >
    > char* screen = (char*)0xb8000;
    >
    > This compiles fine, but when I try to access it with screen[0]='a', it
    > gives me segmentation fault. Anyone knows what's wrong with it?
    > I'm using c++ v3.2.2 that came with my linux box.
    >[/color]

    The real question is, Why are you trying to do this ? If it some code
    you found in a text book, the book is 1) very old and 2) not applicable
    to your OS (linux).

    here is a man page for curses which might help:



    For better advice ask in a newsgroup that supports your platform
    and/or your compiler, there is alas no standard way of writing
    directly to the screen.

    HTH.

    Rob.
    --

    Comment

    • Jeff Schwab

      #3
      Re: Accessing memory at 0xb800

      lupher cypher wrote:[color=blue]
      > Hi,
      >
      > I'm trying to access memory directly at 0xb800 (text screen). I tried this:
      >
      > char far* screen = (char far*)0xb8000000 ;
      >
      > but apparently c++ compiler doesn't know "far" (says "syntax error
      > before *"). I've tried using __far, _far, FAR, _FAR, and __FAR, all with
      > the same result. So, then I tried this:[/color]

      "Far" is a kludge to get around pointers that aren't big enough; I've
      only needed it on 8-bit microcontroller s and 16-bit x86 chips. If your
      system is running linux, you should never need to use "far" again.
      [color=blue]
      > char* screen = (char*)0xb8000;[/color]

      I'm pretty sure that's not the address you mean.
      [color=blue]
      > This compiles fine, but when I try to access it with screen[0]='a', it
      > gives me segmentation fault. Anyone knows what's wrong with it?
      > I'm using c++ v3.2.2 that came with my linux box.[/color]

      It sounds like that's not an address you own. Where did you come up
      with that pointer value? Also, why do you sometimes write 0xb8000000,
      sometimes 0xb800, and other times 0xb8000? Your pointers are probably
      thirty-two bits wide; are you assuming that the literal value is being
      zero-extended on one side?

      -Jeff
      [color=blue]
      >
      > Thanks
      > luph
      >[/color]

      Comment

      • r norman

        #4
        Re: Accessing memory at 0xb800

        On Wed, 24 Dec 2003 21:37:08 -0500, Jeff Schwab <jeffplus@comca st.net>
        wrote:
        [color=blue]
        >lupher cypher wrote:[color=green]
        >> Hi,
        >>
        >> I'm trying to access memory directly at 0xb800 (text screen). I tried this:
        >>
        >> char far* screen = (char far*)0xb8000000 ;
        >>
        >> but apparently c++ compiler doesn't know "far" (says "syntax error
        >> before *"). I've tried using __far, _far, FAR, _FAR, and __FAR, all with
        >> the same result. So, then I tried this:[/color]
        >
        >"Far" is a kludge to get around pointers that aren't big enough; I've
        >only needed it on 8-bit microcontroller s and 16-bit x86 chips. If your
        >system is running linux, you should never need to use "far" again.
        >[color=green]
        >> char* screen = (char*)0xb8000;[/color]
        >
        >I'm pretty sure that's not the address you mean.
        >[color=green]
        >> This compiles fine, but when I try to access it with screen[0]='a', it
        >> gives me segmentation fault. Anyone knows what's wrong with it?
        >> I'm using c++ v3.2.2 that came with my linux box.[/color]
        >
        >It sounds like that's not an address you own. Where did you come up
        >with that pointer value? Also, why do you sometimes write 0xb8000000,
        >sometimes 0xb800, and other times 0xb8000? Your pointers are probably
        >thirty-two bits wide; are you assuming that the literal value is being
        >zero-extended on one side?
        >[/color]

        Even assuming that the display is memory mapped the way that old DOS
        systems were, and even assuming the screen is actually in text mode
        you still have serious problems.

        Protected operating systems (using CPU chips that support it) control
        just who gets to read and write which memory. You don't "own" the
        memory that is not allocated to your process so you can't read or
        write it.

        Some operating systems might notice that you are trying to read or
        write that location and guess that you might be trying to access the
        screen and do what is necessary to make things work. But that is only
        true for systems that must support old DOS programs. We are not in
        DOS-land anymore, though.

        Comment

        • Guy Harrison

          #5
          Re: Accessing memory at 0xb800

          lupher cypher wrote:
          [color=blue]
          > Hi,
          >
          > I'm trying to access memory directly at 0xb800 (text screen). I tried
          > this:
          >
          > char far* screen = (char far*)0xb8000000 ;
          >
          > but apparently c++ compiler doesn't know "far" (says "syntax error
          > before *"). I've tried using __far, _far, FAR, _FAR, and __FAR, all with
          > the same result. So, then I tried this:[/color]

          Run off. Anything to do with "far,huge,small " in conjunction with pointers
          is going to be old code and useless to you.
          [color=blue]
          > char* screen = (char*)0xb8000;
          >
          > This compiles fine, but when I try to access it with screen[0]='a', it
          > gives me segmentation fault. Anyone knows what's wrong with it?[/color]

          Machines without hardware protection (or with it turned off) let a program
          access anything anywhere, whether it exists or not. Consider your program
          doing its thing then another came along and did the same. Something's gotta
          give. Such code falls under the realm of "device drivers" - one thing (or a
          chain of them) has responsibility for talking to your hardware. Those will
          provide "standard" (for your system) interfaces (probably at varying
          levels) through which you can talk to them.
          [color=blue]
          > I'm using c++ v3.2.2 that came with my linux box.[/color]

          "man curses/ncurses" for text. For graphics, well there's lots. SDL you can
          draw on (games) and things like wxwindows for apps that want gui's. All
          these are offtopic here though because they're language add-ons. The ones
          I've mentioned are available for windows as well.


          --
          Guy Harrison

          Comment

          • Martijn Lievaart

            #6
            Re: Accessing memory at 0xb800

            On Thu, 25 Dec 2003 01:59:56 +0000, lupher cypher wrote:
            [color=blue]
            > I'm trying to access memory directly at 0xb800 (text screen). I tried this:
            >
            > char far* screen = (char far*)0xb8000000 ;
            >
            > but apparently c++ compiler doesn't know "far" (says "syntax error
            > before *"). I've tried using __far, _far, FAR, _FAR, and __FAR, all with
            > the same result. So, then I tried this:
            >
            > char* screen = (char*)0xb8000;
            >
            > This compiles fine, but when I try to access it with screen[0]='a', it
            > gives me segmentation fault. Anyone knows what's wrong with it?
            > I'm using c++ v3.2.2 that came with my linux box.[/color]

            This worked under DOS, but does not work under any modern OS. The reason
            is that modern CPUs (well modern for microchips, all other CPUs already
            had this) have memory management. That means that the view your program
            has of the memory has nothing to do with the real layout of the memory.

            The big advantages of this are:

            - Your program is isolated from other processes, one ill behaving program
            cannot take down the whole OS or other programs.

            - Your OS can fake more memory than there really is, it uses harddisk
            storage for this (swapfile or swappartition)

            - Programs are not allowed to access hardware directly, they must use the
            OS to access the hardware. This makes it possible for multiple programs to
            use the same hardware.

            The disadvantage is that you cannot access hardware directly (hey, that
            was also an advantage!), you must write a devicedriver to do that.
            Luckily, more often than not, others have already done that. And often
            complete libraries are written to make using this easier. As you use
            Linux, have a look at the ncurses library.

            BTW, ncurses is off topic for this group, if you have any questions about
            that, please ask in a linux/posix group.

            HTH,
            M4

            Comment

            • lupher cypher

              #7
              Re: Accessing memory at 0xb800

              >>[color=blue][color=green]
              >>I'm trying to access memory directly at 0xb800 (text screen). I tried
              >>this:[/color]
              >
              >[color=green]
              >>but apparently c++ compiler doesn't know "far" (says "syntax error
              >>before *"). I've tried using __far, _far, FAR, _FAR, and __FAR, all
              >>with the same result. So, then I tried this:
              >>
              >>char* screen = (char*)0xb8000;
              >>
              >>This compiles fine, but when I try to access it with screen[0]='a', it
              >>gives me segmentation fault. Anyone knows what's wrong with it?
              >>I'm using c++ v3.2.2 that came with my linux box.
              >>[/color]
              > The real question is, Why are you trying to do this ? If it some code
              > you found in a text book, the book is 1) very old and 2) not applicable
              > to your OS (linux).[/color]

              Well, it's not from a book, and I need to redraw text screen without
              "scrolling" it each time (outputting all 25 lines to redraw). So, I
              figured it's easier to simply draw on the screen directly into memory. I
              also need to save the whole screen into a buffer and then flush it back out.
              [color=blue]
              >
              > here is a man page for curses which might help:
              >
              > http://docsrv.caldera.com:507/en/man.../curses.S.html[/color]

              I've tried this, but although it is something like I need, it gives me
              errors (e.g. when I use mvaddch, it would say that waddch and a couple
              of other functions are undefined).
              [color=blue]
              >
              > For better advice ask in a newsgroup that supports your platform
              > and/or your compiler, there is alas no standard way of writing
              > directly to the screen.[/color]

              Hmm.. How about through hardware interrupt 10? :) Unless linux has some
              protection against that, but I wouldn't think so..

              luph

              Comment

              • lupher cypher

                #8
                Re: Accessing memory at 0xb800

                Jeff Schwab wrote:[color=blue]
                >[color=green]
                >> char* screen = (char*)0xb8000;[/color]
                >
                > I'm pretty sure that's not the address you mean.[/color]

                Well, the text video memory resides at b800:0000, so 0xb8000 would be
                the absolute address in memory..
                [color=blue][color=green]
                >> This compiles fine, but when I try to access it with screen[0]='a', it
                >> gives me segmentation fault. Anyone knows what's wrong with it?
                >> I'm using c++ v3.2.2 that came with my linux box.[/color]
                >
                >
                > It sounds like that's not an address you own. Where did you come up
                > with that pointer value? Also, why do you sometimes write 0xb8000000,
                > sometimes 0xb800, and other times 0xb8000? Your pointers are probably
                > thirty-two bits wide; are you assuming that the literal value is being
                > zero-extended on one side?[/color]

                Well, I don't know that much about linux, but it should be pretty much
                the same as in windows in this case - we can open several terminals when
                we run gui, so I assume every terminal process gets it's own chunk of
                memory and when I try to access segment b800, it simply works it out.
                But that should be owned by me anyhow then.. As for writing it in
                different ways - I was looking online to find a way to write there, and
                there were several different codes, so I tried them all :)
                I was a bit confused by 0xb8000000 myself, because that's not the way it
                should be, but then I though maybe it's something about a particular
                compiler. For all I know to get the absolute address from a relative
                one, we shift segment left 4 bits and then add offset.
                By the way, I saw code for linux somewhere where someone was trying to
                access a000:0000 (apparently successfully from what I understood), which
                is graphic video memory :)

                luph

                Comment

                • lupher cypher

                  #9
                  Re: Accessing memory at 0xb800

                  [color=blue]
                  > Even assuming that the display is memory mapped the way that old DOS
                  > systems were, and even assuming the screen is actually in text mode
                  > you still have serious problems.[/color]

                  Why shouldn't it be? I thought that's a standard. I recall taking a
                  class on OS and hardware, and I think it's the video card who simply
                  compies the whole screen from there to the screen using DMA.. Not
                  complitely sure about it, but I think that's what we were talking about,
                  so that CPU doesn't get involved and waste time for the whole thing.
                  [color=blue]
                  > Protected operating systems (using CPU chips that support it) control
                  > just who gets to read and write which memory. You don't "own" the
                  > memory that is not allocated to your process so you can't read or
                  > write it.[/color]

                  Ok, but how would a library like curses read and write from/to the
                  screen? There should be a way.. I was thinking maybe I should try doing
                  it through int 10h.. Although first I'll have to figure out how to
                  insert asm code into c++ programs :)


                  luph

                  Comment

                  • Jeff Schwab

                    #10
                    Re: Accessing memory at 0xb800

                    lupher cypher wrote:
                    [color=blue]
                    > I've tried this, but although it is something like I need, it gives me
                    > errors (e.g. when I use mvaddch, it would say that waddch and a couple
                    > of other functions are undefined).[/color]

                    Lupher, it's going to be a lot easier to fix those errors than to
                    rewrite the library.
                    [color=blue]
                    >[color=green]
                    >>
                    >> For better advice ask in a newsgroup that supports your platform
                    >> and/or your compiler, there is alas no standard way of writing
                    >> directly to the screen.[/color]
                    >
                    >
                    > Hmm.. How about through hardware interrupt 10? :) Unless linux has some
                    > protection against that, but I wouldn't think so..[/color]

                    What is "hardware interrupt 10?"
                    [color=blue]
                    >
                    > luph
                    >[/color]

                    Comment

                    • Jeff Schwab

                      #11
                      Re: Accessing memory at 0xb800

                      lupher cypher wrote:[color=blue]
                      >[color=green]
                      >> Even assuming that the display is memory mapped the way that old DOS
                      >> systems were, and even assuming the screen is actually in text mode
                      >> you still have serious problems.[/color]
                      >
                      >
                      > Why shouldn't it be? I thought that's a standard. I recall taking a
                      > class on OS and hardware, and I think it's the video card who simply
                      > compies the whole screen from there to the screen using DMA.. Not
                      > complitely sure about it, but I think that's what we were talking about,
                      > so that CPU doesn't get involved and waste time for the whole thing.[/color]

                      So, you think your code is running on the video card? Far-out system,
                      man. My code runs on my lamp.
                      [color=blue][color=green]
                      >> Protected operating systems (using CPU chips that support it) control
                      >> just who gets to read and write which memory. You don't "own" the
                      >> memory that is not allocated to your process so you can't read or
                      >> write it.[/color]
                      >
                      >
                      > Ok, but how would a library like curses read and write from/to the
                      > screen? There should be a way..[/color]

                      No, there shouldn't; at least, not without such I/O being gated by the
                      kernel.
                      [color=blue]
                      > I was thinking maybe I should try doing
                      > it through int 10h.. Although first I'll have to figure out how to
                      > insert asm code into c++ programs :)[/color]

                      I think I've figured out what you meant by "hardware interrupt 10,"
                      thanks to this site (thank you Google):



                      FYI, "10h" isn't a standard hardware interrupt, it's a BIOS interrupt.
                      Unless you're hacking your kernel, kiss your BIOS interrupts goodbye,
                      and good riddance. The equivalent in Linux is a request to the kernel,
                      known as a "system call," which manifests itself as a call to a C function.

                      Most processors won't let you write to addresses you don't own because
                      your code is not "privileged ," meaning the chip is not in a sufficiently
                      "privileged mode." The kernel is privileged because it was loaded
                      specially when your system was started. If you want your code to run in
                      a privileged mode, you basically have to write your own kernel (or hack
                      the existing one). You are more than welcome to try these options. Try
                      Googling for "boot loader."

                      Anyway, it sounds like you are very familiar with a particular
                      programming environment. Unfortunately, that particular environment is
                      generally deemed "crappy." Since you are running Linux now, you have
                      access to a truck-load more functionality than you probably realize.

                      So, here's my advice:

                      1) Forget basically every low-level detail you've learned about your
                      system. You don't need to know any of that anymore.

                      2) Learn to write programs that rely only on standard C++, or whatever
                      subset is offered by the best compiler available to you. It's okay to
                      cheat a little by using bash scripts to call your programs in particular
                      ways, e.g. in a graphical terminal emulator.

                      3) When you want to do something not provided by the C++ standard
                      library, find an existing library to do it for you. If you have trouble
                      compiling it (as you did with Curses), track down the problems in the
                      code and fix them yourself. Notify the maintainer of the library of
                      what you did and why.

                      4) When you need some functionality not found in any existing library
                      for your system, and you can't adapt a library from a different system
                      to meet your needs, try writing a new library yourself. Put it under an
                      open-source license like GPL, and make it available to others. Post an
                      announcement about it in one of the "comp.your.syst em.announce" news groups.

                      5) When you're really stuck trying to make your system do what you want,
                      post questions to a news group that has specific expertise about your
                      platform, e.g. the comp.os.linux family.

                      6) When you want to discuss the C++ language, post here.
                      [color=blue]
                      >
                      >
                      > luph
                      >[/color]

                      Good luck,
                      Jeff

                      Comment

                      • Roger Leigh

                        #12
                        Re: Accessing memory at 0xb800

                        lupher cypher <lupher.cypher@ verizon.net> writes:
                        [color=blue][color=green]
                        >> Even assuming that the display is memory mapped the way that old DOS
                        >> systems were, and even assuming the screen is actually in text mode
                        >> you still have serious problems.[/color]
                        >
                        > Why shouldn't it be? I thought that's a standard. I recall taking a
                        > class on OS and hardware, and I think it's the video card who simply
                        > compies the whole screen from there to the screen using DMA.. Not
                        > complitely sure about it, but I think that's what we were talking
                        > about, so that CPU doesn't get involved and waste time for the whole
                        > thing.[/color]

                        No. It's only needed on operating systems that don't provide proper
                        device drivers to do this for you.
                        [color=blue][color=green]
                        >> Protected operating systems (using CPU chips that support it) control
                        >> just who gets to read and write which memory. You don't "own" the
                        >> memory that is not allocated to your process so you can't read or
                        >> write it.[/color]
                        >
                        > Ok, but how would a library like curses read and write from/to the
                        > screen? There should be a way.. I was thinking maybe I should try
                        > doing it through int 10h[/color]

                        The way it's done on Linux (and most UNIX systems) is through device
                        drivers. Have a look under /dev at:
                        /dev/tty?? and /dev/vc/* (both are virtual terminals)
                        /dev/console (system console)
                        /dev/pts/* (pseudo or virtual terminals, used by xterm, screen,
                        ssh etc.)
                        These are all various terminal device drivers. Try this:

                        $ tty
                        /dev/pts/0
                        $ echo 'hello' > /dev/pts/0
                        hello

                        This "device node" is your "gateway" to the hardware. In this case,
                        you are sending it plain text, but terminal devices also support ANSI
                        escape sequences for colour, underlining, and other features through
                        ioctls. This is what ncurses is using to do its stuff with. Try
                        again with some of the others.

                        When you run a C++ program, this is where everything you send to
                        std::cout and std::cerr actually ends up. You can also open them in
                        your program (providing you have the appropriate permissions).

                        Notice how we get hardware access in our program without any need for
                        assembler or direct access with pointers! This is a good thing--it
                        allows resource sharing, ease of writing portable code, simpler code,
                        no hardware knowledge required.
                        [color=blue]
                        > .. Although first I'll have to figure out how
                        > to insert asm code into c++ programs :)[/color]

                        Ugh. Just use "plain" C++ as well as the appropriate system library
                        ([n]curses)!


                        HTH,
                        Roger

                        --
                        Roger Leigh

                        Printing on GNU/Linux? http://gimp-print.sourceforge.net/
                        GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.

                        Comment

                        • Nils O. Selåsdal

                          #13
                          Re: Accessing memory at 0xb800

                          In article <tuJGb.1294$lt. 915@nwrdny02.gn ilink.net>, lupher cypher wrote:[color=blue]
                          >[color=green]
                          >> Even assuming that the display is memory mapped the way that old DOS
                          >> systems were, and even assuming the screen is actually in text mode
                          >> you still have serious problems.[/color]
                          >
                          > Why shouldn't it be? I thought that's a standard. I recall taking a
                          > class on OS and hardware, and I think it's the video card who simply
                          > compies the whole screen from there to the screen using DMA.. Not
                          > complitely sure about it, but I think that's what we were talking about,
                          > so that CPU doesn't get involved and waste time for the whole thing.
                          >[color=green]
                          >> Protected operating systems (using CPU chips that support it) control
                          >> just who gets to read and write which memory. You don't "own" the
                          >> memory that is not allocated to your process so you can't read or
                          >> write it.[/color]
                          >
                          > Ok, but how would a library like curses read and write from/to the
                          > screen? There should be a way.. I was thinking maybe I should try doing
                          > it through int 10h.. Although first I'll have to figure out how to
                          > insert asm code into c++ programs :)[/color]
                          It uses well defined APIs/system calls. These eventually end up in the
                          kernel, and the appropriate device driver. You cannot get around this,
                          atleast not without writing kernel code. You can ofcourse
                          use the very low level system calls to do it though. But
                          why ? Why won't you use e.g. curses ?

                          --
                          Nils Olav Selåsdal <NOS@Utel.no>
                          System Developer, UtelSystems a/s
                          w w w . u t e l s y s t e m s . c o m

                          Comment

                          • Niklas Borson

                            #14
                            Re: Accessing memory at 0xb800

                            lupher cypher <lupher.cypher@ verizon.net> wrote in message news:<9pJGb.218 6$tY5.586@nwrdn y01.gnilink.net >...[color=blue]
                            > Jeff Schwab wrote:[color=green]
                            > >[color=darkred]
                            > >> char* screen = (char*)0xb8000;[/color]
                            > >
                            > > I'm pretty sure that's not the address you mean.[/color]
                            >
                            > Well, the text video memory resides at b800:0000, so 0xb8000 would be
                            > the absolute address in memory..
                            >[color=green][color=darkred]
                            > >> This compiles fine, but when I try to access it with screen[0]='a', it
                            > >> gives me segmentation fault. Anyone knows what's wrong with it?
                            > >> I'm using c++ v3.2.2 that came with my linux box.[/color]
                            > >
                            > >
                            > > It sounds like that's not an address you own. Where did you come up
                            > > with that pointer value? Also, why do you sometimes write 0xb8000000,
                            > > sometimes 0xb800, and other times 0xb8000? Your pointers are probably
                            > > thirty-two bits wide; are you assuming that the literal value is being
                            > > zero-extended on one side?[/color]
                            >
                            > Well, I don't know that much about linux, but it should be pretty much
                            > the same as in windows in this case - we can open several terminals when
                            > we run gui, so I assume every terminal process gets it's own chunk of
                            > memory and when I try to access segment b800, it simply works it out.[/color]

                            What you say is true only if your program is an MS-DOS program, and even
                            then it works not because your program is writing to the real hardware
                            video buffer, but rather a simulated one -- part of a "virtual MS-DOS
                            machine" created by the operating system.

                            The x86 family of processors support a number of different memory
                            addressing modes. The mode used in MS-DOS (and the only mode supported
                            by the 8088 chip used in the original IBM PC) is called real mode. In
                            this mode, the processor translates a segment:offset address to a 20-bit
                            physical address by shifting the segment address left 4 bits and adding
                            the offset. Thus, b800:0000 maps to 0xb8000, which happened to be the
                            address of the memory-mapped video buffer in text mode.

                            However, an MS-DOS program running under Windows executes in a different
                            mode called virtual 8086 mode. Under this mode, a segment:offset address
                            is first translated to a 20-bit address as described above. However, this
                            address is not a physical address, but a so-called linear address. The
                            CPU then references a set of lookup-tables (called page tables) to convert
                            the linear address to a physical address. This level of indirection
                            enables the operation system (which maintains the page tables) to create
                            a separate 1MB address space for each MS-DOS application.

                            Of course, MS-DOS applications expect to have direct access to hardware
                            and expect certain addresses to be "special" -- e.g., the video buffer,
                            the interrupt table, etc. The operating system simulates this by trapping
                            certain kinds of memory access. Thus, while your MS-DOS application THINKS
                            it is writing directly to the video buffer, it's actually just writing to
                            ordinary memory. The operating system detects this and updates the display
                            accordingly.

                            This magic exists solely to preserve compatibility with ancient MS-DOS
                            applications. There's no reason to believe that that the same thing would
                            work for other types of applications or under other operating systems.
                            For example, if you tried to write to linear address 0xb8000 in a Win32
                            application, there's no reason to suppose anything useful would happen.
                            Modern operating systems provide higher-level, hardware-independent
                            methods of accessing resources such as the console.

                            Comment

                            Working...