summaryrefslogtreecommitdiff
path: root/comboot.inc
blob: 2804927472d5a7f4f4618754e58bba011b5c127b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
;; $Id$
;; -----------------------------------------------------------------------
;;   
;;   Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
;;
;;   This program is free software; you can redistribute it and/or modify
;;   it under the terms of the GNU General Public License as published by
;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
;;   Bostom MA 02111-1307, USA; either version 2 of the License, or
;;   (at your option) any later version; incorporated herein by reference.
;;
;; -----------------------------------------------------------------------

;;
;; comboot.inc
;; 
;; Common code for running a COMBOOT image
;;

; Looks like a COMBOOT image but too large
comboot_too_large:
		mov si,err_comlarge
		call cwritestr
		jmp enter_command

;
; Load a COMBOOT image.  A COMBOOT image is basically a DOS .COM file,
; except that it may, of course, not contain any DOS system calls.  We
; do, however, allow the execution of INT 20h to return to SYSLINUX.
;
is_comboot_image:
		and dx,dx
		jnz comboot_too_large
		cmp ax,0ff00h		; Max size in bytes
		jae comboot_too_large

		call comboot_setup_api

		mov cx,comboot_seg
		mov es,cx

		mov bx,100h		; Load at <seg>:0100h

		mov cx,[ClustPerMoby]	; Absolute maximum # of clusters
		call getfssec

		xor di,di
		mov cx,64		; 256 bytes (size of PSP)
		xor eax,eax		; Clear PSP
		rep stosd

		mov word [es:0], 020CDh	; INT 20h instruction
		; First non-free paragraph
		mov word [es:02h], comboot_seg+1000h

		; Copy the command line from high memory
		mov cx,125		; Max cmdline len (minus space and CR)
		mov si,[CmdOptPtr]
		mov di,081h		; Offset in PSP for command line
		mov al,' '		; DOS command lines begin with a space
		stosb

comboot_cmd_cp:	lodsb
		and al,al
		jz comboot_end_cmd
		stosb
		loop comboot_cmd_cp
comboot_end_cmd: mov al,0Dh		; CR after last character
		stosb
		mov al,126		; Include space but not CR
		sub al,cl
		mov [es:80h], al	; Store command line length

		mov [SavedSSSP],sp
		mov [SavedSSSP+2],ss	; Save away SS:SP

		mov ax,es
		mov ds,ax
		mov ss,ax
		xor sp,sp
		push word 0		; Return to address 0 -> exit

		jmp comboot_seg:100h	; Run it

; Proper return vector
comboot_return:	cli			; Don't trust anyone
		xor ax,ax
		jmp comboot_exit

;
; Set up the COMBOOT API interrupt vectors.  This is also used
; by the COM32 code.
;
comboot_setup_api:
		mov di,4*0x20		; DOS interrupt vectors
		mov eax,comboot_return	; INT 20h = exit
		stosd
		mov ax,comboot_int21	; INT 21h = DOS-compatible syscalls
		stosd
		mov ax,comboot_int22	; INT 22h = proprietary syscalls
		stosd
		mov ax,comboot_bogus
		mov cx,29		; All remaining DOS vectors
		rep stosd
		ret

; INT 21h: generic DOS system call
comboot_int21:	push ds
		push cs
		pop ds			; Set DS <- CS
		and ah,ah		; 00 = return
		je comboot_return
		cmp ah,02h
		jb comboot_getkeyecho	; 01 = get key with echo
		je comboot_writechr	; 02 = writechr
		cmp ah,08h		; 08 = get key w/o echo
		je comboot_getkey
		cmp ah,09h		; 09 = writestr
		je comboot_writestr
		cmp ah,0Bh		; 0B = check keyboard
		je comboot_checkkey
		cmp ah,30h		; 30 = check version
		je comboot_checkver
		cmp ah,4Ch		; 4C = return with status
		je comboot_return

		; Otherwise fall through to comboot_bogus

; Attempted to execute non-21h DOS system call
comboot_bogus:	cli			; Don't trust anyone
		mov ax,err_notdos
;
; Generic COMBOOT return to command line code
;  AX -> message (if any)
;  BX -> where to go next
;
comboot_exit:
		mov bx,enter_command	; Normal return to command prompt
comboot_exit_special:
		xor dx,dx
		mov ds,dx
		mov es,dx
		lss sp,[SavedSSSP]
		sti
		cld
		and ax,ax
		je .nomsg
		mov si,KernelCName
		call cwritestr
		xchg si,ax
		call cwritestr
.nomsg:		jmp bx

;
; INT 21h system calls
;
comboot_getkeyecho:			; 01 = get key with echo
		call vgashowcursor
		call getchar
		call vgahidecursor
		call writechr
		jmp comboot_resume_ok

comboot_writechr:			; 02 = writechr
		xchg ax,dx
		call writechr
		xchg ax,dx
		jmp comboot_resume_ok

