11 * Data structures and type definitions
15 /* Segment:offset structure. Note that the order within the structure
21 } __attribute__ (( packed ));
23 typedef struct segoff segoff_t;
25 /* Macro hackery needed to stringify bits of inline assembly */
27 #define RM_STR(x) RM_XSTR(x)
29 /* Drag in the selected real-mode transition library header */
37 * The API to some functions is identical between librm and libkir, so
38 * they are documented here, even though the prototypes are in librm.h
44 * Declaration of variables in .data16
46 * To place a variable in the .data16 segment, declare it using the
49 * int __data16 ( foo );
50 * #define foo __use_data16 ( foo );
52 * extern uint32_t __data16 ( bar );
53 * #define bar __use_data16 ( bar );
55 * static long __data16 ( baz ) = 0xff000000UL;
56 * #define baz __use_data16 ( baz );
58 * i.e. take a normal declaration, add __data16() around the variable
59 * name, and add a line saying "#define <name> __use_data16 ( <name> )
61 * You can then access them just like any other variable, for example
65 * This magic is achieved at a cost of only around 7 extra bytes per
66 * group of accesses to .data16 variables. When using KEEP_IT_REAL,
67 * there is no extra cost.
69 * You should place variables in .data16 when they need to be accessed
70 * by real-mode code. Real-mode assembly (e.g. as created by
71 * REAL_EXEC()) can access these variables via the usual data segment.
72 * You can therefore write something like
74 * static uint16_t __data16 ( foo );
75 * #define foo __use_data16 ( foo )
85 * Variables may also be placed in .text16 using __text16 and
86 * __use_text16. Some variables (e.g. chained interrupt vectors) fit
87 * most naturally in .text16; most should be in .data16.
89 * If you have only a pointer to a magic symbol within .data16 or
90 * .text16, rather than the symbol itself, you can attempt to extract
91 * the underlying symbol name using __from_data16() or
92 * __from_text16(). This is not for the faint-hearted; check the
93 * assembler output to make sure that it's doing the right thing.
97 * void copy_to_real ( uint16_t dest_seg, uint16_t dest_off,
98 * void *src, size_t n )
99 * void copy_from_real ( void *dest, uint16_t src_seg, uint16_t src_off,
102 * These functions can be used to copy data to and from arbitrary
103 * locations in base memory.
107 * put_real ( variable, uint16_t dest_seg, uint16_t dest_off )
108 * get_real ( variable, uint16_t src_seg, uint16_t src_off )
110 * These macros can be used to read or write single variables to and
111 * from arbitrary locations in base memory. "variable" must be a
112 * variable of either 1, 2 or 4 bytes in length.
116 * REAL_CALL ( routine, num_out_constraints, out_constraints,
117 * in_constraints, clobber )
118 * REAL_EXEC ( name, asm_code_str, num_out_constraints, out_constraints,
119 * in_constraints, clobber )
121 * If you have a pre-existing real-mode routine that you want to make
122 * a far call to, use REAL_CALL. If you have a code fragment that you
123 * want to copy down to base memory, execute, and then remove, use
126 * out_constraints must be of the form OUT_CONSTRAINTS(constraints),
127 * and in_constraints must be of the form IN_CONSTRAINTS(constraints),
128 * where "constraints" is a constraints list as would be used in an
131 * clobber must be of the form CLOBBER ( clobber_list ), where
132 * "clobber_list" is a clobber list as would be used in an inline
135 * These are best illustrated by example. To write a character to the
136 * console using INT 10, you would do something like:
138 * REAL_EXEC ( rm_test_librm,
141 * OUT_CONSTRAINTS ( "=a" ( discard ) ),
142 * IN_CONSTRAINTS ( "a" ( 0x0e00 + character ),
144 * CLOBBER ( "ebx", "ecx", "edx", "ebp", "esi", "edi" ) );
146 * IMPORTANT: gcc does not automatically assume that input operands
147 * get clobbered. The only way to specify that an input operand may
148 * be modified is to also specify it as an output operand; hence the
149 * "(discard)" in the above code.
152 #endif /* ASSEMBLY */
154 #endif /* REALMODE_H */