Merge branch 'syslinux-3.7x'
[profile/ivi/syslinux.git] / core / comboot.inc
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
4 ;;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
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 ;;   Boston 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                 section .text
21
22 ; Parameter registers definition; this is the definition
23 ; of the stack frame used by INT 21h and INT 22h.
24 %define         P_FLAGS         word [bp+44]
25 %define         P_FLAGSL        byte [bp+44]
26 %define         P_FLAGSH        byte [bp+45]
27 %define         P_CS            word [bp+42]
28 %define         P_IP            word [bp+40]
29 %define         P_CSIP          dword [bp+40]
30 %define         P_DS            word [bp+38]
31 %define         P_ES            word [bp+36]
32 %define         P_FS            word [bp+34]
33 %define         P_GS            word [bp+32]
34 %define         P_EAX           dword [bp+28]
35 %define         P_AX            word [bp+28]
36 %define         P_HAX           word [bp+30]
37 %define         P_AL            byte [bp+28]
38 %define         P_AH            byte [bp+29]
39 %define         P_ECX           dword [bp+24]
40 %define         P_CX            word [bp+24]
41 %define         P_HCX           word [bp+26]
42 %define         P_CL            byte [bp+24]
43 %define         P_CH            byte [bp+25]
44 %define         P_EDX           dword [bp+20]
45 %define         P_DX            word [bp+20]
46 %define         P_HDX           word [bp+22]
47 %define         P_DL            byte [bp+20]
48 %define         P_DH            byte [bp+21]
49 %define         P_EBX           dword [bp+16]
50 %define         P_BX            word [bp+16]
51 %define         P_HBX           word [bp+18]
52 %define         P_BL            byte [bp+16]
53 %define         P_BH            byte [bp+17]
54 %define         P_EBP           dword [bp+8]
55 %define         P_BP            word [bp+8]
56 %define         P_HBP           word [bp+10]
57 %define         P_ESI           dword [bp+4]
58 %define         P_SI            word [bp+4]
59 %define         P_HSI           word [bp+6]
60 %define         P_EDI           dword [bp]
61 %define         P_DI            word [bp]
62 %define         P_HDI           word [bp+2]
63
64 ; Looks like a COMBOOT image but too large
65 comboot_too_large:
66                 call close_file
67                 mov si,err_comlarge
68                 call writestr
69                 jmp enter_command
70
71 ;
72 ; Load a COMBOOT image.  A COMBOOT image is basically a DOS .COM file,
73 ; except that it may, of course, not contain any DOS system calls.  We
74 ; do, however, allow the execution of INT 20h to return to SYSLINUX.
75 ;
76 is_comboot_image:
77                 push si                 ; Save file handle
78
79                 call make_plain_cmdline
80
81                 call comboot_setup_api
82
83                 mov cx,comboot_seg
84                 mov es,cx
85
86                 xor di,di
87                 mov cx,64               ; 256 bytes (size of PSP)
88                 xor eax,eax             ; Clear PSP
89                 rep stosd
90
91                 mov word [es:0], 020CDh ; INT 20h instruction
92                 ; First non-free paragraph
93                 ; This is valid because comboot_seg == real_mode_seg
94                 ; == the highest segment used by all derivatives
95                 int 12h                 ; Get DOS memory size
96                 shl ax,6                ; Kilobytes -> paragraphs
97                 mov word [es:02h],ax
98
99 %ifndef DEPEND
100 %if real_mode_seg != comboot_seg
101 %error "This code assumes real_mode_seg == comboot_seg"
102 %endif
103 %endif
104                 ; Copy the command line from high memory
105                 mov si,cmd_line_here
106                 mov cx,125              ; Max cmdline len (minus space and CR)
107                 mov di,081h             ; Offset in PSP for command line
108                 mov al,' '              ; DOS command lines begin with a space
109                 stosb
110
111 .loop:          es lodsb
112                 and al,al
113                 jz .done
114                 stosb
115                 loop .loop
116 .done:
117
118                 mov al,0Dh              ; CR after last character
119                 stosb
120                 mov ax,di
121                 sub al,82h              ; Include space but not CR
122                 mov [es:80h],al         ; Store command line length
123
124                 ; Now actually load the file...
125                 pop si                  ; File handle
126                 mov bx,100h             ; Load at <seg>:0100h
127                 mov cx,10000h >> SECTOR_SHIFT
128                                         ; Absolute maximum # of sectors
129                 call getfssec
130                 cmp ecx,65536-256-2     ; Maximum size
131                 ja comboot_too_large
132
133                 ; And invoke the program...
134                 mov ax,es
135                 mov ds,ax
136                 mov ss,ax
137                 xor sp,sp
138                 push word 0             ; Return to address 0 -> exit
139
140                 jmp comboot_seg:100h    ; Run it
141
142 ; Proper return vector
143 ; Note: this gets invoked both via INT 21h and directly via INT 20h.
144 ; We don't need to cld explicitly here, because comboot_exit does that
145 ; when invoking RESET_STACK_AND_SEGS.
146 comboot_return: cli                     ; Don't trust anyone
147                 push enter_command      ; Normal return to command prompt
148                 jmp comboot_exit
149
150 ;
151 ; Set up the COMBOOT API interrupt vectors.  This is also used
152 ; by the COM32 code.
153 ;
154 comboot_setup_api:
155                 mov di,DOSErrTramp      ; Error trampolines
156                 mov cx,32
157                 push cx
158                 mov eax,02EB206Ah       ; push 20h; jmp $+4
159 .loop1:         stosd
160                 inc ah
161                 loop .loop1
162                 dec di
163                 mov byte [di-1],0E9h
164                 mov ax,comboot_bogus-2
165                 sub ax,di
166                 stosw
167
168                 pop cx                  ; CX <- 32
169                 mov si,4*20h            ; DOS interrupt vectors
170                 mov bx,comboot_vectors
171                 mov di,DOSSaveVectors
172 .loop2:
173                 movsd
174                 movzx eax,word [bx]
175                 inc bx
176                 inc bx
177                 mov [si-4],eax
178                 loop .loop2
179                 ret
180
181                 section .bss
182                 alignb 4
183 DOSSaveVectors  resd 32
184
185                 section .data
186 %define comboot_err(x) (DOSErrTramp+4*((x)-20h))
187
188 comboot_vectors:
189                 dw comboot_return       ; INT 20 = exit
190                 dw comboot_int21        ; INT 21 = DOS-compatible system calls
191                 dw comboot_int22        ; INT 22 = native system calls
192                 dw comboot_err(23h)     ; INT 23 = DOS Ctrl-C handler
193                 dw comboot_err(24h)     ; INT 24 = DOS critical error handler
194                 dw comboot_err(25h)     ; INT 25 = DOS absolute disk read
195                 dw comboot_err(26h)     ; INT 26 = DOS absolute disk write
196                 dw comboot_err(27h)     ; INT 27 = DOS TSR
197                 dw comboot_int28        ; INT 28 = DOS idle interrupt
198                 dw comboot_int29        ; INT 29 = DOS fast console output
199                 dw comboot_err(2Ah)     ; INT 2A = DOS network API (NetBIOS)
200                 dw comboot_err(2Bh)     ; INT 2B = DOS reserved
201                 dw comboot_err(2Ch)     ; INT 2C = DOS reserved
202                 dw comboot_iret         ; INT 2D = DOS reserved, AMIS
203                 dw comboot_err(2Eh)     ; INT 2E = DOS run command
204                 dw comboot_iret         ; INT 2F = DOS multiplex interrupt
205                 dw comboot_err(30h)     ; INT 30 = DOS CP/M system calls
206                 dw comboot_err(31h)     ; INT 31 = DPMI
207                 dw comboot_err(32h)     ; INT 32 = DOS reserved
208                 dw comboot_iret         ; INT 33 = DOS mouse API
209                 dw comboot_err(34h)     ; INT 34 = DOS FPU emulation
210                 dw comboot_err(35h)     ; INT 35 = DOS FPU emulation
211                 dw comboot_err(36h)     ; INT 36 = DOS FPU emulation
212                 dw comboot_err(37h)     ; INT 37 = DOS FPU emulation
213                 dw comboot_err(38h)     ; INT 38 = DOS FPU emulation
214                 dw comboot_err(39h)     ; INT 39 = DOS FPU emulation
215                 dw comboot_err(3Ah)     ; INT 3A = DOS FPU emulation
216                 dw comboot_err(3Bh)     ; INT 3B = DOS FPU emulation
217                 dw comboot_err(3Ch)     ; INT 3C = DOS FPU emulation
218                 dw comboot_err(3Dh)     ; INT 3D = DOS FPU emulation
219                 dw comboot_err(3Eh)     ; INT 3E = DOS FPU emulation
220                 dw comboot_err(3Fh)     ; INT 3F = DOS overlay manager
221
222                 section .text
223
224 ; INT 21h: generic DOS system call
225 comboot_int21:  cli
226                 push ds
227                 push es
228                 push fs
229                 push gs
230                 pushad
231                 cld
232                 mov bp,cs
233                 mov ds,bp
234                 mov es,bp
235                 mov bp,sp                       ; Set up stack frame
236
237                 call adjust_screen              ; The COMBOOT program might have changed the screen
238
239                 mov cx,int21_count
240                 mov si,int21_table
241 .again:         lodsb
242                 cmp al,P_AH
243                 lodsw
244                 loopne .again
245                 ; The last function in the list is the
246                 ; "no such function" function
247                 clc
248                 call ax                 ; Call the invoked function
249 comboot_resume:
250                 mov bp,sp               ; In case the function clobbers BP
251                 setc P_FLAGSL           ; Propagate CF->error
252                 popad
253                 pop gs
254                 pop fs
255                 pop es
256                 pop ds
257 comboot_iret:
258                 iret
259
260 comboot_bad_int21:
261                 mov ax,P_AX
262                 push P_CSIP
263                 push 21h
264                 ; Fall through
265
266 ; Attempted to execute invalid DOS system call
267 ; The interrupt number is on the stack.
268 comboot_bogus:  cli                     ; Don't trust anyone
269                 pop dx                  ; Interrupt number
270                 pop edi                 ; CS:IP
271                 mov cx,err_notdos
272                 push comboot_bogus_tail
273                 jmp comboot_exit_msg
274 comboot_bogus_tail:
275                 xchg ax,dx
276                 call writehex2          ; Interrupt number
277                 mov al,' '
278                 call writechr
279                 xchg ax,dx
280                 call writehex4          ; Function number (AX)
281                 mov al,' '
282                 call writechr
283                 mov eax,edi
284                 call writehex8          ; CS:IP of the origin
285                 call crlf
286                 jmp enter_command
287
288 ;
289 ; Generic COMBOOT return to command line code
290 ;  stack -> where to go next
291 ;     CX -> message (for _msg version)
292 ;
293 comboot_exit:
294                 xor cx,cx
295 comboot_exit_msg:
296                 pop bx                  ; Return address
297                 RESET_STACK_AND_SEGS SI ; Contains cld
298                 call adjust_screen      ; The COMBOOT program might have changed the screen
299                 pusha
300                 mov si,DOSSaveVectors
301                 mov di,4*20h
302                 mov cx,20h
303                 rep movsd               ; Restore DOS-range vectors
304                 popa
305                 jcxz .nomsg
306                 mov si,KernelCName
307                 call writestr
308                 mov si,cx
309                 call writestr
310 .nomsg:
311                 jmp bx
312
313 ;
314 ; INT 21h system calls
315 ;
316 comboot_getkey:                         ; 01 = get key with echo
317                 call vgashowcursor
318                 call comboot_getchar
319                 call vgahidecursor
320                 call writechr
321                 clc
322                 ret
323
324 comboot_writechr:                       ; 02 = writechr
325                 mov al,P_DL
326                 call writechr
327                 clc
328                 ret
329
330 comboot_writeserial:                    ; 04 = write serial port
331                 mov al,P_DL
332                 call write_serial
333                 clc
334                 ret
335
336 comboot_getkeynoecho:                   ; 08 = get key w/o echo
337                 call comboot_getchar
338                 clc
339                 ret
340
341 comboot_writestr:                       ; 09 = write DOS string
342                 mov es,P_DS
343                 mov si,P_DX
344 .loop:          es lodsb
345                 cmp al,'$'              ; End string with $ - bizarre
346                 je .done
347                 call writechr
348                 jmp short .loop
349 .done:          clc
350                 ret
351
352 comboot_checkkey:                       ; 0B = check keyboard status
353                 cmp byte [APIKeyFlag],00h
354                 jnz .waiting
355                 call pollchar
356 .waiting:       setz al
357                 dec al                  ; AL = 0FFh if present, 0 if not
358                 mov P_AL,al
359                 clc
360                 ret
361
362 comboot_checkver:                       ; 30 = check DOS version
363                 ; We return 0 in all DOS-compatible version registers,
364                 ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
365                 mov P_EAX,'SY' << 16
366                 mov P_EBX,'SL' << 16
367                 mov P_ECX,'IN' << 16
368                 mov P_EDX,'UX' << 16
369                 ret
370
371 comboot_getchar:
372                 cmp byte [APIKeyFlag],00h
373                 jne .queued
374                 call getchar            ; If not queued get input
375                 and al,al               ; Function key?  (CF <- 0)
376                 jnz .done
377                 mov [APIKeyWait],ah     ; High part of key
378                 inc byte [APIKeyFlag]   ; Set flag
379 .done:          mov P_AL,al
380                 ret
381 .queued:        mov al,[APIKeyWait]
382                 dec byte [APIKeyFlag]
383                 jmp .done
384
385 ;
386 ; INT 28h - DOS idle
387 ;
388 %ifdef HAVE_IDLE
389 comboot_int28:
390                 cli
391                 cld
392                 pushad
393                 xor ax,ax
394                 push ds
395                 push es
396                 mov ds,ax
397                 mov es,ax
398                 DO_IDLE
399                 pop es
400                 pop ds
401                 popad
402                 iret
403 %else
404 comboot_int28   equ comboot_iret
405 %endif
406
407 ;
408 ; INT 29h - DOS fast write character
409 ;
410 comboot_int29:
411                 cli
412                 cld
413                 call writechr                   ; Preserves registers!
414                 iret
415
416 ;
417 ; INT 22h - SYSLINUX-specific system calls
418 ;           System call number in ax
419 ;
420 comboot_int22:
421                 cli
422                 push ds
423                 push es
424                 push fs
425                 push gs
426                 pushad
427                 cld
428                 mov bp,cs
429                 mov ds,bp
430                 mov es,bp
431                 mov bp,sp                       ; Set up stack frame
432
433                 call adjust_screen              ; The COMBOOT program might have changed the screen
434
435                 cmp ax,int22_count
436                 jb .ok
437                 xor ax,ax                       ; Function 0 -> unimplemented
438 .ok:
439                 xchg ax,bx
440                 add bx,bx                       ; CF <- 0
441                 call [bx+int22_table]
442                 jmp comboot_resume              ; On return
443
444 ;
445 ; INT 22h AX=0000h      Unimplemented call
446 ;
447 comapi_err:
448                 stc
449                 ret
450
451 ;
452 ; INT 22h AX=0001h      Get SYSLINUX version
453 ;
454 comapi_get_version:
455                 ; Number of API functions supported
456                 mov P_AX,int22_count
457                 ; SYSLINUX version
458                 mov P_CX,(VERSION_MAJOR << 8)+VERSION_MINOR
459                 ; SYSLINUX derivative ID byte
460                 mov P_DX,my_id
461                 ; For future use
462                 mov P_BX,cs     ; cs == 0
463
464                 mov P_ES,ds
465                 ; ES:SI -> version banner
466                 mov P_SI,syslinux_banner
467                 ; ES:DI -> copyright string
468                 mov P_DI,copyright_str
469
470 comapi_nop:
471                 clc
472                 ret
473
474 ;
475 ; INT 22h AX=0002h      Write string
476 ;
477 ; Write null-terminated string in ES:BX
478 ;
479 comapi_writestr:
480                 mov ds,P_ES
481                 mov si,P_BX
482                 call writestr
483                 clc
484                 ret
485
486 ;
487 ; INT 22h AX=0003h      Run command
488 ;
489 ; Terminates the COMBOOT program and executes the command line in
490 ; ES:BX as if it had been entered by the user.
491 ;
492 comapi_run:
493                 mov ds,P_ES
494                 mov si,P_BX
495                 mov di,command_line
496                 call strcpy
497                 push load_kernel                ; Run a new kernel
498                 jmp comboot_exit                ; Terminate task, clean up
499
500 ;
501 ; INT 22h AX=0004h      Run default command
502 ;
503 ; Terminates the COMBOOT program and executes the default command line
504 ; as if a timeout had happened or the user pressed <Enter>.
505 ;
506 comapi_run_default:
507                 push auto_boot
508                 jmp comboot_exit
509
510 ;
511 ; INT 22h AX=0005h      Force text mode
512 ;
513 ; Puts the video in standard text mode
514 ;
515 comapi_textmode:
516                 call vgaclearmode
517                 clc
518                 ret
519
520 ;
521 ; INT 22h AX=0006h      Open file
522 ;
523 comapi_open:
524                 push ds
525                 mov ds,P_ES
526                 mov si,P_SI
527                 mov di,InitRD
528                 call mangle_name
529                 pop ds
530                 call searchdir
531                 jz comapi_err
532                 mov P_EAX,eax
533                 mov P_CX,SECTOR_SIZE
534                 mov P_SI,si
535                 clc
536                 ret
537
538 ;
539 ; INT 22h AX=0007h      Read file
540 ;
541 comapi_read:
542                 mov es,P_ES
543                 mov bx,P_BX
544                 mov si,P_SI
545                 mov cx,P_CX
546                 call getfssec
547                 jnc .noteof
548                 xor si,si               ; SI <- 0 on EOF, CF <- 0
549 .noteof:        mov P_SI,si
550                 mov P_ECX,ecx
551                 ret
552
553 ;
554 ; INT 22h AX=0008h      Close file
555 ;
556 comapi_close:
557                 mov si,P_SI
558                 call close_file
559                 clc
560                 ret
561
562 ;
563 ; INT 22h AX=0009h      Call PXE stack
564 ;
565 %if IS_PXELINUX
566 comapi_pxecall:
567                 mov bx,P_BX
568                 mov es,P_ES
569                 mov di,P_DI
570                 call pxenv
571                 mov ax,[PXEStatus]
572                 mov P_AX,ax
573                 ret
574 %else
575 comapi_pxecall  equ comapi_err                  ; Not available
576 %endif
577
578 ;
579 ; INT 22h AX=000Ah      Get Derivative-Specific Info
580 ;
581 comapi_derinfo:
582                 mov P_AL,my_id
583 %if IS_PXELINUX
584                 mov ax,[APIVer]
585                 mov P_DX,ax
586                 mov ax,[StrucPtr]
587                 mov P_BX,ax
588                 mov ax,[StrucPtr+2]
589                 mov P_ES,ax
590                 mov ax,[InitStack]
591                 mov P_SI,ax
592                 mov ax,[InitStack+2]
593                 mov P_FS,ax
594 %else
595                 ; Physical medium...
596
597                 mov P_CL,SECTOR_SHIFT
598                 mov al,[DriveNumber]
599                 mov P_DL,al
600                 mov P_FS,cs
601                 mov P_SI,OrigESDI
602 %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
603                 mov P_ES,cs
604                 mov P_BX,PartInfo
605 %elif IS_ISOLINUX
606                 mov P_ES,cs
607                 mov P_BX,spec_packet
608                 mov ax,[BIOSType]
609                 sub ax,bios_cdrom
610                 shr ax,2
611                 mov P_CH,al             ; Mode (el torito/cbios/ebios)
612 %endif
613 %endif
614                 clc
615                 ret
616
617 ;
618 ; INT 22h AX=000Bh      Get Serial Console Configuration
619 ;
620 comapi_serialcfg:
621                 mov ax,[SerialPort]
622                 mov P_DX,ax
623                 mov ax,[BaudDivisor]
624                 mov P_CX,ax
625                 mov ax,[FlowControl]
626                 or al,ah
627                 mov ah,[FlowIgnore]
628                 shr ah,4
629                 test byte [DisplayCon],01h
630                 jnz .normalconsole
631                 or ah,80h
632 .normalconsole:
633                 mov P_BX,ax
634                 clc
635                 ret
636
637 ;
638 ; INT 22h AX=000Ch      Perform final cleanup
639 ;
640 comapi_cleanup:
641 %if IS_PXELINUX
642                 ; Unload PXE if requested
643                 test dl,3
644                 setnz [KeepPXE]
645                 sub bp,sp               ; unload_pxe may move the stack around
646                 call unload_pxe
647                 add bp,sp               ; restore frame pointer...
648 %elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
649                 ; Restore original FDC table
650                 mov eax,[OrigFDCTabPtr]
651                 mov [fdctab],eax
652 %endif
653                 call cleanup_hardware
654                 clc
655                 ret
656
657 ;
658 ; INT 22h AX=000Dh      Clean up then replace bootstrap
659 ;
660 comapi_chainboot:
661                 call comapi_cleanup
662                 mov eax,P_EDI
663                 mov [trackbuf+4],eax            ; Copy from
664                 mov eax,P_ECX
665                 mov [trackbuf+8],eax            ; Total bytes
666                 mov eax,7C00h
667                 mov [trackbuf],eax              ; Copy to
668                 push eax                        ; Entry point on stack
669                 mov esi,P_ESI
670                 mov edx,P_EBX
671                 mov bx,P_DS
672                 jmp replace_bootstrap_one
673
674 ;
675 ; INT 22h AX=000Eh      Get configuration file name
676 ;
677 comapi_configfile:
678                 mov P_ES,cs
679                 mov P_BX,ConfigName
680                 clc
681                 ret
682
683 ;
684 ; INT 22h AX=000Fh      Get IPAPPEND strings
685 ;
686 comapi_ipappend:
687                 mov P_ES,cs
688                 mov P_CX,numIPAppends
689                 mov P_BX,IPAppends
690                 clc
691                 ret
692
693 ;
694 ; INT 22h AX=0010h      Resolve hostname
695 ;
696 %if IS_PXELINUX
697 comapi_dnsresolv:
698                 mov ds,P_ES
699                 mov si,P_BX
700                 call dns_resolv
701                 mov P_EAX,eax
702                 clc
703                 ret
704 %else
705 comapi_dnsresolv equ comapi_err
706 %endif
707
708                 section .text
709
710 ;
711 ; INT 22h AX=0011h      Obsolete
712 ;
713
714 ;
715 ; INT 22h AX=0012h      Obsolete
716 ;
717
718 ;
719 ; INT 22h AX=0013h      Idle call
720 ;
721 ;
722 ; *** FIX THIS ***
723 ; The idle call seems to have detrimental effects on some machines when
724 ; called from a COM32 context (WHY?) --  disable it for now.
725 ; *** IS THIS STILL TRUE? ***
726 ;
727 %ifdef HAVE_IDLE
728 comapi_idle:
729                 DO_IDLE
730                 clc
731                 ret
732
733 %else
734 comapi_idle     equ comapi_err
735 %endif
736
737 ;
738 ; INT 22h AX=0014h      Local boot
739 ;
740 %if HAS_LOCALBOOT
741 comapi_localboot:
742                 mov ax,P_DX
743                 jmp local_boot
744 %else
745 comapi_localboot equ comapi_err
746 %endif ; HAS_LOCALBOOT
747
748 ;
749 ; INT 22h AX=0015h      Feature flags
750 ;
751 comapi_features:
752                 mov P_ES,cs
753                 mov P_BX,feature_flags
754                 mov P_CX,feature_flags_len
755                 clc
756                 ret
757
758 ;
759 ; INT 22h AX=0016h      Run kernel image
760 ;
761 comapi_runkernel:
762                 mov al,P_DL
763                 cmp al,VK_TYPES-1
764                 ja .error
765                 mov [KernelType],al
766                 push ds
767                 mov ds,P_DS
768                 mov si,P_SI
769                 mov di,KernelName
770                 call mangle_name
771                 pop ds
772                 call searchdir
773                 jz comapi_err
774
775                 ; The kernel image was found, so we can load it...
776                 mov [Kernel_SI],si
777                 mov [Kernel_EAX],eax
778
779                 ; It's not just possible, but quite likely, that ES:BX
780                 ; points into real_mode_seg or xfer_buf_seg, so we
781                 ; need to exercise some special care here... use
782                 ; trackbuf as an intermediary
783                 push ds
784                 mov ds,P_ES
785                 mov si,P_BX
786                 mov di,trackbuf
787                 call strcpy
788                 pop ds
789
790 %if IS_PXELINUX
791                 mov al,P_CL
792                 mov [IPAppend],al
793 %endif
794
795                 call comboot_exit
796
797 .finish:
798                 ; Copy the command line into its proper place
799                 push es
800                 mov dx,real_mode_seg
801                 mov es,dx
802                 mov si,trackbuf
803                 mov di,cmd_line_here
804                 call strcpy
805                 mov byte [es:di-1],' '          ; Simulate APPEND
806                 pop es
807                 mov [CmdLinePtr],di
808                 mov word [CmdOptPtr],zero_string
809                 jmp kernel_good_saved
810
811 .error          equ comapi_usingvga.error
812
813 ;
814 ; INT 22h AX=0017h  Report video mode change
815 ;
816 comapi_usingvga:
817                 mov ax,P_BX
818                 cmp ax,0Fh              ; Unknown flags = failure
819                 ja .error
820                 mov [UsingVGA],al
821                 mov cx,P_CX
822                 mov dx,P_DX
823                 mov [GXPixCols],cx
824                 mov [GXPixRows],dx
825                 test al,08h
826                 jnz .notext
827                 call adjust_screen
828 .notext:
829                 clc
830                 ret
831 .error:
832                 stc
833                 ret
834
835 ;
836 ; INT 22h AX=0018h  Query custom font
837 ;
838 comapi_userfont:
839                 mov al,[UserFont]
840                 and al,al
841                 jz .done
842                 mov al,[VGAFontSize]
843                 mov P_ES,aux_seg
844                 mov P_BX,aux.fontbuf
845
846 .done:          ; CF=0 here
847                 mov P_AL,al
848                 ret
849
850 ;
851 ; INT 22h AX=0019h  Read disk
852 ;
853 %if IS_SYSLINUX || IS_MDSLINUX || IS_ISOLINUX || IS_EXTLINUX
854 comapi_readdisk:
855                 mov esi,P_ESI           ; Enforce ESI == EDI == 0, these
856                 or esi,P_EDI            ; are reserved for future expansion
857                 jnz .err
858                 mov eax,P_EDX
859                 mov es,P_ES
860                 mov bx,P_BX
861                 mov bp,P_CX             ; WE CANNOT use P_* after touching bp!
862                 call getlinsec
863                 clc
864                 ret
865 .err:
866                 stc
867                 ret
868 %else
869 comapi_readdisk equ comapi_err
870 %endif
871
872 ;
873 ; INT 22h AX=001Ah      Obsolete
874 ;
875
876 ;
877 ; INT 22h AX=001Bh      Obsolete
878 ;
879
880 ;
881 ; INT 22h AX=001Ch      Get pointer to auxillary data vector
882 ;
883 comapi_getadv:
884                 mov P_ES,ds
885                 mov P_BX,adv0.data
886                 mov P_CX,ADV_LEN
887                 ret
888
889 ;
890 ; INT 22h AX=001Dh      Write auxillary data vector
891 ;
892 comapi_writeadv equ adv_write
893
894 ;
895 ; INT 22h AX=001Eh      Keyboard remapping table
896 comapi_kbdtable:
897                 cmp P_DX,0
898                 jne .err
899                 mov P_AX,1                      ; Version
900                 mov P_CX,256                    ; Length
901                 mov P_ES,cs
902                 mov P_BX,KbdMap
903                 ret
904 .err:
905                 stc
906                 ret
907
908 ;
909 ; INT 22h AX=001Fh      Get current working directory
910 ;
911 comapi_getcwd:
912                 mov P_ES,cs
913                 mov P_BX,CurrentDirName
914                 clc
915                 ret
916
917 ;
918 ; INT 22h AX=0020h      Open directory
919 ;
920 %if IS_SYSLINUX
921 comapi_opendir:
922                 push ds
923                 mov ds,P_ES
924                 mov si,P_SI
925                 mov di,InitRD
926                 call mangle_name
927                 pop ds
928                 call searchdir
929                 jnz comapi_err  ; Didn't find a directory
930                 cmp eax,0
931                 jz comapi_err   ; Found nothing
932                         ;ZF is unset
933                 call alloc_fill_dir
934                 mov P_EAX,eax
935                 mov P_CX,SECTOR_SIZE
936                 mov P_SI,si
937                 clc
938                 ret
939 %else
940 comapi_opendir  equ comapi_err
941 %endif
942
943 ;
944 ; INT 22h AX=0021h      Read directory
945 ;
946 %if IS_SYSLINUX
947 comapi_readdir:
948                 mov es,P_ES
949                 mov di,P_DI
950                 mov si,P_SI
951                 call readdir
952                 mov P_EAX,eax
953                 mov P_DL,dl
954                 mov P_EBX,ebx
955                 mov P_SI,si
956                 ret
957 %else
958 comapi_readdir  equ comapi_err
959 %endif
960
961 ;
962 ; INT 22h AX=0022h      Close directory
963 ;
964 %if IS_SYSLINUX
965 comapi_closedir:
966                 mov si,P_SI
967                 call close_dir
968                 clc
969                 ret
970 %else
971 comapi_closedir equ comapi_err
972 %endif
973
974 ;
975 ; INT 22h AX=0023h      Query shuffler size
976 ;
977 comapi_shufsize:
978                 mov P_CX,bcopyxx_safe
979                 ret
980
981 ;
982 ; INT 22h AX=0024h      Cleanup, shuffle and boot raw
983 ;
984 comapi_shufraw:
985                 call comapi_cleanup
986                 mov edi,P_EDI
987                 mov esi,P_ESI
988                 mov ecx,P_ECX
989                 jmp shuffle_and_boot_raw
990
991                 section .data
992
993 %macro          int21 2
994                 db %1
995                 dw %2
996 %endmacro
997
998 int21_table:
999                 int21   00h, comboot_return
1000                 int21   01h, comboot_getkey
1001                 int21   02h, comboot_writechr
1002                 int21   04h, comboot_writeserial
1003                 int21   08h, comboot_getkeynoecho
1004                 int21   09h, comboot_writestr
1005                 int21   0Bh, comboot_checkkey
1006                 int21   30h, comboot_checkver
1007                 int21   4Ch, comboot_return
1008                 int21    -1, comboot_bad_int21
1009 int21_count     equ ($-int21_table)/3
1010
1011                 alignz 2
1012 int22_table:
1013                 dw comapi_err           ; 0000 unimplemented syscall
1014                 dw comapi_get_version   ; 0001 get SYSLINUX version
1015                 dw comapi_writestr      ; 0002 write string
1016                 dw comapi_run           ; 0003 run specified command
1017                 dw comapi_run_default   ; 0004 run default command
1018                 dw comapi_textmode      ; 0005 force text mode
1019                 dw comapi_open          ; 0006 open file
1020                 dw comapi_read          ; 0007 read file
1021                 dw comapi_close         ; 0008 close file
1022                 dw comapi_pxecall       ; 0009 call PXE stack
1023                 dw comapi_derinfo       ; 000A derivative-specific info
1024                 dw comapi_serialcfg     ; 000B get serial port config
1025                 dw comapi_cleanup       ; 000C perform final cleanup
1026                 dw comapi_err           ; 000D clean up then bootstrap
1027                 dw comapi_configfile    ; 000E get name of config file
1028                 dw comapi_ipappend      ; 000F get ipappend strings
1029                 dw comapi_dnsresolv     ; 0010 resolve hostname
1030                 dw comapi_err           ; 0011 maximum shuffle descriptors
1031                 dw comapi_err           ; 0012 cleanup, shuffle and boot
1032                 dw comapi_idle          ; 0013 idle call
1033                 dw comapi_localboot     ; 0014 local boot
1034                 dw comapi_features      ; 0015 feature flags
1035                 dw comapi_runkernel     ; 0016 run kernel image
1036                 dw comapi_usingvga      ; 0017 report video mode change
1037                 dw comapi_userfont      ; 0018 query custom font
1038                 dw comapi_readdisk      ; 0019 read disk
1039                 dw comapi_err           ; 001A cleanup, shuffle and boot to pm
1040                 dw comapi_err           ; 001B cleanup, shuffle and boot to rm
1041                 dw comapi_getadv        ; 001C get pointer to ADV
1042                 dw comapi_writeadv      ; 001D write ADV to disk
1043                 dw comapi_kbdtable      ; 001E keyboard remapping table
1044                 dw comapi_getcwd        ; 001F get current working directory
1045                 dw comapi_opendir       ; 0020 open directory
1046                 dw comapi_readdir       ; 0021 read directory
1047                 dw comapi_closedir      ; 0022 close directory
1048                 dw comapi_shufsize      ; 0023 query shuffler size
1049                 dw comapi_shufraw       ; 0024 cleanup, shuffle and boot raw
1050 int22_count     equ ($-int22_table)/2
1051
1052 APIKeyWait      db 0
1053 APIKeyFlag      db 0
1054
1055 zero_string     db 0                    ; Empty, null-terminated string
1056
1057 ;
1058 ; This is the feature flag array for INT 22h AX=0015h
1059 ;
1060 ; Note: PXELINUX clears the idle is noop flag if appropriate
1061 ; in pxe_detect_nic_type
1062 ;
1063 feature_flags:
1064                 db 3                    ; Have local boot, idle is noop
1065 feature_flags_len equ ($-feature_flags)
1066
1067 err_notdos      db ': attempted DOS system call INT ',0
1068 err_comlarge    db 'COMBOOT image too large.', CR, LF, 0
1069
1070                 section .bss1
1071                 alignb 4
1072 DOSErrTramp     resd    33              ; Error trampolines
1073 ConfigName      resb    FILENAME_MAX
1074 CurrentDirName  resb    FILENAME_MAX