-
I wrote a 16-bit VESA BIOS Extension (VBE) driver that loads the VBE Mode Information structure and attempts to bank switch using the real-mode far pointer WinFuncPtr. However because this emulates VBE Function 05h (Display Window Control) it requires the window number parameter to be passed in DX. typedef struct VBE_mode_info VBE_mode_info;
struct VBE_mode_info {
uint16_t mode_attributes; /* mode attributes */
uint8_t window_a_attributes; /* window A attributes */
uint8_t window_b_attributes; /* window B attributes */
uint16_t window_granularity; /* window granularity kB */
uint16_t window_size; /* window size kB */
uint16_t window_a_segment; /* window A segment */
uint16_t window_b_segment; /* window B segment */
#pragma aux win_func_ptr parm [dx]
void (far *win_func_ptr)(int p);/* pointer to window function */
uint16_t bytes_per_scanline; /* bytes per scanline */
uint16_t pixel_width; /* horizontal resolution */
uint16_t pixel_height; /* vertical resolution */
uint8_t x_char_size; /* character cell width */
uint8_t y_char_size; /* character cell height */
uint8_t number_of_planes; /* number of memory planes */
uint8_t bits_per_pixel; /* bits per pixel */
uint8_t number_of_banks; /* number of CGA style banks */
uint8_t memory_model; /* memory model type */
uint8_t bank_size; /* size of CGA style banks */
uint8_t number_of_image_pages; /* number of image pages */
uint8_t reserved; /* reserved */
/* VBE 1.2 */
uint8_t red_mask_size; /* size of direct color red mask */
uint8_t red_field_position; /* bit position of red mask LSB */
uint8_t green_mask_size; /* size of direct color green mask */
uint8_t green_field_position; /* bit position of green mask LSB */
uint8_t blue_mask_size; /* size of direct color blue mask */
uint8_t blue_field_position; /* bit position of blue mask LSB */
uint8_t reserve_mask_size; /* size of direct color blue mask */
uint8_t reserve_field_position; /* bit position of blue mask LSB */
uint8_t direct_color_mode_info; /* direct color mode attributes */
/* VBE 2.0 */
uint32_t physical_base_ptr; /* physical address for linear frame buffer */
uint32_t off_screen_mem_offset; /* pointer to start of off secreen memory */
uint16_t off_screen_mem_size; /* amount of off screen memory in 1kB units */
uint8_t reserved2[206]; /* pad to 256 byte block size */
};
int VBE_get_mode_info(VBE_mode_info far *vbe_mode_info, int mode);
#pragma aux VBE_get_mode_info parm [es di] [cx] modify [ax] value [ax] = \
"mov ax, 0x4f01" \
"int 0x10"
VBE_mode_info mode_info;
#pragma aux main modify [ax bx cx dx di si]
void main() {
VBE_get_mode_info(&mode_info, 0x101);
mode_info.win_func_ptr(1);
} Compiling this and disassembling shows that the parameter is passed in AX and not DX. What is the right way to use pragma to tell WATCOM compiler wcc to pass the value in DX?
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
I think you have to distinguish between a function definition / declaration and a function pointer. If you change your code as
you get what you expected
|
Beta Was this translation helpful? Give feedback.
-
Awesome! I just tried this in my driver code and it works perfectly. Thank you for showing me how to pass parameters into function pointer types. This is actually super useful and will let me fix some cruft elsewhere too. Thanks! |
Beta Was this translation helpful? Give feedback.
I think you have to distinguish between a function definition / declaration and a function pointer.
you specify a pragma for the variable that contains the function pointer, so it does not work as expected.
The pragma must be defined for the function itself.
If you change your code as