From 32f428c681e06add996b1b850a31a27abaadd23b Mon Sep 17 00:00:00 2001 From: hpa Date: Fri, 26 Apr 2002 22:43:29 +0000 Subject: [PATCH] Even more common code factoring --- isolinux.asm | 416 ++--------------------------------------------------------- ldlinux.asm | 401 +------------------------------------------------------- pxelinux.asm | 392 +------------------------------------------------------ writehex.inc | 54 ++++++++ writestr.inc | 43 ++++++ 5 files changed, 115 insertions(+), 1191 deletions(-) create mode 100644 writehex.inc create mode 100644 writestr.inc diff --git a/isolinux.asm b/isolinux.asm index 5138633..a61b24a 100644 --- a/isolinux.asm +++ b/isolinux.asm @@ -461,67 +461,6 @@ writemsg: push ax ret ; -; crlf: Print a newline -; -crlf: mov si,crlf_msg - ; Fall through - -; -; cwritestr: write a null-terminated string to the console, saving -; registers on entry. -; -; Note: writestr and cwritestr are distinct in SYSLINUX, not in ISOLINUX -; -cwritestr: - pushfd - pushad -.top: lodsb - and al,al - jz .end - call writechr - jmp short .top -.end: popad - popfd - ret - -writestr equ cwritestr - -; -; writehex[248]: Write a hex number in (AL, AX, EAX) to the console -; -writehex2: - pushfd - pushad - shl eax,24 - mov cx,2 - jmp short writehex_common -writehex4: - pushfd - pushad - shl eax,16 - mov cx,4 - jmp short writehex_common -writehex8: - pushfd - pushad - mov cx,8 -writehex_common: -.loop: rol eax,4 - push eax - and al,0Fh - cmp al,10 - jae .high -.low: add al,'0' - jmp short .ischar -.high: add al,'A'-10 -.ischar: call writechr - pop eax - loop .loop - popad - popfd - ret - -; ; Write a character to the screen. There is a more "sophisticated" ; version of this in the subsequent code, so we patch the pointer ; when appropriate. @@ -630,9 +569,18 @@ kaboom: mov word [BIOS_magic],0 ; Cold reboot jmp 0F000h:0FFF0h ; Reset vector address -; +; ----------------------------------------------------------------------------- +; Common modules needed in the first sector +; ----------------------------------------------------------------------------- + +%include "writestr.inc" ; String output +writestr equ cwritestr +%include "writehex.inc" ; Hexadecimal output + +; ----------------------------------------------------------------------------- ; Data that needs to be in the first sector -; +; ----------------------------------------------------------------------------- + isolinux_banner db CR, LF, 'ISOLINUX ', version_str, ' ', date, ' ', 0 copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin' db CR, LF, 0 @@ -3073,276 +3021,6 @@ strcpy: push ax ret ; -; loadkeys: Load a LILO-style keymap; SI and DX:AX set by searchdir -; -loadkeys: - and dx,dx ; Should be 256 bytes exactly - jne loadkeys_ret - cmp ax,256 - jne loadkeys_ret - - mov bx,trackbuf - mov cx,1 ; 1 cluster should be >= 256 bytes - call getfssec - - mov si,trackbuf - mov di,KbdMap - mov cx,256 >> 2 - rep movsd - -loadkeys_ret: ret - -; -; get_msg_file: Load a text file and write its contents to the screen, -; interpreting color codes. Is called with SI and DX:AX -; set by routine searchdir -; -get_msg_file: - push es - shl edx,16 ; EDX <- DX:AX (length of file) - mov dx,ax - mov ax,xfer_buf_seg ; Use for temporary storage - mov es,ax - - mov byte [TextAttribute],07h ; Default grey on white - mov byte [DisplayMask],07h ; Display text in all modes - call msg_initvars - -get_msg_chunk: push edx ; EDX = length of file - xor bx,bx ; == xbs_textbuf - mov cx,[BufSafe] - call getfssec - pop edx - push si ; Save current cluster - xor si,si ; == xbs_textbuf - mov cx,[BufSafeBytes] ; Number of bytes left in chunk -print_msg_file: - push cx - push edx - es lodsb - cmp al,1Ah ; DOS EOF? - je msg_done_pop - push si - mov cl,[UsingVGA] - inc cl ; 01h = text mode, 02h = graphics - call [NextCharJump] ; Do what shall be done - pop si - pop edx - pop cx - dec edx - jz msg_done - loop print_msg_file - pop si - jmp short get_msg_chunk -msg_done_pop: - add sp,byte 6 ; Drop pushed EDX, CX -msg_done: - pop si - pop es - ret -msg_putchar: ; Normal character - cmp al,0Fh ; ^O = color code follows - je msg_ctrl_o - cmp al,0Dh ; Ignore - je msg_ignore - cmp al,0Ah ; = newline - je msg_newline - cmp al,0Ch ; = clear screen - je msg_formfeed - cmp al,19h ; = return to text mode - je near msg_novga - cmp al,18h ; = VGA filename follows - je near msg_vga - jnb .not_modectl - cmp al,10h ; 10h to 17h are mode controls - jae near msg_modectl -.not_modectl: - -msg_normal: call write_serial_displaymask ; Write to serial port - test [DisplayMask],cl - jz msg_ignore ; Not screen - mov bx,[TextAttrBX] - mov ah,09h ; Write character/attribute - mov cx,1 ; One character only - int 10h ; Write to screen - mov al,[CursorCol] - inc ax - cmp al,[VidCols] - ja msg_line_wrap ; Screen wraparound - mov [CursorCol],al - -msg_gotoxy: mov bh,[TextPage] - mov dx,[CursorDX] - mov ah,02h ; Set cursor position - int 10h -msg_ignore: ret -msg_ctrl_o: ; ^O = color code follows - mov word [NextCharJump],msg_setbg - ret -msg_newline: ; Newline char or end of line - mov si,crlf_msg - call write_serial_str_displaymask -msg_line_wrap: ; Screen wraparound - test [DisplayMask],cl - jz msg_ignore - mov byte [CursorCol],0 - mov al,[CursorRow] - inc ax - cmp al,[VidRows] - ja msg_scroll - mov [CursorRow],al - jmp short msg_gotoxy -msg_scroll: xor cx,cx ; Upper left hand corner - mov dx,[ScreenSize] - mov [CursorRow],dh ; New cursor at the bottom - mov bh,[ScrollAttribute] - mov ax,0601h ; Scroll up one line - int 10h - jmp short msg_gotoxy -msg_formfeed: ; Form feed character - mov si,crff_msg - call write_serial_str_displaymask - test [DisplayMask],cl - jz msg_ignore - xor cx,cx - mov [CursorDX],cx ; Upper lefthand corner - mov dx,[ScreenSize] - mov bh,[TextAttribute] - mov ax,0600h ; Clear screen region - int 10h - jmp short msg_gotoxy -msg_setbg: ; Color background character - call unhexchar - jc msg_color_bad - shl al,4 - test [DisplayMask],cl - jz .dontset - mov [TextAttribute],al -.dontset: - mov word [NextCharJump],msg_setfg - ret -msg_setfg: ; Color foreground character - call unhexchar - jc msg_color_bad - test [DisplayMask],cl - jz .dontset - or [TextAttribute],al ; setbg set foreground to 0 -.dontset: - jmp short msg_putcharnext -msg_vga: - mov word [NextCharJump],msg_filename - mov di, VGAFileBuf - jmp short msg_setvgafileptr - -msg_color_bad: - mov byte [TextAttribute],07h ; Default attribute -msg_putcharnext: - mov word [NextCharJump],msg_putchar - ret - -msg_filename: ; Getting VGA filename - cmp al,0Ah ; = end of filename - je msg_viewimage - cmp al,' ' - jbe msg_ret ; Ignore space/control char - mov di,[VGAFilePtr] - cmp di,VGAFileBufEnd - jnb msg_ret - mov [di],al ; Can't use stosb (DS:) - inc di -msg_setvgafileptr: - mov [VGAFilePtr],di -msg_ret: ret - -msg_novga: - call vgaclearmode - jmp short msg_initvars - -msg_viewimage: - push es - push ds - pop es ; ES <- DS - mov si,VGAFileBuf - mov di,VGAFileMBuf - push di - call mangle_name - pop di - call searchdir - pop es - jz msg_putcharnext ; Not there - call vgadisplayfile - ; Fall through - - ; Subroutine to initialize variables, also needed - ; after loading a graphics file -msg_initvars: - pusha - mov bh,[TextPage] - mov ah,03h ; Read cursor position - int 10h - mov [CursorDX],dx - popa - jmp short msg_putcharnext ; Initialize state machine - -msg_modectl: - and al,07h - mov [DisplayMask],al - jmp short msg_putcharnext - -; -; write_serial: If serial output is enabled, write character on serial port -; write_serial_displaymask: d:o, but ignore if DisplayMask & 04h == 0 -; -write_serial_displaymask: - test byte [DisplayMask], 04h - jz write_serial.end -write_serial: - pushfd - pushad - mov bx,[SerialPort] - and bx,bx - je .noserial - push ax - mov ah,[FlowInput] -.waitspace: - ; Wait for space in transmit register - lea dx,[bx+5] ; DX -> LSR - in al,dx - test al,20h - jz .waitspace - - ; Wait for input flow control - inc dx ; DX -> MSR - in al,dx - and al,ah - cmp al,ah - jne .waitspace -.no_flow: - - xchg dx,bx ; DX -> THR - pop ax - call slow_out ; Send data -.noserial: popad - popfd -.end: ret - -; -; write_serial_str: write_serial for strings -; write_serial_str_displaymask: d:o, but ignore if DisplayMask & 04h == 0 -; -write_serial_str_displaymask: - test byte [DisplayMask], 04h - jz write_serial_str.end - -write_serial_str: -.loop lodsb - and al,al - jz .end - call write_serial - jmp short .loop -.end: ret - -; ; writechr: Write a single character in AL to the console without ; mangling any registers. This does raw console writes, ; since some PXE BIOSes seem to interfere regular console I/O. @@ -3403,77 +3081,6 @@ writechr_full: jmp short .curxyok ; -; debug hack to print a character with minimal code impact -; -debug_tracer: pushad - pushfd - mov bp,sp - mov bx,[bp+9*4] ; Get return address - mov al,[cs:bx] ; Get data byte - inc word [bp+9*4] ; Return to after data byte - call writechr - popfd - popad - ret - -; -; pollchar: check if we have an input character pending (ZF = 0) -; -pollchar: - pushad - mov ah,1 ; Poll keyboard - int 16h - jnz .done ; Keyboard response - mov dx,[SerialPort] - and dx,dx - jz .done ; No serial port -> no input - add dx,byte 5 ; DX -> LSR - in al,dx - test al,1 ; ZF = 0 if data pending - jz .done - inc dx ; DX -> MSR - mov ah,[FlowIgnore] ; Required status bits - in al,dx - and al,ah - cmp al,ah - setne al - dec al ; Set ZF = 0 if equal -.done: popad - ret - -; -; getchar: Read a character from keyboard or serial port -; -getchar: -.again: mov ah,1 ; Poll keyboard - int 16h - jnz .kbd ; Keyboard input? - mov bx,[SerialPort] - and bx,bx - jz .again - lea dx,[bx+5] ; DX -> LSR - in al,dx - test al,1 - jz .again - inc dx ; DX -> MSR - mov ah,[FlowIgnore] - in al,dx - and al,ah - cmp al,ah - jne .again -.serial: xor ah,ah ; Avoid confusion - xchg dx,bx ; Data port - in al,dx - ret -.kbd: xor ax,ax ; Get keyboard input - int 16h - and al,al - jz .func_key - mov bx,KbdMap ; Convert character sets - xlatb -.func_key: ret - -; ; getkeyword: Get a keyword from the current "getc" file; only the two ; first characters are considered significant. ; @@ -3645,6 +3252,7 @@ getfssec: ; ----------------------------------------------------------------------------- %include "getc.inc" ; getc et al +%include "conio.inc" ; Console I/O %include "font.inc" ; VGA font stuff %include "graphics.inc" ; VGA graphics diff --git a/ldlinux.asm b/ldlinux.asm index dde4103..4c83e0d 100644 --- a/ldlinux.asm +++ b/ldlinux.asm @@ -2884,276 +2884,6 @@ dir_return: ret ; -; loadkeys: Load a LILO-style keymap; SI and DX:AX set by searchdir -; -loadkeys: - and dx,dx ; Should be 256 bytes exactly - jne loadkeys_ret - cmp ax,256 - jne loadkeys_ret - - mov bx,trackbuf - mov cx,1 ; 1 cluster should be >= 256 bytes - call getfssec - - mov si,trackbuf - mov di,KbdMap - mov cx,256 >> 2 - rep movsd - -loadkeys_ret: ret - -; -; get_msg_file: Load a text file and write its contents to the screen, -; interpreting color codes. Is called with SI and DX:AX -; set by routine searchdir -; -get_msg_file: - push es - shl edx,16 ; EDX <- DX:AX (length of file) - mov dx,ax - mov ax,xfer_buf_seg ; Use for temporary storage - mov es,ax - - mov byte [TextAttribute],07h ; Default grey on white - mov byte [DisplayMask],07h ; Display text in all modes - call msg_initvars - -get_msg_chunk: push edx ; EDX = length of file - xor bx,bx ; == xbs_textbuf - mov cx,[BufSafe] - call getfssec - pop edx - push si ; Save current cluster - xor si,si ; == xbs_textbuf - mov cx,[BufSafeBytes] ; Number of bytes left in chunk -print_msg_file: - push cx - push edx - es lodsb - cmp al,1Ah ; DOS EOF? - je msg_done_pop - push si - mov cl,[UsingVGA] - inc cl ; 01h = text mode, 02h = graphics - call [NextCharJump] ; Do what shall be done - pop si - pop edx - pop cx - dec edx - jz msg_done - loop print_msg_file - pop si - jmp short get_msg_chunk -msg_done_pop: - add sp,byte 6 ; Drop pushed EDX, CX -msg_done: - pop si - pop es - ret -msg_putchar: ; Normal character - cmp al,0Fh ; ^O = color code follows - je msg_ctrl_o - cmp al,0Dh ; Ignore - je msg_ignore - cmp al,0Ah ; = newline - je msg_newline - cmp al,0Ch ; = clear screen - je msg_formfeed - cmp al,19h ; = return to text mode - je near msg_novga - cmp al,18h ; = VGA filename follows - je near msg_vga - jnb .not_modectl - cmp al,10h ; 10h to 17h are mode controls - jae near msg_modectl -.not_modectl: - -msg_normal: call write_serial_displaymask ; Write to serial port - test [DisplayMask],cl - jz msg_ignore ; Not screen - mov bx,[TextAttrBX] - mov ah,09h ; Write character/attribute - mov cx,1 ; One character only - int 10h ; Write to screen - mov al,[CursorCol] - inc ax - cmp al,[VidCols] - ja msg_line_wrap ; Screen wraparound - mov [CursorCol],al - -msg_gotoxy: mov bh,[TextPage] - mov dx,[CursorDX] - mov ah,02h ; Set cursor position - int 10h -msg_ignore: ret -msg_ctrl_o: ; ^O = color code follows - mov word [NextCharJump],msg_setbg - ret -msg_newline: ; Newline char or end of line - mov si,crlf_msg - call write_serial_str_displaymask -msg_line_wrap: ; Screen wraparound - test [DisplayMask],cl - jz msg_ignore - mov byte [CursorCol],0 - mov al,[CursorRow] - inc ax - cmp al,[VidRows] - ja msg_scroll - mov [CursorRow],al - jmp short msg_gotoxy -msg_scroll: xor cx,cx ; Upper left hand corner - mov dx,[ScreenSize] - mov [CursorRow],dh ; New cursor at the bottom - mov bh,[ScrollAttribute] - mov ax,0601h ; Scroll up one line - int 10h - jmp short msg_gotoxy -msg_formfeed: ; Form feed character - mov si,crff_msg - call write_serial_str_displaymask - test [DisplayMask],cl - jz msg_ignore - xor cx,cx - mov [CursorDX],cx ; Upper lefthand corner - mov dx,[ScreenSize] - mov bh,[TextAttribute] - mov ax,0600h ; Clear screen region - int 10h - jmp short msg_gotoxy -msg_setbg: ; Color background character - call unhexchar - jc msg_color_bad - shl al,4 - test [DisplayMask],cl - jz .dontset - mov [TextAttribute],al -.dontset: - mov word [NextCharJump],msg_setfg - ret -msg_setfg: ; Color foreground character - call unhexchar - jc msg_color_bad - test [DisplayMask],cl - jz .dontset - or [TextAttribute],al ; setbg set foreground to 0 -.dontset: - jmp short msg_putcharnext -msg_vga: - mov word [NextCharJump],msg_filename - mov di, VGAFileBuf - jmp short msg_setvgafileptr - -msg_color_bad: - mov byte [TextAttribute],07h ; Default attribute -msg_putcharnext: - mov word [NextCharJump],msg_putchar - ret - -msg_filename: ; Getting VGA filename - cmp al,0Ah ; = end of filename - je msg_viewimage - cmp al,' ' - jbe msg_ret ; Ignore space/control char - mov di,[VGAFilePtr] - cmp di,VGAFileBufEnd - jnb msg_ret - mov [di],al ; Can't use stosb (DS:) - inc di -msg_setvgafileptr: - mov [VGAFilePtr],di -msg_ret: ret - -msg_novga: - call vgaclearmode - jmp short msg_initvars - -msg_viewimage: - push es - push ds - pop es ; ES <- DS - mov si,VGAFileBuf - mov di,VGAFileMBuf - push di - call mangle_name - pop di - call searchdir - pop es - jz msg_putcharnext ; Not there - call vgadisplayfile - ; Fall through - - ; Subroutine to initialize variables, also needed - ; after loading a graphics file -msg_initvars: - pusha - mov bh,[TextPage] - mov ah,03h ; Read cursor position - int 10h - mov [CursorDX],dx - popa - jmp short msg_putcharnext ; Initialize state machine - -msg_modectl: - and al,07h - mov [DisplayMask],al - jmp short msg_putcharnext - -; -; write_serial: If serial output is enabled, write character on serial port -; write_serial_displaymask: d:o, but ignore if DisplayMask & 04h == 0 -; -write_serial_displaymask: - test byte [DisplayMask], 04h - jz write_serial.end -write_serial: - pushfd - pushad - mov bx,[SerialPort] - and bx,bx - je .noserial - push ax - mov ah,[FlowInput] -.waitspace: - ; Wait for space in transmit register - lea dx,[bx+5] ; DX -> LSR - in al,dx - test al,20h - jz .waitspace - - ; Wait for input flow control - inc dx ; DX -> MSR - in al,dx - and al,ah - cmp al,ah - jne .waitspace -.no_flow: - - xchg dx,bx ; DX -> THR - pop ax - call slow_out ; Send data -.noserial: popad - popfd -.end: ret - -; -; write_serial_str: write_serial for strings -; write_serial_str_displaymask: d:o, but ignore if DisplayMask & 04h == 0 -; -write_serial_str_displaymask: - test byte [DisplayMask], 04h - jz write_serial_str.end - -write_serial_str: -.loop lodsb - and al,al - jz .end - call write_serial - jmp short .loop -.end: ret - -; ; writechr: Write a single character in AL to the console without ; mangling any registers ; @@ -3169,135 +2899,6 @@ writechr: ret ; -; crlf: Print a newline -; -crlf: mov si,crlf_msg - ; Fall through - -; -; cwritestr: write a null-terminated string to the console, saving -; registers on entry. -; -cwritestr: - pushfd - pushad -.top: lodsb - and al,al - jz .end - call writechr - jmp short .top -.end: popad - popfd - ret - -%ifdef debug - -; -; writehex[248]: Write a hex number in (AL, AX, EAX) to the console -; -writehex2: - pushfd - pushad - rol eax,24 - mov cx,2 - jmp short writehex_common -writehex4: - pushfd - pushad - rol eax,16 - mov cx,4 - jmp short writehex_common -writehex8: - pushfd - pushad - mov cx,8 -writehex_common: -.loop: rol eax,4 - push eax - and al,0Fh - cmp al,10 - jae .high -.low: add al,'0' - jmp short .ischar -.high: add al,'A'-10 -.ischar: call writechr - pop eax - loop .loop - popad - popfd - ret - -; -; crlf: write CR LF -; -crlf: push ax - mov al, 13 - call writechr - mov al, 10 - call writechr - pop ax - ret - -%endif - -; -; pollchar: check if we have an input character pending (ZF = 0) -; -pollchar: - pushad - mov ah,1 ; Poll keyboard - int 16h - jnz .done ; Keyboard response - mov dx,[SerialPort] - and dx,dx - jz .done ; No serial port -> no input - add dx,byte 5 ; DX -> LSR - in al,dx - test al,1 ; ZF = 0 if data pending - jz .done - inc dx ; DX -> MSR - mov ah,[FlowIgnore] ; Required status bits - in al,dx - and al,ah - cmp al,ah - setne al - dec al ; Set ZF = 0 if equal -.done: popad - ret - -; -; getchar: Read a character from keyboard or serial port -; -getchar: -.again: mov ah,1 ; Poll keyboard - int 16h - jnz .kbd ; Keyboard input? - mov bx,[SerialPort] - and bx,bx - jz .again - lea dx,[bx+5] ; DX -> LSR - in al,dx - test al,1 - jz .again - inc dx ; DX -> MSR - mov ah,[FlowIgnore] - in al,dx - and al,ah - cmp al,ah - jne .again -.serial: xor ah,ah ; Avoid confusion - xchg dx,bx ; Data port - in al,dx - ret -.kbd: xor ax,ax ; Get keyboard input - int 16h - and al,al - jz .func_key - mov bx,KbdMap ; Convert character sets - xlatb -.func_key: ret - -; ; ; kaboom2: once everything is loaded, replace the part of kaboom ; starting with "kaboom.patch" with this part @@ -3483,6 +3084,8 @@ lc_ret: ret ; ----------------------------------------------------------------------------- %include "getc.inc" ; getc et al +%include "conio.inc" ; Console I/O +%include "writestr.inc" ; String output %include "font.inc" ; VGA font stuff %include "graphics.inc" ; VGA graphics diff --git a/pxelinux.asm b/pxelinux.asm index 3f259cf..18299f8 100644 --- a/pxelinux.asm +++ b/pxelinux.asm @@ -3003,276 +3003,6 @@ strcpy: push ax ret ; -; loadkeys: Load a LILO-style keymap; SI and DX:AX set by searchdir -; -loadkeys: - and dx,dx ; Should be 256 bytes exactly - jne loadkeys_ret - cmp ax,256 - jne loadkeys_ret - - mov bx,trackbuf - mov cx,1 ; 1 cluster should be >= 256 bytes - call getfssec - - mov si,trackbuf - mov di,KbdMap - mov cx,256 >> 2 - rep movsd - -loadkeys_ret: ret - -; -; get_msg_file: Load a text file and write its contents to the screen, -; interpreting color codes. Is called with SI and DX:AX -; set by routine searchdir -; -get_msg_file: - push es - shl edx,16 ; EDX <- DX:AX (length of file) - mov dx,ax - mov ax,xfer_buf_seg ; Use for temporary storage - mov es,ax - - mov byte [TextAttribute],07h ; Default grey on white - mov byte [DisplayMask],07h ; Display text in all modes - call msg_initvars - -get_msg_chunk: push edx ; EDX = length of file - xor bx,bx ; == xbs_textbuf - mov cx,[BufSafe] - call getfssec - pop edx - push si ; Save current cluster - xor si,si ; == xbs_textbuf - mov cx,[BufSafeBytes] ; Number of bytes left in chunk -print_msg_file: - push cx - push edx - es lodsb - cmp al,1Ah ; DOS EOF? - je msg_done_pop - push si - mov cl,[UsingVGA] - inc cl ; 01h = text mode, 02h = graphics - call [NextCharJump] ; Do what shall be done - pop si - pop edx - pop cx - dec edx - jz msg_done - loop print_msg_file - pop si - jmp short get_msg_chunk -msg_done_pop: - add sp,byte 6 ; Drop pushed EDX, CX -msg_done: - pop si - pop es - ret -msg_putchar: ; Normal character - cmp al,0Fh ; ^O = color code follows - je msg_ctrl_o - cmp al,0Dh ; Ignore - je msg_ignore - cmp al,0Ah ; = newline - je msg_newline - cmp al,0Ch ; = clear screen - je msg_formfeed - cmp al,19h ; = return to text mode - je near msg_novga - cmp al,18h ; = VGA filename follows - je near msg_vga - jnb .not_modectl - cmp al,10h ; 10h to 17h are mode controls - jae near msg_modectl -.not_modectl: - -msg_normal: call write_serial_displaymask ; Write to serial port - test [DisplayMask],cl - jz msg_ignore ; Not screen - mov bx,[TextAttrBX] - mov ah,09h ; Write character/attribute - mov cx,1 ; One character only - int 10h ; Write to screen - mov al,[CursorCol] - inc ax - cmp al,[VidCols] - ja msg_line_wrap ; Screen wraparound - mov [CursorCol],al - -msg_gotoxy: mov bh,[TextPage] - mov dx,[CursorDX] - mov ah,02h ; Set cursor position - int 10h -msg_ignore: ret -msg_ctrl_o: ; ^O = color code follows - mov word [NextCharJump],msg_setbg - ret -msg_newline: ; Newline char or end of line - mov si,crlf_msg - call write_serial_str_displaymask -msg_line_wrap: ; Screen wraparound - test [DisplayMask],cl - jz msg_ignore - mov byte [CursorCol],0 - mov al,[CursorRow] - inc ax - cmp al,[VidRows] - ja msg_scroll - mov [CursorRow],al - jmp short msg_gotoxy -msg_scroll: xor cx,cx ; Upper left hand corner - mov dx,[ScreenSize] - mov [CursorRow],dh ; New cursor at the bottom - mov bh,[ScrollAttribute] - mov ax,0601h ; Scroll up one line - int 10h - jmp short msg_gotoxy -msg_formfeed: ; Form feed character - mov si,crff_msg - call write_serial_str_displaymask - test [DisplayMask],cl - jz msg_ignore - xor cx,cx - mov [CursorDX],cx ; Upper lefthand corner - mov dx,[ScreenSize] - mov bh,[TextAttribute] - mov ax,0600h ; Clear screen region - int 10h - jmp short msg_gotoxy -msg_setbg: ; Color background character - call unhexchar - jc msg_color_bad - shl al,4 - test [DisplayMask],cl - jz .dontset - mov [TextAttribute],al -.dontset: - mov word [NextCharJump],msg_setfg - ret -msg_setfg: ; Color foreground character - call unhexchar - jc msg_color_bad - test [DisplayMask],cl - jz .dontset - or [TextAttribute],al ; setbg set foreground to 0 -.dontset: - jmp short msg_putcharnext -msg_vga: - mov word [NextCharJump],msg_filename - mov di, VGAFileBuf - jmp short msg_setvgafileptr - -msg_color_bad: - mov byte [TextAttribute],07h ; Default attribute -msg_putcharnext: - mov word [NextCharJump],msg_putchar - ret - -msg_filename: ; Getting VGA filename - cmp al,0Ah ; = end of filename - je msg_viewimage - cmp al,' ' - jbe msg_ret ; Ignore space/control char - mov di,[VGAFilePtr] - cmp di,VGAFileBufEnd - jnb msg_ret - mov [di],al ; Can't use stosb (DS:) - inc di -msg_setvgafileptr: - mov [VGAFilePtr],di -msg_ret: ret - -msg_novga: - call vgaclearmode - jmp short msg_initvars - -msg_viewimage: - push es - push ds - pop es ; ES <- DS - mov si,VGAFileBuf - mov di,VGAFileMBuf - push di - call mangle_name - pop di - call searchdir - pop es - jz msg_putcharnext ; Not there - call vgadisplayfile - ; Fall through - - ; Subroutine to initialize variables, also needed - ; after loading a graphics file -msg_initvars: - pusha - mov bh,[TextPage] - mov ah,03h ; Read cursor position - int 10h - mov [CursorDX],dx - popa - jmp short msg_putcharnext ; Initialize state machine - -msg_modectl: - and al,07h - mov [DisplayMask],al - jmp short msg_putcharnext - -; -; write_serial: If serial output is enabled, write character on serial port -; write_serial_displaymask: d:o, but ignore if DisplayMask & 04h == 0 -; -write_serial_displaymask: - test byte [DisplayMask], 04h - jz write_serial.end -write_serial: - pushfd - pushad - mov bx,[SerialPort] - and bx,bx - je .noserial - push ax - mov ah,[FlowInput] -.waitspace: - ; Wait for space in transmit register - lea dx,[bx+5] ; DX -> LSR - in al,dx - test al,20h - jz .waitspace - - ; Wait for input flow control - inc dx ; DX -> MSR - in al,dx - and al,ah - cmp al,ah - jne .waitspace -.no_flow: - - xchg dx,bx ; DX -> THR - pop ax - call slow_out ; Send data -.noserial: popad - popfd -.end: ret - -; -; write_serial_str: write_serial for strings -; write_serial_str_displaymask: d:o, but ignore if DisplayMask & 04h == 0 -; -write_serial_str_displaymask: - test byte [DisplayMask], 04h - jz write_serial_str.end - -write_serial_str: -.loop lodsb - and al,al - jz .end - call write_serial - jmp short .loop -.end: ret - -; ; writechr: Write a single character in AL to the console without ; mangling any registers. This does raw console writes, ; since some PXE BIOSes seem to interfere regular console I/O. @@ -3333,124 +3063,6 @@ writechr: jmp short .curxyok ; -; crlf: Print a newline -; -crlf: mov si,crlf_msg - ; Fall through - -; -; cwritestr: write a null-terminated string to the console, saving -; registers on entry. -; -; Note: writestr and cwritestr are distinct in SYSLINUX, not in PXELINUX -; -cwritestr: - pushfd - pushad -.top: lodsb - and al,al - jz .end - call writechr - jmp short .top -.end: popad - popfd - ret - -writestr equ cwritestr - -; -; writehex[248]: Write a hex number in (AL, AX, EAX) to the console -; -writehex2: - pushfd - pushad - rol eax,24 - mov cx,2 - jmp short writehex_common -writehex4: - pushfd - pushad - rol eax,16 - mov cx,4 - jmp short writehex_common -writehex8: - pushfd - pushad - mov cx,8 -writehex_common: -.loop: rol eax,4 - push eax - and al,0Fh - cmp al,10 - jae .high -.low: add al,'0' - jmp short .ischar -.high: add al,'A'-10 -.ischar: call writechr - pop eax - loop .loop - popad - popfd - ret - -; -; pollchar: check if we have an input character pending (ZF = 0) -; -pollchar: - pushad - mov ah,1 ; Poll keyboard - int 16h - jnz .done ; Keyboard response - mov dx,[SerialPort] - and dx,dx - jz .done ; No serial port -> no input - add dx,byte 5 ; DX -> LSR - in al,dx - test al,1 ; ZF = 0 if data pending - jz .done - inc dx ; DX -> MSR - mov ah,[FlowIgnore] ; Required status bits - in al,dx - and al,ah - cmp al,ah - setne al - dec al ; Set ZF = 0 if equal -.done: popad - ret - -; -; getchar: Read a character from keyboard or serial port -; -getchar: -.again: mov ah,1 ; Poll keyboard - int 16h - jnz .kbd ; Keyboard input? - mov bx,[SerialPort] - and bx,bx - jz .again - lea dx,[bx+5] ; DX -> LSR - in al,dx - test al,1 - jz .again - inc dx ; DX -> MSR - mov ah,[FlowIgnore] - in al,dx - and al,ah - cmp al,ah - jne .again -.serial: xor ah,ah ; Avoid confusion - xchg dx,bx ; Data port - in al,dx - ret -.kbd: xor ax,ax ; Get keyboard input - int 16h - and al,al - jz .func_key - mov bx,KbdMap ; Convert character sets - xlatb -.func_key: ret - -; ; getkeyword: Get a keyword from the current "getc" file; only the two ; first characters are considered significant. ; @@ -4052,6 +3664,10 @@ genipopt: ; ----------------------------------------------------------------------------- %include "getc.inc" ; getc et al +%include "conio.inc" ; Console I/O +%include "writestr.inc" ; String output +writestr equ cwritestr +%include "writehex.inc" ; Hexadecimal output %include "font.inc" ; VGA font stuff %include "graphics.inc" ; VGA graphics diff --git a/writehex.inc b/writehex.inc new file mode 100644 index 0000000..4fd9164 --- /dev/null +++ b/writehex.inc @@ -0,0 +1,54 @@ +;; $Id$ +;; ----------------------------------------------------------------------- +;; +;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, +;; Bostom MA 02111-1307, USA; either version 2 of the License, or +;; (at your option) any later version; incorporated herein by reference. +;; +;; ----------------------------------------------------------------------- + +;; +;; writehex.inc +;; +;; Write hexadecimal numbers to the console +;; + +; +; writehex[248]: Write a hex number in (AL, AX, EAX) to the console +; +writehex2: + pushfd + pushad + rol eax,24 + mov cx,2 + jmp short writehex_common +writehex4: + pushfd + pushad + rol eax,16 + mov cx,4 + jmp short writehex_common +writehex8: + pushfd + pushad + mov cx,8 +writehex_common: +.loop: rol eax,4 + push eax + and al,0Fh + cmp al,10 + jae .high +.low: add al,'0' + jmp short .ischar +.high: add al,'A'-10 +.ischar: call writechr + pop eax + loop .loop + popad + popfd + ret + diff --git a/writestr.inc b/writestr.inc new file mode 100644 index 0000000..8b614cd --- /dev/null +++ b/writestr.inc @@ -0,0 +1,43 @@ +;; $Id$ +;; ----------------------------------------------------------------------- +;; +;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, +;; Bostom MA 02111-1307, USA; either version 2 of the License, or +;; (at your option) any later version; incorporated herein by reference. +;; +;; ----------------------------------------------------------------------- + +;; +;; writestr.inc +;; +;; Code to write a simple string. +;; + +; +; crlf: Print a newline +; +crlf: mov si,crlf_msg + ; Fall through + +; +; cwritestr: write a null-terminated string to the console, saving +; registers on entry. +; +; Note: writestr and cwritestr are distinct in SYSLINUX (only) +; +cwritestr: + pushfd + pushad +.top: lodsb + and al,al + jz .end + call writechr + jmp short .top +.end: popad + popfd + ret + -- 2.7.4