📄 ub.asm
字号:
;** 6145-F, Northbelt Parkway, Norcross, **;
;** **;
;** Georgia - 30071, USA. Phone-(770)-246-8600. **;
;** **;
;*****************************************************************;
;*****************************************************************;
;-----------------------------------------------------------------------;
;---------------------------------------;
; SETUP INTERRUPT VECTORS ;
;---------------------------------------;
;;;;r_memory_0:
check_point_ini 0e0h ; ========== E0
mov ds:word ptr [13h],200h ; base memory size
xor ax,ax
mov ds:word ptr [72h],ax ; clear CTRL-ALT-DEL
mov es:word ptr [0eh*4],offset cgroup:int_0e
mov es:word ptr [0eh*4+2],ax
mov es:word ptr [1eh*4],offset cgroup:diskette_parameter_table
mov es:word ptr [1eh*4+2],ax
mov es:word ptr [13h*4],offset cgroup:int_40
mov es:word ptr [13h*4+2],ax
;---------------------------------------;
; INITIALISE DMA CONTROLLER ;
;---------------------------------------;
out dma_1_byte_ptr_ff_reset,al; data not important (#1)
io_delay
out dma_2_byte_ptr_ff_reset,al; data not important (#2)
mov al,00000000b
io_delay
out dma_unit_1_command_port,al; enable DMA unit (#1)
io_delay
out dma_unit_2_command_port,al; enable DMA unit (#2)
call init_8237_dma ; initialize DMA unit #1, #2
mov al,00000000b
out dma_unit_2_writ_req_reg,al; clear write request reg
io_delay
out dma_unit_2_mask_s_r_reg,al; clear mask set/reset reg
;---------------------------------------;
; 8259 INTERRUPT CNTLR TEST ;
;---------------------------------------;
intr_0:
mov al,00010001b ; icw1, edge, icw4
out i_c_s_port,al ; int cntlr slave port
io_delay
out i_c_m_port,al ; int cntlr master port
io_delay
mov al,level_1_int ; start vector for intr #2
out i_s_m_port,al
io_delay
mov al,level_2_int ; start vector for intr #1
out i_m_m_port,al
io_delay
mov al,02 ; setup icw3, slave, level 2
out i_s_m_port,al
io_delay
mov al,04 ; setup icw3, master, level 2
out i_m_m_port,al
io_delay
mov al,01 ; setup icw4, 8086 mode,slave
out i_s_m_port,al
io_delay
out i_m_m_port,al ; setup icw4 for master
io_delay
mov al,11111111b ; (#2) mask value
out i_s_m_port,al
io_delay
mov al,10111111b ; (#1) mask value
out i_m_m_port,al
;---------------------------------------;
; ENABLE INTERNAL CACHE ;
;---------------------------------------;
call enable_internal_cache
;;;; jmp int_19
;-----------------------------------------------------------------------;
; INT19 ;
; this routine replaces the normal INT19 used for booting OS. it does ;
; the following: ;
; * checks for diskette (must be in DOS format) to be inserted in the ;
; floppy drive A:. ;
; * search for the presence of a pre-defined file (say, BIOS.ROM) in ;
; the diskette. ;
; * if not found, informs the user and starts afresh. ;
; * reads BIOS.ROM file from the diskette into RAM. ;
; * in case of any error during reading, it informs the user and starts;
; afresh. ;
; * program the flash. ;
;-----------------------------------------------------------------------;
ptr_to_source_buffer equ 100000h ; 1m:0 has the full BIOS file data
read_file_segment equ 2000h ; segment where BIOS file is being read
sec_1_buffer equ 0500h ; offset where 1st sector is being read
dir_cluster_buffer equ 0600h ; offset where dir sector is being read
; and where cluster#s of the file is being stored
drive_number equ 0000h ; 00 for A:, 01 for B:
no_of_bytes_dir_entry equ 0020h ; 32 bytes per director entry
end_of_cluster equ 0ffffh ; end of cluster indicator
;---------------------------------------;
;;;;int_19:
check_point_ini 0edh ; ======== ED
; F000 segment is free and can be programmed freely..
;---------------------------------------;
; FLOPPY UNIT INITIALISATION ;
;---------------------------------------;
sti
extrn floppy_diskette_setup:near
call floppy_diskette_setup ; floppy cntlr & data setup
jnc dse_00 ; ok
; (CORE0211+)>
public dummy_ret
extern atapi_setup(dummy_ret):near
call atapi_setup ; ATAPI controller/device setup
jnc short dse_00 ; ok
; <(CORE0211+)
mov si,offset cgroup:floppy_cntlr_err
jmp display_blink_halt ; display and halt
dse_00:
;---------------------------------------;
; set DS, ES for reading the 1st sector of the diskette..
xor ax,ax
mov ds,ax
mov es,ax
; ask user to insert the diskette in drive A:..
check_point_ini 0eeh ; ======== EE
i19_02_00:
mov si,offset cgroup:flp_ins_msg; inform user to insert diskette
i19_02:
call display_on_port ; in drive A:
mov cx,8000h
call fixed_delay
i19_00:
; reset diskette system..
mov ah,00h ; reset func#
mov dl,drive_number ; drive A:
int 13h ; reset
; read sector 1, hd 0, cyl 0..
mov bx,sec_1_buffer ; ES:BX ptr to buffer
mov si,bx ; ES:BX = ES:SI
mov cx,0001h ; CH = cyl#, CL = sec#
mov dh,00h ; DH = hd#, DL = drv#
mov ax,0201h ; read 1 sector
int 13h
jnc i19_01 ; ok..
cmp ah,80h ; drive not ready ?
jz i19_02_00 ; yes..so try again..
cmp ah,06h ; media change ?
jz i19_00 ; yes..so try again..
pusha
check_point_ini 0efh ; ======== EF
popa
i19_03:
; read error..
mov si,offset cgroup:read_err_msg; read error
jmp short i19_02 ; display error and retry..
i19_01:
; ES:BX = ES:SI = DS:BX = DS:SI..ptr to content of sec 1, hd 0, cyl 0 of diskette in drive A:..
pusha
mov si,offset cgroup:flp_read_msg; indicate floppy reading going on
call display_on_port
popa
; find absolute start sector# of root directory..
mov al,[si+10h] ; AL = #of FATs
mov ah,00h ; AX = #of FATs
mul word ptr [si+16h] ; multiply by #of sectors per FAT
; AX = #of sectors occupied by FATs
; !!!! DX destroyed by MUL instruction
add ax,[si+1ch] ; add #of hidden sectors
add ax,[si+0eh] ; add #of reserved sectors
; AX = absolute start sector# of root directory..
mov bp,ax ; BP = abs start sector# of root directory
mov ax,no_of_bytes_dir_entry; 32 bytes per director entry
mul word ptr [si+11h] ; multiply by #of entries in directory
; DX:AX = #of bytes in root directory
div word ptr [si+0bh] ; divide by #of bytes per sector
or dx,dx
jz i19_04
inc ax
i19_04:
; AX = #of sectors occupied by root directory..
; BP = abs start sector# of root directory..
mov cx,ax ; CX = #of sectors in root directory
add ax,bp ; AX = start absolute sector# of data area
mov [si],ax ; save start absolute sector# of data area
mov ax,[si+0bh] ; #of bytes per sector
mov bl,no_of_bytes_dir_entry; 32 bytes per directory entry
div bl ; AL = #of entries in one dir sector
mov ah,00h
mov di,ax ; DI = #of entries in one dir sector
i19_05:
pusha
check_point_ini 0f0h ; ======== F0
popa
mov ax,bp ; absolute sector# of next root dir sector
push cx
push di
mov si,sec_1_buffer ; DS:SI ptr to floppy BPB informn
call find_sector_head_cyl ; calculate cyl#, head#, sector#
mov bx,dir_cluster_buffer ; ES:BX ptr to buffer
mov ax,0201h ; read 1 sector
int 13h
jc i19_03 ; error..
i19_06:
; search for the pre-defined file name..
push di
mov di,bx ; ES:DI ptr to dir entry
mov si,offset cgroup:rom_filename; DS:SI ptr to pre-defined ROM filename
mov cx,000bh ; 11 bytes in filename
repz cmps cs:byte ptr [si],es:byte ptr [di]; match filename in directory
pop di
jz i19_07 ; filename found..
add bx,no_of_bytes_dir_entry; ptr to next dir entry
dec di
jnz i19_06 ; continue searching in this dir sector
pop di ; DI = #of entries in one dir sector
pop cx
inc bp ; abs sector# of next dir sector
loop i19_05 ; goto search in next dir sector
pusha
check_point_ini 0f1h ; ======== F1
popa
; file not found..
mov si,offset cgroup:file_abs_msg
jmp i19_02
i19_07:
pop di
pop cx
; file found in root dirctory..ES:BX ptr to concerned dir entry..
; store the cluster#s of the file serially in the dir_cluster_buffer..
mov di,dir_cluster_buffer
mov ax,es:[bx+1ah] ; start cluster# of the file from the
; concerned directory entry
mov [di],ax ; save the start cluster number
; read the FAT sectors one by one at scratch segment..
mov si,sec_1_buffer
mov bp,[si+16h] ; BP = #of sectors in a FAT
push ds
mov bx,0040h
mov ds,bx ; DS = 0040h
mov bx,ds:[0013h] ; #of 1Ks memory below 1M
pop ds
shr bx,06h ; #of 64Ks memory below 1M
dec bx
shl bx,0ch ; BX = last segment below 640K
mov es,bx ; ES = segment where fat sectors is
; going to be read
pusha
check_point_ini 0f2h ; ======== F2
popa
xor bx,bx ; fat_segment:0 will have the FAT sectors
mov dx,00h*256+drive_number ; DH,DL = head# of 1st sect, drive#
mov cx,0001h ; CH,CL = cyl#, sec# of 1st sector
i19_08:
call find_next_sector_hd_cyl ; find sec#, hd#, cyl# of next sector
; read next FAT sector..
; DH,DL = head# of next FAT sector, drive#..
; CH,CL = cyl#, sector# of next FAT sector..
mov ax,0201h ; read one FAT sector at a time
int 13h
jc i19_03_00 ; read error..
add bx,[si+0bh] ; update ptr to buffer
dec bp
jnz i19_08 ; read all FAT sectors
; all FAT sectors are read at ES:0000..
; DS:SI ptr to BPB information..
; DS:DI ptr to cluster# storage area..
mov ax,[di] ; get start cluster# of the file
inc di
inc di
call find_store_cluster_nos ; find and store the cluster#s
; all cluster#s (WORD) of the file are stored serially
; at DS:dir_cluster_buffer..
; DS:SI ptr to BPB information..
; read the file cluster by cluster..
mov di,dir_cluster_buffer
xchg si,di
; DS:SI ptr to cluster# storage area..
; DS:DI ptr to BPB information..
mov dword ptr [di+80h],ptr_to_source_buffer; init ptr to source buffer
mov bp,[di+0dh]
and bp,00ffh ; BP = #of sectors per cluster
pusha
check_point_ini 0f3h ; ======== F3
popa
i19_10:
lodsw ; get next cluster#
cmp ax,0ffffh ; end of file ?
jz i19_09 ; yes..
push read_file_segment ; segment:0 where next cluster will be read
pop es
xor bx,bx
push bx
call read_1_cluster
pop bx
jc i19_03_00 ; read error
; copy the read data to the source buffer
; ES:BX = ptr to read data, BP = #of sectors read
; DS:DI = ptr to BPB information
pushad
mov ax,[di+0bh] ; #of bytes per sector
mul bp
push dx
push ax
pop ecx ; ECX = #of bytes read
push di
mov edi,dword ptr ds:[di+80h]; EDI = ptr to source buffer
movzx esi,bx
push es
push ds
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -