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