⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stuixldr.asm

📁 一个朋友写的操作系统源码
💻 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 + -