PXELINUX: Enable idle calls on select platforms
[syslinux.git] / core / comboot.inc
blobb843372f9d8310bea1229fb9804b16231235e7be
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4 ;;
5 ;;   This program is free software; you can redistribute it and/or modify
6 ;;   it under the terms of the GNU General Public License as published by
7 ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;;   (at your option) any later version; incorporated herein by reference.
11 ;; -----------------------------------------------------------------------
14 ;; comboot.inc
16 ;; Common code for running a COMBOOT image
19                 section .text
21 ; Parameter registers definition; this is the definition
22 ; of the stack frame used by INT 21h and INT 22h.
23 %define         P_FLAGS         word [bp+44]
24 %define         P_FLAGSL        byte [bp+44]
25 %define         P_FLAGSH        byte [bp+45]
26 %define         P_CS            word [bp+42]
27 %define         P_IP            word [bp+40]
28 %define         P_DS            word [bp+38]
29 %define         P_ES            word [bp+36]
30 %define         P_FS            word [bp+34]
31 %define         P_GS            word [bp+32]
32 %define         P_EAX           dword [bp+28]
33 %define         P_AX            word [bp+28]
34 %define         P_HAX           word [bp+30]
35 %define         P_AL            byte [bp+28]
36 %define         P_AH            byte [bp+29]
37 %define         P_ECX           dword [bp+24]
38 %define         P_CX            word [bp+24]
39 %define         P_HCX           word [bp+26]
40 %define         P_CL            byte [bp+24]
41 %define         P_CH            byte [bp+25]
42 %define         P_EDX           dword [bp+20]
43 %define         P_DX            word [bp+20]
44 %define         P_HDX           word [bp+22]
45 %define         P_DL            byte [bp+20]
46 %define         P_DH            byte [bp+21]
47 %define         P_EBX           dword [bp+16]
48 %define         P_BX            word [bp+16]
49 %define         P_HBX           word [bp+18]
50 %define         P_BL            byte [bp+16]
51 %define         P_BH            byte [bp+17]
52 %define         P_EBP           dword [bp+8]
53 %define         P_BP            word [bp+8]
54 %define         P_HBP           word [bp+10]
55 %define         P_ESI           dword [bp+4]
56 %define         P_SI            word [bp+4]
57 %define         P_HSI           word [bp+6]
58 %define         P_EDI           dword [bp]
59 %define         P_DI            word [bp]
60 %define         P_HDI           word [bp+2]
62 ; Looks like a COMBOOT image but too large
63 comboot_too_large:
64                 call close_file
65                 mov si,err_comlarge
66                 call cwritestr
67                 jmp enter_command
70 ; Load a COMBOOT image.  A COMBOOT image is basically a DOS .COM file,
71 ; except that it may, of course, not contain any DOS system calls.  We
72 ; do, however, allow the execution of INT 20h to return to SYSLINUX.
74 is_comboot_image:
75                 push si                 ; Save file handle
77                 call make_plain_cmdline
79                 call comboot_setup_api
81                 mov cx,comboot_seg
82                 mov es,cx
84                 xor di,di
85                 mov cx,64               ; 256 bytes (size of PSP)
86                 xor eax,eax             ; Clear PSP
87                 rep stosd
89                 mov word [es:0], 020CDh ; INT 20h instruction
90                 ; First non-free paragraph
91                 ; This is valid because comboot_seg == real_mode_seg
92                 ; == the highest segment used by all derivatives
93                 int 12h                 ; Get DOS memory size
94                 shl ax,6                ; Kilobytes -> paragraphs
95                 mov word [es:02h],ax
97 %ifndef DEPEND
98 %if real_mode_seg != comboot_seg
99 %error "This code assumes real_mode_seg == comboot_seg"
100 %endif
101 %endif
102                 ; Copy the command line from high memory
103                 mov si,cmd_line_here
104                 mov cx,125              ; Max cmdline len (minus space and CR)
105                 mov di,081h             ; Offset in PSP for command line
106                 mov al,' '              ; DOS command lines begin with a space
107                 stosb
109 .loop:          es lodsb
110                 and al,al
111                 jz .done
112                 stosb
113                 loop .loop
114 .done:
116                 mov al,0Dh              ; CR after last character
117                 stosb
118                 mov ax,di
119                 sub al,82h              ; Include space but not CR
120                 mov [es:80h],al         ; Store command line length
122                 ; Now actually load the file...
123                 pop si                  ; File handle
124                 mov bx,100h             ; Load at <seg>:0100h
125                 mov cx,10000h >> SECTOR_SHIFT
126                                         ; Absolute maximum # of sectors
127                 call getfssec
128                 cmp ecx,65536-256-2     ; Maximum size
129                 ja comboot_too_large
131                 ; And invoke the program...
132                 mov ax,es
133                 mov ds,ax
134                 mov ss,ax
135                 xor sp,sp
136                 push word 0             ; Return to address 0 -> exit
138                 jmp comboot_seg:100h    ; Run it
140 ; Proper return vector
141 comboot_return: cli                     ; Don't trust anyone
142                 push enter_command      ; Normal return to command prompt
143                 jmp comboot_exit
146 ; Set up the COMBOOT API interrupt vectors.  This is also used
147 ; by the COM32 code.
149 comboot_setup_api:
150                 mov di,4*0x20           ; DOS interrupt vectors
151                 mov eax,comboot_return  ; INT 20h = exit
152                 stosd
153                 mov ax,comboot_int21    ; INT 21h = DOS-compatible syscalls
154                 stosd
155                 mov ax,comboot_int22    ; INT 22h = proprietary syscalls
156                 stosd
157                 mov ax,comboot_bogus
158                 mov cx,29               ; All remaining DOS vectors
159                 rep stosd
160                 ret
162 ; INT 21h: generic DOS system call
163 comboot_int21:  cli
164                 push ds
165                 push es
166                 push fs
167                 push gs
168                 pushad
169                 cld
170                 mov bp,cs
171                 mov ds,bp
172                 mov es,bp
173                 mov bp,sp                       ; Set up stack frame
175                 call adjust_screen              ; The COMBOOT program might have changed the screen
177                 mov cx,int21_count
178                 mov si,int21_table
179 .again:         lodsb
180                 cmp al,P_AH
181                 lodsw
182                 loopne .again
183                 ; The last function in the list is the
184                 ; "no such function" function
185                 clc
186                 call ax                 ; Call the invoked function
187 comboot_resume:
188                 mov bp,sp               ; In case the function clobbers BP
189                 setc P_FLAGSL           ; Propagate CF->error
190                 popad
191                 pop gs
192                 pop fs
193                 pop es
194                 pop ds
195                 iret
197 ; Attempted to execute non-21h DOS system call
198 comboot_bogus:  cli                     ; Don't trust anyone
199                 mov cx,err_notdos
200                 push enter_command
201                 jmp comboot_exit_msg
204 ; Generic COMBOOT return to command line code
205 ;  stack -> where to go next
206 ;     CX -> message (for _msg version)
208 comboot_exit:
209                 xor cx,cx
210 comboot_exit_msg:
211                 pop bx                  ; Return address
212                 RESET_STACK_AND_SEGS AX
213                 call adjust_screen      ; The COMBOOT program might have changed the screen
214                 jcxz .nomsg
215                 mov si,KernelCName
216                 call cwritestr
217                 mov si,cx
218                 call cwritestr
219 .nomsg:
220                 jmp bx
223 ; INT 21h system calls
225 comboot_getkey:                         ; 01 = get key with echo
226                 call vgashowcursor
227                 call comboot_getchar
228                 call vgahidecursor
229                 call writechr
230                 clc
231                 ret
233 comboot_writechr:                       ; 02 = writechr
234                 mov al,P_DL
235                 call writechr
236                 clc
237                 ret
239 comboot_writeserial:                    ; 04 = write serial port
240                 mov al,P_DL
241                 call write_serial
242                 clc
243                 ret
245 comboot_getkeynoecho:                   ; 08 = get key w/o echo
246                 call comboot_getchar
247                 clc
248                 ret
250 comboot_writestr:                       ; 09 = write DOS string
251                 mov es,P_DS
252                 mov si,P_DX
253 .loop:          es lodsb
254                 cmp al,'$'              ; End string with $ - bizarre
255                 je .done
256                 call writechr
257                 jmp short .loop
258 .done:          clc
259                 ret
261 comboot_checkkey:                       ; 0B = check keyboard status
262                 cmp byte [APIKeyFlag],00h
263                 jnz .waiting
264                 call pollchar
265 .waiting:       setz al
266                 dec al                  ; AL = 0FFh if present, 0 if not
267                 mov P_AL,al
268                 clc
269                 ret
271 comboot_checkver:                       ; 30 = check DOS version
272                 ; We return 0 in all DOS-compatible version registers,
273                 ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
274                 mov P_EAX,'SY' << 16
275                 mov P_EBX,'SL' << 16
276                 mov P_ECX,'IN' << 16
277                 mov P_EDX,'UX' << 16
278                 ret
280 comboot_getchar:
281                 cmp byte [APIKeyFlag],00h
282                 jne .queued
283                 call getchar            ; If not queued get input
284                 and al,al               ; Function key?  (CF <- 0)
285                 jnz .done
286                 mov [APIKeyWait],ah     ; High part of key
287                 inc byte [APIKeyFlag]   ; Set flag
288 .done:          mov P_AL,al
289                 ret
290 .queued:        mov al,[APIKeyWait]
291                 dec byte [APIKeyFlag]
292                 jmp .done
295 ; INT 22h - SYSLINUX-specific system calls
296 ;           System call number in ax
298 comboot_int22:
299                 cli
300                 push ds
301                 push es
302                 push fs
303                 push gs
304                 pushad
305                 cld
306                 mov bp,cs
307                 mov ds,bp
308                 mov es,bp
309                 mov bp,sp                       ; Set up stack frame
311                 call adjust_screen              ; The COMBOOT program might have changed the screen
313                 cmp ax,int22_count
314                 jb .ok
315                 xor ax,ax                       ; Function 0 -> unimplemented
316 .ok:
317                 xchg ax,bx
318                 add bx,bx                       ; CF <- 0
319                 call [bx+int22_table]
320                 jmp comboot_resume              ; On return
323 ; INT 22h AX=0000h      Unimplemented call
325 comapi_err:
326                 stc
327                 ret
330 ; INT 22h AX=0001h      Get SYSLINUX version
332 comapi_get_version:
333                 ; Number of API functions supported
334                 mov P_AX,int22_count
335                 ; SYSLINUX version
336                 mov P_CX,(VER_MAJOR << 8)+VER_MINOR
337                 ; SYSLINUX derivative ID byte
338                 mov P_DX,my_id
339                 ; For future use
340                 mov P_BX,cs     ; cs == 0
342                 mov P_ES,ds
343                 ; ES:SI -> version banner
344                 mov P_SI,syslinux_banner
345                 ; ES:DI -> copyright string
346                 mov P_DI,copyright_str
348 comapi_nop:
349                 clc
350                 ret
353 ; INT 22h AX=0002h      Write string
355 ; Write null-terminated string in ES:BX
357 comapi_writestr:
358                 mov ds,P_ES
359                 mov si,P_BX
360                 call writestr
361                 clc
362                 ret
365 ; INT 22h AX=0003h      Run command
367 ; Terminates the COMBOOT program and executes the command line in
368 ; ES:BX as if it had been entered by the user.
370 comapi_run:
371                 mov ds,P_ES
372                 mov si,P_BX
373                 mov di,command_line
374                 call strcpy
375                 push load_kernel                ; Run a new kernel
376                 jmp comboot_exit                ; Terminate task, clean up
379 ; INT 22h AX=0004h      Run default command
381 ; Terminates the COMBOOT program and executes the default command line
382 ; as if a timeout had happened or the user pressed <Enter>.
384 comapi_run_default:
385                 push auto_boot
386                 jmp comboot_exit
389 ; INT 22h AX=0005h      Force text mode
391 ; Puts the video in standard text mode
393 comapi_textmode:
394                 call vgaclearmode
395                 clc
396                 ret
399 ; INT 22h AX=0006h      Open file
401 comapi_open:
402                 push ds
403                 mov ds,P_ES
404                 mov si,P_SI
405                 mov di,InitRD
406                 call mangle_name
407                 pop ds
408                 call searchdir
409                 jz comapi_err
410                 mov P_EAX,eax
411                 mov P_CX,SECTOR_SIZE
412                 mov P_SI,si
413                 clc
414                 ret
417 ; INT 22h AX=0007h      Read file
419 comapi_read:
420                 mov es,P_ES
421                 mov bx,P_BX
422                 mov si,P_SI
423                 mov cx,P_CX
424                 call getfssec
425                 jnc .noteof
426                 xor si,si               ; SI <- 0 on EOF, CF <- 0
427 .noteof:        mov P_SI,si
428                 mov P_ECX,ecx
429                 ret
432 ; INT 22h AX=0008h      Close file
434 comapi_close:
435                 mov si,P_SI
436                 call close_file
437                 clc
438                 ret
441 ; INT 22h AX=0009h      Call PXE stack
443 %if IS_PXELINUX
444 comapi_pxecall:
445                 mov bx,P_BX
446                 mov es,P_ES
447                 mov di,P_DI
448                 call pxenv
449                 mov ax,[PXEStatus]
450                 mov P_AX,ax
451                 ret
452 %else
453 comapi_pxecall  equ comapi_err                  ; Not available
454 %endif
457 ; INT 22h AX=000Ah      Get Derivative-Specific Info
459 comapi_derinfo:
460                 mov P_AL,my_id
461 %if IS_PXELINUX
462                 mov ax,[APIVer]
463                 mov P_DX,ax
464                 mov ax,[StrucPtr]
465                 mov P_BX,ax
466                 mov ax,[StrucPtr+2]
467                 mov P_ES,ax
468                 mov ax,[InitStack]
469                 mov P_SI,ax
470                 mov ax,[InitStack+2]
471                 mov P_FS,ax
472 %else
473                 ; Physical medium...
475                 mov P_CL,SECTOR_SHIFT
476                 mov al,[DriveNumber]
477                 mov P_DL,al
478                 mov P_FS,cs
479                 mov P_SI,OrigESDI
480 %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
481                 mov P_ES,cs
482                 mov P_BX,PartInfo
483 %elif IS_ISOLINUX
484                 mov P_ES,cs
485                 mov P_BX,spec_packet
486 %endif
487 %endif
488                 clc
489                 ret
492 ; INT 22h AX=000Bh      Get Serial Console Configuration
494 comapi_serialcfg:
495                 mov ax,[SerialPort]
496                 mov P_DX,ax
497                 mov ax,[BaudDivisor]
498                 mov P_CX,ax
499                 mov ax,[FlowControl]
500                 or al,ah
501                 mov ah,[FlowIgnore]
502                 shr ah,4
503                 test byte [DisplayCon],01h
504                 jnz .normalconsole
505                 or ah,80h
506 .normalconsole:
507                 mov P_BX,ax
508                 clc
509                 ret
512 ; INT 22h AX=000Ch      Perform final cleanup
514 comapi_cleanup:
515 %if IS_PXELINUX
516                 ; Unload PXE if requested
517                 test dl,3
518                 setnz [KeepPXE]
519                 sub bp,sp               ; unload_pxe may move the stack around
520                 call unload_pxe
521                 add bp,sp               ; restore frame pointer...
522 %elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
523                 ; Restore original FDC table
524                 mov eax,[OrigFDCTabPtr]
525                 mov [fdctab],eax
526 %endif
527                 ; Reset the floppy disk subsystem
528                 xor ax,ax
529                 xor dx,dx
530                 int 13h
531                 clc
532                 ret
535 ; INT 22h AX=000Dh      Clean up then replace bootstrap
537 comapi_chainboot:
538                 call comapi_cleanup
539                 mov eax,P_EDI
540                 mov [trackbuf+4],eax            ; Copy from
541                 mov eax,P_ECX
542                 mov [trackbuf+8],eax            ; Total bytes
543                 mov eax,7C00h
544                 mov [trackbuf],eax              ; Copy to
545                 mov [EntryPoint],eax            ; CS:IP entry point
546                 mov esi,P_ESI
547                 mov edx,P_EBX
548                 mov bx,P_DS
549                 jmp replace_bootstrap_one
553 ; INT 22h AX=000Eh      Get configuration file name
555 comapi_configfile:
556                 mov P_ES,cs
557                 mov P_BX,ConfigName
558                 clc
559                 ret
562 ; INT 22h AX=000Fh      Get IPAPPEND strings
564 %if IS_PXELINUX
565 comapi_ipappend:
566                 mov P_ES,cs
567                 mov P_CX,numIPAppends
568                 mov P_BX,IPAppends
569                 clc
570                 ret
572                 section .data
573                 alignb 2, db 0
574 IPAppends       dw IPOption
575                 dw BOOTIFStr
576 numIPAppends    equ ($-IPAppends)/2
578 %else
579 comapi_ipappend equ comapi_err
580 %endif
582                 section .text
585 ; INT 22h AX=0010h      Resolve hostname
587 %if IS_PXELINUX
588 comapi_dnsresolv:
589                 mov ds,P_ES
590                 mov si,P_BX
591                 call dns_resolv
592                 mov P_EAX,eax
593                 clc
594                 ret
595 %else
596 comapi_dnsresolv equ comapi_err
597 %endif
599                 section .text
602 ; INT 22h AX=0011h      Maximum number of shuffle descriptors
604 comapi_maxshuffle:
605                 mov P_CX,trackbufsize/12
606                 ret
609 ; INT 22h AX=0012h      Cleanup, shuffle and boot
611 comapi_shuffle:
612                 cmp P_CX,(2*trackbufsize)/12
613                 ja .error
615                 call comapi_cleanup
617                 mov cx, P_CX
618                 push cx                         ; On stack: descriptor count
620                 lea cx,[ecx+ecx*2]              ; CX *= 3
622                 mov fs,P_ES
623                 mov si,P_DI
624                 mov di,trackbuf
625                 push di                         ; On stack: descriptor list address
626                 fs rep movsd                    ; Copy the list
628                 mov eax,P_EBP
629                 mov [EntryPoint],eax            ; CS:IP entry point
630                 mov esi,P_ESI
631                 mov edx,P_EBX
632                 mov bx,P_DS
633                 jmp replace_bootstrap
634 .error:
635                 stc
636                 ret
639 ; INT 22h AX=0013h      Idle call
642 ; *** FIX THIS ***
643 ; The idle call seems to have detrimental effects on some machines when
644 ; called from a COM32 context (WHY?) --  disable it for now.
646 %if 0 ; def HAVE_IDLE
648 comapi_idle:
649                 DO_IDLE
650                 clc
651                 ret
653 %else
655 comapi_idle     equ comapi_err
657 %endif
660 ; INT 22h AX=0014h      Local boot
662 %if HAS_LOCALBOOT
663 comapi_localboot:
664                 mov ax,P_DX
665                 jmp local_boot
666 %else
667 comapi_localboot equ comapi_err
668 %endif ; HAS_LOCALBOOT
671 ; INT 22h AX=0015h      Feature flags
673 comapi_features:
674                 mov P_ES,cs
675                 mov P_BX,feature_flags
676                 mov P_CX,feature_flags_len
677                 clc
678                 ret
681 ; INT 22h AX=0016h      Run kernel image
683 comapi_runkernel:
684                 mov al,P_DL
685                 cmp al,VK_TYPES-1
686                 ja .error
687                 mov [KernelType],al
688                 push ds
689                 mov ds,P_DS
690                 mov si,P_SI
691                 mov di,KernelName
692                 call mangle_name
693                 pop ds
694                 call searchdir
695                 jz comapi_err
697                 ; The kernel image was found, so we can load it...
698                 mov [Kernel_SI],si
699                 mov [Kernel_EAX],eax
701                 ; It's not just possible, but quite likely, that ES:BX
702                 ; points into real_mode_seg, so we need to exercise some
703                 ; special care here... use xfer_buf_seg as an intermediary
704                 push ds
705                 push es
706                 mov ax,xfer_buf_seg
707                 mov ds,P_ES
708                 mov si,P_BX
709                 mov es,ax
710                 xor di,di
711                 call strcpy
712                 pop es
713                 pop ds
715 %if IS_PXELINUX
716                 mov al,P_CL
717                 mov [IPAppend],al
718 %endif
720                 call comboot_exit
722 .finish:
723                 ; Copy the command line into its proper place
724                 push ds
725                 push es
726                 mov ax,xfer_buf_seg
727                 mov dx,real_mode_seg
728                 mov ds,ax
729                 mov es,dx
730                 xor si,si
731                 mov di,cmd_line_here
732                 call strcpy
733                 mov byte [es:di-1],' '          ; Simulate APPEND
734                 pop es
735                 pop ds
736                 mov [CmdLinePtr],di
737                 mov word [CmdOptPtr],zero_string
738                 jmp kernel_good_saved
740 .error          equ comapi_shuffle.error
743 ; INT 22h AX=0017h  Report video mode change
745 comapi_usingvga:
746                 mov ax,P_BX
747                 cmp ax,0Fh              ; Unknown flags = failure
748                 ja .error
749                 mov [UsingVGA],al
750                 mov cx,P_CX
751                 mov dx,P_DX
752                 mov [GXPixCols],cx
753                 mov [GXPixRows],dx
754                 test al,08h
755                 jnz .notext
756                 call adjust_screen
757 .notext:
758                 clc
759                 ret
760 .error:
761                 stc
762                 ret
765 ; INT 22h AX=0018h  Query custom font
767 comapi_userfont:
768                 mov al,[UserFont]
769                 and al,al
770                 jz .done
771                 mov al,[VGAFontSize]
772                 mov P_ES,ds
773                 mov P_BX,vgafontbuf
775 .done:          ; CF=0 here
776                 mov P_AL,al
777                 ret
780 ; INT 22h AX=0019h  Read disk
782 %if IS_SYSLINUX || IS_MDSLINUX || IS_ISOLINUX || IS_EXTLINUX
783 comapi_readdisk:
784                 mov esi,P_ESI           ; Enforce ESI == EDI == 0, these
785                 or esi,P_EDI            ; are reserved for future expansion
786                 jnz .err
787                 mov eax,P_EDX
788                 mov es,P_ES
789                 mov bx,P_BX
790                 mov bp,P_CX             ; WE CANNOT use P_* after touching bp!
791                 call getlinsec
792                 clc
793                 ret
794 .err:
795                 stc
796                 ret
797 %else
798 comapi_readdisk equ comapi_err
799 %endif
802 ; INT 22h AX=001Ah      Cleanup, shuffle and boot to flat protected mode
804 comapi_shufflepm:
805                 cmp P_CX,(2*trackbufsize)/12
806                 ja .error
808                 call comapi_cleanup
810                 mov cx, P_CX
811                 push cx                         ; On stack: descriptor count
813                 lea cx,[ecx+ecx*2]              ; CX *= 3
815                 mov fs,P_ES
816                 mov si,P_DI
817                 mov di,trackbuf
818                 push di                         ; On stack: descriptor list address
819                 fs rep movsd                    ; Copy the list
821                 mov fs,P_DS
822                 mov si,P_SI
823                 mov edi,TrampolineBuf
824                 mov al,0B8h                     ; MOV EAX opcode
825                 mov cl,9
826 .maketramp:
827                 stosb                           ; MOV opcode
828                 inc ax                          ; Next register opcode
829                 fs movsd                        ; immediate value
830                 loop .maketramp
831                 mov byte [di-5],0E9h            ; Last opcode is JMP
832                 sub [di-4],edi                  ; Make JMP target relative
834                 mov dword [EntryPoint],trampoline_to_pm
835                 xor bx,bx                       ; DS on entry
836                 jmp replace_bootstrap
837 .error:
838                 stc
839                 ret
842 ; INT 22h AX=001Bh      Cleanup, shuffle and boot with register setting
844 comapi_shufflerm:
845                 cmp P_CX,(2*trackbufsize)/12
846                 ja .error
848                 call comapi_cleanup
850                 mov cx, P_CX
851                 push cx                         ; On stack: descriptor count
853                 lea cx,[ecx+ecx*2]              ; CX *= 3
855                 mov fs,P_ES
856                 mov si,P_DI
857                 mov di,trackbuf
858                 push di                         ; On stack: descriptor list address
859                 fs rep movsd                    ; Copy the list
861                 mov fs,P_DS
862                 mov si,P_SI
863                 mov di,TrampolineBuf
865                 ; Generate segment-loading instructions
866                 mov bx,0C08Eh                   ; MOV ES,AX
867                 mov cl,6                        ; 6 segment registers (incl CS)
868 .segtramp:
869                 mov al,0B8h
870                 stosb                           ; MOV AX,imm16 opcode
871                 fs movsw                        ; imm16
872                 mov ax,bx
873                 add bh,8
874                 stosw                           ; MOV xS,AX
875                 loop .segtramp
877                 ; Clobber the MOV CS,AX instruction.
878                 mov word [di-22], 9090h         ; NOP NOP
880                 ; Generate GPR-loading instructions
881                 mov ax,0B866h                   ; MOV EAX,imm32
882                 mov cl,8                        ; 8 GPRs
883 .gprtramp:
884                 stosw                           ; MOV ExX,imm32 opcode
885                 fs movsd                        ; imm32
886                 inc ah
887                 loop .gprtramp
889                 mov al,0EAh                     ; JMP FAR imm16:imm16 opcode
890                 stosb
891                 fs movsd                        ; CS:IP
893                 mov dword [EntryPoint],TrampolineBuf
894                 jmp replace_bootstrap
895 .error:
896                 stc
897                 ret
900 ; INT 22h AX=001Ch      Get pointer to auxillary data vector
902 comapi_getadv:
903                 mov P_ES,ds
904                 mov P_BX,adv0.data
905                 mov P_CX,ADV_LEN
906                 ret
909 ; INT 22h AX=001Dh      Write auxillary data vector
911 comapi_writeadv equ adv_write
913                 section .data
915 %macro          int21 2
916                 db %1
917                 dw %2
918 %endmacro
920 int21_table:
921                 int21   00h, comboot_return
922                 int21   01h, comboot_getkey
923                 int21   02h, comboot_writechr
924                 int21   04h, comboot_writeserial
925                 int21   08h, comboot_getkeynoecho
926                 int21   09h, comboot_writestr
927                 int21   0Bh, comboot_checkkey
928                 int21   30h, comboot_checkver
929                 int21   4Ch, comboot_return
930                 int21    -1, comboot_bogus
931 int21_count     equ ($-int21_table)/3
933                 align 2, db 0
934 int22_table:
935                 dw comapi_err           ; 0000 unimplemented syscall
936                 dw comapi_get_version   ; 0001 get SYSLINUX version
937                 dw comapi_writestr      ; 0002 write string
938                 dw comapi_run           ; 0003 run specified command
939                 dw comapi_run_default   ; 0004 run default command
940                 dw comapi_textmode      ; 0005 force text mode
941                 dw comapi_open          ; 0006 open file
942                 dw comapi_read          ; 0007 read file
943                 dw comapi_close         ; 0008 close file
944                 dw comapi_pxecall       ; 0009 call PXE stack
945                 dw comapi_derinfo       ; 000A derivative-specific info
946                 dw comapi_serialcfg     ; 000B get serial port config
947                 dw comapi_cleanup       ; 000C perform final cleanup
948                 dw comapi_chainboot     ; 000D clean up then bootstrap
949                 dw comapi_configfile    ; 000E get name of config file
950                 dw comapi_ipappend      ; 000F get ipappend strings
951                 dw comapi_dnsresolv     ; 0010 resolve hostname
952                 dw comapi_maxshuffle    ; 0011 maximum shuffle descriptors
953                 dw comapi_shuffle       ; 0012 cleanup, shuffle and boot
954                 dw comapi_idle          ; 0013 idle call
955                 dw comapi_localboot     ; 0014 local boot
956                 dw comapi_features      ; 0015 feature flags
957                 dw comapi_runkernel     ; 0016 run kernel image
958                 dw comapi_usingvga      ; 0017 report video mode change
959                 dw comapi_userfont      ; 0018 query custom font
960                 dw comapi_readdisk      ; 0019 read disk
961                 dw comapi_shufflepm     ; 001A cleanup, shuffle and boot to pm
962                 dw comapi_shufflerm     ; 001B cleanup, shuffle and boot to rm
963                 dw comapi_getadv        ; 001C get pointer to ADV
964                 dw comapi_writeadv      ; 001D write ADV to disk
965 int22_count     equ ($-int22_table)/2
967 APIKeyWait      db 0
968 APIKeyFlag      db 0
970 zero_string     db 0                    ; Empty, null-terminated string
973 ; This is the feature flag array for INT 22h AX=0015h
975 ; Note: PXELINUX clears the idle is noop flag if appropriate
976 ; in pxe_detect_nic_type
978 feature_flags:
979                 db 3                    ; Have local boot, idle is noop
980 feature_flags_len equ ($-feature_flags)
982 err_notdos      db ': attempted DOS system call', CR, LF, 0
983 err_comlarge    db 'COMBOOT image too large.', CR, LF, 0
985                 section .bss1
986 ConfigName      resb    FILENAME_MAX