Add an API for COMBOOT images, and add support for "COM32" -- 32-bit
[profile/ivi/syslinux.git] / comboot.inc
1 ;; $Id$
2 ;; -----------------------------------------------------------------------
3 ;;   
4 ;;   Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
5 ;;
6 ;;   This program is free software; you can redistribute it and/or modify
7 ;;   it under the terms of the GNU General Public License as published by
8 ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9 ;;   Bostom MA 02111-1307, USA; either version 2 of the License, or
10 ;;   (at your option) any later version; incorporated herein by reference.
11 ;;
12 ;; -----------------------------------------------------------------------
13
14 ;;
15 ;; comboot.inc
16 ;; 
17 ;; Common code for running a COMBOOT image
18 ;;
19
20 ; Looks like a COMBOOT image but too large
21 comboot_too_large:
22                 mov si,err_comlarge
23                 call cwritestr
24                 jmp enter_command
25
26 ;
27 ; Load a COMBOOT image.  A COMBOOT image is basically a DOS .COM file,
28 ; except that it may, of course, not contain any DOS system calls.  We
29 ; do, however, allow the execution of INT 20h to return to SYSLINUX.
30 ;
31 is_comboot_image:
32                 and dx,dx
33                 jnz comboot_too_large
34                 cmp ax,0ff00h           ; Max size in bytes
35                 jae comboot_too_large
36
37                 call comboot_setup_api
38
39                 mov cx,comboot_seg
40                 mov es,cx
41
42                 mov bx,100h             ; Load at <seg>:0100h
43
44                 mov cx,[ClustPerMoby]   ; Absolute maximum # of clusters
45                 call getfssec
46
47                 xor di,di
48                 mov cx,64               ; 256 bytes (size of PSP)
49                 xor eax,eax             ; Clear PSP
50                 rep stosd
51
52                 mov word [es:0], 020CDh ; INT 20h instruction
53                 ; First non-free paragraph
54                 mov word [es:02h], comboot_seg+1000h
55
56                 ; Copy the command line from high memory
57                 mov cx,125              ; Max cmdline len (minus space and CR)
58                 mov si,[CmdOptPtr]
59                 mov di,081h             ; Offset in PSP for command line
60                 mov al,' '              ; DOS command lines begin with a space
61                 stosb
62
63 comboot_cmd_cp: lodsb
64                 and al,al
65                 jz comboot_end_cmd
66                 stosb
67                 loop comboot_cmd_cp
68 comboot_end_cmd: mov al,0Dh             ; CR after last character
69                 stosb
70                 mov al,126              ; Include space but not CR
71                 sub al,cl
72                 mov [es:80h], al        ; Store command line length
73
74                 mov [SavedSSSP],sp
75                 mov [SavedSSSP+2],ss    ; Save away SS:SP
76
77                 mov ax,es
78                 mov ds,ax
79                 mov ss,ax
80                 xor sp,sp
81                 push word 0             ; Return to address 0 -> exit
82
83                 jmp comboot_seg:100h    ; Run it
84
85 ; Proper return vector
86 comboot_return: cli                     ; Don't trust anyone
87                 xor ax,ax
88                 jmp comboot_exit
89
90 ;
91 ; Set up the COMBOOT API interrupt vectors.  This is also used
92 ; by the COM32 code.
93 ;
94 comboot_setup_api:
95                 mov di,4*0x20           ; DOS interrupt vectors
96                 mov eax,comboot_return  ; INT 20h = exit
97                 stosd
98                 mov ax,comboot_int21    ; INT 21h = DOS-compatible syscalls
99                 stosd
100                 mov ax,comboot_int22    ; INT 22h = proprietary syscalls
101                 stosd
102                 mov ax,comboot_bogus
103                 mov cx,29               ; All remaining DOS vectors
104                 rep stosd
105                 ret
106
107 ; INT 21h: generic DOS system call
108 comboot_int21:  push ds
109                 push cs
110                 pop ds                  ; Set DS <- CS
111                 and ah,ah               ; 00 = return
112                 je comboot_return
113                 cmp ah,02h
114                 jb comboot_getkeyecho   ; 01 = get key with echo
115                 je comboot_writechr     ; 02 = writechr
116                 cmp ah,08h              ; 08 = get key w/o echo
117                 je comboot_getkey
118                 cmp ah,09h              ; 09 = writestr
119                 je comboot_writestr
120                 cmp ah,0Bh              ; 0B = check keyboard
121                 je comboot_checkkey
122                 cmp ah,30h              ; 30 = check version
123                 je comboot_checkver
124                 cmp ah,4Ch              ; 4C = return with status
125                 je comboot_return
126
127                 ; Otherwise fall through to comboot_bogus
128
129 ; Attempted to execute non-21h DOS system call
130 comboot_bogus:  cli                     ; Don't trust anyone
131                 mov ax,err_notdos
132 ;
133 ; Generic COMBOOT return to command line code
134 ;  AX -> message (if any)
135 ;  BX -> where to go next
136 ;
137 comboot_exit:
138                 mov bx,enter_command    ; Normal return to command prompt
139 comboot_exit_special:
140                 xor dx,dx
141                 mov ds,dx
142                 mov es,dx
143                 lss sp,[SavedSSSP]
144                 sti
145                 cld
146                 and ax,ax
147                 je .nomsg
148                 mov si,KernelCName
149                 call cwritestr
150                 xchg si,ax
151                 call cwritestr
152 .nomsg:         jmp bx
153
154 ;
155 ; INT 21h system calls
156 ;
157 comboot_getkeyecho:                     ; 01 = get key with echo
158                 call vgashowcursor
159                 call getchar
160                 call vgahidecursor
161                 call writechr
162                 jmp comboot_resume_ok
163
164 comboot_writechr:                       ; 02 = writechr
165                 xchg ax,dx
166                 call writechr
167                 xchg ax,dx
168                 jmp comboot_resume_ok
169
170 comboot_getkey:                         ; 08 = get key w/o echo
171                 call vgashowcursor
172                 call getchar
173                 call vgahidecursor
174                 jmp comboot_resume_ok
175
176 comboot_writestr:                       ; 09 = write string
177                 pusha
178                 push es
179                 mov bp,sp
180                 mov es,[bp-20]          ; Old DS
181                 mov si,dx
182 .loop:          es lodsb
183                 cmp al,'$'              ; End string with $ - bizarre
184                 je .done
185                 call writechr
186                 jmp short .loop
187 .done:          pop es
188                 popa
189                 jmp comboot_resume_ok
190
191 comboot_checkkey:                       ; 0B = check keyboard status
192                 call pollchar
193                 setz al
194                 dec al                  ; AL = 0FFh if present, 0 if not
195                 jmp comboot_resume_ok
196
197 comboot_checkver:                       ; 30 = check DOS version
198                 ; We return 0 in all DOS-compatible version registers,
199                 ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
200                 mov eax,'SY' << 16
201                 mov ebx,'SL' << 16
202                 mov ecx,'IN' << 16
203                 mov edx,'UX' << 16
204                 ;jmp comboot_resume_ok
205
206 ;
207 ; Resume comboot execution
208 ;
209 comboot_resume_ok:
210                 clc
211 comboot_resume:
212                 pop ds
213                 iret
214
215 comboot_apierr:
216                 stc
217                 jmp comboot_resume
218
219 ;
220 ; INT 22h - SYSLINUX-specific system calls
221 ;           System call number in ax
222 ;
223 comboot_int22:
224                 push ds
225                 push cs
226                 pop ds
227
228                 cmp ax,int22_count
229                 jae comboot_apierr
230
231                 xchg ax,bx
232                 add bx,bx
233                 call [bx+int22_table]
234                 jmp comboot_resume              ; On return
235
236 ;
237 ; INT 22h AX=0000h      Null system call
238 ; INT 22h AX=0001h      Get SYSLINUX version
239 ;
240 comapi_get_version:
241                 ; Number of API functions supported
242                 mov ax,int22_count
243                 ; SYSLINUX version
244                 mov cx,(VER_MAJOR << 8)+VER_MINOR
245                 ; SYSLINUX derivative ID byte
246                 mov dx,my_id
247                 ; For future use
248                 xor bx,bx
249
250                 push cs
251                 pop es
252                 ; ES:SI -> version banner
253                 mov si,syslinux_banner
254                 ; ES:DI -> copyright string
255                 mov di,copyright_str
256
257 comapi_nop:
258                 clc
259                 ret
260
261 ;
262 ; INT 22h AX=0002h      Write string
263 ;
264 ; Write null-terminated string in ES:BX
265 ;
266 comapi_writestr:
267                 push es
268                 pop ds
269                 mov si,ax
270                 jmp writestr                    ; Write string from ES:BX
271
272 ;
273 ; INT 22h AX=0003h      Run command
274 ;
275 ; Terminates the COMBOOT program and executes the command line in
276 ; ES:BX as if it had been entered by the user.
277 ;
278 comapi_run:
279                 push es
280                 push ds
281                 pop es
282                 pop ds
283                 mov si,ax
284                 mov di,command_line
285 .copyloop:
286                 lodsb
287                 stosb
288                 and al,al
289                 jnz .copyloop
290                 xor ax,ax
291                 mov bx,load_kernel              ; Run a new kernel
292                 jmp comboot_exit_special        ; Terminate task, clean up
293
294 ;
295 ; INT 22h AX=0004h      Run default command             
296 ;
297 ; Terminates the COMBOOT program and executes the default command line
298 ; as if a timeout had happened or the user pressed <Enter>.
299 ;
300 comapi_run_default:
301                 mov bx,auto_boot
302                 jmp comboot_exit_special
303
304 ;
305 ; INT 22h AX=0005h      Force text mode
306 ;
307 ; Puts the video in standard text mode
308 ;
309 comapi_textmode:
310                 call vgaclearmode
311                 clc
312                 ret
313
314 ;
315 ; INT 22h AX=0006h      Open file
316 ;
317 comapi_open:
318                 push ds
319                 push ds
320                 push es
321                 pop ds
322                 pop es
323                 mov di,InitRD
324                 push di
325                 call mangle_name
326                 pop di
327                 pop ds
328                 call searchdir
329                 jz .err
330                 xchg eax,edx
331                 shr eax,16
332                 xchg ax,dx
333                 mov cx,[SecPerClust]
334                 clc
335                 ret
336 .err:
337                 stc
338                 ret
339
340
341 ;
342 ; INT 22h AX=0007h      Read file
343 ;
344 comapi_read:
345                 xchg ax,bx
346                 call getfssec
347                 jnc .noteof
348                 xor si,si               ; SI <- 0 on EOF, CF <- 0
349 .noteof:        ret
350
351 ;
352 ; INT 22h AX=0008h      Close file
353 ;
354 comapi_close:
355                 ; Do nothing for now.  Eventually implement
356                 ; an internal API for this.
357                 clc
358                 ret
359
360
361                 align 2, db 0
362 int22_table:
363                 dw comapi_nop                   ; 0000 null syscall
364                 dw comapi_get_version           ; 0001 get SYSLINUX version
365                 dw comapi_writestr              ; 0002 write string
366                 dw comapi_run                   ; 0003 run specified command
367                 dw comapi_run_default           ; 0004 run default command
368                 dw comapi_textmode              ; 0005 force text mode
369                 dw comapi_open                  ; 0006 open file
370                 dw comapi_read                  ; 0007 read file
371                 dw comapi_close                 ; 0008 close file
372 int22_count     equ ($-int22_table)/2