comboot_getkey:				; 08 = get key w/o echo
		call vgashowcursor
		call getchar
		call vgahidecursor
		jmp comboot_resume_ok

comboot_writestr:			; 09 = write string
		pusha
		push es
		mov bp,sp
		mov es,[bp-20]		; Old DS
		mov si,dx
.loop:		es lodsb
		cmp al,'$'		; End string with $ - bizarre
		je .done
		call writechr
		jmp short .loop
.done:		pop es
		popa
		jmp comboot_resume_ok

comboot_checkkey:			; 0B = check keyboard status
		call pollchar
		setz al
		dec al			; AL = 0FFh if present, 0 if not
		jmp comboot_resume_ok

comboot_checkver:			; 30 = check DOS version
		; We return 0 in all DOS-compatible version registers,
		; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
		mov eax,'SY' << 16
		mov ebx,'SL' << 16
		mov ecx,'IN' << 16
		mov edx,'UX' << 16
		;jmp comboot_resume_ok

;
; Resume comboot execution
;
comboot_resume_ok:
		clc
comboot_resume:
		pop ds
		iret

comboot_apierr:
		stc
		jmp comboot_resume

;
; INT 22h - SYSLINUX-specific system calls
;           System call number in ax
;
comboot_int22:
		push ds
		push cs
		pop ds

		cmp ax,int22_count
		jae comboot_apierr

		xchg ax,bx
		add bx,bx
		call [bx+int22_table]
		jmp comboot_resume		; On return

;
; INT 22h AX=0000h	Null system call
; INT 22h AX=0001h	Get SYSLINUX version
;
comapi_get_version:
		; Number of API functions supported
		mov ax,int22_count
		; SYSLINUX version
		mov cx,(VER_MAJOR << 8)+VER_MINOR
		; SYSLINUX derivative ID byte
		mov dx,my_id
		; For future use
		xor bx,bx

		push cs
		pop es
		; ES:SI -> version banner
		mov si,syslinux_banner
		; ES:DI -> copyright string
		mov di,copyright_str

comapi_nop:
		clc
		ret

;
; INT 22h AX=0002h	Write string
;
; Write null-terminated string in ES:BX
;
comapi_writestr:
		push es
		pop ds
		mov si,ax
		jmp writestr			; Write string from ES:BX

;
; INT 22h AX=0003h	Run command
;
; Terminates the COMBOOT program and executes the command line in
; ES:BX as if it had been entered by the user.
;
comapi_run:
		push es
		push ds
		pop es
		pop ds
		mov si,ax
		mov di,command_line
.copyloop:
		lodsb
		stosb
		and al,al
		jnz .copyloop
		xor ax,ax
		mov bx,load_kernel		; Run a new kernel
		jmp comboot_exit_special	; Terminate task, clean up

;
; INT 22h AX=0004h	Run default command		
;
; Terminates the COMBOOT program and executes the default command line
; as if a timeout had happened or the user pressed <Enter>.
;
comapi_run_default:
		mov bx,auto_boot
		jmp comboot_exit_special

;
; INT 22h AX=0005h	Force text mode
;
; Puts the video in standard text mode
;
comapi_textmode:
		call vgaclearmode
		clc
		ret

;
; INT 22h AX=0006h	Open file
;
comapi_open:
		push ds
		push ds
		push es
		pop ds
		pop es
		mov di,InitRD
		push di
		call mangle_name
		pop di
		pop ds
		call searchdir
		jz .err
		xchg eax,edx
		shr eax,16
		xchg ax,dx
		mov cx,[ClustSize]
		clc
		ret
.err:
		stc
		ret


;
; INT 22h AX=0007h	Read file
;
comapi_read:
		xchg ax,bx
		call getfssec
		jnc .noteof
		xor si,si		; SI <- 0 on EOF, CF <- 0
.noteof:	ret

;
; INT 22h AX=0008h	Close file
;
comapi_close:
		; Do nothing for now.  Eventually implement
		; an internal API for this.
		clc
		ret

;
; INT 22h AX=0009h	Call PXE stack
;
%if IS_PXELINUX
		call far [PXENVEntry]
		clc
		ret
%else
		stc				; Function not available
		ret
%endif

		align 2, db 0
int22_table:
		dw comapi_nop			; 0000 null syscall
		dw comapi_get_version		; 0001 get SYSLINUX version
		dw comapi_writestr		; 0002 write string
		dw comapi_run			; 0003 run specified command
		dw comapi_run_default		; 0004 run default command
		dw comapi_textmode		; 0005 force text mode
		dw comapi_open			; 0006 open file
		dw comapi_read			; 0007 read file
		dw comapi_close			; 0008 close file
		dw comapi_pxecall		; 0009 call PXE stack
int22_count	equ ($-int22_table)/2