📄 stuixldr.asm
字号:
include const.inc
include comstruc.inc
dseg segment para public 'global'
bmpdata db 1024*10 dup (0) ; contain compressed info
pad dw 1023 ; can hold last byte and '|' maybe
palette db 1024 dup (0)
testmes db 13,10,13,10,'read to switch to protected mode ...','$'
; Global varibles store here
; May be linked to other modual
public parambuf,paramnr,inodeblk,superblk
public configbuf,zonespace
public dirp,fn,dbuf,prom
superblk equ this byte ; superblk is used once, just multiplex
zonespace db 1024 dup (0) ; in floppy fs, block = zone
parambuf db '/etc/fstab$/stuix/kernel.bin$#'
db 64 dup (0)
paramnr dw 0 ; init to 0, only used for syntax checking
inodeblk db 1024 dup (0) ; block incore version
dirp dw 0 ; path character indicator
fn dw 0 ; files have been processed
dbuf db 14 dup (0) ; current pathname component
prom db '%d files have been converted!','$'
configbuf db 1024 dup (0) ; holding /etc/fstab
a20mes db 13,10,'opening A20# address line',13,10,'$'
extrn newline:byte
dseg ends
overlap segment para common 'strucinfo'
; this is the only way to reference
; extern struct
inodeinfo minixinode <>
superinfo minixsuper <>
dent dirent <>
overlap ends
sseg segment stack
db 128 dup (0)
sseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,es:dseg,ss:sseg
extrn printf:near
extrn panic:near
extrn printmenu:near
extrn pathinput:near
extrn lodmbr:near
extrn joinbuf:near
extrn chksynx:near
extrn eatpath:near
extrn getsuper:near
extrn getzone:near
extrn getinode:near
start:
push bp
mov bp,sp
sub sp,2
mov word ptr [bp-2],offset testmes
mov ax,dseg
mov ds,ax
mov es,ax
; file sytem self test
call getsuper ; init incore super structure slot
; if the fs magic number can't be found
; we have to stop here
; next we will try to analysis the parambuf
mov ax,1 ; get root inode
push ax
call getinode
pop ax
mov ax,1 ; read zone 1
push ax
call getzone
pop ax
; verify the attrib of root inode
push ds
mov ax,overlap
mov ds,ax
assume ds:overlap
mov ax,[inodeinfo.i_mode]
pop ds
assume ds:dseg ; restore segment
and ax,I_TYPE
cmp ax,I_DIRECTORY
je noproblem
mov ax,88h ; generate an unknow error
push ax
call panic
noproblem:
; display stuix logo
call dispbmp
call printmenu
; according to the value printmenu return
; we will branch to diffent subroutines
cmp ax,0
jne mbnext1
call lodmbr
; control will pass to hard disk mbr
mbnext1:
cmp ax,1
jne mbnext2
; clean the screen
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,7
mov al,0
mov ah,6
int 10h ; clean screen
mov bh,0
mov dh,0
mov dl,0
mov ah,2
int 10h ; home cursor
call eatpath
jmp finish
mbnext2:
; the last, ax must be 2
call pathinput
push ax
call joinbuf
pop cx
call chksynx ; almost verbose in this environment
; clean the screen
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,7
mov al,0
mov ah,6
int 10h ; clean screen
mov bh,0
mov dh,0
mov dl,0
mov ah,2
int 10h ; home cursor
call eatpath
finish:
; if fn < 2, it indicates there's some problem
; loading kernel or fstab, we can't move on
cmp word ptr [fn],2
je movon
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,13
push ax
call panic
movon:
mov ax,offset a20mes
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
call enablea20
mov ax,[bp-2]
push ax
call printf
pop cx
hang:
jmp hang
;/============================================================================
;
; dispbmp
;
;============================================================================/
dispbmp proc near
push ds
push es
push bp
mov bp,sp
sub sp,2
; stack arranges like this
; [bp-2] : palette index
; first it should clear the screen in
; text mode and move the cursor to the
; the uper left conner
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,7
mov al,0
mov ah,6
int 10h
mov bh,0
mov dh,0
mov dl,0
mov ah,2
int 10h
; now we switch to graphice mode
mov ah,0 ; mode setting
mov al,13h ; 0x13 mode for 320*200
int 10h
; it is the opportunity to set palette
mov al,0 ; set palette register array index
mov dx,3c8h
out dx,al
mov word ptr [bp-2],0
bmw1loop:
cmp word ptr [bp-2],256*3
jae bmnext1
mov si,[bp-2]
mov al,palette[si]
mov dx,3c9h
out dx,al
inc word ptr [bp-2]
jmp bmw1loop
bmnext1:
; decompress data and load to video memory
call decompress
; delay 2 second to show boot menu
mov ax,36
push ax
call delay
pop cx
; switch back to test mode
mov ah,0
mov al,3
int 10h
mov sp,bp
pop bp
pop es
pop ds
ret
dispbmp endp
;/============================================================================
;
; decompress
;
;============================================================================/
decompress proc near
push ds
push es
push bp
mov bp,sp
sub sp,4
; stack arranges like this
; [bp-2] : compressed buf index
; [bp-4] : video memory index
mov ax,0a000h
mov es,ax
; initialize local variable
mov word ptr [bp-2],0
mov word ptr [bp-4],0
; search for a ~, if not found, move
; current pixel byte to video memory
; increase the video memory index and
; compressed buf index. if found, expand
; the original pixels to the video memory
; add the count to the video memory index
; and the compressed buf index, skip to
; next element
mov word ptr [bp-2],offset bmpdata
mov word ptr [bp-4],0
dpw1loop:
mov si,[bp-2]
cld
lodsb
inc word ptr [bp-2] ; we don't know what will happen
cmp al,7ch ; |
je depover
cmp al,7eh ; ~
jne dpnext1
; if this is a compressed element
add word ptr [bp-2],3 ; move to the next element
lodsw ; get compress count of element
mov cx,ax
mov di,[bp-4]
add word ptr [bp-4],cx
lodsb
repnz stosb ; expand to video memory
jmp dpw1loop
dpnext1:
mov di,[bp-4]
inc word ptr [bp-4]
stosb
jmp dpw1loop
depover:
; we have finish our job, just
; go back to dispbmp
mov sp,bp
pop bp
pop es
pop ds
ret
decompress endp
;/============================================================================
;
; enablea20
;
;============================================================================/
enablea20 proc near
push ds
push es
push bp
mov bp,sp
sub sp,4
; stack arranges like this
; [bp-2] : retry time
; [bp-4] : output port image
cli ; disable interrupt
mov word ptr [bp-2],5
; we allow 5 attempts to turn A20 if necessary
startattempt1:
; read / write output port command require
; the output buf empty before issue
commandwait1:
in al,64h
test al,1
jnz commandwait1
; we will issue read output port
mov al,0d0h
out 64h,al
; wait for the controller to be
; ready with a byte of data
datawait1:
in al,64h
test al,1
jz datawait1
xor ax,ax
in al,60h
mov [bp-4],ax ; save the image of output port
commandwait2:
in al,64h
test al,1
jnz commandwait2
; issue the write output port command
mov al,0d1h
out 64h,al
commandwait3:
in al,64h
test al,1
jnz commandwait3
mov ax,[bp-4]
; turn on A20
or al,00000010b
out 60h,al
; we have to wait at least 25 us
; so write to a unused port. ie 0xed
mov cx,100
waitport1:
xor al,al
out 0edh,al ; each time consume 1 us
dec cx
cmp cx,0
jnz waitport1
; insure A20 was enabled
commandwait4:
in al,64h
test al,1
jnz commandwait4
mov al,0d0h
out 64h,al
; wait for the controller to be ready
; with a byte of data
datawait2:
in al,64h
test al,1
jz datawait2
in al,60h
; test if A20 enable
test al,2
jnz ea20suc
dec word ptr [bp-2]
cmp word ptr [bp-2],0
jnz startattempt1 ; try again
; well, our initialize attempt to set A20 has failed
; now we will try a backup method which is supposedly
; not supported on many chipsets but which seems to
; be the only method that works on other chipsets
; reinitialize retry counter
mov word ptr [bp-2],5
jmp startattempt2
ea20suc:
mov sp,bp
pop bp
pop es
pop ds
ret
startattempt2:
; wait for the keyboard to be ready for
; another command
commandwait6:
in al,64h
test al,1
jnz commandwait6
; tell the controller we want to turn on A20
mov al,0dfh
out 64h,al
; we have to wait at least 25 us
; so write to a unused port. ie 0xed
mov cx,100
waitport2:
xor al,al
out 0edh,al ; each time consume 1 us
dec cx
cmp cx,0
jnz waitport2
; agian we will attempt to read back
; the A20 status to insure it was enabled
; wait for the controller to be ready
; for a command
commandwait7:
in al,64h
test al,1
jnz commandwait7
; send the command 0d0h, read output port
mov al,0d0h
out 64h,al
; wait for the controller to be ready
; with a byte of data
datawait3:
in al,64h
test ax,1
jz datawait3
; read current port status from port 60h
in al,60h
test ax,2
jnz ea20suc
dec word ptr [bp-2]
cmp word ptr [bp-2],0
jnz startattempt2 ; try again alter method
; unfortunately, we failed again!
mov ax,16
push ax
call panic
enablea20 endp
;/============================================================================
;
; delay
;
;============================================================================/
delay proc near
push ds
push es
push bp
mov bp,sp
sub sp,8
; stack arranges like this
; [bp-2] : delay ticks
; [bp-4] : delay begin low 16bit
; [bp-6] : wakeup high 16bit
; [bp-8] : wakeup low 16bit
mov ax,8[bp]
mov [bp-2],ax
; get the low 16 bit of clock ticks
mov ax,40h ; clock ticks segment in BIOS
mov ds,ax
mov si,6ch ; low word offset in BIOS memory
mov ax,[si]
mov [bp-4],ax
add ax,[bp-2] ; calulate the wakeup time
mov [bp-8],ax
cmp ax,[bp-4]
jae dnext1
; wrap around detected, we have to store
; the high 16bit
mov si,6eh
mov ax,[si]
mov [bp-6],ax
inc word ptr [bp-6]
; assume it can't be second wrap around
; now wait for counter reaches that value
dw1loop:
mov si,6eh
mov ax,[si]
cmp ax,[bp-6]
je dnext2
jmp dw1loop
dnext2:
mov si,6ch
mov ax,[si]
cmp ax,[bp-8]
je dnext3
jmp dnext2
dnext3:
; time to go
mov sp,bp
pop bp
pop es
pop ds
ret
dnext1:
jmp dnext2
delay endp
cseg ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -