;
; 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
+; interpreting color codes. Call with the file already
+; on the top of the open/getc stack.
+;
+; Assumes CS == DS == ES.
;
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
+.getc:
+ call getc
+ jc .done
cmp al,1Ah ; DOS EOF?
- je msg_done_pop
- push si
- mov cl,[UsingVGA]
+ 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
- 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
+ jmp .getc
+.done:
+ jmp close ; Tailcall!
+
msg_putchar: ; Normal character
cmp al,0Fh ; ^O = color code follows
je msg_ctrl_o
jmp short msg_initvars
msg_viewimage:
- push es
- push ds
- pop es ; ES <- DS
mov si,[VGAFilePtr]
mov byte [si],0 ; Zero-terminate filename
mov si,VGAFileBuf
mov di,VGAFileMBuf
call mangle_name
- call searchdir
- pop es
+ call open
jz msg_putcharnext ; Not there
call vgadisplayfile
; Fall through
alignb open_file_t_size
Files resb MAX_OPEN*open_file_t_size
-;
-; Constants for the xfer_buf_seg
-;
-; The xfer_buf_seg is also used to store message file buffers. We
-; need two trackbuffers (text and graphics), plus a work buffer
-; for the graphics decompressor.
-;
-xbs_textbuf equ 0 ; Also hard-coded, do not change
-xbs_vgabuf equ trackbufsize
-xbs_vgatmpbuf equ 2*trackbufsize
-
-
section .text
;
; Some of the things that have to be saved very early are saved
;
; vgadisplayfile:
; Display a graphical splash screen.
+; The file is already opened on the top of the getc stack.
;
-; Input:
-;
-; SI = cluster/socket pointer
+; Assumes CS == DS == ES.
;
section .text
vgadisplayfile:
- mov [VGACluster],si
- push es
-
; This is a cheap and easy way to make sure the screen is
; cleared in case we were in graphics mode already
call vgaclearmode
jnz .error_nz
.graphalready:
- mov ax,xfer_buf_seg ; Use as temporary storage
- mov es,ax
- mov fs,ax
-
- call vgagetchunk ; Get the first chunk
+ ; Load the header.
+ mov cx,4+2*2+16*3
+ mov di,LSSHeader
+.gethdr:
+ call getc
+ stosb
+ loop .gethdr
+ jc .error
; The header WILL be in the first chunk.
- cmp dword [es:xbs_vgabuf],0x1413f33d ; Magic number
+ cmp dword [LSSMagic],0x1413f33d ; Magic number
.error_nz: jne .error
- mov ax,[es:xbs_vgabuf+4]
- mov [GraphXSize],ax
- mov dx,xbs_vgabuf+8 ; Color map offset
+ mov dx,GraphColorMap ; Color map offset
mov ax,1012h ; Set RGB registers
xor bx,bx ; First register number
mov cx,16 ; 16 registers
int 10h
.movecursor:
- mov ax,[es:xbs_vgabuf+6] ; Number of pixel rows
+ mov ax,[GraphYSize] ; Number of pixel rows
mov dx,[VGAFontSize]
add ax,dx
dec ax
xor bx,bx
int 10h ; Set cursor below image
- mov cx,[es:xbs_vgabuf+6] ; Number of graphics rows
-
- mov si,xbs_vgabuf+8+3*16 ; Beginning of pixel data
+ mov cx,[GraphYSize] ; Number of graphics rows
mov word [VGAPos],0
.drawpixelrow:
push cx
- mov cx,[GraphXSize]
- mov di,xbs_vgatmpbuf ; Row buffer
- call rledecode ; Decode one row
- push si
- mov si,xbs_vgatmpbuf
- mov di,si
- add di,[GraphXSize]
+ mov di,VGARowBuffer
+ ; Pre-clear the row buffer
+ push di
mov cx,640/4
xor eax,eax
- rep stosd ; Clear rest of row
+ rep stosd
+ pop di
+ push di
+ mov cx,[GraphXSize]
+ call rledecode ; Decode one row
+ pop si
+ push es
mov di,0A000h ; VGA segment
mov es,di
mov di,[VGAPos]
mov bp,640
call packedpixel2vga
- add word [VGAPos],byte 80 ; Advance to next pixel row
- push fs
+ add word [VGAPos],80
pop es
- pop si
pop cx
loop .drawpixelrow
.error:
- pop es
- ret
+ jmp close ; Tailcall!
;
; rledecode:
; Decode a pixel row in RLE16 format.
;
-; FS:SI -> input
-; CX -> pixel count
-; ES:DI -> output (packed pixel)
+; getc stack -> input
+; CX -> pixel count
+; ES:DI -> output (packed pixel)
;
rledecode:
- shl esi,1 ; Nybble pointer
- xor dl,dl ; Last pixel
+ xor dx,dx ; DL = last pixel, DH = nybble buffer
.loop:
call .getnybble
cmp al,dl
dec cx
jnz .loop
.done:
- shr esi,1
- adc si,byte 0
ret
.run:
xor bx,bx
call .getnybble
- and al,al
+ or bl,al
jz .longrun
- mov bl,al
.dorun:
push cx
mov cx,bx
jmp short .done
.longrun:
call .getnybble
- mov ah,al
+ mov bl,al
call .getnybble
shl al,4
- or al,ah
- mov bl,al
+ or bl,al
add bx,16
jmp short .dorun
+
.getnybble:
- shr esi,1
- fs lodsb
- jc .high
- dec si
- and al,0Fh
- stc
- rcl esi,1
+ test dh,10h
+ jz .low
+ and dh,0Fh
+ mov al,dh
ret
-.high:
- shr al,4
- cmp si,xbs_vgabuf+trackbufsize ; Chunk overrun
- jb .nonewchunk
- call vgagetchunk
- mov si,xbs_vgabuf ; Start at beginning of buffer
-.nonewchunk:
- shl esi,1
- ret
-
-;
-; vgagetchunk:
-; Get a new trackbufsize chunk of VGA image data
-;
-; On input, ES is assumed to point to the buffer segment.
-;
-vgagetchunk:
- pushad
- mov si,[VGACluster]
- and si,si
- jz .eof ; EOF overrun, not much to do...
-
- mov cx,[BufSafe] ; One trackbuf worth of data
- mov bx,xbs_vgabuf
- call getfssec
-
- jnc .noteof
- xor si,si
-.noteof: mov [VGACluster],si
-
-.eof: popad
+.low:
+ call getc
+ mov dh,al
+ shr dh,4
+ or dh,10h ; Nybble already read
+ and al,0Fh
ret
;
; packedpixel2vga:
; Convert packed-pixel to VGA bitplanes
;
-; FS:SI -> packed pixel string
+; DS:SI -> packed pixel string
; BP -> pixel count (multiple of 8)
; ES:DI -> output
;
mov cx,8
.loop2:
xchg cx,bx
- fs lodsb
+ lodsb
shr al,cl
rcl ch,1 ; VGA is bigendian. Sigh.
xchg cx,bx
UsingVGA db 0
section .bss1
- alignb 2
+ alignb 4
+LSSHeader equ $
+LSSMagic resd 1 ; Magic number
GraphXSize resw 1 ; Width of splash screen file
+GraphYSize resw 1 ; Height of splash screen file
+GraphColorMap resb 3*16
VGAPos resw 1 ; Pointer into VGA memory
-VGACluster resw 1 ; Cluster pointer for VGA image file
VGAFilePtr resw 1 ; Pointer into VGAFileBuf
-TextColorReg resb 17 ; VGA color registers for text mode
+; TextColorReg resb 17 ; VGA color registers for text mode
%if IS_SYSLINUX
VGAFileBuf resb FILENAME_MAX+2 ; Unmangled VGA image name
%else
%endif
VGAFileBufEnd equ $
VGAFileMBuf resb FILENAME_MAX ; Mangled VGA image name
+
+; We need a buffer of 640+80 bytes. At this point, command_line should
+; not be in use, so use that buffer.
+VGARowBuffer equ command_line
alignb open_file_t_size
Files resb MAX_OPEN*open_file_t_size
-;
-; Constants for the xfer_buf_seg
-;
-; The xfer_buf_seg is also used to store message file buffers. We
-; need two trackbuffers (text and graphics), plus a work buffer
-; for the graphics decompressor.
-;
-xbs_textbuf equ 0 ; Also hard-coded, do not change
-xbs_vgabuf equ trackbufsize
-xbs_vgatmpbuf equ 2*trackbufsize
-
section .text
;;
;; Primary entry point. Because BIOSes are buggy, we only load the first
keywd_table:
keyword menu, pc_comment
keyword text, pc_text
- keyword include, pc_filecmd, pc_include
+ keyword include, pc_opencmd, pc_include
keyword append, pc_append
keyword default, pc_default
- keyword display, pc_filecmd, get_msg_file
+ keyword display, pc_opencmd, get_msg_file
keyword font, pc_filecmd, loadfont
keyword implicit, pc_setint16, AllowImplicit
keyword kbdmap, pc_filecmd, loadkeys
alignb open_file_t_size
Files resb MAX_OPEN*open_file_t_size
-;
-; Constants for the xfer_buf_seg
-;
-; The xfer_buf_seg is also used to store message file buffers. We
-; need two trackbuffers (text and graphics), plus a work buffer
-; for the graphics decompressor.
-;
-xbs_textbuf equ 0 ; Also hard-coded, do not change
-xbs_vgabuf equ trackbufsize
-xbs_vgatmpbuf equ 2*trackbufsize
-
-
section .text
;
; Some of the things that have to be saved very early are saved
;
; Generic file-processing commands:
-; "display", "font", "kbdmap", "include"
+; "font", "kbdmap",
;
pc_filecmd: push ax ; Function to tailcall
call pc_getline
mov di,MNameBuf
call mangle_name
- call searchdir ; tailcall
+ call searchdir
jnz .ok
pop ax ; Drop the successor function
.ok: ret ; Tailcall if OK, error return
;
-; "include" command (invoked from pc_filecmd)
+; Commands that expect the file to be opened on top of the getc stack.
+; "display", "include"
;
-pc_include: call openfd
- jz .err
- inc word [IncludeLevel]
+pc_opencmd: push ax ; Function to tailcall
+ call pc_getline
+ mov di,MNameBuf
+ call mangle_name
+ call open
+ jnz .ok
+ pop ax ; Drop the successor function
+.ok: ret ; Tailcall if OK, error return
+
+;
+; "include" command (invoked from pc_opencmd)
+;
+pc_include: inc word [IncludeLevel]
.err: ret
;
packet_buf resb 2048 ; Transfer packet
packet_buf_size equ $-packet_buf
-;
-; Constants for the xfer_buf_seg
-;
-; The xfer_buf_seg is also used to store message file buffers. We
-; need two trackbuffers (text and graphics), plus a work buffer
-; for the graphics decompressor.
-;
-xbs_textbuf equ 0 ; Also hard-coded, do not change
-xbs_vgabuf equ trackbufsize
-xbs_vgatmpbuf equ 2*trackbufsize
-
section .text
;
; PXELINUX needs more BSS than the other derivatives;
xchg di,ax
cmp byte [di+NULLOFFSET],NULLFILE
je short fk_nofile ; Undefined F-key
- call searchdir
+ call open
jz short fk_nofile ; File not found
- push si
call crlf
- pop si
call get_msg_file
jmp short fk_wrcmd