aboutsummaryrefslogtreecommitdiffstats
path: root/core/conio.inc
diff options
context:
space:
mode:
Diffstat (limited to 'core/conio.inc')
-rw-r--r--core/conio.inc391
1 files changed, 391 insertions, 0 deletions
diff --git a/core/conio.inc b/core/conio.inc
new file mode 100644
index 00000000..47005961
--- /dev/null
+++ b/core/conio.inc
@@ -0,0 +1,391 @@
+;; -----------------------------------------------------------------------
+;;
+;; Copyright 1994-2008 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,
+;; Boston MA 02111-1307, USA; either version 2 of the License, or
+;; (at your option) any later version; incorporated herein by reference.
+;;
+;; -----------------------------------------------------------------------
+
+;;
+;; conio.inc
+;;
+;; Console I/O code, except:
+;; writechr, writestr - module-dependent
+;; cwritestr, crlf - writestr.inc
+;; writehex* - writehex.inc
+;;
+
+;
+; loadkeys: Load a LILO-style keymap; SI and DX:AX set by searchdir
+;
+ section .text
+
+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. Call with the file already
+; on the top of the open/getc stack.
+;
+; Assumes CS == DS == ES.
+;
+get_msg_file:
+ mov byte [TextAttribute],07h ; Default grey on white
+ mov byte [DisplayMask],07h ; Display text in all modes
+ call msg_initvars
+
+print_msg_file:
+.getc:
+ call getc
+ jc .done
+ cmp al,1Ah ; DOS EOF?
+ je .done
+ movzx cx,byte [UsingVGA]
+ and cl,01h
+ inc cx ; CL <- 01h = text mode,
+ ; 02h = graphics mode
+ call [NextCharJump] ; Do what shall be done
+ jmp .getc
+.done:
+ jmp close ; Tailcall!
+
+msg_putchar: ; Normal character
+ cmp al,0Fh ; ^O = color code follows
+ je msg_ctrl_o
+ cmp al,0Dh ; Ignore <CR>
+ je msg_ignore
+ cmp al,0Ah ; <LF> = newline
+ je msg_newline
+ cmp al,0Ch ; <FF> = clear screen
+ je msg_formfeed
+ cmp al,07h ; <BEL> = beep
+ je msg_beep
+ cmp al,19h ; <EM> = return to text mode
+ je msg_novga
+ cmp al,18h ; <CAN> = VGA filename follows
+ je msg_vga
+ jnb .not_modectl
+ cmp al,10h ; 10h to 17h are mode controls
+ jae msg_modectl
+.not_modectl:
+
+msg_normal: call write_serial_displaymask ; Write to serial port
+ test [DisplayMask],cl
+ jz msg_ignore ; Not screen
+ test byte [DisplayCon],01h
+ jz msg_ignore
+ mov bl,[TextAttribute]
+ mov bh,[BIOS_page]
+ 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,[BIOS_page]
+ mov dx,[CursorDX]
+ mov ah,02h ; Set cursor position
+ int 10h
+msg_ignore: ret
+
+msg_beep: mov ax,0E07h ; Beep
+ xor bx,bx
+ int 10h
+ 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 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 ; <LF> = 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:
+ mov si,[VGAFilePtr]
+ mov byte [si],0 ; Zero-terminate filename
+ mov si,VGAFileBuf
+ mov di,VGAFileMBuf
+ call mangle_name
+ call open
+ 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,[BIOS_page]
+ 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
+
+;
+; pollchar: check if we have an input character pending (ZF = 0)
+;
+pollchar:
+ pushad
+ mov ah,11h ; 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:
+ RESET_IDLE
+.again:
+ DO_IDLE
+ mov ah,11h ; 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: mov ah,10h ; Get keyboard input
+ int 16h
+ cmp al,0E0h
+ jnz .not_ext
+ xor al,al
+.not_ext:
+ and al,al
+ jz .func_key
+ mov bx,KbdMap ; Convert character sets
+ xlatb
+.func_key: ret
+
+%ifdef DEBUG_TRACERS
+;
+; 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
+%endif ; DEBUG_TRACERS
+
+ section .data
+%if IS_ISOLINUX == 0 ; Defined elsewhere for ISOLINUX
+crlf_msg db CR, LF
+null_msg db 0
+%endif
+crff_msg db CR, FF, 0
+
+ section .config
+ ; This is a word to pc_setint16 can set it
+DisplayCon dw 01h ; Console display enabled
+
+ScrollAttribute db 07h ; Grey on white (normal text color)
+
+ section .bss
+ alignb 2
+NextCharJump resw 1 ; Routine to interpret next print char
+CursorDX equ $
+CursorCol resb 1 ; Cursor column for message file
+CursorRow resb 1 ; Cursor row for message file
+ScreenSize equ $
+VidCols resb 1 ; Columns on screen-1
+VidRows resb 1 ; Rows on screen-1
+
+; Serial console stuff...
+BaudDivisor resw 1 ; Baud rate divisor
+FlowControl equ $
+FlowOutput resb 1 ; Outputs to assert for serial flow
+FlowInput resb 1 ; Input bits for serial flow
+FlowIgnore resb 1 ; Ignore input unless these bits set
+
+TextAttribute resb 1 ; Text attribute for message file
+DisplayMask resb 1 ; Display modes mask