Thread: getting a variable's segment and offset address using gcc(kernel mode programming)

  1. #16
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Even the desire for this speaks to technological understanding 25 years behind the times.
    Which is really odd considering that you go on to recommend earlier modes; even more so as you recommend it without reason seeing as you can get a simple linear buffer with VESA as well.

    These registers don't even exist any more and since the indtroduction of the 386 processor memory is addressed as a continuous block starting at 0.
    They do still exist by virtue of the compatibility requirement.




    Well then where do I find this mythical documentation of yours?
    If it is an operating system development question, "OS-Dev" will probably have an answer.




    Are you writing a real-mode or protected-mode operating system?
    Considering the "segmentffset" thing he brought up, isn't it a safe bet to assume he is working in real mode, at least for now.




    One source is the Microsoft Driver SDK which is freely dowloadable.
    Okay, how in the world is the "Microsoft Driver Development Kit" going to help anyone developing their own operating system? Did you even read his request?

    Soma

  2. #17
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    Quote Originally Posted by phantomotap View Post
    Is this an allocated black of memory, something setting on the stack, a static global, or something else?

    You aren't going to get any answers if you don't give more information.



    O_o

    Swing and a miss.

    Soma
    my kernel switches from protected mode to real mode every time that I need to the video BIOS.

  3. #18
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    Quote Originally Posted by brewbuck View Post
    Bah, don't listen to those guys.

    Are you writing a real-mode or protected-mode operating system?
    My operating system uses real-mode for BIOS interrupts and protected-mode for everything else.

  4. #19
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    my kernel switches from protected mode to real mode every time that I need to the video BIOS
    Yikes.

    I strongly suggest you look around for "VBE" and the protected mode stuff to get a linear buffer you can play with without that hassle.

    Soma

  5. #20
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    Quote Originally Posted by phantomotap View Post
    Which is really odd considering that you go on to recommend earlier modes; even more so as you recommend it without reason seeing as you can get a simple linear buffer with VESA as well.



    They do still exist by virtue of the compatibility requirement.






    If it is an operating system development question, "OS-Dev" will probably have an answer.






    Considering the "segmentffset" thing he brought up, isn't it a safe bet to assume he is working in real mode, at least for now.






    Okay, how in the world is the "Microsoft Driver Development Kit" going to help anyone developing their own operating system? Did you even read his request?

    Soma
    Thank You

  6. #21
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    You so didn't have to quote the entire post...

    Don't forget to check back though; you never know what brewbuck was shooting at.

    Soma

  7. #22
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by phantomotap View Post
    O_o

    You so didn't have to quote the entire post...

    Don't forget to check back though; you never know what brewbuck was shooting at.

    Soma
    The segments are all still there in protected mode. Most commercial operating systems just set them up so they all overlap each other perfectly and you can forget they exist. I think the OP is going to have to give a LOT more detail if we're going to help. But can we quit the complaining? People sit around and blab about writing their own OS, here's somebody who's doing more than just blabbing about it.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #23
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    Quote Originally Posted by phantomotap View Post
    Yikes.

    I strongly suggest you look around for "VBE" and the protected mode stuff to get a linear buffer you can play with without that hassle.

    Soma
    I already know how to use VBE. I have been using it for over 8 years now. The problem is: 1) how do you assign the segment address of Video.ModeAttributes to regs.es? 2 how do you assign the offset address of Video.ModeAttributes to regs.di? 3. how do you detect the address of the liner frame-buffer?

  9. #24
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    Quote Originally Posted by brewbuck View Post
    The segments are all still there in protected mode. Most commercial operating systems just set them up so they all overlap each other perfectly and you can forget they exist. I think the OP is going to have to give a LOT more detail if we're going to help. But can we quit the complaining? People sit around and blab about writing their own OS, here's somebody who's doing more than just blabbing about it.
    Code:
    #define WHITE_TXT 0x07 // white on black text
    //---------------------------------------------------
    //
    // Color palette addresses
    //
    
    #define PAL_WRITE_ADDR (0x3c8)      // palette write address
    #define PAL_READ_ADDR  (0x3c7)      // palette write address
    #define PAL_DATA       (0x3c9)      // palette data register
    
    #define FP_SEG(fp) (*((unsigned *)&(fp) + 1))
    #define FP_OFF(fp) (*((unsigned *)&(fp)))
    
    #define NULL 0
    //---------------------------------------------------
    //
    // VBE modes.
    //
    // Note that ALL standard VGA video modes can be used
    // with the vbe functions.
    //
    
    #define    t40x25          0x003
    #define    g320x200c256    0x013
    #define    g640x400c256    0x100
    #define    g640x480c256    0x101
    #define    g800x600c16     0x102
    #define    g800x600c256    0x103
    #define    g1024x768c16    0x104
    #define    g1024x768c256   0x105
    #define    g1280x1024c16   0x106
    #define    g1280x1024c256  0x107
    #define    t80x60          0x108
    #define    t132x25         0x109
    #define    t132x43         0x10a
    #define    t132x50         0x10b
    #define    t132x60         0x10c
    #define    g320x200c32k    0x10d
    #define    g320x200c64k    0x10e
    #define    g320x200c16m    0x10f
    #define    g640x480c32k    0x110
    #define    g640x480c64k    0x111
    #define    g640x480c16m    0x112
    #define    g800x600c32k    0x113
    #define    g800x600c64k    0x114
    #define    g800x600c16m    0x115
    #define    g1024x768c32k   0x116
    #define    g1024x768c64k   0x117
    #define    g1024x768c16m   0x118
    #define    g1280x1024c32k  0x119
    #define    g1280x1024c64k  0x11a
    #define    g1280x1024c16m  0x11b
    #define ptrszint  signed long long
    #define ptrszuint unsigned long long
    #define ptrsz 8
    
    //img_struct flags
    #define IMG_FREEPAL 1 //free palette data before freeing image_struct
    #define IMG_SCREEN  2 //img is linked to other screen pages
    #define IMG_FREEMEM 4 //if set, memory must be freed
    
    typedef enum __attribute__ ((packed)) {
      FALSE = 0, TRUE = 1
    } _bool;
    
    typedef struct __attribute__ ((packed)) {
      unsigned char video_memory_model;
      unsigned char number_of_planes;
      _bool packed_pixel;
      _bool planer;
    } _memory_model;
    
    typedef struct __attribute__ ((packed)) {
     _bool               color_mode;
     _bool               graphics_mode;
     _bool               text_mode;
     _bool               bank_A_exists;
     _bool               bank_A_readable;
     _bool               bank_A_writable;
     _bool               bank_B_exists;
     _bool               bank_B_readable;
     _bool               bank_B_writable;
     unsigned char       bank_granularity;
     unsigned char       bank_size;
     unsigned char      *bank_A_start;
     unsigned char      *bank_B_start;
     unsigned char      *positioning_function;
     unsigned short int  bytes_per_scanline;
     unsigned short int  width;
     unsigned short int  height;
     unsigned short int  char_width;
     unsigned short int  char_height;
     unsigned short int  number_of_planes;
     unsigned short int  bits_per_pixel;
     unsigned short int  number_of_banks;
     _memory_model       memory_model;
     unsigned short int  images_pages;
     unsigned short int  red_mask_size;
     unsigned short int  green_mask_size;
     unsigned short int  blue_mask_size;
     unsigned short int  alpha_mask_size;
     unsigned short int  rsvd_mask;
     unsigned short int  red_field_pos;
     unsigned short int  green_field_pos;
     unsigned short int  blue_field_pos;
     unsigned short int  alpha_field_pos;
     _bool               color_map_is_programmable;
     unsigned char       rsvd[255];
    } _mode_info;
    
    _mode_info video;
    
    typedef signed char _int8;
    typedef signed short int _int16;
    typedef signed long int _int32;
    typedef signed long long _int64;
    
    typedef unsigned char _uint8;
    typedef unsigned short int _uint16;
    typedef unsigned long int _uint32;
    typedef unsigned long long _uint64;
    
    typedef float _float32;
    typedef double _float64;
    //QBOS string descriptor table
    typedef struct __attribute__ ((packed)) {
      signed long int  fileno;
      signed long long fileid;
      signed long long size;
      signed long long offset;
    } qbs_field;
    
    typedef struct __attribute__ ((packed)) {
      unsigned char      *ch;                     //a 32-bit pointer to string data
      unsigned long int   len;                    //
      unsigned char       in_cmem;                //set to 1 if in the conventional memory DBLOCK
      unsigned short int *cmem_descriptor;        //
      unsigned short int  cmem_descriptor_offset; //
      unsigned long int   listi;                  //the index int the list of strings that it references it
      unsigned char       tmp;                    //set to 1 if the string can be deleted immadiately after being processed
      unsigned long int   tmplisti;               //the index in the list of strings that references it
      unsigned char       fixed;                  //fixed length string
      unsigned char       readonly;               //set to 1 if string is read only
      qbs_field *feild;
    } qbs;
    
    typedef struct __attribute__ ((packed)) {
     unsigned char      valid;                                            //0, 1 0=invalid
     unsigned char      text;                                             //if set, surface is a text surface
     unsigned short int width, height;                                    //
     unsigned char      bytes_per_pixel;                                  //1,2,3,4
     unsigned char      bits_per_pixel;                                   //1,2,4,8,12,15,16,24,32
     unsigned long int  mask;                                             //1,3,0xF,0xFF,0xFFFF,0xFFFFFFFF
     unsigned short int compatible_mode;                                  //0,1,2,7,8,9,10,11,12,12-bit,13,15,16,24,32
     unsigned long int  color, background_color, draw_color;              //
     unsigned long int  font;                                             //8,14,16,?
     signed short int   top_row, bottom_row;                              //VIEW PRINT settings, unique (as in QB) to each "page"
     signed short int   cursor_x, cursor_y;                               //unique (as in QB) to each "page"
     unsigned char      cursor_show, cursor_firstvalue, cursor_lastvalue; //										    
     union {                                                              //
       unsigned char     *offset;                                         //
       unsigned long int *offset32;                                       //   
     };                                                                   //
     unsigned long int  flags;                                            //
     unsigned long int  *pal;                                             //
     signed short int   transparent_color;                                //-1 means no color is transperent
     unsigned char      alpha_disabled;                                   //
     unsigned char      holding_cursor;                                   //
     unsigned char      print_mode;                                       //
     //BEGIN apm ('active page migration')
     //everything between apm points is migrated during active page changes
     //note: apm data is only relevent to graphics modes
     unsigned char apm_p1;
     signed long int view_x1, view_y1, view_x2, view_y2;
     signed long int view_offset_x, view_offset_y;
     float x, y;
     unsigned char clipping_or_scaling;
     float caling_x, scaling_y, scaling_offset_x, scaling_offset_y;
     float window_x1, window_y1, window_x2, window_y2;
     double draw_ta;
     double draw_scale;
     unsigned amp_p2;
     //END apm
    } img_struct;
    
    typedef struct __attribute__ ((packed)) {
    	unsigned short di, si, bp, sp, bx, dx, cx, ax;
    	unsigned short gs, fs, es, ds, eflags;
    } regs16_t;
    
    //format:[deadkey's symbol in UTF16], [ASCII code of letter], ,[resulting UTF16 character]...0
    static unsigned short int deadchar_lookup[] = {
    96,97,224,96,65,192,180,97,225,180,65,193,94,97,226,94,65,194,126,97,227,126,65,195,168,97,228,168,65,196,730,97,229,730,65,197,180,99,263,94,99,265,96,101,232,96,69,200,180,101,233,180,69,201,94,101,234,94,69,202,126,101,7869,168,101,235,168,69,203,180,103,501,94,103,285,94,104,293,168,104,7719,96,105,236,96,73,204,180,105,237,180,73,205,94,105,238,94,73,206,126,105,297,168,105,239,168,73,207,94,106,309,180,107,7729,180,108,314,180,109,7743,96,110,505,180,110,324,126,110,241,126,78,209,96,111,242,96,79,210,180,111,243,180,79,211,94,111,244,94,79,212,126,111,245,126,79,213,168,111,246,168,79,214,180,112,7765,180,114,341,180,115,347,94,115,349,168,116,7831,96,117,249,96,85,217,180,117,250,180,85,218,94,117,251,94,85,219,126,117,361,168,117,252,168,85,220,730,117,367,126,118,7805,96,119,7809,180,119,7811,94,119,373,168,119,7813,730,119,7832,168,120,7821,96,121,7923,180,121,253,180,89,221,94,121,375,126,121,7929,168,121,255,168,89,376,730,121,7833,180,122,378,94,122,7825
    
    ,0 
    };  
    
    static unsigned short int codepage437_to_unicode16[] = {
    0x0020,0x263A,0x263B,0x2665,0x2666,0x2663,0x2660,0x2022,0x25D8,0x25CB,0x25D9,0x2642,0x2640,0x266A,0x266B,0x263C,
    
    0x25BA,0x25C4,0x2195,0x203C,0x00B6,0x00A7,0x25AC,0x21A8,0x2191,0x2193,0x2192,0x2190,0x221F,0x2194,0x25B2,0x25BC,
    
    0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
    
    0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
    
    0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
    
    0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
    
    0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
    
    0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x2302,
    
    0x00C7,0x00FC,0x00E9,0x00E2,0x00E4,0x00E0,0x00E5,0x00E7,0x00EA,0x00EB,0x00E8,0x00EF,0x00EE,0x00EC,0x00C4,0x00C5,
    
    0x00C9,0x00E6,0x00C6,0x00F4,0x00F6,0x00F2,0x00FB,0x00F9,0x00FF,0x00D6,0x00DC,0x00A2,0x00A3,0x00A5,0x20A7,0x0192,
    
    0x00E1,0x00ED,0x00F3,0x00FA,0x00F1,0x00D1,0x00AA,0x00BA,0x00BF,0x2310,0x00AC,0x00BD,0x00BC,0x00A1,0x00AB,0x00BB,
    
    0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255D,0x255C,0x255B,0x2510,
    
    0x2514,0x2534,0x252C,0x251C,0x2500,0x253C,0x255E,0x255F,0x255A,0x2554,0x2569,0x2566,0x2560,0x2550,0x256C,0x2567,
    
    0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256B,0x256A,0x2518,0x250C,0x2588,0x2584,0x258C,0x2590,0x2580,
    
    0x03B1,0x00DF,0x0393,0x03C0,0x03A3,0x03C3,0x00B5,0x03C4,0x03A6,0x0398,0x03A9,0x03B4,0x221E,0x03C6,0x03B5,0x2229,
    
    0x2261,0x00B1,0x2265,0x2264,0x2320,0x2321,0x00F7,0x2248,0x00B0,0x2219,0x00B7,0x221A,0x207F,0x00B2,0x25A0,0x0020  
    };  
    
    void kclear_screen();
    unsigned int kprintf(char *message, unsigned int line);
    extern void int32(unsigned char intnum, regs16_t *regs);
    void update_cursor(int row, int col);
    unsigned char inportb(unsigned int port);
    unsigned char inportw(unsigned int port);
    void outportb(unsigned int port,unsigned char value);
    void outportw(unsigned int port,unsigned int value);
    void int32_test();
    int screen(unsigned short int mode);
    void write_video_buffer(unsigned long int x, unsigned long int y, unsigned long int c);
    int set_bank_b(unsigned short int addr);
    int set_bank_b(unsigned short int addr);
    void draw_line(unsigned long int x1, unsigned long int y1, unsigned long int x2, unsigned long int y2, unsigned long int c);
    void write_text(char *message, unsigned long int x, unsigned long int y, unsigned long int c);
    void draw_box(unsigned long int x1, unsigned long int y1, unsigned long int x2, unsigned long int y2, unsigned long int c, unsigned char filled);
    void draw_window(unsigned long int x1, unsigned long int y1, unsigned long int x2, unsigned long int y2, unsigned long int c, char *message);
    void plot4points(signed long int cx, signed long int cy, signed long int x, signed long int y, signed long int c);
    void plot8points(signed long int cx, signed long int cy, signed long int x, signed long int y, signed long int c);
    void draw_circle(signed long int cx, signed long int cy, signed long int radius, signed long int c);
    unsigned long int _lrotl(unsigned long int word, unsigned long int shift);
    signed long long int qbr(long double f);
    unsigned long long int qbr_longdouble_to_uint64(long double f);
    signed long int qbr_float_to_long(float f);
    signed long int qbr_double_to_long(double f);
    unsigned long long getubits(unsigned long int bsize, unsigned char *base, ptrszint i);
    unsigned long long getbits(unsigned long int bsize, unsigned char *base, ptrszint i);
    void setbits(unsigned long int bsize, unsigned char *base, ptrszint i, signed long long val);
    unsigned short int convert_unicode(unsigned short int src_fmt, void *src_buf, unsigned short int src_size, unsigned short int dest_fmt, void *dest_buf);
    
    unsigned char *vbemem = (unsigned char *) 0xA0000, Bpp;
    unsigned long int  ScrWidth, ScrHeight, FontSeg, FontOffset;
    unsigned long int  NewBank, Bank, Power2[15];
    unsigned short int Ww = 0xFFFF;
    static signed long long bmask, bval64;
    static unsigned long long *bptr64;
    signed long int lock_mainloop = 0, lpos = 1, width_lprint = 80;
    signed long int autodisplay = 1, key_display_state = 0, keydown_glyph=0;
    signed long int key_display = 0, key_display_redraw = 0, qbOS_ime_reading=0;
    //keyhit cyclic buffer
    //keyhit specific internal flags: (stored in high 32-bits)
    //&429467296->numpad was used
    //note: if full, the oldest message is discarded to make way for the next message
    signed long long keyhit[8192], keyhit_nextfree=0, keyhit_next = 0;
    unsigned long int bindkey=0;
    void kmain( void* mbd, unsigned int magic )
    {
       int y, x;
       if ( magic != 0x2BADB002 )
       {
          /* Something went not according to specs. Print an error */
          /* message and halt, but do *not* rely on the multiboot */
          /* data structure. */
       }
     
       /* You could either use multiboot.h */
       /* (http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#multiboot_002eh) */
       /* or do your offsets yourself. The following is merely an example. */ 
       char * boot_loader_name =(char*) ((long*)mbd)[16];
     
       /* Print a letter to screen to see everything is working: */
       unsigned char *videoram = (unsigned char *) 0xb8000;
       //int32_test;
       screen(0x101);
       /*while(y < 200)
       {
        draw_line(0, y, 320, y, y);
        y++;
       }*/
       draw_circle(50, 50, 50, 29);
       //draw_window(110, 60, 220, 120, 29, "");
       //draw_box(1, 1, 50, 50, 7, TRUE);
       //write_text("Hello World", 10, 1, 7);
       //kclear_screen();
       // wait for key
       regs16_t regs;
       regs.ax = 0x0000;
       int32(0x16, &regs);
       screen(t40x25);
       kprintf("Hi!\nHow's this for a starter OS?", 0);
    
       /* Write your kernel here. */
    }
    
    void kclear_screen() // clear the entire text screen
    {
    	char *vidmem = (char *) 0xb8000;
    	unsigned short i=0;
    	while(i < (80*24*2))
    	{
    		vidmem[i]=' ';
    		i++;
    		vidmem[i]=WHITE_TXT;
    		i++;
    	};
    };
    
    // the message, col, row, forground color, background color, blink flag
    unsigned int kprintf(char *message, unsigned int line) // the message and then the line #
    {
    	char *vidmem = (char *) 0xb8000;
    	unsigned short int i=0;
    
    	i=(line*80*2);
    
    	while(*message!=0)
    	{
    		if(*message=='\n') // check for a new line
    		{
    			line++;
    			i=(line*80*2);
    			*message++;
    		} else {
    			vidmem[i]=*message;
    			*message++;
    			i++;
    			vidmem[i]=WHITE_TXT;
    			i++;
    		};
    	};
    
    	return(1);
    };
    
    /* Input a byte from a port */
    unsigned char inportb(unsigned int port)
    {
       unsigned char ret;
       asm volatile ("inb %%dx,%%al":"=a" (ret):"d" (port));
       return ret;
    };
    
    /* Output a byte to a port */
    void outportb(unsigned int port,unsigned char value)
    {
       asm volatile ("outb %%al,%%dx": :"d" (port), "a" (value));
    };
    
    /* Input a word from a port */
    unsigned char inportw(unsigned int port)
    {
       unsigned char ret;
       asm volatile ("inw %%dx,%%ax":"=a" (ret):"d" (port));
       return ret;
    };
    
    /* Output a word to a port */
    void outportw(unsigned int port,unsigned int value)
    {
       asm volatile ("outw %%ax,%%dx": :"d" (port), "a" (value));
    };
    
    
    void update_cursor(int row, int col)
    {
     unsigned short position=(row*80) + col;
     // cursor LOW port to vga INDEX register
     outportb(0x3D4, 0x0F);
     outportb(0x3D5, (unsigned char)(position&0xFF));
     // cursor HIGH port to vga INDEX register
     outportb(0x3D4, 0x0E);
     outportb(0x3D5, (unsigned char)((position>>8)&0xFF));
    };
    
    // int32 test
    void int32_test()
    {
    	int y;
    	regs16_t regs;
    	
    	// switch to 320x200x256 graphics mode
    	regs.ax = 0x0013;
    	int32(0x10, &regs);
    
    	for(y = 0; y < 200; y++)
    		vbemem[y] = y;
    	
    	// wait for key
    	regs.ax = 0x0000;
    	int32(0x16, &regs);
    	
    	// switch to 80x25x16 text mode
    	regs.ax = 0x0003;
    	int32(0x10, &regs);
    };
    
    int screen(unsigned short int mode)
    {
      unsigned short int k;
      for(k=0; k<14; k++)
        Power2[k] = 2 ^ k;
      regs16_t regs;
      regs.ax = 0x4F02;
      regs.bx = mode;
      int32(0x10, &regs);
      regs.ax = 0x1130;
      regs.bx = 6 * 256;
      int32(0x10, &regs);
      FontSeg = regs.es;
      FontOffset = regs.bp;
      switch(mode)
      {
        case 0x013:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 320;
          video.width = 320;
          video.height = 200;
          video.char_width = 8;
          video.char_height = 8;
          video.bits_per_pixel = 8;
          break;
        case 0x100: 
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 640;        
          break;
        case 0x101:
          video.bank_A_start = (unsigned char *) 0xA0000; //liner framebuffer 0xd0000000; 
          video.bytes_per_scanline = 640;
          break;
        case 0x102:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 100;
          break;
        case 0x103:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 800;
          break;
        case 0x104:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 128;
          break;
        case 0x105:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 1024;
          break;
        case 0x106:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 160;
          break;
        case 0x107:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 1280;
          break;
        case 0x108:
          video.bank_A_start = (unsigned char *) 0xB8000;
          video.bytes_per_scanline = 160;
          break;
        case 0x109:
          video.bank_A_start = (unsigned char *) 0xB8000;
          video.bytes_per_scanline = 286;
          break;
        case 0x10A:
          video.bank_A_start = (unsigned char *) 0xB8000;
          video.bytes_per_scanline = 264;
          break;
        case 0x10C:
          video.bank_A_start = (unsigned char *) 0xB8000;
          video.bytes_per_scanline = 264;
          break;  
        case 0x10D:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 640;
        case 0x10E:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 640;
        case 0x110:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 1280;
        case 0x111:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 1280;
        case 0x113:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 1600;
        case 0x114:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 1600;
        case 0x116:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 2048;
        case 0x117:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 2048;
        case 0x119:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 2560;
        case 0x11A:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 2400;
        case 0x120:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 1600;
        case 0x140:
          video.bank_A_start = (unsigned char *) 0xA0000;
          video.bytes_per_scanline = 320;
      };
      return (regs.ax == 0x004F);
    };
    
    int set_bank_a(unsigned short int addr)
    {
     regs16_t regs;
     regs.ax = 0x4F05;
     regs.bx = 0x0000;
     regs.dx = (addr / 65536);
     int32(0x10, &regs);
     Bank = NewBank;
     return (regs.ax == 0x004F);
    };
    
    int set_bank_b(unsigned short int addr)
    {
     regs16_t regs;
     regs.ax = 0x4F05;
     regs.bx = 0x0001;
     regs.dx = (addr / 65536);
     int32(0x10, &regs);
     return (regs.ax == 0x004F);
    };
    
    void write_video_buffer(unsigned long int x, unsigned long int y, unsigned long int c)
    {
     //if(NewBank!=Bank){set_bank_a(NewBank);} 
     video.bank_A_start[((y * video.bytes_per_scanline) + x)] = c; 
    };
    
    void draw_line(unsigned long int x1, unsigned long int y1, unsigned long int x2, unsigned long int y2, unsigned long int c)
    {
      unsigned long int r, a, x, y;
      double s;
      r = x2 - x1;
      a = y2 - y1;
      if(a==0){
        for(x=x1; x<x2; x++)
          write_video_buffer(x, y1, c);
      }else if(r==0){
        for(y=y1; y<y2; y++)
          write_video_buffer(x1, y, c);  
      }else if(r>a){
          s = a / r;
          for(x=x1; x<x2; x++){
    	y= y1 + (s * (x - x1));
    	write_video_buffer(x, y, c);
           };	
          }else{
    	s = r / a;
    	for(y=y1; y<y2; y++){
    	  x = x1 + (s * (y - y1));
    	  write_video_buffer(x, y, c);
       	}; 
          };  
    };  
    
    void write_text(char *message, unsigned long int x, unsigned long int y, unsigned long int c)
    {
      unsigned long int j, k, i=1;
      unsigned long int byte, letter=1;
      char *bios_font = (unsigned char *) FontSeg;
      while(*message!=0)
      { 
        if(*message=='\n')
        {
         x = x + video.char_height; y = 0;
         *message++;
        }else{
          letter = *message;
          for(j=0; j<1; j++)
          {		
           byte = bios_font[16 * letter + j + FontOffset];
           for(k=0; k<7; k++)
    	 if(byte & Power2[k]){write_video_buffer(x - k - 1 + 8 * i, y + j, c);}
          };
          *message++;
          i++;
        };  
      };
    };
    
    void draw_box(unsigned long int x1, unsigned long int y1, unsigned long int x2, unsigned long int y2, unsigned long int c, unsigned char filled)
    {
      unsigned long int x, y;
      if(filled)
      {
        for(x=x1; x<x2; x++)
        {
          for(y=y1; y<y2; y++)
    	write_video_buffer(x, y, c);
        };
      }else{
        draw_line(x1, y1, x1, y2, c);
        draw_line(x1, y1, x2, y1, c);
        draw_line(x1, y2, x2, y2, c);
        draw_line(x2, y1, x2, y2, c);
      };  
    }; 
    
    void draw_window(unsigned long int x1, unsigned long int y1, unsigned long int x2, unsigned long int y2, unsigned long int c, char *message)
    {
    //Draw Main Box
     draw_box(x1, y1, x2, y2, c, TRUE);
     draw_box(x1, y1, x2, y2, c - 4, FALSE);
     draw_line(x1 + 1, y1 + 1, x1 + 1, y2 - 1, c - 14);
     draw_line(x1 + 1, y1 + 1, x2 - 1, y1 + 1, c - 14);
     draw_line(x2 + 1, y1, x2 + 1, y2 + 1, c - 21);
     draw_line(x1, y2 + 1, x2 + 1, y2 + 1, c - 21);
    //Title bar
     draw_box(x1 + 4, y1 + 4, x2 - 4, y1 + 22, c - 21, TRUE);
     draw_box(x1 + 4, y1 + 4, x2 - 4, y1 + 22, c - 4, FALSE);
     draw_line(x2 - 3, y1 + 4, x2 - 3, y1 + 22, c - 14);
     draw_line(x1 + 4, y1 + 23, x2 - 3, y1 + 23, c - 14);
    //Displays char *message
     //write_text(*message, x1 + 7, y1 + 10, c - 4);
     //write_text(*message, x1 + 6, y1 + 9, c);  
    };
    
    // The '(x != 0 && y != 0)' test in the last line of this function
    // may be omitted for a performance benefit if the radius of the
    // circle is known to be non-zero.
    void plot4points(signed long int cx, signed long int cy, signed long int x, signed long int y, signed long int c)
    {
      write_video_buffer(cx + x, cy + y, c);
      if(x!=0){write_video_buffer(cx - x, cy + y, c);};
      if(y!=0){write_video_buffer(cx + x, cy - y, c);};
      if(x!=0 && y!=0){write_video_buffer(cx-x, cy-y, c);};
    };
    
    void plot8points(signed long int cx, signed long int cy, signed long int x, signed long int y, signed long int c)
    {
     plot4points(cx, cy, x, y, c);
     if(x!=y){plot4points(cx, cy, y, x, c);};
    }
    
    // 'cx' and 'cy' denote the offset of the circle center from the origin.
    void draw_circle(signed long int cx, signed long int cy, signed long int radius, signed long int c)
    {
      signed long int error = -radius;
      signed long int x = radius;
      signed long int y = 0;
      
      // The following while loop may altered to 'while(x>y)' for a
      // proformance benefit, as long as a call to 'plot4points follows
      // the body of the loop. This allows for the elimination of the
      // '(x!=y) test in 'plot4points', providing a further benefit.
      //
      // For the sake of clarity, this is not shown here.
      while(x>=y)
      {
        plot8points(cx, cy, x, y, c);
        error += y;
        y++;
        error += y;
        
        //The following test may be implemented in assembly language in
        //most machines by testing the carry flag after adding 'y' to
        //the value of 'error' in the previous step, since 'error;
        // norminally has a negative value.
        if(error>=0)
        {
          --x;
          error -= x;
          error -= x;
        };
      }; 
    };  
    
    unsigned long int _lrotl(unsigned long int word, unsigned long int shift)
    {
      return (word << shift) | (word >> (32 - shift));
    };
    
    inline signed long long int qbr(long double f)
    {
      if(f<0){return(f-0.5f);}else{return(f+0.5f);};
    };
    
    unsigned long long int qbr_longdouble_to_uint64(long double f)
    {
      if(f<0){return(f-0.5f);}else{return(f+0.5f);};  
    };
    
    signed long int qbr_float_to_long(float f)
    {
      if(f<0){return(f-0.5f);}else{return(f+0.5f);};  
    };
    
    signed long int qbr_double_to_long(double f)
    {
      if(f<0){return(f-0.5f);}else{return(f+0.5f);};  
    };
    
    //bit-array access functions
    unsigned long long getubits(unsigned long int bsize, unsigned char *base, ptrszint i)
    {
     bmask=~(-(((signed long long)1)<<bsize));
     i*=bsize;
     return ((*(unsigned long long*)(base+(i>>3)))>>(i&7))&bmask;
    }
    
    unsigned long long getbits(unsigned long int bsize, unsigned char *base, ptrszint i)
    {
     bmask=~(-(((signed long long)1)<<bsize));
     i*=bsize;
     bval64=((*(unsigned long long*)(base+(i>>3)))>>(i&7))&bmask;
     if(bval64&(((signed long long)1)<<(bsize-1))){return bval64|(~bmask);};
    return bval64;
    }
    
    void setbits(unsigned long int bsize, unsigned char *base, ptrszint i, signed long long val)
    {
     bmask=-(((unsigned long long)1)<<bsize);
     i*=bsize;
     bptr64=(unsigned long long*)(base+(i>>3));
     *bptr64=(*bptr64&(bmask<<(i&7)))|((val&(~bmask))<<(i&7));
    };
    
    unsigned short int convert_unicode(unsigned short int src_fmt, void *src_buf, unsigned short int src_size, unsigned short int dest_fmt, void *dest_buf)
    {
     /*
    important:  to ensure enough space is available for the conversion, dest_buf must be at least src_size*4+4 in length
    
    returns:    the number of bytes written to dest_buf
    
    fmt values: 1=ASCII(CP437)
    
    	    8=UTF8
    
    	    16=UTF16
    
    	    32=UTF32
    
    */
    
     static unsigned short int dest_size;
     dest_size=0;
    
     //setup source
     unsigned char *src_uint8p=NULL;
     if(src_fmt==1){
       src_uint8p=(unsigned char*)src_buf;
     };
     unsigned short int *src_uint16p=NULL;
     if(src_fmt==16){
       src_uint16p=(unsigned short int*)src_buf;
       src_size=src_size-(src_size&1); //cull trailing bytes
     };
     unsigned long int *src_uint32p=NULL;
     if(src_fmt==32){
       src_uint32p=(unsigned long int*)src_buf;
       src_size=src_size-(src_size&3); //cull trailing bytes
    
     };
    
     //setup dest
     unsigned short int *dest_uint16p=NULL;
     if(dest_fmt==16){
       dest_uint16p=(unsigned short int*)dest_buf;
     };
     unsigned long int *dest_uint32p=NULL;
     if(dest_fmt==32){
       dest_uint32p=(unsigned long int*)dest_buf;
     };
    
     unsigned long int x; //scalar
    
     while(src_size){
    
      //convert src to scalar UNICODE value 'x'
    
      if(src_fmt==1){ //CP437
        x=*src_uint8p++;
        src_size--;
        x=codepage437_to_unicode16[x];
      }
      if(src_fmt==16){ //UTF16
        src_size-=2;
        x=*src_uint16p++;
        //note: does not handle surrogate pairs yet
      }
      if(src_fmt==32){ //UTF32
        src_size-=4;
        x=*src_uint32p++;
      }
    
     //convert scalar UNICODE value 'x' to dest
    
      if(dest_fmt==16){ //UTF16
        *dest_uint16p++=x;
        dest_size+=2;
      //note: does not handle surrogate pairs yet
    
      }
      if(dest_fmt==32){ //UTF32
        *dest_uint32p++=x;
        dest_size+=4;
      }
    
     } //loop
    
     //add NULL terminator (does not change the size in bytes returned)
     if (dest_fmt==16) *dest_uint16p=0;
     if (dest_fmt==32) *dest_uint32p=0;
    
     return dest_size;
    }

  10. #25
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Okay, so what's the point of the vertical scroll in the code box?

    Anyway, we want information about what you are doing; I don't think anyone has the time to read through all of that to try and track it down ourselves.

    In any event, you'll have to use a little inline assembler to load the values into the register, if you don't have that already, and it depends on what you are doing, how you are compiling, the phase of the moon, and how much GCC loves you, you'll probably want something like this for real mode (assuming the allocation takes place under real mode rules and `vmb' is a pointer).

    Code:
    di = vmb & 0x0F;
    es = (vmb >> 4) & 0xFFFF;
    Soma

  11. #26
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    So, what's the thing you need to get the offset and segment of, and what will be using those values? Are you trying to pass the address of something in your driver to a real mode BIOS interrupt? How do you have segmentation configured? Are you doing virtual paging?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #27
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    Quote Originally Posted by phantomotap View Post
    O_o

    Okay, so what's the point of the vertical scroll in the code box?

    Anyway, we want information about what you are doing; I don't think anyone has the time to read through all of that to try and track it down ourselves.

    In any event, you'll have to use a little inline assembler to load the values into the register, if you don't have that already, and it depends on what you are doing, how you are compiling, the phase of the moon, and how much GCC loves you, you'll probably want something like this for real mode (assuming the allocation takes place under real mode rules and `vmb' is a pointer).

    Code:
    di = vmb & 0x0F;
    es = (vmb >> 4) & 0xFFFF;
    Soma
    This kernel is to be used as a game engine/library which will allow a programer with minimum programming kills to create games which will be able to either to run directly on their hardware, or hosted using QEMU, Virtual Box, JPC, vmware player, etc. The programmer will be able to compile and link the game:

    Code:
    $ gcc -c kernel.c -o kernel.o -m32
    $gcc -c game.c -o game.o -m32
    $ ld -T linker.ld -o kernel.bin loader.o int32.o kernel.o game.o -melf_i386
    after which the programmer will be able to test the game using QEMU:

    Code:
    $qemu -kernel kernel.bin

  13. #28
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    I will be passing both the segment and offset addresses of Video.ModeAttributes regs.es and regs.di respectively. Then I will be passing both regs.es and regs.di to real mode BIOS interrupt 10 using VESA function 4F00h to get the VBE controller information table, function 4F01h to get the VBE mode information table. Then I will switch to the detected video mode.

    The following code should help illastrate what I am trying to implament:

    Code:
    SUB DetVesa (XWidth, xHeight, xBpp)
    
    CLS
    
    Regs.ax = &H4F00
    
    Regs.es = VARSEG(Video.ModeAttributes)
    
    Regs.di = VARPTR(Video.ModeAttributes)
    
    CALL Interrupt(&H10, Regs, Regs)
    
    IF Regs.ax <> &H4F THEN
    
    PRINT "No VESA Card detected"
    
    WaitKey
    
    SYSTEM
    
    ELSE
    
    PRINT "                        VESA Card detected"
    
    PRINT
    
    PRINT "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»"
    
    PRINT "º Quit the program immediatly if you have a monochrome display   º"
    
    PRINT "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ"
    
    PRINT
    
    END IF
    
    FOR mode = &H100 TO &HFFF
    
     Regs.ax = &H4F01
    
     Regs.cx = mode
    
     Regs.es = VARSEG(Video.ModeAttributes)
    
     Regs.di = VARPTR(Video.ModeAttributes)
    
     CALL Interrupt(&H10, Regs, Regs)
    
     ScrWidth = Video.xResolution
    
     ScrHeight = Video.yResolution
    
     Bpp = ASC(Video.BitsPerPixel)
    
     IF Bpp > 0 AND ScrWidth > 0 AND ScrHeight > 0 THEN
    
       IF xBpp = Bpp AND XWidth = ScrWidth AND xHeight = ScrHeight THEN
    
        Regs.ax = &H4F02
    
        Regs.bx = mode
    
        CALL Interrupt(&H10, Regs, Regs)
    
        ScrWidth = Video.xResolution
    
        ScrHeight = Video.yResolution
    
        Bpsl = Video.BytesPerScanLine
    
        Bpp = ASC(Video.BitsPerPixel) / 8
    
        Bpl = ScrWidth * Bpp
    
        IF Bpl <> Bpsl AND Bpsl <> 0 THEN Bpl = Bpsl
    
        FullScreen
    
        DEF SEG = Video.WinASegment
    
        CurBank% = 0
    
        REDIM yLut(ScrHeight - 1) AS ySVGA
    
        FOR y% = 0 TO ScrHeight - 1
    
         temp& = CLNG(Video.BytesPerScanLine) * y%
    
         yLut(y%).Bank = temp& \ &H10000
    
         yLut(y%).Offset = temp& AND &HFFFF&
    
        NEXT
    
        REDIM xBpp&(ScrWidth - 1)
    
        FOR x% = 0 TO ScrWidth - 1
    
         xBpp&(x%) = Bpp * x%
    
        NEXT
    
        'Get segment and offset of the ROM fonts
    
        Regs.ax = &H1130
    
        Regs.bx = 6 * 256
    
        CALL Interrupt(&H10, Regs, Regs)
    
        FontSeg% = Regs.es
    
        FontOffset% = Regs.bp
    
       ' Powers of two precalculation
    
        REDIM Power2%(15)
    
        FOR k% = 0 TO 14: Power2%(k%) = 2 ^ k%: NEXT k%
    
        EXIT SUB
    
       END IF
    
     END IF
    
    NEXT mode
    
    END SUB
    I do not have segmentation configured and I do not have any plans to do virtual paging as most of the operating system will be running in protected mode.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 09-04-2008, 01:27 PM
  2. User mode and Kernel Mode
    By learner01 in forum Linux Programming
    Replies: 9
    Last Post: 08-10-2006, 08:20 PM
  3. User mode and Kernel mode
    By learner01 in forum C++ Programming
    Replies: 7
    Last Post: 08-09-2006, 02:38 PM
  4. Replies: 3
    Last Post: 01-23-2006, 07:25 PM
  5. User-mode and Kernel-mode
    By Eibro in forum Tech Board
    Replies: 1
    Last Post: 06-30-2003, 09:27 PM