sseg segment stack
db 128 dup (0)
sseg ends
dseg segment para public 'global'
extrn parambuf:byte
extrn paramnr:word
extrn zonespace:byte
extrn newline:byte
configpath db 'config.txt',0 ; file name to be open
inprom db 13,10,13,10
db ' please input the full path for your kernel image:',13,10
db 13,10,20h,'#','$'
verion db 13,10
db ' stuix boot manager verion 1.0',13,10
db ' ============================='
db 13,10,13,10,'$'
lodwin db ' 1. To load windows, press [w] key','$'
lodstuix db ' 2. To load stuix, press [s] key','$'
custlod db ' 3. To load a custom kernel press [m] key'
db 13,10,13,10,' please enter your choice: ','$'
canonbuf db 21 dup (24h)
clsbuf db 21 dup (20h)
db '$'
dseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,ss:sseg
public rdconfig,chksynx,printmenu,pathinput,lodmbr,joinbuf
extrn panic:near
extrn printf:near
;/============================================================================
;
; rdconfig
;
;============================================================================/
rdconfig proc near
push ds ; save caller's segment
push es
push bp ; make stack frame
mov bp,sp
mov ax,3d00h ; read only open file
mov dx,offset configpath
int 21h
jnc suc
; don't clear carry if error detected
mov sp,bp
pop bp ; restore stack frame
pop es
pop ds
ret ; leave error code in ax
suc:
mov bx,ax ;we will read the config file
xor ax,ax
mov ah,3fh
mov dx,offset parambuf
mov cx,1024
int 21h
jnc suc1
mov sp,bp
pop bp
pop es
pop ds
ret
suc1:
mov [paramnr],ax ; indicate how many byte we read from config file
clc ; guaratee no error
; the file handler is already set properly
mov ah,3eh
int 21h ; close config file
; we don't care if this operating is successful
mov sp,bp
pop bp
pop es
pop ds
ret
rdconfig endp
;/============================================================================
;
; chksynx
;
;============================================================================/
chksynx proc near
push ds
push es
push bp
mov bp,sp
sub sp,4
; stack arranges like this
; [bp-2] : first '/' char position
; [bp-4] : first '$' char position
; try to find the '#', if '#' not present in our parameter
; buf, we will refuse to continue operating and panic
cmp word ptr [paramnr],0 ; configuration file can't be NULL
jne cnext1
mov ax,105
push ax
call panic
cnext1:
cld ; clear direction
mov di,offset parambuf
mov cx,[paramnr]
mov al,35 ; '#'
repnz scasb ; find first '#' char
jz found1
mov ax,100 ; get appropriate error code
push ax
call panic
found1:
; '/' should be first encounted
cld ; clear direction
mov di,offset parambuf
mov cx,[paramnr]
mov al,47 ; '/'
repnz scasb ; find first '/' char
jz found2
mov ax,106
push ax
call panic
found2:
mov [bp-2],di ; save position of '/'
cld ; clear direction
mov di,offset parambuf
mov cx,[paramnr]
mov al,36 ; '$'
repnz scasb ; find first '$' char
jz found3
mov ax,106
push ax
call panic
found3:
mov [bp-4],di
cmp [bp-2],di ; who is big?
jb right
mov ax,106
push ax
call panic
right:
mov sp,bp
pop bp
pop es
pop ds
ret
chksynx endp
;/============================================================================
;
; printmenu
;
;============================================================================/
printmenu proc near
push ds
push es
; clear the screen and home cursor
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,07
mov al,0
mov ah,6
int 10h ; clear screen
mov bh,0
mov dh,0
mov dl,0
mov ah,2
int 10h ; home cursor
mov ax,offset verion
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset lodwin
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset lodstuix
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset custlod
push ax
call printf
pop cx
; wait to accept user input, it only support
; w, s, m key, if other key is pressed, it
; will refuse to operate as if nothing hapens
waitkey:
mov ah,0
int 16h
cmp al,77h ; 'w'
jne pmnext1
mov ax,0
pop es
pop ds
ret
pmnext1:
cmp al,73h ; 's'
jne pmnext2
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,07
mov al,0
mov ah,6
int 10h ; clear screen
mov bh,0
mov dh,0
mov dl,0
mov ah,2
int 10h ; home cursor
mov ax,1
pop es
pop ds
ret
pmnext2:
cmp al,6dh ; 'm'
jne pmnext3
mov ax,offset inprom
push ax
call printf
pop cx
mov ax,2
pop es
pop ds
ret
pmnext3:
jmp waitkey
printmenu endp
;/============================================================================
;
; pathinput
;
;============================================================================/
pathinput proc near
push ds
push es
push bp
mov bp,sp
sub sp,8
; stack arranges like this
; [bp-2] : canonical buf pointer
; [bp-4] : canonical buf limiter
; [bp-6] : cursor line
; [bp-8] : cursor column
; initialize local variable
mov word ptr [bp-2],offset canonbuf
mov ax,offset canonbuf
add ax,20
mov [bp-4],ax
; save original cursor position
mov ah,3
mov bh,0
int 10h
mov [bp-6],dh
mov [bp-8],dl
; create an input loop, until '$' is encounted
; it treat enter key as '$'
inputloop:
; first check the canonbuf pointer, if it
; execeed limiter, it's time to return
mov ax,[bp-2]
cmp ax,[bp-4]
jb noful
jmp endinput
noful:
; accept user input
mov ah,0
int 16h
cmp al,1bh ; 'esc'
jne ipnext1
mov word ptr [bp-2],offset canonbuf
mov di,offset canonbuf
mov al,24h ; '$'
mov cx,21
cld
repnz stosb
; restore cursor and clear the echo
; at last restore cursor again
mov dh,[bp-6]
mov dl,[bp-8]
mov bh,0
mov ah,2
int 10h
mov ax,offset clsbuf
push ax
call printf ; line feed
pop cx
mov dh,[bp-6]
mov dl,[bp-8]
mov ah,2
int 10h
jmp inputloop
ipnext1:
cmp al,8 ; back space
jne ipnext2
cmp word ptr [bp-2],offset canonbuf
jne accept
jmp inputloop
accept:
dec word ptr [bp-2] ; obsolete one char
mov al,24h ; feed with '$'
mov di,[bp-2]
cld
stosb
; get current cursor position and obsolete one echo
mov ah,3
mov bh,0
int 10h
dec dl
mov bh,0
mov ah,2
int 10h
mov ah,3
mov bh,0
int 10h
push dx
mov ax,[bp-2]
sub ax,offset canonbuf
add ax,offset clsbuf
push ax
call printf
pop cx
pop dx
mov ah,2
mov bh,0
int 10h
jmp inputloop
ipnext2:
cmp al,13 ; carridge return
jne ipnext3
endinput:
mov di,[bp-2]
mov al,36 ; '$'
cld
stosb
mov ax,[bp-2]
sub ax,offset canonbuf
inc ax
; return the number of char in canonbuf, including '$'
mov sp,bp
pop bp
pop es
pop ds
ret
ipnext3:
cmp al,36 ; '$'
; '$' don't need echo
jne ipnext4
jmp endinput
ipnext4:
; ordinary char process and echo
mov di,[bp-2]
cld
stosb
mov [bp-2],di
mov bh,0
mov ah,0eh
int 10h
jmp inputloop
pathinput endp
;/============================================================================
;
; lodmbr
;
;============================================================================/
lodmbr proc near
push ds
push es
; we just load mbr at 7c00h and execute it
mov bx,offset zonespace
mov dl,80h
mov dh,0
mov ch,0
mov cl,1
mov al,1
mov ah,2
int 13h
mov ah,1
int 13h
cmp ah,0
je hdok
pop es
pop ds ; conversation method
mov al,ah
xor ah,ah
push ax
call panic
hdok:
; we don't believe the hard disk will fail
; if so, it must be a fatal error, it is
; not necessary to try any more
pop es
pop ds
push ds
push es
mov ax,0
mov es,ax
mov di,7c00h
mov si,offset zonespace
mov cx,512
cld
repnz movsb
mov ax,0
mov ds,ax
mov si,7c00h
add si,200h-2
lodsw
cmp ax,0aa55h
je execmbr
pop es
pop ds
mov ax,11
push ax
call panic
execmbr:
db 0eah
dw 7c00h
dw 0
; now stuix boot manager is obsoleting
lodmbr endp
;/============================================================================
;
; joinbuf
;
;============================================================================/
joinbuf proc near
push ds
push es
push bp
mov bp,sp
sub sp,2
; stack arranges like this
; [bp-2] : number of char need to be concatenate
mov ax,8[bp]
mov [bp-2],ax
mov si,offset canonbuf
mov di,offset parambuf
add di,11 ; skip string '/etc/fstab$'
mov cx,[bp-2]
cld
repnz movsb
mov al,23h ; '#'
stosb ; append at tail
; calulate the total effective character in parambuf
mov si,offset parambuf
sub di,si
mov [paramnr],di ; used by syntax check
mov sp,bp
pop bp
pop es
pop ds
ret
joinbuf endp
cseg ends
end