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