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