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