* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / libc / bios / bios.c
blob41b02c271c6d36e0184cc8704dab73fb829d3010
1 /* Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk>
2 * This file is part of the Linux-8086 C library and is distributed
3 * under the GNU Library General Public License.
4 */
6 #undef AOUT_STANDALONE
8 #if !__FIRST_ARG_IN_AX__
9 #ifdef __AS386_16__
10 #ifdef __STANDALONE__
12 #include <bios.h>
13 #include <fcntl.h>
14 #include <errno.h>
16 #ifdef L_bios_start
18 char ** environ = { 0 };
19 int errno;
21 void (*__cleanup)() = 0;
23 #asm
24 .data
25 export ___argr
26 ___argr:
27 .word 0,0,0,0,0,0,0,0 ! A struct REGS: ax, bx, cx, dx, si, di, cflag, flags
28 defarg:
29 .word boot_str, 0
30 boot_str:
31 .asciz "boot"
32 loop_save:
33 .word 0
35 .text
36 export ___cstartup ! Crt0 startup
37 ___cstartup:
38 cli
39 #ifndef AOUT_STANDALONE
40 seg cs
41 cmp word ptr [0],#$20CD ! "int 20h" at psp: CS:0000
42 jne not_dos
44 ! DOS - only AX has a defined value.
45 ! All the segment registers are pointing at the PSP
46 ! SP points to the top of the segment so is probably useable.
48 push ax ! Save AX
49 mov ax,cs
50 add ax,#$10 ! bump CS by 0x10
51 push ax
52 mov ax,#is_dos ! resume address
53 push ax
54 retf ! continue at next instruction
55 dos_flag:
56 .word 0 ! Set to 1 if DOS
57 is_dos:
58 seg cs
59 inc dos_flag
60 pop ax ! restore saved AX
62 not_dos:
63 mov sp,cs
64 add sp,#__segoff
65 mov ds,sp
66 mov ss,sp
67 mov bp,#__heap_top
68 mov sp,#___argr+14
69 seg cs
70 push [dos_flag] ! Set the carry flag if we're under DOS.
71 #else
72 mov bp,sp
73 mov sp,#___argr+12
74 #endif
75 push di
76 push si
77 push dx
78 push cx
79 push bx
80 push ax
81 mov sp,bp
82 sti
84 zap_bss: ! Clear the BSS
85 push ds
86 pop es ! ES now data seg
87 mov di,#__edata
88 mov cx,#__end
89 sub cx,di
90 xor ax,ax
91 cld
92 rep
93 stosb
95 !mov bp,ax ! Top frame pointer, only needed if we get a debugger
96 push [_environ]
97 mov ax,#defarg ! Don`t define __mkargv, standalone programs don`t
98 push ax ! get any arguments.
99 mov ax,#1
100 push ax
102 mov bx,#auto_start ! Pointer to first autostart function
103 auto_run:
104 mov [loop_save],bx
105 mov bx,[bx]
106 test bx,bx
107 jz no_entry
108 call bx ! Call the function
109 no_entry:
110 mov bx,[loop_save]
111 inc bx ! next
112 inc bx
113 jmp auto_run ! And round for the next.
115 call_exit: ! Last item called by above.
116 pop bx ! Be tidy.
117 push ax ! At the end the last called was main() push it`s
118 call _exit ! return val and call exit();
119 bad_exit:
120 jmp bad_exit ! Exit returned !!
122 loc 2
123 .word _main ! Segment 2 is the trailing pointers, main and the
124 .word call_exit ! routine to call exit.
125 data_start:
127 .text
128 export _exit
129 _exit: ! exit(rv) function
130 mov bx,sp
131 push [bx+2] ! Copy the `rv` for the exit fuctions.
132 mov bx,[___cleanup] ! Call exit, normally this is `__do_exit`
133 test bx,bx
134 je no_clean ! But it`s default is null
135 call bx
136 no_clean:
137 inc sp
138 inc sp
140 export __exit
141 __exit:
142 #ifndef AOUT_STANDALONE
143 seg cs
144 cmp [dos_flag],#0 ! Should we do a DOS exit
145 je do_reboot
146 mov ax,#$4c00
147 int $21
148 do_reboot:
149 #endif
150 xor ax,ax
151 mov ds,ax
152 mov ax,cs
153 mov [$E6*4+2],ax
154 mov ax,#iret_ins
155 mov [$E6*4],ax
156 mov ax,#$FFFF
157 int $E6 ! Try to exit DOSEMU
158 ! If we get here we`re not in dosemu.
159 mov [$472],#$1234 ! Warm reboot.
160 jmpi $0000,$FFFF
161 iret_ins:
162 iret
164 #endasm
166 #endif
168 /****************************************************************************/
170 #ifdef L_bios_write
171 write(fd,buf,len)
172 int fd,len;
173 char * buf;
175 register int v, c;
176 if(fd == 1 || fd == 2)
178 for(v=len; v>0; v--)
180 c= *buf++;
181 putch(c);
183 return len;
185 return (*__files)(CMD_WRITE, fd, buf, len);
187 #endif
189 /****************************************************************************/
191 #ifdef L_bios_read
192 read(fd,buf,len)
193 int fd,len;
194 char * buf;
196 if(fd == 0) return bios_rdline(buf, len);
197 return (*__files)(CMD_READ, fd, buf, len);
199 #endif
201 /****************************************************************************/
203 #ifdef L_bios_lseek
204 long
205 lseek(fd, offt, whence)
206 int fd, whence;
207 long offt;
209 if( fd >= 0 && fd <= 2 ) errno = ESPIPE;
210 else
212 if( (*__files)(CMD_LSEEK, fd, &offt, whence) >= 0 )
213 return offt;
215 return -1L;
217 #endif
219 /****************************************************************************/
221 #ifdef L_bios_close
222 close(fd)
223 int fd;
225 if( fd >= 0 && fd <= 2 ) errno = ENOSYS;
226 else
227 return (*__files)(CMD_CLOSE, fd);
228 return -1;
230 #endif
232 /****************************************************************************/
234 #ifdef L_bios_nofiles
235 int (*__files)() = __nofiles;
237 int __nofiles(cmd, fd, buf, len)
238 int cmd, fd, len;
239 char * buf;
241 errno = EBADF;
242 return -1;
245 #endif
247 /****************************************************************************/
249 #ifdef L_bios_isatty
250 isatty(fd)
251 int fd;
253 if( fd >= 0 && fd <= 2 ) return 1;
254 return 0;
256 #endif
258 /****************************************************************************/
260 #ifdef L_bios_abort
261 abort()
263 static const char msg[] = "Program aborted, press return:";
264 write(2, msg, sizeof(msg)-1);
265 getch();
266 _exit(255);
269 #endif
271 /****************************************************************************/
273 #endif
274 #endif
275 #endif