Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1 → Rev 2

/trunk/memmap.inc
File deleted
/trunk/gui/skindata.inc
File deleted
/trunk/gui/skincode.inc
File deleted
/trunk/gui/event.inc
File deleted
/trunk/gui/font.inc
File deleted
/trunk/gui/window.inc
File deleted
/trunk/gui/mouse.inc
File deleted
\ No newline at end of file
/trunk/gui/button.inc
File deleted
/trunk/build_en.bat
File deleted
\ No newline at end of file
/trunk/sound/sb16.inc
File deleted
/trunk/sound/playnote.inc
File deleted
/trunk/core/sched.inc
File deleted
/trunk/core/fpu.inc
File deleted
/trunk/core/syscall.inc
File deleted
/trunk/core/sync.inc
File deleted
/trunk/core/mem.inc
File deleted
/trunk/core/newproce.inc
File deleted
/trunk/core/memmanag.inc
File deleted
/trunk/core/physmem.inc
File deleted
\ No newline at end of file
/trunk/core/sys32.inc
File deleted
/trunk/network/queue.inc
File deleted
/trunk/network/stack.inc
File deleted
/trunk/network/tcp.inc
File deleted
/trunk/network/ip.inc
File deleted
\ No newline at end of file
/trunk/network/udp.inc
File deleted
\ No newline at end of file
/trunk/network/eth_drv/rtl8029.inc
File deleted
/trunk/network/eth_drv/i8255x.inc
File deleted
\ No newline at end of file
/trunk/network/eth_drv/rtl8139.inc
File deleted
/trunk/network/eth_drv/sis900.inc
File deleted
/trunk/network/eth_drv/3c59x.inc
File deleted
/trunk/network/eth_drv/ethernet.inc
File deleted
/trunk/network/eth_drv/pcnet32.inc
File deleted
/trunk/bus/pci/pci32.inc
File deleted
/trunk/bus/pci/pci16.inc
File deleted
\ No newline at end of file
/trunk/vmodeint.inc
File deleted
/trunk/kernel32.inc
File deleted
/trunk/kernel16.inc
File deleted
\ No newline at end of file
/trunk/kernel.asm
File deleted
/trunk/vmodeld.inc
File deleted
\ No newline at end of file
/trunk/boot/booteng.inc
File deleted
/trunk/boot/bootcode.inc
File deleted
/trunk/boot/rdload.inc
File deleted
/trunk/boot/ru.inc
File deleted
\ No newline at end of file
/trunk/boot/bootru.inc
File deleted
/trunk/boot/preboot.inc
File deleted
/trunk/boot/shutdown.inc
File deleted
/trunk/hid/keyboard.inc
File deleted
/trunk/hid/set_dtc.inc
File deleted
/trunk/video/vga.inc
File deleted
/trunk/video/vesa20.inc
File deleted
/trunk/video/vesa12.inc
File deleted
/trunk/kglobals.inc
File deleted
/trunk/blkdev/fdc.inc
File deleted
\ No newline at end of file
/trunk/blkdev/flp_drv.inc
File deleted
/trunk/blkdev/cdrom.inc
File deleted
/trunk/blkdev/rdsave.inc
File deleted
/trunk/blkdev/rd.inc
File deleted
/trunk/fs/fs.inc
File deleted
/trunk/fs/fs_phys.inc
File deleted
\ No newline at end of file
/trunk/fs/fat12.inc
File deleted
/trunk/fs/fat32.inc
File deleted
/trunk/detect/sear_par.inc
File deleted
/trunk/detect/disks.inc
File deleted
/trunk/detect/dev_hdcd.inc
File deleted
/trunk/detect/commouse.inc
File deleted
/trunk/detect/dev_fd.inc
File deleted
/trunk/build_ru.bat
File deleted
\ No newline at end of file
/trunk
Property changes:
Deleted: svn:ignore
-*.mnt
-lang.inc
-*.bat
-out.txt
-scin*
/kernel/trunk/blkdev/cdrom.inc
0,0 → 1,261
sys_cd_audio:
 
cmp word [cdbase],word 0
jnz @f
mov eax,1
ret
@@:
 
; eax=1 cdplay at ebx 0x00FFSSMM
; eax=2 get tracklist size of ecx to [ebx]
; eax=3 stop/pause playing
 
cmp eax,1
jnz nocdp
call sys_cdplay
ret
nocdp:
 
cmp eax,2
jnz nocdtl
mov edi,[0x3010]
add edi,0x10
add ebx,[edi]
call sys_cdtracklist
ret
nocdtl:
 
cmp eax,3
jnz nocdpause
call sys_cdpause
ret
nocdpause:
 
mov eax,0xffffff01
ret
 
 
 
sys_cd_atapi_command:
 
pushad
 
mov dx,word [cdbase]
add dx,6
mov ax,word [cdid]
out dx,al
mov esi,10
call delay_ms
mov dx,word [cdbase]
add dx,7
in al,dx
and al,0x80
cmp al,0
jnz res
jmp cdl6
res:
mov dx,word [cdbase]
add dx,7
mov al,0x8
out dx,al
mov dx,word [cdbase]
add dx,0x206
mov al,0xe
out dx,al
mov esi,1
call delay_ms
mov dx,word [cdbase]
add dx,0x206
mov al,0x8
out dx,al
mov esi,30
call delay_ms
xor cx,cx
cdl5:
inc cx
cmp cx,10
jz cdl6
mov dx,word [cdbase]
add dx,7
in al,dx
and al,0x88
cmp al,0x00
jz cdl5
mov esi,100
call delay_ms
jmp cdl5
cdl6:
mov dx,word [cdbase]
add dx,4
mov al,0
out dx,al
mov dx,word [cdbase]
add dx,5
mov al,0
out dx,al
mov dx,word [cdbase]
add dx,7
mov al,0xec
out dx,al
mov esi,5
call delay_ms
mov dx,word [cdbase]
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,128
out dx,al
add dx,2
mov al,0xa0
out dx,al
xor cx,cx
mov dx,word [cdbase]
add dx,7
cdl1:
inc cx
cmp cx,100
jz cdl2
in al,dx
and ax,0x88
cmp al,0x8
jz cdl2
mov esi,2
call delay_ms
jmp cdl1
cdl2:
 
popad
ret
 
 
sys_cdplay:
 
mov ax,5
push ax
push ebx
cdplay:
call sys_cd_atapi_command
cli
mov dx,word [cdbase]
mov ax,0x0047
out dx,ax
mov al,1
mov ah,[esp+0] ; min xx
out dx,ax
mov ax,[esp+1] ; fr sec
out dx,ax
mov ax,256+99
out dx,ax
mov ax,0x0001
out dx,ax
mov ax,0x0000
out dx,ax
mov esi,10
call delay_ms
sti
add dx,7
in al,dx
test al,1
jz cdplayok
mov ax,[esp+4]
dec ax
mov [esp+4],ax
cmp ax,0
jz cdplayfail
jmp cdplay
cdplayfail:
cdplayok:
pop ebx
pop ax
xor eax, eax
ret
 
 
sys_cdtracklist:
 
push ebx
tcdplay:
call sys_cd_atapi_command
mov dx,word [cdbase]
mov ax,0x43+2*256
out dx,ax
mov ax,0x0
out dx,ax
mov ax,0x0
out dx,ax
mov ax,0x0
out dx,ax
mov ax,200
out dx,ax
mov ax,0x0
out dx,ax
in al,dx
mov cx,1000
mov dx,word [cdbase]
add dx,7
cld
cdtrnwewait:
mov esi,10
call delay_ms
in al,dx
and al,128
cmp al,0
jz cdtrl1
loop cdtrnwewait
cdtrl1:
; read the result
mov ecx,[esp+0]
mov dx,word [cdbase]
cdtrread:
add dx,7
in al,dx
and al,8
cmp al,8
jnz cdtrdone
sub dx,7
in ax,dx
mov [ecx],ax
add ecx,2
jmp cdtrread
cdtrdone:
pop ecx
xor eax, eax
ret
 
 
sys_cdpause:
 
call sys_cd_atapi_command
 
mov dx,word [cdbase]
mov ax,0x004B
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
 
mov esi,10
call delay_ms
add dx,7
in al,dx
 
xor eax, eax
ret
 
/kernel/trunk/blkdev/fdc.inc
0,0 → 1,369
;### fdc.inc ### Menuetos floppy stuff.
;Version 0.2: Write individual tracks. / Sync ramdisk <-> floppy
;Version 0.1: Write full ramdisk to floppy.
;£loppyright Tolle.
 
;depends on:
;restorefatchain
;memmove
;Int 6 (sys32.inc) should call fdc_irq func.
;The ramdisk should be at 0x100000
 
;Keeping track of the tracks.
iglobal
cylinder db 0
sector db 1
head db 0
 
;Memory and dma variables.
fdcmem dd 0x100000
cpymem dd 0x100000
dmamem dd 0x100000
endg
 
uglobal
dmasize db 0x0
dmamode db 0x0
endg
 
iglobal
;function pointers.
fdc_irq_func dd fdc_null
fdc_pump_func dd fdc_null
endg
 
uglobal
;General stuff
fdc_st0 db 0 ;status register 0 of last resultphase.
fdc_mutex db 0 ;wait in line. (Block calling app)
fdc_callspending db 0 ;mystery sauce
fdc_settings dd 0 ;bitfield.
endg
;Bit 0 enable direct file write [yes/no]
 
fdc_set: ;ebx: fdc_settings bitfield.
mov [fdc_settings],ebx
ret
 
fdc_get: ;returns fdc_settings in ecx
mov ecx, [fdc_settings]
ret
 
fdc_init: ;start with clean tracks.
mov edi,0xD201
mov al,0
mov ecx,160
rep stosb
ret
 
fdc_filesave: ;ebx: cluster to be saved.
pusha ;returns immediately. does not trigger a write.
mov eax,ebx
add eax,31
mov bl,18
div bl
mov ah,0
add eax,0xD201
mov [eax],byte 1 ;This track is now dirty.
popa
ret
 
 
fdc_writeramdisk: ;mark all tracks as dirty.
mov edi,0xD201
mov al,1
mov ecx,160
rep stosb
jmp fdc_commitflush
fdc_commitfile: ;flush dirty tracks to floppy
test [fdc_settings],1 ;...but only if this is really wanted by the user.
je fdc_commitend
fdc_commitflush:
cmp [fdc_callspending],5
je fdc_commitend
inc [fdc_callspending]
cmp [fdc_callspending],1
je fdc_commitonce
fdc_commitend:
ret
 
fdc_commitonce: ;One at a time.
.stall:
cli
cmp [fdc_mutex],0
jne .stallret
mov [fdc_mutex],1
jmp .goahead
.stallret:
sti
jmp .stall
.goahead:
sti
 
fdc_commitramdisk:
 
call restorefatchain
;Move the bootsector to a safe place.
mov eax,0x100000
mov ebx,0xD000
mov ecx,512
call memmove
;Always write the FAT table
mov eax,0xD201
mov [eax],byte 1
inc eax
mov [eax],byte 1
 
mov [dmamode],0x4A ;read from memory to floppy.
mov [dmasize],0x1 ;read 512 bytes sectors.
mov [fdc_irq_func],fdc_commitramdisk1
call fdc_floppy_on ;start floppy A: moter starts interruptflow.
ret
fdc_commitramdisk1:
mov [fdc_irq_func],fdc_recalibrate_result
mov [fdc_pump_func],fdc_commitramdisk2
call fdc_recalibrate ;retract the head to cylinder 0, sector 1
ret
fdc_commitramdisk2:
mov[head],0 ;set variables.
mov[cylinder],0
mov [sector],1
mov[cpymem],0x102400
mov [fdc_pump_func],fdc_fullpump
call fdc_write ;fdc_write will continue interruptflow
ret
 
fdc_fullpump:
add [dmamem],512
add [sector],1
cmp [sector],19
jne .clusterwrite
sub [dmamem],9216
mov eax,[cpymem]
mov ebx,[fdcmem]
mov ecx,9216
call memmove
add [cpymem],9216
cmp [head],0
je .nocylinderchange
add [cylinder],1
.nocylinderchange:
xor [head],1
cmp [cylinder],80
jne .noendofwrite
mov[fdc_irq_func],fdc_complete
call fdc_floppy_off
call fdc_init
jmp .end
.noendofwrite:
mov [sector],1
.clusterwrite:
xor eax,eax
mov al,[cylinder]
shl eax,1
add al,[head]
add eax,0xD201
mov bl,[eax]
cmp bl,1
jne fdc_fullpump
call fdc_write
.end:
ret
 
fdc_write:
call fdc_program_dma
call fdc_seek
ret
 
fdc_seek:
mov al, 0x0f
call fdc_write_reg
mov al,[head]
shl al,2
call fdc_write_reg
mov al,[cylinder]
call fdc_write_reg
mov [fdc_irq_func],fdc_seek_result
ret
 
fdc_seek_result:
call fdc_sensei
cmp al,[cylinder]
je .succes
call fdc_seek
jmp .end
.succes:
call fdc_write_sector
.end:
ret
 
fdc_write_sector:
mov al,0x45 ;write sector command
fdc_commandphase:
call fdc_write_reg
mov al,[head]
shl al,2
call fdc_write_reg
mov al,[cylinder]
call fdc_write_reg
mov al,[head]
call fdc_write_reg
mov al,[sector]
call fdc_write_reg
mov al,2 ;Sector size (2 ~> 512 bytes)
call fdc_write_reg
mov al,18 ;last sector on track.
call fdc_write_reg
mov al,27 ;length of GAP3
call fdc_write_reg
mov al,0xFF ;data length, ignored.
call fdc_write_reg
mov [fdc_irq_func],fdc_resultphase
ret
 
fdc_resultphase:
call fdc_read_reg
mov [fdc_st0],al
mov cx,6
.readresult:
call fdc_read_reg
loop .readresult
and [fdc_st0],11000000b
cmp [fdc_st0],byte 0
jz .succes
call fdc_seek
jmp .end
.succes:
call [fdc_pump_func]
.end:
ret
 
fdc_sensei:
mov al,0x08 ;get interrupt status command
call fdc_write_reg
call fdc_read_reg ;get result in al;
and al,0x80
cmp al,0x80
je fdc_sensei ;retry
call fdc_read_reg
ret
 
fdc_program_dma:
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov al,6 ; mask channel 2 so we can reprogram it.
out 0x0a,al
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy
out 0x0b,al
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov eax,[dmamem]
out 0x04,al ; set the channel 2 starting address to 0
shr eax,8
out 0x04,al
shr eax,8
out 0x81,al
mov al,0
out 0x0c, al ; reset flip-flop
mov al, 0xff ;set count (actual size -1)
out 0x5, al
mov al, [dmasize] ;(0x1ff = 511 / 0x23ff =9215)
out 0x5,al
mov al,2
out 0xa,al
ret
 
fdc_recalibrate:
mov al,0x07 ;calibrate command
call fdc_write_reg
mov al,0 ;select drive 0
call fdc_write_reg
ret
 
fdc_recalibrate_result:
mov al,0x08 ;get interrupt status command
call fdc_write_reg ;send it
call fdc_read_reg ;get command in al;
cmp al,0x80
je fdc_recalibrate_result
mov ah,al
call fdc_read_reg
cmp ah,0x70
jne .end
call fdc_recalibrate
jmp .reallyend
.end:
call [fdc_pump_func]
.reallyend:
ret
 
fdc_busy:
.command_check:
mov dx,0x3F4
in al,dx
and al,0x10
cmp al,0x10
je .command_check
ret
 
fdc_read_reg:
status_check:
mov dx,0x3F4
in al,dx
and al,0xc0
cmp al,0xc0
jne status_check
mov dx, 0x3F5
in al, dx
ret
 
fdc_write_reg:
mov bl,al
.command_check:
mov dx,0x3F4
in al,dx
and al,0x80
cmp al,0x80
jne .command_check
mov al,bl
mov dx,0x3F5
out dx,al
ret
 
fdc_floppy_off:
mov al,0xC
mov dx,0x3f2
out dx,al
ret
 
fdc_floppy_on:
mov dx,0x3f2
mov al,0x0
out dx,al
mov al,0x1C
out dx,al
mov eax,50
call delay_hs
ret
 
fdc_complete:
mov eax,0xD000
mov ebx,0x100000
mov ecx,512
call memmove
 
mov [fdc_irq_func],fdc_null
mov [fdc_mutex],0
dec [fdc_callspending]
cmp [fdc_callspending],0
je .realyend
mov [fdc_mutex],1
call fdc_commitramdisk
.realyend:
ret
 
fdc_irq:
call [fdc_irq_func]
fdc_null:
ret
/kernel/trunk/blkdev/flp_drv.inc
0,0 → 1,685
;**********************************************************
; ¥¯®á।á⢥­­ ï à ¡®â  á ª®­â஫«¥à®¬ £¨¡ª®£® ¤¨áª 
;**********************************************************
; €¢â®à ¨á室­®£® ⥪áâ  Šã« ª®¢ ‚« ¤¨¬¨à ƒ¥­­ ¤ì¥¢¨ç.
; €¤ ¯â æ¨ï ¨ ¤®à ¡®âª  Mario79
fdd_read_and_write:
pusha
read_sector:
cmp eax,1
jne write_sector
call save_HTS_values
call flp_readsector
call give_back_application_data
jmp fdd_read_end
write_sector:
cmp eax,2
jne fdd_read_end
call save_HTS_values
call take_data_from_application
call flp_writesector
fdd_read_end:
popa
ret
 
save_HTS_values:
mov [FDD_Sector],bl
mov [FDD_Head],bh
shr ebx,16
mov [FDD_Track],bl
mov [FDD_Type],bh
ret
 
give_back_application_data: ; ¯¥à¥á« âì ¯à¨«®¦¥­¨î
mov edi,[3010h]
mov edi,[edi+10h]
add edi,ecx
give_back_application_data_1:
mov esi,0xD000 ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
 
take_data_from_application: ; ¢§ïâì ¨§ ¯à¨«®¦¥­¨ï
mov esi,[3010h]
mov esi,[esi+10h]
add esi,ecx
take_data_from_application_1:
mov edi,0xD000 ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
 
flp_initialization:
; “áâ ­®¢¨âì ­®¢ë© ®¡à ¡®â稪 ¯à¥à뢠­¨ï ƒŒ„
call SetUserInterrupts
; ‚ª«îç¨âì ¬®â®à ¤¨áª®¢®¤ 
call FDDMotorON
; ˆ­¨æ¨ «¨§¨à®¢ âì ¯¥à¥¬¥­­ë¥
; mov [FDD_Track],0
; mov [FDD_Head],0
; mov [FDD_Sector],1
; à®¢¥á⨠४ «¨¡à®¢ªã ¨ ¯®¨áª ­ã«¥¢®© ¤®à®¦ª¨
call RecalibrateFDD
call SeekTrack
ret
 
flp_readsector:
call flp_initialization
; à®ç¨â âì ᥪâ®à
call ReadSectWithRetr
; call ReadSector
; cmp [FDC_Status],0
; jne @@SectorNotFound
mov [fdc_irq_func],fdc_null
; call FDDMotorOFF
ret
 
flp_writesector:
call flp_initialization
; ‡ ¯¨á âì ᥪâ®à
call WriteSectWithRetr
; call WriteSector
; cmp [FDC_Status],0
; jne @@SectorNotFound
mov [fdc_irq_func],fdc_null
; call FDDMotorOFF
ret
 
@@DiskNotFound:
ret
@@SectorNotFound:
ret
 
; Š®¤ë § ¢¥à襭¨ï ®¯¥à æ¨¨ á ª®­â஫«¥à®¬ (FDC_Status)
FDC_Normal equ 0 ;­®à¬ «ì­®¥ § ¢¥à襭¨¥
FDC_TimeOut equ 1 ;®è¨¡ª  â ©¬- ãâ 
FDC_DiskNotFound equ 2 ;¢ ¤¨áª®¢®¤¥ ­¥â ¤¨áª 
FDC_TrackNotFound equ 3 ;¤®à®¦ª  ­¥ ­ ©¤¥­ 
FDC_SectorNotFound equ 4 ;ᥪâ®à ­¥ ­ ©¤¥­
 
; Œ ªá¨¬ «ì­ë¥ §­ ç¥­¨ï ª®®à¤¨­ â ᥪâ®à  (§ ¤ ­­ë¥
; §­ ç¥­¨ï ᮮ⢥âáâ¢ãîâ ¯ à ¬¥âà ¬ áâ ­¤ àâ­®£®
; âà¥å¤î©¬®¢®£® £¨¡ª®£® ¤¨áª  ®¡ê¥¬®¬ 1,44 Œ¡)
MAX_Track equ 79
MAX_Head equ 1
MAX_Sector equ 18
 
; ‘ç¥â稪 ⨪®¢ â ©¬¥à 
TickCounter dd ?
; Š®¤ § ¢¥à襭¨ï ®¯¥à æ¨¨ á ª®­â஫«¥à®¬ ƒŒ„
FDC_Status DB ?
; ”« £ ¯à¥à뢠­¨ï ®â ƒŒ„
FDD_IntFlag DB ?
; Œ®¬¥­â ­ ç «  ¯®á«¥¤­¥© ®¯¥à æ¨¨ á ƒŒ„
FDD_Time DD ?
; ®¬¥à ¤¨áª®¢®¤ 
FDD_Type db 0
; Š®®à¤¨­ âë ᥪâ®à 
FDD_Track DB ?
FDD_Head DB ?
FDD_Sector DB ?
 
; «®ª १ã«ìâ â  ®¯¥à æ¨¨
FDC_ST0 DB ?
FDC_ST1 DB ?
FDC_ST2 DB ?
FDC_C DB ?
FDC_H DB ?
FDC_R DB ?
FDC_N DB ?
; ‘ç¥â稪 ¯®¢â®à¥­¨ï ®¯¥à æ¨¨ ç⥭¨ï
ReadRepCounter DB ?
; ‘ç¥â稪 ¯®¢â®à¥­¨ï ®¯¥à æ¨¨ ४ «¨¡à®¢ª¨
RecalRepCounter DB ?
; Ž¡« áâì ¯ ¬ï⨠¤«ï åà ­¥­¨ï ¯à®ç¨â ­­®£® ᥪâ®à 
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?)
fdd_motor_status db 0
timer_fdd_motor dd 0
 
;*************************************
;* ˆˆ–ˆ€‹ˆ‡€–ˆŸ …†ˆŒ€ „ „‹Ÿ ƒŒ„ *
;*************************************
Init_FDC_DMA:
pushad
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov al,6 ; mask channel 2 so we can reprogram it.
out 0x0a,al
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy
out 0x0b,al
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov eax,0xD000
out 0x04,al ; set the channel 2 starting address to 0
shr eax,8
out 0x04,al
shr eax,8
out 0x81,al
mov al,0
out 0x0c, al ; reset flip-flop
mov al, 0xff ;set count (actual size -1)
out 0x5, al
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215)
out 0x5,al
mov al,2
out 0xa,al
popad
ret
 
;***********************************
;* ‡€ˆ‘€’œ €‰’ ‚ Ž’ „€›• FDC *
;*  à ¬¥âàë: *
;* AL - ¢ë¢®¤¨¬ë© ¡ ©â. *
;***********************************
FDCDataOutput:
; pusha
push ax cx dx
mov AH,AL ;§ ¯®¬­¨âì ¡ ©â ¢ AH
; ‘¡à®á¨âì ¯¥à¥¬¥­­ãî á®áâ®ï­¨ï ª®­â஫«¥à 
mov [FDC_Status],FDC_Normal
; à®¢¥à¨âì £®â®¢­®áâì ª®­â஫«¥à  ª ¯à¨¥¬ã ¤ ­­ëå
mov DX,3F4h ;(¯®àâ á®áâ®ï­¨ï FDC)
xor CX,CX ;ãáâ ­®¢¨âì áç¥â稪 â ©¬- ãâ 
@@TestRS:
in AL,DX ;¯à®ç¨â âì ॣ¨áâà RS
and AL,0C0h ;¢ë¤¥«¨âì à §àï¤ë 6 ¨ 7
cmp AL,80h ;¯à®¢¥à¨âì à §àï¤ë 6 ¨ 7
je @@OutByteToFDC
loop @@TestRS
; Žè¨¡ª  â ©¬- ãâ 
mov [FDC_Status],FDC_TimeOut
jmp @@End_5
; ‚뢥á⨠¡ ©â ¢ ¯®àâ ¤ ­­ëå
@@OutByteToFDC:
inc DX
mov AL,AH
out DX,AL
@@End_5:
; popa
pop dx cx ax
ret
 
;******************************************
;* Ž—ˆ’€’œ €‰’ ˆ‡ Ž’€ „€›• FDC *
;* à®æ¥¤ãà  ­¥ ¨¬¥¥â ¢å®¤­ëå ¯ à ¬¥â஢. *
;* ‚ë室­ë¥ ¤ ­­ë¥: *
;* AL - áç¨â ­­ë© ¡ ©â. *
;******************************************
FDCDataInput:
push ECX
push DX
; ‘¡à®á¨âì ¯¥à¥¬¥­­ãî á®áâ®ï­¨ï ª®­â஫«¥à 
mov [FDC_Status],FDC_Normal
; à®¢¥à¨âì £®â®¢­®áâì ª®­â஫«¥à  ª ¯¥à¥¤ ç¥ ¤ ­­ëå
mov DX,3F4h ;(¯®àâ á®áâ®ï­¨ï FDC)
xor CX,CX ;ãáâ ­®¢¨âì áç¥â稪 â ©¬- ãâ 
@@TestRS_1:
in AL,DX ;¯à®ç¨â âì ॣ¨áâà RS
and AL,0C0h ;¢ë¤«¨âì à §àï¤ë 6 ¨ 7
cmp AL,0C0h ;¯à®¢¥à¨âì à §àï¤ë 6 ¨ 7
je @@GetByteFromFDC
loop @@TestRS_1
; Žè¨¡ª  â ©¬- ãâ 
mov [FDC_Status],FDC_TimeOut
jmp @@End_6
; ‚¢¥á⨠¡ ©â ¨§ ¯®àâ  ¤ ­­ëå
@@GetByteFromFDC:
inc DX
in AL,DX
@@End_6: pop DX
pop ECX
ret
 
;*********************************************
;* Ž€Ž’—ˆŠ …›‚€ˆŸ Ž’ ŠŽ’Ž‹‹…€ ƒŒ„ *
;*********************************************
FDCInterrupt:
;  §à¥è¨âì ¯à¥à뢠­¨ï
; sti
; push AX
; “áâ ­®¢¨âì ä« £ ¯à¥à뢠­¨ï
mov [FDD_IntFlag],1
; ®á« âì ª®¬ ­¤ã EOI ª®­â஫«¥àã ¯à¥à뢠­¨©
; mov AL,20h
; out 20h,AL
; pop AX
ret
 
 
;******************************************
;* “‘’€Ž‚ˆ’œ Ž‚›‰ Ž€Ž’—ˆŠ …›‚€ˆ‰ *
;* ƒŒ„ *
;******************************************
SetUserInterrupts:
mov [fdc_irq_func],FDCInterrupt
ret
 
;*******************************************
;* Ž†ˆ„€ˆ… …›‚€ˆŸ Ž’ ŠŽ’Ž‹‹…€ ƒŒ„ *
;*******************************************
WaitFDCInterrupt:
pusha
; ‘¡à®á¨âì ¡ ©â á®áâ®ï­¨ï ®¯¥à æ¨¨
mov [FDC_Status],FDC_Normal
; ‘¡à®á¨âì ä« £ ¯à¥à뢠­¨ï
mov [FDD_IntFlag],0
; Ž¡­ã«¨âì áç¥â稪 ⨪®¢
mov eax,[timer_ticks]
mov [TickCounter],eax
; Ž¦¨¤ âì ãáâ ­®¢ª¨ ä« £  ¯à¥à뢠­¨ï ƒŒ„
@@TestRS_2:
cmp [FDD_IntFlag],0
jnz @@End_7 ;¯à¥à뢠­¨¥ ¯à®¨§®è«®
mov eax,[timer_ticks]
sub eax,[TickCounter]
cmp eax,50 ;25 ;5 ;®¦¨¤ âì 5 ⨪®¢
jb @@TestRS_2
; jl @@TestRS_2
; Žè¨¡ª  â ©¬- ãâ 
mov [FDC_Status],FDC_TimeOut
; mov [flp_status],0
@@End_7: popa
ret
 
;*********************************
;* ‚Š‹ž—ˆ’œ ŒŽ’Ž „ˆ‘ŠŽ‚Ž„€ "A:" *
;*********************************
FDDMotorON:
pusha
; cmp [fdd_motor_status],1
; je fdd_motor_on
mov al,[flp_number]
cmp [fdd_motor_status],al
je fdd_motor_on
; à®¨§¢¥á⨠á¡à®á ª®­â஫«¥à  ƒŒ„
mov DX,3F2h ;¯®àâ ã¯à ¢«¥­¨ï ¤¢¨£ â¥«ï¬¨
mov AL,0
out DX,AL
; ‚ë¡à âì ¨ ¢ª«îç¨âì ¬®â®à ¤¨áª®¢®¤ 
cmp [flp_number],1
jne FDDMotorON_B
; call FDDMotorOFF_B
mov AL,1Ch ; Floppy A
jmp FDDMotorON_1
FDDMotorON_B:
; call FDDMotorOFF_A
mov AL,2Dh ; Floppy B
FDDMotorON_1:
out DX,AL
; Ž¡­ã«¨âì áç¥â稪 ⨪®¢
mov eax,[timer_ticks]
mov [TickCounter],eax
; Ž¦¨¤ âì 0,5 á
@@dT:
mov eax,[timer_ticks]
sub eax,[TickCounter]
cmp eax,50 ;10
jb @@dT
cmp [flp_number],1
jne fdd_motor_on_B
mov [fdd_motor_status],1
jmp fdd_motor_on
fdd_motor_on_B:
mov [fdd_motor_status],2
fdd_motor_on:
call save_timer_fdd_motor
popa
ret
 
;*****************************************
;* ‘Ž•€…ˆ… “Š€‡€’…‹Ÿ ‚…Œ…ˆ *
;*****************************************
save_timer_fdd_motor:
mov eax,[timer_ticks]
mov [timer_fdd_motor],eax
ret
 
;*****************************************
;* Ž‚…Š€ ‡€„…†Šˆ ‚›Š‹ž—…ˆŸ ŒŽ’Ž€ *
;*****************************************
check_fdd_motor_status:
cmp [fdd_motor_status],0
je end_check_fdd_motor_status
mov eax,[timer_ticks]
sub eax,[timer_fdd_motor]
cmp eax,500
jb end_check_fdd_motor_status
call FDDMotorOFF
mov [fdd_motor_status],0
end_check_fdd_motor_status:
ret
 
;**********************************
;* ‚›Š‹ž—ˆ’œ ŒŽ’Ž „ˆ‘ŠŽ‚Ž„€ *
;**********************************
FDDMotorOFF:
push AX
push DX
cmp [flp_number],1
jne FDDMotorOFF_1
call FDDMotorOFF_A
jmp FDDMotorOFF_2
FDDMotorOFF_1:
call FDDMotorOFF_B
FDDMotorOFF_2:
pop DX
pop AX
; á¡à®á ä« £®¢ ª¥è¨à®¢ ­¨ï ¢ á¢ï§¨ á ãáâ à¥¢ ­¨¥¬ ¨­ä®à¬ æ¨¨
mov [root_read],0
mov [flp_fat],0
ret
 
FDDMotorOFF_A:
mov DX,3F2h ;¯®àâ ã¯à ¢«¥­¨ï ¤¢¨£ â¥«ï¬¨
mov AL,0Ch ; Floppy A
out DX,AL
ret
 
FDDMotorOFF_B:
mov DX,3F2h ;¯®àâ ã¯à ¢«¥­¨ï ¤¢¨£ â¥«ï¬¨
mov AL,5h ; Floppy B
out DX,AL
ret
 
;*******************************
;* …Š€‹ˆŽ‚Š€ „ˆ‘ŠŽ‚Ž„€ "A:" *
;*******************************
RecalibrateFDD:
pusha
call save_timer_fdd_motor
; ®¤ âì ª®¬ ­¤ã "¥ª «¨¡à®¢ª "
mov AL,07h
call FDCDataOutput
mov AL,00h
call FDCDataOutput
; Ž¦¨¤ âì § ¢¥à襭¨ï ®¯¥à æ¨¨
call WaitFDCInterrupt
; cmp [FDC_Status],0
; je no_fdc_status_error
; mov [flp_status],0
;no_fdc_status_error:
call save_timer_fdd_motor
popa
ret
 
;*****************************************************
;* Žˆ‘Š „ŽŽ†Šˆ *
;*  à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1). *
;* ¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ FDC_Status. *
;*****************************************************
SeekTrack:
pusha
call save_timer_fdd_motor
; ®¤ âì ª®¬ ­¤ã "®¨áª"
mov AL,0Fh
call FDCDataOutput
; ¥à¥¤ âì ¡ ©â ­®¬¥à  £®«®¢ª¨/­ ª®¯¨â¥«ï
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
; ¥à¥¤ âì ¡ ©â ­®¬¥à  ¤®à®¦ª¨
mov AL,[FDD_Track]
call FDCDataOutput
; Ž¦¨¤ âì § ¢¥à襭¨ï ®¯¥à æ¨¨
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit
; ‘®åà ­¨âì १ã«ìâ â ¯®¨áª 
mov AL,08h
call FDCDataOutput
call FDCDataInput
mov [FDC_ST0],AL
call FDCDataInput
mov [FDC_C],AL
; à®¢¥à¨âì १ã«ìâ â ¯®¨áª 
; ®¨áª § ¢¥à襭?
test [FDC_ST0],100000b
je @@Err
; ‡ ¤ ­­ë© â४ ­ ©¤¥­?
mov AL,[FDC_C]
cmp AL,[FDD_Track]
jne @@Err
; ®¬¥à £®«®¢ª¨ ᮢ¯ ¤ ¥â á § ¤ ­­ë¬?
mov AL,[FDC_ST0]
and AL,100b
shr AL,2
cmp AL,[FDD_Head]
jne @@Err
; Ž¯¥à æ¨ï § ¢¥à襭  ãᯥ譮
mov [FDC_Status],FDC_Normal
jmp @@Exit
@@Err: ; ’४ ­¥ ­ ©¤¥­
mov [FDC_Status],FDC_TrackNotFound
; mov [flp_status],0
@@Exit:
call save_timer_fdd_motor
popa
ret
 
;*******************************************************
;* —’…ˆ… ‘…Š’Ž€ „€›• *
;*  à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1); *
;* FDD_Sector - ­®¬¥à ᥪâ®à  (1-18). *
;* ¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ FDC_Status. *
;* ‚ á«ãç ¥ ãᯥ譮£® ¢ë¯®«­¥­¨ï ®¯¥à æ¨¨ ç⥭¨ï *
;* ᮤ¥à¦¨¬®¥ ᥪâ®à  ¡ã¤¥â § ­¥á¥­® ¢ FDD_DataBuffer. *
;*******************************************************
ReadSector:
pushad
call save_timer_fdd_motor
; “áâ ­®¢¨âì ᪮à®áâì ¯¥à¥¤ ç¨ 500 Š¡ ©â/á
mov AX,0
mov DX,03F7h
out DX,AL
; ˆ­¨æ¨ «¨§¨à®¢ âì ª ­ « ¯àאַ£® ¤®áâ㯠 ª ¯ ¬ïâ¨
mov [dmamode],0x46
call Init_FDC_DMA
; ®¤ âì ª®¬ ­¤ã "—⥭¨¥ ¤ ­­ëå"
mov AL,0E6h ;ç⥭¨¥ ¢ ¬ã«ìâ¨â४®¢®¬ ०¨¬¥
call FDCDataOutput
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
mov AL,[FDD_Track]
call FDCDataOutput
mov AL,[FDD_Head]
call FDCDataOutput
mov AL,[FDD_Sector]
call FDCDataOutput
mov AL,2 ;ª®¤ à §¬¥à  ᥪâ®à  (512 ¡ ©â)
call FDCDataOutput
mov AL,18 ;+1; 3Fh ;ç¨á«® ᥪâ®à®¢ ­  ¤®à®¦ª¥
call FDCDataOutput
mov AL,1Bh ;§­ ç¥­¨¥ GPL
call FDCDataOutput
mov AL,0FFh ;§­ ç¥­¨¥ DTL
call FDCDataOutput
 
; Ž¦¨¤ ¥¬ ¯à¥à뢠­¨¥ ¯® § ¢¥à襭¨¨ ®¯¥à æ¨¨
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit_1
; ‘ç¨â뢠¥¬ áâ âãá § ¢¥à襭¨ï ®¯¥à æ¨¨
call GetStatusInfo
test [FDC_ST0],11011000b
jnz @@Err_1
mov [FDC_Status],FDC_Normal
jmp @@Exit_1
@@Err_1: mov [FDC_Status],FDC_SectorNotFound
; mov [flp_status],0
@@Exit_1:
call save_timer_fdd_motor
popad
ret
 
;*******************************************************
;* —’…ˆ… ‘…Š’Ž€ (‘ Ž‚’Ž…ˆ…Œ Ž…€–ˆˆ ˆ ‘Ž…) *
;*  à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1); *
;* FDD_Sector - ­®¬¥à ᥪâ®à  (1-18). *
;* ¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ FDC_Status. *
;* ‚ á«ãç ¥ ãᯥ譮£® ¢ë¯®«­¥­¨ï ®¯¥à æ¨¨ ç⥭¨ï *
;* ᮤ¥à¦¨¬®¥ ᥪâ®à  ¡ã¤¥â § ­¥á¥­® ¢ FDD_DataBuffer. *
;*******************************************************
ReadSectWithRetr:
pusha
; Ž¡­ã«¨âì áç¥â稪 ¯®¢â®à¥­¨ï ®¯¥à æ¨¨ ४ «¨¡à®¢ª¨
mov [RecalRepCounter],0
@@TryAgain:
; Ž¡­ã«¨âì áç¥â稪 ¯®¢â®à¥­¨ï ®¯¥à æ¨¨ ç⥭¨ï
mov [ReadRepCounter],0
@@ReadSector_1:
call ReadSector
cmp [FDC_Status],0
je @@Exit_2
cmp [FDC_Status],1
je @@Err_3
; ’஥ªà â­®¥ ¯®¢â®à¥­¨¥ ç⥭¨ï
inc [ReadRepCounter]
cmp [ReadRepCounter],3
jb @@ReadSector_1
; ’஥ªà â­®¥ ¯®¢â®à¥­¨¥ ४ «¨¡à®¢ª¨
call RecalibrateFDD
call SeekTrack
inc [RecalRepCounter]
cmp [RecalRepCounter],3
jb @@TryAgain
; mov [flp_status],0
@@Exit_2:
popa
ret
@@Err_3:
mov [flp_status],0
popa
ret
 
;*******************************************************
;* ‡€ˆ‘œ ‘…Š’Ž€ „€›• *
;*  à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1); *
;* FDD_Sector - ­®¬¥à ᥪâ®à  (1-18). *
;* ¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ FDC_Status. *
;* ‚ á«ãç ¥ ãᯥ譮£® ¢ë¯®«­¥­¨ï ®¯¥à æ¨¨ § ¯¨á¨ *
;* ᮤ¥à¦¨¬®¥ FDD_DataBuffer ¡ã¤¥â § ­¥á¥­® ¢ ᥪâ®à. *
;*******************************************************
WriteSector:
pushad
call save_timer_fdd_motor
; “áâ ­®¢¨âì ᪮à®áâì ¯¥à¥¤ ç¨ 500 Š¡ ©â/á
mov AX,0
mov DX,03F7h
out DX,AL
; ˆ­¨æ¨ «¨§¨à®¢ âì ª ­ « ¯àאַ£® ¤®áâ㯠 ª ¯ ¬ïâ¨
mov [dmamode],0x4A
call Init_FDC_DMA
; ®¤ âì ª®¬ ­¤ã "‡ ¯¨áì ¤ ­­ëå"
mov AL,0xC5 ;0x45 ;§ ¯¨áì ¢ ¬ã«ìâ¨â४®¢®¬ ०¨¬¥
call FDCDataOutput
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
mov AL,[FDD_Track]
call FDCDataOutput
mov AL,[FDD_Head]
call FDCDataOutput
mov AL,[FDD_Sector]
call FDCDataOutput
mov AL,2 ;ª®¤ à §¬¥à  ᥪâ®à  (512 ¡ ©â)
call FDCDataOutput
mov AL,18; 3Fh ;ç¨á«® ᥪâ®à®¢ ­  ¤®à®¦ª¥
call FDCDataOutput
mov AL,1Bh ;§­ ç¥­¨¥ GPL
call FDCDataOutput
mov AL,0FFh ;§­ ç¥­¨¥ DTL
call FDCDataOutput
 
; Ž¦¨¤ ¥¬ ¯à¥à뢠­¨¥ ¯® § ¢¥à襭¨¨ ®¯¥à æ¨¨
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit_3
; ‘ç¨â뢠¥¬ áâ âãá § ¢¥à襭¨ï ®¯¥à æ¨¨
call GetStatusInfo
test [FDC_ST0],11000000b ;11011000b
jnz @@Err_2
mov [FDC_Status],FDC_Normal
jmp @@Exit_3
@@Err_2: mov [FDC_Status],FDC_SectorNotFound
@@Exit_3:
call save_timer_fdd_motor
popad
ret
 
;*******************************************************
;* ‡€ˆ‘œ ‘…Š’Ž€ (‘ Ž‚’Ž…ˆ…Œ Ž…€–ˆˆ ˆ ‘Ž…) *
;*  à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1); *
;* FDD_Sector - ­®¬¥à ᥪâ®à  (1-18). *
;* ¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ FDC_Status. *
;* ‚ á«ãç ¥ ãᯥ譮£® ¢ë¯®«­¥­¨ï ®¯¥à æ¨¨ § ¯¨á¨ *
;* ᮤ¥à¦¨¬®¥ FDD_DataBuffer ¡ã¤¥â § ­¥á¥­® ¢ ᥪâ®à. *
;*******************************************************
WriteSectWithRetr:
pusha
; Ž¡­ã«¨âì áç¥â稪 ¯®¢â®à¥­¨ï ®¯¥à æ¨¨ ४ «¨¡à®¢ª¨
mov [RecalRepCounter],0
@@TryAgain_1:
; Ž¡­ã«¨âì áç¥â稪 ¯®¢â®à¥­¨ï ®¯¥à æ¨¨ ç⥭¨ï
mov [ReadRepCounter],0
@@WriteSector_1:
call WriteSector
cmp [FDC_Status],0
je @@Exit_4
cmp [FDC_Status],1
je @@Err_4
; ’஥ªà â­®¥ ¯®¢â®à¥­¨¥ ç⥭¨ï
inc [ReadRepCounter]
cmp [ReadRepCounter],3
jb @@WriteSector_1
; ’஥ªà â­®¥ ¯®¢â®à¥­¨¥ ४ «¨¡à®¢ª¨
call RecalibrateFDD
call SeekTrack
inc [RecalRepCounter]
cmp [RecalRepCounter],3
jb @@TryAgain_1
@@Exit_4:
popa
ret
@@Err_4:
mov [flp_status],0
popa
ret
 
;*********************************************
;* Ž‹“—ˆ’œ ˆ”ŽŒ€–ˆž Ž …‡“‹œ’€’… Ž…€–ˆˆ *
;*********************************************
GetStatusInfo:
push AX
call FDCDataInput
mov [FDC_ST0],AL
call FDCDataInput
mov [FDC_ST1],AL
call FDCDataInput
mov [FDC_ST2],AL
call FDCDataInput
mov [FDC_C],AL
call FDCDataInput
mov [FDC_H],AL
call FDCDataInput
mov [FDC_R],AL
call FDCDataInput
mov [FDC_N],AL
pop AX
ret
 
/kernel/trunk/blkdev/rd.inc
0,0 → 1,446
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; RAMDISK functions ;;
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; Addings by M.Lisovin ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
ramdisk_free_space:
;---------------------------------------------
;
; returns free space in edi
; rewr.by Mihasik
;---------------------------------------------
 
push eax ebx ecx
 
mov edi,0x280000 ;start of FAT
xor ax,ax ;Free cluster=0x0000 in FAT
xor ebx,ebx ;counter
mov ecx,2847 ;2849 ;2849 clusters
cld
rdfs1:
repne scasw
jnz rdfs2 ;if last cluster not 0
inc ebx
jcxz rdfs2 ;if last cluster=0
jmp rdfs1 ;if not last
rdfs2:
shl ebx,9 ;free clusters*512
mov edi,ebx
pop ecx ebx eax
ret
 
 
expand_filename:
;---------------------------------------------
;
; exapand filename with '.' to 11 character
; eax - pointer to filename
;---------------------------------------------
 
push esi edi ebx
 
mov edi,esp ; check for '.' in the name
add edi,12+8
 
mov esi,eax
 
mov eax,edi
mov [eax+0],dword ' '
mov [eax+4],dword ' '
mov [eax+8],dword ' '
 
flr1:
 
cmp [esi],byte '.'
jne flr2
mov edi,eax
add edi,7
jmp flr3
 
flr2:
 
mov bl,[esi]
mov [edi],bl
 
flr3:
 
inc esi
inc edi
 
mov ebx,eax
add ebx,11
 
cmp edi,ebx
jbe flr1
 
pop ebx edi esi
ret
 
fileread:
;----------------------------------------------------------------
;
; fileread - sys floppy
;
; eax points to filename 11 chars
; ebx first wanted block ; 1+ ; if 0 then set to 1
; ecx number of blocks to read ; 1+ ; if 0 then set to 1
; edx mem location to return data
; esi length of filename 12*X 0=root
;
; ret ebx = size or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
test ebx,ebx ;if ebx=0 - set to 1
jnz frfl5
inc ebx
frfl5:
test ecx,ecx ;if ecx=0 - set to 1
jnz frfl6
inc ecx
frfl6:
test esi,esi ; return ramdisk root
jnz fr_noroot ;if not root
cmp ebx,14 ;14 clusters=root dir
ja oorr
cmp ecx,14
ja oorr
jmp fr_do
oorr:
mov eax,5 ;out of root range (fnf)
xor ebx,ebx
dec ebx ;0xffffffff
ret
 
fr_do: ;reading rootdir
mov edi,edx
dec ebx
push edx
mov edx,ecx
add edx,ebx
cmp edx,14 ;ebx+ecx=14
pushf
jbe fr_do1
sub edx,14
sub ecx,edx
fr_do1:
shl ebx,9
mov esi,0x100000+512*19
add esi,ebx
shl ecx,7
cld
rep movsd
popf
pop edx
; jae fr_do2
xor eax,eax ; ok read
xor ebx,ebx
ret
fr_do2: ;if last cluster
mov eax,6 ;end of file
xor ebx,ebx
ret
 
fr_noroot:
 
sub esp,32
call expand_filename
 
dec ebx
 
push eax
 
push eax ebx ecx edx esi edi
call rd_findfile
je fifound
add esp,32+28 ;if file not found
ret
 
fifound:
 
mov ebx,[edi-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
add edi,0xf
movzx eax,word [edi]
mov edi,eax ;edi=cluster
 
frnew:
 
add eax,31 ;bootsector+2*fat+filenames
shl eax,9 ;*512
add eax,0x100000 ;image base
mov ebx,[esp+8]
mov ecx,512 ;[esp+4]
 
cmp [esp+16],dword 0 ; wanted cluster ?
jne frfl7
call memmove
add [esp+8],dword 512
dec dword [esp+12] ; last wanted cluster ?
cmp [esp+12],dword 0
je frnoread
jmp frfl8
frfl7:
dec dword [esp+16]
frfl8:
shl edi,1 ;find next cluster from FAT
add edi,0x280000
movzx eax,word [edi]
mov edi,eax
cmp edi,4095 ;eof - cluster
jz frnoread2
 
cmp [esp+24],dword 512 ;eof - size
jb frnoread
sub [esp+24],dword 512
 
jmp frnew
 
frnoread2:
 
cmp [esp+16],dword 0 ; eof without read ?
je frnoread
 
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,6 ; end of file
ret
 
frnoread:
 
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
xor eax,eax ;read ok
ret
 
filedelete:
;--------------------------------------------
;
; filedelete - sys floppy
; in:
; eax - pointer to filename 11 chars
;
; out:
; eax - 0 = successful, 5 = file not found
;
;--------------------------------------------
 
sub esp,32
call expand_filename
 
push eax ebx ecx edx esi edi
call rd_findfile
je fifoundd
pop edi esi edx ecx ebx eax ;file not found
add esp,32
mov eax,5
ret
 
fifoundd:
 
mov [edi-11],byte 0xE5 ;mark filename deleted
add edi,0xf
movzx eax,word [edi]
mov edi,eax ;edi = cluster
 
frnewd:
 
shl edi,1 ;find next cluster from FAT
add edi,0x280000
movzx eax,word [edi]
mov [edi],word 0x0 ;clear fat chain cluster
mov edi,eax
cmp edi,dword 0xff8 ;last cluster ?
jb frnewd
 
pop edi esi edx ecx ebx eax
add esp,32
xor eax,eax ; file found
ret
 
 
filesave:
;----------------------------------------------------------
;
; filesave - sys floppy
;
; eax points to filename 11 chars
;
; eax ; pointer to file name
; ebx ; buffer
; ecx ; count to write in bytes
; edx ; 0 create new , 1 append
;
;-----------------------------------------------------------
 
sub esp,32
call expand_filename
test edx,edx
jnz fsdel
pusha
call filedelete
popa
 
fsdel:
 
call ramdisk_free_space
cmp ecx,edi
jbe rd_do_save
add esp,32
mov eax,8 ;disk full
ret
 
rd_do_save:
 
push eax ebx ecx edx esi edi
 
mov edi,0x100000+512*18+512 ;Point at directory
mov edx,224 +1
; find an empty spot for filename in the root dir
l20ds:
dec edx
test edx,edx
jz frnoreadds
l21ds:
cmp [edi],byte 0xE5
jz fifoundds
cmp [edi],byte 0x0
jz fifoundds
add edi,32 ; Advance to next entry
jmp l20ds
fifoundds:
 
push edi ; move the filename to root dir
mov esi,[esp+4+20]
mov ecx,11
cld
rep movsb
pop edi
mov edx,edi
add edx,11+0xf ; edx <- cluster save position
mov ebx,[esp+12] ; save file size
mov [edi+28],ebx
mov [edi+11],byte 0x20 ; attribute
; Ivan Poddubny 11/12/2003:
call get_date_for_file ; from FAT32.INC
mov [edi+24],ax ; date
call get_time_for_file ; from FAT32.INC
mov [edi+22],ax ; time
; End
mov edi,0x280000 ;pointer to first cluster
mov ecx,2849
cld
frnewds:
xor ax,ax
repne scasw
mov ebx,2848
sub ebx,ecx
mov [edx],bx ; save next cluster pos. to prev cl.
mov edx,edi ; next save pos abs mem add
dec edx
dec edx
call fdc_filesave
pusha ; move save to floppy cluster
add ebx,31
shl ebx,9
add ebx,0x100000
mov eax,[esp+32+16]
mov ecx,512
call memmove
popa
 
mov eax,[esp+12]
cmp eax,512
jb flnsa
sub eax,512
mov [esp+12],eax
mov eax,[esp+16]
add eax,512
mov [esp+16],eax
jmp frnewds
 
flnsa:
dec edi
dec edi
mov [edi],word 4095 ; mark end of file - last cluster
 
frnoreadds:
 
pop edi esi edx ecx ebx eax
add esp,32
 
pusha
cli
call fdc_commitfile
sti
popa
 
xor eax,eax ;ok write
ret
 
rd_findfile:
;by Mihasik
;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx
 
mov edi,0x100000+512*18+512 ;Point at directory
cld
rd_newsearch:
mov esi,eax
mov ecx,11
rep cmpsb
je rd_ff
add cl,21
add edi,ecx
cmp edi,0x100000+512*33
jb rd_newsearch
mov eax,5 ;if file not found - eax=5
xor ebx,ebx
dec ebx ;ebx=0xffffffff and zf=0
rd_ff:
ret
 
rd_getfileinfo:
;get date, time, size or attributes of file
;IN: eax - pointer to file, ebx - type of function: 12-get filesize, 13-get fileattr, 14-get filedate
;ecx - filelengh 0=root
;OUT: eax=0 - Ok or 5 - file not found ebx - date/time, size or attributes
test ecx,ecx
jnz no_getfinfo_root
mov eax,5 ;if root - fnf
xor ebx,ebx
dec ebx
ret
no_getfinfo_root: ;if not root
sub esp,32
call expand_filename
call rd_findfile
je fifoundi
add esp,32 ;if file not found
ret
fifoundi:
cmp ebx,13
jne no_rd_attr
movzx ebx,byte [edi] ;get attributes
jmp rd_getfileinfo_end
no_rd_attr:
cmp ebx,14
jne no_rd_date
mov ebx,dword [edi+11] ;get date/time
jmp rd_getfileinfo_end
no_rd_date:
mov ebx,dword [edi+17] ;get size
rd_getfileinfo_end:
xor eax,eax
add esp,32
ret
/kernel/trunk/blkdev/rdsave.inc
0,0 → 1,26
cmp eax,6 ; SAVE FLOPPY IMAGE (HD version only)
jnz nosaveimage
cmp ebx,1
jnz img_save_hd_1
mov edx,bootpath ; path = '/KOLIBRI '
jmp img_save_hd_3
img_save_hd_1:
cmp ebx,2
jnz img_save_hd_2
mov edx,bootpath2 ; path = 0 (root dir)
jmp img_save_hd_3
img_save_hd_2:
cmp ebx,3
jnz exit_for_anyone
mov edx,[3010h]
mov edx,[edx+10h]
add edx,ecx
img_save_hd_3:
call restorefatchain ; restore FAT !!!
mov eax,image_save
mov ebx,1440*1024 ; size 1440 Kb
mov ecx,0x100000 ; address of image
call file_write
ret
 
nosaveimage:
/kernel/trunk/boot/bootcode.inc
0,0 → 1,917
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; BOOTCODE.INC ;;
;; ;;
;; 16 bit bootcode for MenuetOS ;;
;; ;;
;; Copyright 2002 Ville Turjanmaa ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 
;==========================================================================
;
; 16 BIT FUNCTIONS
;
;==========================================================================
 
print: push si
mov si,leftpr-0x10000
call printplain
pop si
 
printplain: pusha
mov dx,0x1000
mov es,dx
cmp byte [es:display_atboot-0x10000],2
je printplain_exit
mov ds,dx
cld
lodsb
prpl1:
mov ah,0xe
xor bh,bh
int 0x10
lodsb
cmp al,0
jne prpl1
printplain_exit:
popa
ret
 
setbase1000: push ax
mov ax,0x1000
mov es,ax
mov ds,ax
pop ax
ret
 
getkey: push ecx
push edx
add ebx,0x0101
xor eax,eax
 
gk1:
in al,0x60
mov cl,al
gk0:
in al,0x60
cmp al,cl
je gk0
cmp ax,11
jg gk0
gk0_1:
mov cl,al
 
; add al,47
; mov [ds:keyinbs-0x10000],al
; mov si,keyinbs-0x10000
; call printplain
 
gk12:
in al,0x60
cmp al,cl
je gk12
cmp ax,240
jne gk13
mov al,cl
jmp gk14
gk13:
add cl,128
cmp al,cl
jne gk1
sub al,128
gk14:
 
movzx edx,bl
cmp eax,edx
jb gk1
movzx edx,bh
cmp eax,edx
jg gk1
test ebx,0x010000
jnz gk3
mov cx,0x1000
mov dx,cx
add eax,47
mov cx,ax
cmp cx,58
jb gk_nozero
sub cx,10
gk_nozero:
mov [ds:keyin-0x10000],cl
mov si,keyin-0x10000
call printplain
gk3:
sub eax,48
pop edx
pop ecx
ret
 
 
;=========================================================================
;
; 16 BIT CODE
;
;=========================================================================
 
 
start_of_code:
 
; RESET 16 BIT SELECTORS/REGISTERS/STACK
 
mov ax,0x1000
mov es,ax
mov ds,ax
 
mov ax,0x2000
mov ss,ax
mov sp,0xffff
 
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
xor si,si
xor di,di
xor bp,bp
 
 
 
; DRAW FRAMES
 
call setbase1000
 
cmp byte [es:display_atboot-0x10000],2
je no_mode_atboot
 
mov ax,0x0003
mov bx,0x0000
mov dx,0x0000
int 0x10
 
no_mode_atboot:
 
; Load & set russian VGA font (RU.INC)
mov bp,RU_FNT1-10000h ; RU_FNT1 - First part
mov bx,1000h ; 768 bytes
mov cx,30h ; 48 symbols
mov dx,80h ; 128 - position of first symbol
mov ax,1100h
push cs
pop es
int 10h
 
mov bp,RU_FNT2-10000h ; RU_FNT2 -Second part
mov bx,1000h ; 512 bytes
mov cx,20h ; 32 symbols
mov dx,0E0h ; 224 - position of first symbol
mov ax,1100h
push cs
pop es
int 10h
; End set VGA russian font
 
call setbase1000
mov ax,0xb800
mov es,ax
mov di,0
mov si,d80x25-0x10000
mov cx,80*25
mov ah,1*16+15
dfl1:
cld
lodsb
stosw
loop dfl1
 
call setbase1000
 
 
; SAY HI TO USER
 
mov si,linef2-0x10000
call printplain
mov si,version-0x10000
call print
 
 
; TEST FOR 386+
 
pushf
pop ax
mov dx,ax
xor ax,0x4000
push ax
popf
pushf
pop ax
and ax,0x4000
and dx,0x4000
cmp ax,dx
jnz cpugood
mov si,not386-0x10000
call print
jmp $
cpugood:
 
; RESET 32 BIT SELECTORS/REGISTERS/SELECTORS
 
mov ax,0x1000
mov es,ax
mov ds,ax
 
mov ax,0x2000
mov ss,ax
mov esp,0xffff
 
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
xor esi,esi
xor edi,edi
xor ebp,ebp
 
 
 
; FLUSH 8042 KEYBOARD CONTROLLER
 
;// mike.dld [
; mov al,0xED
; out 0x60,al
; or cx,-1
; @@:
; in al,0x64
; test al,2
; jz @f
; loop @b
; @@:
; mov al,0
; out 0x60,al
; or cx,-1
; @@:
; in al,0x64
; test al,2
; jz @f
; loop @b
; @@:
;// mike.dld ]
 
; mov ecx,10000
; fl1:
; in al,0x64
; loop fl1
; test al,1
; jz fl2
; in al,0x60
; jmp fl1
; fl2:
 
;****************************************************************
; The function is modified Mario79
;*****************************************************************
; wait_kbd: ; variant 1
; mov cx,2500h ;çàäåðæêà ïîðÿäêà 10 ìñåê
; test_kbd:
; in al,64h ;÷èòàåì ñîñòîÿíèå êëàâèàòóðû
; test al,2 ;ïðîâåðêà áèòà ãîòîâíîñòè
; loopnz test_kbd
 
mov al,0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
out 0x60,al
mov cx,0
wait_loop: ; variant 2
; reading state of port of 8042 controller
in al,64h
and al,00000010b ; ready flag
; wait until 8042 controller is ready
loopnz wait_loop
 
; DISPLAY VESA INFORMATION
 
mov ax,0x0
mov es,ax
mov ax,0x4f00
mov di,0xa000
int 0x10
cmp ax,0x004f
je vesaok2
mov dx,0x1000
mov es,dx
mov si,novesa-0x10000
call print
mov ax,16
jmp novesafound
vesaok2:
mov ax,[es:di+4]
mov dx,ax
add ax,'0'*256+'0'
push word 0x1000
pop es
mov [es:vervesa+vervesa_off-0x10000], ah
mov [es:vervesa+vervesa_off+2-0x10000], al
; ivan 24/11/2004 begin
;push ax
; ivan 24/11/2004 end
mov si,vervesa-0x10000
call print
novesafound:
call setbase1000
; ivan 24/11/2004 begin
;pop bx
; ivan 24/11/2004 end
 
 
; ASK GRAPHICS MODE
 
movzx eax,byte [es:preboot_graph-0x10000]
cmp eax,0
jne pre_graph
mov si,gr_mode-0x10000
call printplain
gml0:
mov ebx,0x0A01
call getkey
pre_graph:
cmp eax,1
jl sgml1
cmp eax,8
jg sgml1
mov si,ax
sub si,1
shl si,4
add si,gr_table-0x10000
mov bx,[es:si+0]
mov cx,[es:si+4]
mov dx,[es:si+8]
jmp gml10
sgml1:
cmp al,9
jnz gml00
mov bx,0x13
mov cx,640
mov dx,480
push word 0x0
pop es
mov [es:0x9000],byte 32
mov dword [es:0x9018],0x800000
push word 0x1000
pop es
jmp gml10
gml00:
cmp al,0xa
jnz gml02
mov bx,0x12
mov cx,640
mov dx,480
push word 0x0
pop es
mov [es:0x9000],byte 32
mov dword [es:0x9018],0x800000
push word 0x1000
pop es
jmp gml10
gml02:
jmp gml0
gr_table:
dd 0x112+0100000000000000b , 640 , 480 , 0
dd 0x115+0100000000000000b , 800 , 600 , 0
dd 0x118+0100000000000000b , 1024 , 768 , 0
dd 0x11B+0100000000000000b , 1280 , 1024 , 0
dd 0x112 , 640 , 480 , 0
dd 0x115 , 800 , 600 , 0
dd 0x118 , 1024 , 768 , 0
dd 0x11B , 1280 ,1024 , 0
gml10:
push word 0x0000
pop es
mov [es:0x9008],bx
mov [es:0x900A],cx
mov [es:0x900C],dx
push word 0x1000
pop es
mov ax,32
cmp bx,0x13
je nov
cmp bx,0x12
je nov
 
 
; USE DEFAULTS OR PROBE
 
; bx - mode : cx - x size : dx - y size
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
movzx ax,[es:preboot_gprobe-0x10000]
test ax,ax
jne pre_probe
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
test bx,0100000000000000b
jz noprobe
 
mov si,probetext-0x10000
call printplain
push bx
mov ebx,0x0201
call getkey
pop bx
 
pre_probe:
cmp ax,1
je noprobe
 
push cx dx
 
mov bx,0x100
 
newprobe:
 
inc bx
cmp bx,0x17f
jne probemore
 
mov si,prnotfnd-0x10000
call printplain
 
jmp $
 
probemore:
 
mov ax,0x4f01
mov cx,bx
and cx,0xfff
push word 0x0000
pop es
mov di,0xa000
int 0x10
 
mov eax,[es:di] ; lfb ?
test eax,10000000b
jz newprobe
 
mov eax,[es:di+0x12] ; x size ?
cmp ax,word [esp+2]
jne newprobe
 
mov eax,[es:di+0x14] ; y size ?
cmp ax,dx
jne newprobe
 
movzx eax,byte [es:di+0x19]
cmp eax,32 ;24
jb newprobe
 
push word 0x0000 ; save probed mode
pop es
add bx,0100000000000000b
mov [es:0x9008],bx
push word 0x1000
pop es
 
push bx
 
mov si,prid-0x10000
call printplain
 
pop bx dx cx
 
noprobe:
 
 
; FIND VESA 2.0 LFB & BPP
 
mov ax,0x4f01
mov cx,bx
and cx,0xfff
push word 0x0000
pop es
mov di,0xa000
int 0x10
; LFB
mov ecx,[es:di+0x28]
mov [es:0x9018],ecx
; BPP
movzx ax,byte [es:di+0x19]
mov [es:0x9000],ax
; ---- vbe voodoo
BytesPerScanLine equ 0x10
push ax
mov ax, [es:di+BytesPerScanLine]
mov [es:0x9001],ax
pop ax
; -----
nov:
cmp ax,24
jnz nbpp24
mov si,bt24-0x10000
jmp bppl
nbpp24:
cmp ax,32
jnz nbpp32
mov si,bt32-0x10000
jmp bppl
nbpp32:
mov si,btns-0x10000
call print
jmp $
bppl:
call printplain
 
 
; FIND VESA 1.2 PM BANK SWITCH ADDRESS
 
mov ax,0x4f0A
mov bx,0x0
int 0x10
xor eax,eax
xor ebx,ebx
mov ax,es
shl eax,4
mov bx,di
add eax,ebx
xor ebx,ebx
mov bx,[es:di]
add eax,ebx
push word 0x0
pop es
mov [es:0x9014],eax
push word 0x1000
pop es
 
 
 
; GRAPHICS ACCELERATION
 
mov al, [es:preboot_mtrr-0x10000]
test al,al
jne pre_mtrr
mov si,gr_acc-0x10000
call printplain
mov ebx,0x0201
call getkey
pre_mtrr:
push word 0x0000
pop es
mov [es:0x901C],al
push word 0x1000
pop es
mov si,linef-0x10000
call printplain
 
 
; VRR_M USE
 
mov al,[es:preboot_vrrm-0x10000]
test al,al
jne pre_vrrm
mov si,vrrmprint-0x10000
call print
mov ebx,0x0301
call getkey
pre_vrrm:
push word 0x0000
pop es
mov [es:0x9030],al
push word 0x1000
pop es
mov si,linef2-0x10000
call printplain
 
 
; MEMORY MODEL
 
; movzx eax,byte [es:preboot_memory-0x10000]
; cmp eax,0
; jne pre_mem
;;;;;;;;;;;;;;;;;;;;;;;;;
; mario79 - memory size ;
;;;;;;;;;;;;;;;;;;;;;;;;;
; mov ax,0E801h
;;; xor bx,bx ; thanks to Alexei for bugfix [18.07.2004]
; xor cx, cx
; xor dx, dx
; int 0x15
; movzx ebx, dx ;bx
; movzx eax, cx ;ax
; shl ebx,6 ; ïåðåâîä â êèëîáàéòû (x64)
; add eax,ebx
; add eax, 1000h ;440h
; cmp eax,40000h ; 256?
; jge mem_256_z
; cmp eax,20000h ; 128?
; jge mem_128_z
; cmp eax,10000h ; 64?
; jge mem_64_z
; cmp eax,8000h ; 32?
; jge mem_32_z
; jmp mem_16_z
;
;mem_256_z: mov si,memokz256-0x10000
; call printplain
; mov eax,5
; jmp pre_mem
;mem_128_z: mov si,memokz128-0x10000
; call printplain
; mov eax,4
; jmp pre_mem
;mem_64_z: mov si,memokz64-0x10000
; call printplain
; mov eax,3
; jmp pre_mem
;mem_32_z: mov si,memokz32-0x10000
; call printplain
; mov eax,2
; jmp pre_mem
;mem_16_z: mov si,memokz16-0x10000
; call printplain
; mov eax,1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; pre_mem:
; push word 0x0000
; pop es
; mov [es:0x9030],al
; push word 0x1000
; pop es
; mov si,linef-0x10000
; call printplain
 
 
 
 
; DIRECT WRITE TO LFB, PAGING DISABLED
 
; movzx eax,byte [es:preboot_lfb-0x10000]
; mov eax,1 ; paging disabled
; cmp eax,0
; jne pre_lfb
; mov si,gr_direct-0x10000
; call printplain
; mov ebx,0x0201
; call getkey
; pre_lfb:
; push word 0x0000
; pop es
; mov [es:0x901E],al
; mov ax,0x1000
; mov es,ax
; mov si,linef-0x10000
; call printplain
push 0
pop es
mov [es:0x901E],byte 1
push 0x1000
pop es
 
 
 
; BOOT DEVICE
 
movzx eax,byte [es:preboot_device-0x10000]
cmp eax,0
jne pre_device
mov si,bdev-0x10000
call printplain
mov ebx,0x0301
call getkey
pre_device:
dec al
mov [es:boot_dev-0x10000],al
mov si,linef-0x10000
call printplain
 
 
 
; READ DISKETTE TO MEMORY
 
cmp [boot_dev-0x10000],0
jne no_sys_on_floppy
mov si,diskload-0x10000
call print
mov ax,0x0000 ; reset drive
mov dx,0x0000
int 0x13
mov cx,0x0001 ; startcyl,startsector
mov dx,0x0000 ; starthead,drive
push word 80*2 ; read no of sect
reads:
pusha
xor si,si
newread:
push word 0x0
pop es
mov bx,0xa000 ; es:bx -> data area
mov ax,0x0200+18 ; read, no of sectors to read
int 0x13
cmp ah,0
jz goodread
add si,1
cmp si,10
jnz newread
mov si,badsect-0x10000
call printplain
jmp $
goodread:
; move -> 1mb
mov si,movedesc-0x10000
push word 0x1000
pop es
mov cx,256*18
mov ah,0x87
int 0x15
 
cmp ah,0 ; was the move successfull ?
je goodmove
mov dx,0x3f2 ; floppy motor off
mov al,0
out dx,al
mov si,memmovefailed-0x10000
call print
jmp $
goodmove:
 
mov eax,[es:movedesc-0x10000+0x18+2]
add eax,512*18
mov [es:movedesc-0x10000+0x18+2],eax
popa
inc dh
cmp dh,2
jnz bb2
mov dh,0
inc ch
pusha ; print prosentage
push word 0x1000
pop es
xor eax,eax ; 5
mov al,ch
shr eax,2
and eax,1
mov ebx,5
mul bx
add al,48
mov [es:pros+1-0x10000],al
xor eax,eax ; 10
mov al,ch
shr eax,3
add al,48
mov [es:pros-0x10000],al
mov si,pros-0x10000
call printplain
popa
bb2:
pop ax
dec ax
push ax
cmp ax,0
jnz rs
jmp readdone
rs:
jmp reads
movedesc:
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
 
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
readdone:
pop ax
mov dx,0x3f2 ; floppy motor off
mov al,0
out dx,al
mov si,backspace-0x10000
call printplain
call printplain
mov si,okt-0x10000
call printplain
no_sys_on_floppy:
mov ax,0x0000 ; reset drive
mov dx,0x0000
int 0x13
mov dx,0x3f2 ; floppy motor off
mov al,0
out dx,al
 
 
; PAGE TABLE
 
push word 0x0000
pop es
mov ecx,[es:0x9018]
push ecx
 
map_mem equ 64 ; amount of memory to map
 
mov bx,0x6000
mov es,bx ; [es:di] = 6000:0
xor edi,edi
mov ecx,256*map_mem ; Map (mapmem) M
mov eax,7
cld
pt2:
cmp ecx,256*(map_mem-8) ; 8 M map to LFB
jnz pt3
pop eax
add eax,7
pt3:
cmp ecx,256*(map_mem-12) ; 12 M back to linear = physical
jnz pt4
mov eax,12*0x100000 + 7
pt4:
stosd
add eax,4096
loop pt2
mov bx,0x7100
mov es,bx
xor edi,edi
mov eax,8*0x100000+7
mov ecx,256*4
pt5:
stosd
add eax,0x1000
loop pt5
; 4 KB PAGE DIRECTORY
 
mov bx , 0x7F00
mov es , bx ; [es:di] = 7000:0
xor edi, edi
mov ecx, 64 / 4
mov eax, 0x60007 ; for 0 M
cld
pd4k:
stosd
add eax, 0x1000
loop pd4k
mov dword [es:0x800],0x71007 ;map region 0x80000000-0x803FFFFF to 0x800000-0xCFFFFF
xor esi,esi
mov edi,second_base_address shr 20
mov ecx,64/4
mov bx,0x7F00
mov ds,bx
rep movsd
mov bx,0x1000
mov ds,bx
mov eax, 0x7F000 +8+16 ; Page directory and enable caches
mov cr3, eax
 
; SET GRAPHICS
 
mov dx,0x0000
mov es,dx
mov bx,[es:0x9008]
mov ax,bx ; vga & 320x200
cmp ax,0x13
je setgr
cmp ax,0x12
je setgr
mov ax,0x4f02 ; Vesa
setgr:
int 0x10
cmp ah,0
jz gmok
mov si,fatalsel-0x10000
call print
jmp $
gmok:
mov dx,0x1000
mov es,dx
 
; set mode 0x12 graphics registers:
 
cmp bx,0x12
jne gmok2
 
mov al,0x05
mov dx,0x03ce
out dx,al ; select GDC mode register
mov al,0x02
mov dx,0x03cf
out dx,al ; set write mode 2
 
mov al,0x02
mov dx,0x03c4
out dx,al ; select VGA sequencer map mask register
mov al,0x0f
mov dx,0x03c5
out dx,al ; set mask for all planes 0-3
 
mov al,0x08
mov dx,0x03ce
out dx,al ; select GDC bit mask register
; for writes to 0x03cf
 
gmok2:
mov dx,0x1000
mov es,dx
/kernel/trunk/boot/booteng.inc
0,0 → 1,109
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25: line_full_top
line_space
line_space
line_half
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
db 186,' Kolibri OS comes with ABSOLUTELY NO WARR'
db 'ANTY; See file COPYING for details ',186
line_full_bottom
 
novesa db "Display: EGA/CGA",13,10,0
vervesa db "Version of Vesa: Vesa x.x ",13,10,0
vervesa_off=22
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 Colors: [9] 320x200, "
db "VGA 16 Colors: [0] 640x480",13,10
db 186," Select mode: ",0
bt24 db 13,10,186," Bits Per Pixel: 24",13,10,0
bt32 db 13,10,186," Bits Per Pixel: 32",13,10,0
vrrmprint db 13,10,186," Apply VRR? (picture frequency greater than 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0
askmouse db " Mouse at:"
db " [1] PS/2 (USB), [2] Com1, [3] Com2."
db " Select port [1-3]: ",0
no_com1 db 13,10,186, " No COM1 mouse",0
no_com2 db 13,10,186, " No COM2 mouse",0
gr_acc db 13,10,186," Vesa 2.0+ : MTRR graphics acceleration "
db "[1-yes/2-no] ? ",0
gr_direct db 186," Use direct LFB writing? "
db "[1-yes/2-no] ? ",0
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
bdev db 13,10,186
db " Load ramdisk from [1-floppy; 2-C:\menuet.img (FAT32);"
db 13,10,186," "
db "3-use preloaded ram-image from kernel restart]: ",0
probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, "
db "2-probe bios (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prid db " pr.",0
prnotfnd db " pr. - not found.",0
modena db "Fatal - VBE 0x112+ required.",0
not386 db "Fatal - CPU 386+ required.",0
btns db 13,10,186,"Fatal - Can't determine color depth.",0
fatalsel db 13,10,"Fatal - Graphics mode not supported by hardware.",0
badsect db 13,10,186," Fatal - Bad sector. Replace floppy. ",0
memmovefailed db "Fatal - Int 0x15 move failed.",0
linef2 db 13,10
linef db 13,10,0
okt db " ... OK",0
keyin db "x",0
keyinbs db "x",8,0
diskload db 13,10,186," Loading diskette: 00 %",8,8,8,8,0
backspace db 8,0
pros db "00",8,8,0
leftpr db 186," ",0
boot_dev db 0 ; 0=floppy, 1=hd
/kernel/trunk/boot/bootru.inc
0,0 → 1,110
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25: line_full_top
line_space
line_space
line_half
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
line_space
db 186,' Kolibri OS ­¥ ¯à¥¤®áâ ¢«ï¥â ­¨ª ª¨å £ àa'
db '­â¨©; ®¤à®¡­¥¥ - á¬. GNU.TXT ',186
line_full_bottom
 
novesa db "‚¨¤¥®ª àâ : EGA/CGA",13,10,0
vervesa db "‚¥àá¨ï VESA: Vesa x.x ",13,10,0
vervesa_off=19
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 –¢¥â®¢: [9] 320x200, "
db "VGA 16 –¢¥â®¢: [0] 640x480",13,10
db 186," ‚ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",0
bt24 db 13,10,186," ƒ«ã¡¨­  梥â : 24",13,10,0
bt32 db 13,10,186," ƒ«ã¡¨­  梥â : 32",13,10,0
vrrmprint db 13,10,186," ˆá¯®«ì§®¢ âì VRR? (ç áâ®â  ª ¤à®¢ ¢ëè¥ 60 ƒæ"
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-­¥â]: ",0
askmouse db "Œëèì:" ; 186, " "
db " [1] PS/2 (USB), [2] Com1, [3] Com2."
db " ‚ë¡¥à¨â¥ ¯®àâ [1-3]: ",0
no_com1 db 13,10,186," No COM1 mouse",0
no_com2 db 13,10,186," No COM2 mouse",0
gr_acc db 13,10,186," Vesa 2.0+: ‚ª«îç¨âì MTRR ¤«ï ã᪮७¨ï £à ä¨ª¨? "
db "[1-¤ /2-­¥â]: ",0
gr_direct db 186," ˆá¯®«ì§®¢ âì «¨­¥©­ë© ¢¨¤¥®¡ãä¥à? "
db "[1-¤ /2-­¥â]: ",0
;mem_model db 13,10,186," Ž¡ê+¬ ¯ ¬ï⨠[1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb]: ",0
bootlog db 13,10,186," à®á¬®âà¥âì ¦ãà­ « § £à㧪¨? [1-­¥â/2-¤ ]: ",0
bdev db 186
db " ‡ £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\menuet.img (FAT32);"
db 13,10,186," "
db "3-¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §]: ",0
probetext db 13,10,13,10,186," ‘â ­¤ àâ­ë© ¢¨¤¥®à¥¦¨¬? [1-¤ , "
db "2-¯à®¢¥à¨âì ¤à㣨¥ (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prid db " pr.",0
prnotfnd db " pr. - ®è¨¡ª .",0
modena db "Žè¨¡ª  - ’ॡã¥âáï ¯®¤¤¥à¦ª  VBE 0x112+.",0
not386 db "Žè¨¡ª  - ’ॡã¥âáï ¯à®æ¥áá®à 386+.",0
btns db 13,10,186," Žè¨¡ª  - ¥ ¬®£ã ®¯à¥¤¥«¨âì £«ã¡¨­ã 梥â .",0
fatalsel db 13,10,"Žè¨¡ª  - ‚ë¡à ­­ë© ¢¨¤¥®à¥¦¨¬ ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0
badsect db 13,10,186," Žè¨¡ª  - „¨áª¥â  ¯®¢à¥¦¤¥­ . ®¯à®¡ã©â¥ ¤àã£ãî. "
db 0
memmovefailed db "Fatal - Int 0x15 move failed.",0
linef2 db 13,10
linef db 13,10,0
okt db " ... OK",0
keyin db "x",0
keyinbs db "x",8,0
diskload db 13,10,186," ‡ £à㧪  ¤¨áª¥âë: 00 %",8,8,8,8,0
backspace db 8,0
pros db "00",8,8,0
leftpr db 186," ",0
boot_dev db 0
/kernel/trunk/boot/preboot.inc
0,0 → 1,23
display_modechg db 0 ; display mode change for text, yes/no (0 or 2)
;
; !! Important note !!
;
; Must be set to 2, to avoid two screenmode
; changes within a very short period of time.
 
display_atboot db 0 ; show boot screen messages ( 2-no )
 
preboot_graph db 0 ; graph mode
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
;;preboot_mouse db 0 ; mouse port (1-PS2, 2-COM1, 3-COM2)
preboot_mtrr db 0 ; mtrr acceleration (1-yes, 2-no)
preboot_device db 0 ; boot device
; (1-floppy 2-harddisk 3-kernel restart)
;;preboot_memory db 0 ; amount of memory
; (1-16Mb;2-32Mb;3-64Mb;4-128Mb;5-256Mb)
; !!!! 0 - autodetect !!!!
preboot_blogesc db 0 ; start immediately after bootlog
 
hdsysimage db 'MENUET IMG' ; load from
image_save db 'MENUET IMG' ; save to
/kernel/trunk/boot/rdload.inc
0,0 → 1,95
; READ RAMDISK IMAGE FROM HD
 
cmp [boot_dev],1
jne no_sys_on_hd
 
test [0x40001],byte 0x40
jz position_2
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [fat32part],0
position_1_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [0x40002]
cmp [fat32part],eax
jle position_1_1
position_2:
test [0x40001],byte 0x10
jz position_3
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [fat32part],0
position_2_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [0x40003]
cmp eax,[fat32part]
jle position_2_1
position_3:
test [0x40001],byte 0x4
jz position_4
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [fat32part],0
position_3_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [0x40004]
cmp eax,[fat32part]
jle position_3_1
position_4:
test [0x40001],byte 0x1
jz no_sys_on_hd
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [fat32part],0
position_4_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [0x40005]
cmp eax,[fat32part]
jle position_4_1
jmp yes_sys_on_hd
 
search_and_read_image:
; mov [0xfe10],dword 0 ; entries in hd cache
call set_FAT32_variables
mov edx, bootpath
call read_image
test eax, eax
jz image_present
mov edx, bootpath2
call read_image
test eax, eax
jz image_present
ret
image_present:
mov [image_retrieved],1
ret
 
read_image:
mov eax, hdsysimage
mov ebx, 1474560/512
mov ecx, 0x100000
mov esi, 0
mov edi, 12
call file_read
ret
 
image_retrieved db 0
counter_of_partitions db 0
no_sys_on_hd:
yes_sys_on_hd:
/kernel/trunk/boot/ru.inc
0,0 → 1,92
; Generated by RUFNT.EXE
; By BadBugsKiller (C)
; Modifyed by BadBugsKiller 12.01.2004 17:45
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé,
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà.
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòàíèöà 866.
RU_FNT1:
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
RU_FNT2:
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
/kernel/trunk/boot/shutdown.inc
0,0 → 1,496
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Shutdown for Menuet
;;
;; Distributed under General Public License
;; See file COPYING for details.
;; Copyright 2003 Ville Turjanmaa
;;
 
 
system_shutdown: ; shut down the system
 
mov eax,3 ; stop playing cd
call sys_cd_audio
cli
cld
 
mov al,[0x2f0000+0x9030]
cmp al,1
jl no_shutdown_parameter
cmp al,4
jg no_shutdown_parameter
jmp yes_shutdown_param
no_shutdown_parameter:
 
movzx ecx,word [0x2f0000+0x900A]
movzx esi,word [0x2f0000+0x900C]
imul ecx,esi ;[0xfe04]
; mov ecx,0x500000/4 ;3fff00/4 ; darken screen
push ecx
mov esi,[0xfe80]
cmp esi,32*0x100000
jbe no_darken_screen
mov edi,16*0x100000
sdnewpix:
mov eax,[esi]
add esi,4
shr eax,1
and eax,0x7f7f7f7f
stosd
loop sdnewpix
pop ecx
mov esi,16*0x100000
mov edi,[0xfe80]
cld
rep movsd
no_darken_screen:
 
mov eax,[0xfe00]
shr eax,1
sub eax,220
 
mov ebx,[0xfe04]
shr ebx,1
mov [shutdownpos],ebx
sub ebx,120
 
mov edi,1
mov ecx,0x0000ff
 
sdnewpix2:
 
call [putpixel]
 
inc eax
mov esi,[0xfe00]
shr esi,1
add esi,220
cmp eax,esi
jnz sdnewpix2
 
dec ecx
 
mov eax,[0xfe00]
shr eax,1
sub eax,220
 
inc ebx
 
mov edx,[shutdownpos]
add edx,105
cmp ebx,edx
jnz sdnewpix2
 
 
mov esi,[0xfe00] ; menuet version
shr esi,1
sub esi,220
add esi,27
shl esi,16
mov eax,esi
add eax,[shutdownpos]
sub eax,105
mov ebx,0xffff00
mov ecx,version
mov edx,34
mov edi,1
call dtext
 
mov esi,[0xfe00] ; 'it is safe..'
shr esi,1
sub esi,220
add esi,27
shl esi,16
mov eax,esi
add eax,[shutdownpos]
add eax,33
mov esi,6
mov ebx,0xffffff
mov ecx,shutdowntext
mov edx,40
mov edi,1
newsdt:
call dtext
add eax,10
add ecx,40
dec esi
jnz newsdt
 
mov eax,rosef ; load rose.txt
mov ebx,0
mov ecx,16800
mov edx,0x90000
mov esi,12
call fileread
 
mov esi,[0xfe00] ; draw rose
shr esi,1
add esi,20
shl esi,16
mov eax,esi
add eax,[shutdownpos]
sub eax,110
 
mov ebx,0x00ff00
mov ecx,0x90001
mov edx,27
mov edi,1
 
nrl:
call dtext
sub ebx,0x050000
add eax,8
add ecx,31
cmp ecx,dword 0x90001+25*31
jnz nrl
 
call checkEgaCga
 
yes_shutdown_param:
 
cli
 
mov eax,kernel ; load kernel.mnt to 0x8000:0
mov esi,12
mov ebx,0
mov ecx,-1
mov edx,0x80000
call fileread
 
mov esi,restart_kernel_4000 ; move kernel re-starter to 0x4000:0
mov edi,0x40000
mov ecx,1000
cld
rep movsb
 
mov eax,0x2F0000 ; restore 0x0 - 0xffff
mov ebx,0x0000
mov ecx,0xffff
call memmove
 
call restorefatchain
 
mov eax,pr_mode_exit
mov [0x467+0],ax
mov [0x467+2],word 0x1000
 
mov al,0x0F
out 0x70,al
mov al,0x05
out 0x71,al
 
mov al,0xFE
out 0x64,al
hlt
 
use16
 
pr_mode_exit:
 
mov ax,1000
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
; mov bl,[shutdown_parameter]
mov al,2
out 0x21,al
mov al,0
out 0xA1,al
 
; mov [es:shutdown_parameter-0x10000],bl
 
jmp real_mode-0x10000
 
old_ints_h:
dw 4*0x20
dd 0
dw 0
 
real_mode:
 
lidt [cs:old_ints_h-0x10000]
mov sp,0xfff0
 
sti
 
jmp temp_3456
 
nbw:
xor ax,ax
in al,0x60
call pause_key
cmp al,7
jge nbw
mov bl,al
nbw2:
in al,0x60
call pause_key
cmp al,bl
je nbw2
cmp al,240 ;ax,240
jne nbw31
mov al,bl
dec al
jmp nbw32
nbw31:
add bl,128
cmp al,bl
jne nbw
sub al,129
 
nbw32:
cmp al,1 ; write floppy
jne no_floppy_write
call floppy_write
jmp temp_3456 ;nbw
no_floppy_write:
 
cmp al,2 ; poweroff
jne no_apm_off
call APM_PowerOff
no_apm_off:
 
cmp al,3 ; boot
jnz no_sys_boot
mov ax,0x0040
mov ds,ax
mov word[0x0072],0x1234
jmp 0xF000:0xFFF0
no_sys_boot:
 
cmp al,4 ; restart kernel
je restart_kernel
 
temp_3456:
push word 0x0000
pop es
mov al,byte [es:0x9030]
cmp al,1
jl nbw
cmp al,4
jg nbw
jmp nbw32
; jmp nbw
pause_key:
mov ecx,100
pause_key_1:
loop pause_key_1
ret
 
iglobal
kernel db 'KERNEL MNT'
; shutdown_parameter db 0
endg
 
restart_kernel:
 
mov ax,0x0003 ; set text mode for screen
int 0x10
 
jmp 0x4000:0000
 
 
restart_kernel_4000:
 
mov di,0x1000 ; load kernel image from 0x8000:0 -> 0x1000:0
 
new_kernel_block_move:
 
mov ebx,0
 
new_kernel_byte_move:
 
mov ax,di
add ax,0x7000
mov es,ax
mov dl,[es:bx]
mov es,di
mov [es:bx],dl
 
inc ebx
cmp ebx,65536
jbe new_kernel_byte_move
 
add di,0x1000
cmp di,0x2000
jbe new_kernel_block_move
 
wbinvd ; write and invalidate cache
 
mov ax,0x1000
mov es,ax
mov ax,0x2000
mov ss,ax
mov sp,0xff00
 
jmp 0x1000:0000
 
 
APM_PowerOff:
;!!!!!!!!!!!!!!!!!!!!!!!!
mov ax,0x5300
xor bx,bx
int 0x15
push ax
 
mov ax,0x5301
xor bx,bx
int 0x15
 
mov ax,0x5308
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x530E
xor bx,bx
pop cx
int 0x15
 
mov ax,0x530D
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x530F
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x5307
mov bx,1
mov cx,3
int 0x15
;!!!!!!!!!!!!!!!!!!!!!!!!
ret
uglobal
flm db 0
endg
 
floppy_write: ; write diskette image to physical floppy
 
pusha
 
mov ax,0x1000
mov es,ax
cmp [es:flm-0x10000],byte 1
je fwwritedone
mov [es:flm-0x10000],byte 1
 
mov ax,0x0000 ; reset drive
mov dx,0x0000
int 0x13
 
mov cx,0x0001 ; startcyl,startsector
mov dx,0x0000 ; starthead,drive
push word 80*2 ; read no of sect
 
fwwrites:
pusha
 
; move 1mb+ -> 0:a000
 
pusha
mov si,fwmovedesc -0x10000
push word 0x1000
pop es
mov cx,256*18
mov ah,0x87
int 0x15
mov eax,[es:fwmovedesc-0x10000+0x12]
add eax,512*18
mov [es:fwmovedesc-0x10000+0x12],eax
popa
 
xor si,si
fwnewwrite:
push word 0x0
pop es
mov bx,0xa000 ; es:bx -> data area
mov ax,0x0300+18 ; read, no of sectors to read
int 0x13
 
cmp ah,0
jz fwgoodwrite
 
add si,1
cmp si,10
jnz fwnewwrite
 
add esp,32+2
 
popa ; can't access diskette
ret
 
fwgoodwrite:
 
popa
 
inc dh
cmp dh,2
jnz fwbb2
mov dh,0
inc ch
 
fwbb2:
 
cld
pop ax
dec ax
push ax
cmp ax,0
jnz fwrs
 
pop ax
 
jmp fwwritedone
fwrs:
jmp fwwrites
 
fwmovedesc:
 
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
fwwritedone:
 
popa
 
ret
 
 
use32
 
uglobal
shutdownpos dd 0x0
endg
 
iglobal
;shutdowntext:
; db "IT'S SAFE TO POWER OFF COMPUTER OR "
; db ' '
; db '1) SAVE RAMDISK TO FLOPPY '
; db '2) APM - POWEROFF '
; db '3) REBOOT '
; db '4) RESTART KERNEL '
shutdowntext:
db "¥§®¯ á­®¥ ¢ëª«î祭¨¥ ª®¬¯ìîâ¥à  ¨«¨ "
db ' '
db '1) ‘®åà ­¨âì à ¬¤¨áª ­  ¤¨áª¥âã '
db '2) APM - ¢ëª«î祭¨¥ ¯¨â ­¨ï '
db '3) ¥à¥§ £à㧪  á¨á⥬ë '
db '4) ¥áâ àâ ï¤à  ¨§ Ž‡“ '
rosef:
db 'ROSE TXT'
endg
/kernel/trunk/build_en.bat
0,0 → 1,4
@if not exist lang.inc (
@echo lang fix en >lang.inc
)
@fasm kernel.asm kernel.mnt
/kernel/trunk/build_ru.bat
0,0 → 1,4
@if not exist lang.inc (
@echo lang fix ru >lang.inc
)
@fasm kernel.asm kernel.mnt
/kernel/trunk/bus/pci/pci16.inc
0,0 → 1,46
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCI16.INC ;;
;; ;;
;; 16 bit PCI driver code ;;
;; ;;
;; Version 0.2 December 21st, 2002 ;;
;; ;;
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
init_pci_16:
 
pushad
 
xor ax,ax
mov es,ax
mov byte [es:0x9020],1 ;default mechanism:1
mov ax,0xb101
int 0x1a
or ah,ah
jnz pci16skip
 
mov [es:0x9021],cl ;last PCI bus in system
mov [es:0x9022],bx
mov [es:0x9024],edi
 
; we have a PCI BIOS, so check which configuration mechanism(s)
; it supports
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2)
test al,1
jnz pci16skip
test al,2
jz pci16skip
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2
 
pci16skip:
 
mov ax,0x1000
mov es,ax
 
popad
/kernel/trunk/bus/pci/pci32.inc
0,0 → 1,358
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCI32.INC ;;
;; ;;
;; 32 bit PCI driver code ;;
;; ;;
;; Version 0.2 December 21st, 2002 ;;
;; ;;
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
;; Credits: ;;
;; Ralf Brown ;;
;; Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;***************************************************************************
; Function
; pci_api:
;
; Description
; entry point for system PCI calls
;***************************************************************************
 
align 4
 
pci_api:
 
cmp [pci_access_enabled],1
jne no_pci_access_for_applications
 
or al,al
jnz pci_fn_1
; PCI function 0: get pci version (AH.AL)
movzx eax,word [0x2F0000+0x9022]
ret
 
pci_fn_1:
cmp al,1
jnz pci_fn_2
 
; PCI function 1: get last bus in AL
mov al,[0x2F0000+0x9021]
ret
 
pci_fn_2:
cmp al,2
jne pci_fn_3
; PCI function 2: get pci access mechanism
mov al,[0x2F0000+0x9020]
ret
pci_fn_3:
 
cmp al,4
jz pci_read_reg ;byte
cmp al,5
jz pci_read_reg ;word
cmp al,6
jz pci_read_reg ;dword
 
cmp al,8
jz pci_write_reg ;byte
cmp al,9
jz pci_write_reg ;word
cmp al,10
jz pci_write_reg ;dword
 
no_pci_access_for_applications:
 
mov eax,-1
 
ret
 
;***************************************************************************
; Function
; pci_make_config_cmd
;
; Description
; creates a command dword for use with the PCI bus
; bus # in ah
; device+func in bh (dddddfff)
; register in bl
;
; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
;***************************************************************************
 
align 4
 
pci_make_config_cmd:
shl eax,8 ; move bus to bits 16-23
mov ax,bx ; combine all
and eax,0xffffff
or eax,0x80000000
ret
 
;***************************************************************************
; Function
; pci_read_reg:
;
; Description
; read a register from the PCI config space into EAX/AX/AL
; IN: ah=bus,device+func=bh,register address=bl
; number of bytes to read (1,2,4) coded into AL, bits 0-1
;***************************************************************************
 
align 4
 
pci_read_reg:
cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use?
je pci_read_reg_2
 
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
call pci_make_config_cmd
mov ebx,eax
; get current state
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; get requested DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl ; add to port address first 2 bits of register address
 
or esi,esi
jz pci_read_byte1
cmp esi,1
jz pci_read_word1
cmp esi,2
jz pci_read_dword1
jmp pci_fin_read1
 
pci_read_byte1:
in al,dx
jmp pci_fin_read1
pci_read_word1:
in ax,dx
jmp pci_fin_read1
pci_read_dword1:
in eax,dx
jmp pci_fin_read1
pci_fin_read1:
; restore configuration control
xchg eax,[esp]
mov dx,0xcf8
out dx,eax
 
pop eax
pop esi
ret
pci_read_reg_2:
 
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_read_reg_err
 
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
 
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
 
or esi,esi
jz pci_read_byte2
cmp esi,1
jz pci_read_word2
cmp esi,2
jz pci_read_dword2
jmp pci_fin_read2
 
pci_read_byte2:
in al,dx
jmp pci_fin_read2
pci_read_word2:
in ax,dx
jmp pci_fin_read2
pci_read_dword2:
in eax,dx
; jmp pci_fin_read2
pci_fin_read2:
 
; restore configuration space
xchg eax,[esp]
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
 
pop eax
pop esi
ret
 
pci_read_reg_err:
xor eax,eax
dec eax
ret
 
 
;***************************************************************************
; Function
; pci_write_reg:
;
; Description
; write a register from ECX/CX/CL into the PCI config space
; IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
; value to write in ecx
; number of bytes to write (1,2,4) coded into AL, bits 0-1
;***************************************************************************
 
align 4
 
pci_write_reg:
cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use?
je pci_write_reg_2
 
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
call pci_make_config_cmd
mov ebx,eax
; get current state into ecx
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; write DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl
mov eax,ecx
 
or esi,esi
jz pci_write_byte1
cmp esi,1
jz pci_write_word1
cmp esi,2
jz pci_write_dword1
jmp pci_fin_write1
 
pci_write_byte1:
out dx,al
jmp pci_fin_write1
pci_write_word1:
out dx,ax
jmp pci_fin_write1
pci_write_dword1:
out dx,eax
jmp pci_fin_write1
pci_fin_write1:
 
; restore configuration control
pop eax
mov dl,0xf8
out dx,eax
 
xor eax,eax
pop esi
 
ret
pci_write_reg_2:
 
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_write_reg_err
 
 
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
; write register
mov eax,ecx
 
or esi,esi
jz pci_write_byte2
cmp esi,1
jz pci_write_word2
cmp esi,2
jz pci_write_dword2
jmp pci_fin_write2
 
pci_write_byte2:
out dx,al
jmp pci_fin_write2
pci_write_word2:
out dx,ax
jmp pci_fin_write2
pci_write_dword2:
out dx,eax
jmp pci_fin_write2
pci_fin_write2:
; restore configuration space
pop eax
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
 
xor eax,eax
pop esi
ret
 
pci_write_reg_err:
xor eax,eax
dec eax
ret
/kernel/trunk/core/fpu.inc
0,0 → 1,62
iglobal
prev_user_of_fpu dd 0x1 ; set to OS
endg
 
label fpu_tss at 0xB080
label fpu_stack dword at 0xB060
 
 
align 4
fpu_handler:
 
; clear TS flag in CR0 -> for task switching
clts
 
; save FPU context of the previous task
mov eax,[prev_user_of_fpu]
shl eax,8
add eax,0x80000+0x10
fsave [eax]
 
; next task switch save our FPU context
; now restore context of current task (if exists)
mov eax,[0x3000]
mov [prev_user_of_fpu],eax
shl eax,8
add eax,0x80000
cmp [eax+0x7f],byte 0
je bs7_first_fpu
frstor [eax+0x10]
bs7_first_fpu:
mov [eax+0x7f],byte 1
 
; prepare structure in stack for proper IRET
movzx eax,word [fpu_tss+l.ss-tss_sceleton] ; push ss
push eax
mov eax,[fpu_tss+l.esp-tss_sceleton] ; push esp
push eax
mov eax,[fpu_tss+l.eflags-tss_sceleton] ; push eflags
push eax
 
movzx eax,word [fpu_tss+l.cs-tss_sceleton] ; push cs
push eax
mov eax,[fpu_tss+l.eip-tss_sceleton] ; push eip
push eax
 
; save eax
push dword [fpu_tss+l.eax-tss_sceleton]
 
; restore all segment registers
mov ax,[fpu_tss+l.es-tss_sceleton]
mov es,ax
mov ax,[fpu_tss+l.fs-tss_sceleton]
mov fs,ax
mov ax,[fpu_tss+l.gs-tss_sceleton]
mov gs,ax
mov ax,[fpu_tss+l.ds-tss_sceleton]
mov ds,ax
 
; restore eax
pop eax
 
iret
/kernel/trunk/core/mem.inc
0,0 → 1,473
if ~defined mem_inc
mem_inc_fix:
mem_inc fix mem_inc_fix
;include "memmanag.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;High-level memory management in MenuetOS.
;;It uses memory manager in memmanager.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
second_base_address=0xC0000000
std_application_base_address=0x10000000
general_page_table_ dd 0
general_page_table=general_page_table_+second_base_address
;-----------------------------------------------------------------------------
create_general_page_table:
;input
; none
;output
; none
;Procedure create general page directory and write
;it address to [general_page_table].
pushad
mov eax,1 ;alloc 1 page
mov ebx,general_page_table ;write address to [general_page_table]
call MEM_Alloc_Pages ;allocate page directory
mov eax,[general_page_table]
call MEM_Get_Linear_Address ;eax - linear address of page directory
mov edi,eax
mov ebx,eax
xor eax,eax
mov ecx,4096/4
cld
rep stosd ;clear page directory
mov eax,4
mov edx,eax
call MEM_Alloc_Pages ;alloc page tables for 0x0-0x1000000 region
cmp eax,edx
jnz $ ;hang if not enough memory
;fill page tables
xor esi,esi
mov ebp,7
.loop:
;esi - number of page in page directory
;ebp - current page address
;ebx - linear address of page directory
mov eax,[ebx+4*esi]
add dword [ebx+4*esi],7 ;add flags to address of page table
call MEM_Get_Linear_Address
;eax - linear address of page table
mov ecx,4096/4
;ecx (counter) - number of pages in page table
;current address=4Mb*esi
cmp esi,2
jz .start_lfb_map ;lfb map begin at 0x800000
cmp esi,3
jz .end_lfb_map ;lfb map end at 0xC00000
jmp .loop1
.start_lfb_map:
;current address=lfb address
mov ebp,[0x2f0000+0x9018]
add ebp,7 ;add flags
jmp .loop1
.end_lfb_map:
;current address=linear address
mov ebp,12*0x100000+7
.loop1:
mov [eax],ebp ;write page address (with flags) in page table
add eax,4
add ebp,4096 ;size of page=4096 bytes
loop .loop1
inc esi ;next page directory entry
cmp esi,edx
jnz .loop
;map region 0x80000000-0x803fffff to 0x800000-0xcfffff
mov eax,1 ;size of the region is 4Mb so only 1 page table needed
mov edx,ebx ;ebx still contains linear address of the page directory
add ebx,0x800
call MEM_Alloc_Pages ;alloc page table for the region
mov eax,[ebx]
add dword [ebx],7 ;add flags
call MEM_Get_Linear_Address ;get linear address of the page table
mov ebx,eax
mov ecx,4096/4 ;number of pages in page table
mov eax,8*0x100000+7
.loop3:
;ebx - linear address of page table
;eax - current linear address with flags
mov [ebx],eax
add ebx,4
add eax,4096
loop .loop3
;map region 0xC0000000-* to 0x0-*
mov esi,edx ;esi=linear address of the page directory
lea edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00)
mov ecx,4
rep movsd ;first 16Mb of the region mapped as 0x0-0x1000000 block
mov eax,[0xfe8c] ;eax=memory size
add eax,0x3fffff
shr eax,22
mov esi,eax ;calculate number of entries in page directory
sub esi,4 ;subtract entries for first 16Mb.
mov ebp,0x1000000+7 ;start physical address with flags
;mapping memory higher than 16Mb
.loop4:
;esi (counter) - number of entries in page directory
;edi - address of entry
test esi,esi
jle .loop4end
call MEM_Alloc_Page ;alloc page table for entry in page directory
mov [edi],eax
add dword [edi],7 ;write physical address of page table in page directory
add edi,4 ;move entry pointer
call MEM_Get_Linear_Address
mov ecx,eax
xor edx,edx
.loop5:
;ecx - linear address of page table
;edx - index of page in page table
;ebp - current mapped physical address with flags
mov [ecx+4*edx],ebp ;write address of page in page table
add ebp,0x1000 ;move to next page
inc edx
cmp edx,4096/4
jl .loop5
dec esi
jmp .loop4
.loop4end:
.set_cr3:
;set value of cr3 register to the address of page directory
mov eax,[general_page_table]
add eax,8+16 ;add flags
mov cr3,eax ;now we have full access paging
popad
ret
;-----------------------------------------------------------------------------
simple_clone_cr3_table:
;Parameters:
; eax - physical address of cr3 table (page directory)
;result:
; eax - physical address of clone of cr3 table.
;Function copy only page directory.
push ecx
push edx
push esi
push edi
call MEM_Get_Linear_Address
;eax - linear address of cr3 table
mov esi,eax
call MEM_Alloc_Page
test eax,eax
jz .failed
;eax - physical address of new page diretory
mov edx,eax
call MEM_Get_Linear_Address
mov edi,eax
mov ecx,4096/4
cld
;esi - address of old page directory
;edi - address of new page directory
rep movsd ;copy page directory
mov eax,edx
.failed:
pop edi
pop esi
pop edx
pop ecx
ret
;-----------------------------------------------------------------------------
create_app_cr3_table:
;Parameters:
; eax - slot of process (index in 0x3000 table)
;result:
; eax - physical address of table.
;This function create page directory for new process and
;write it physical address to offset 0xB8 of extended
;process information.
push ebx
 
mov ebx,eax
mov eax,[general_page_table]
call simple_clone_cr3_table ;clone general page table
shl ebx,8
mov [second_base_address+0x80000+ebx+0xB8],eax ;save address of page directory
pop ebx
ret
;-----------------------------------------------------------------------------
get_cr3_table:
;Input:
; eax - slot of process
;result:
; eax - physical address of page directory
shl eax,8 ;size of process extended information=256 bytes
mov eax,[second_base_address+0x80000+eax+0xB8]
ret
;-----------------------------------------------------------------------------
dispose_app_cr3_table:
;Input:
; eax - slot of process
;result:
; none
;This procedure frees page directory,
;page tables and all memory of process.
pushad
mov ebp,eax
;ebp = process slot in the procedure.
shl eax,8
mov eax,[second_base_address+0x80000+eax+0xB8]
mov ebx,eax
;ebx = physical address of page directory
call MEM_Get_Linear_Address
mov edi,eax
;edi = linear address of page directory
mov eax,[edi+(std_application_base_address shr 20)]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov esi,eax
;esi = linear address of first page table
 
;search threads
; mov ecx,0x200
xor edx,edx
mov eax,0x2
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [second_base_address+0x3000+ecx+0xa],0 ;if process running?
jnz .next ;slot empty or process is terminating - go to next slot
shl ecx,3
cmp [second_base_address+0x80000+ecx+0xB8],ebx ;compare page directory addresses
jnz .next
inc edx ;thread found
.next:
inc eax
cmp eax,[0x3004] ;exit loop if we look through all processes
jle .loop
;edx = number of threads
;our process is zombi so it isn't counted
test edx,edx
jnz .threadsexists
;if there isn't threads then clear memory.
add edi,std_application_base_address shr 20
.loop1:
;edi = linear address of current directory entry
;esi = linear address of current page table
test esi,esi
jz .loop1end
xor ecx,ecx
.loop2:
;ecx = index of page
mov eax,[esi+4*ecx]
test eax,eax
jz .loopend ;skip empty entries
and eax,not (4096-1) ;clear flags
push ecx
call MEM_Free_Page ;free page
pop ecx
.loopend:
inc ecx
cmp ecx,1024 ;there are 1024 pages in page table
jl .loop2
mov eax,esi
call MEM_Free_Page_Linear ;free page table
.loop1end:
add edi,4 ;move to next directory entry
mov eax,[edi]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov esi,eax ;calculate linear address of new page table
test edi,0x800
jz .loop1 ;test if we at 0x80000000 address?
and edi,not (4096-1) ;clear offset of page directory entry
mov eax,edi
call MEM_Free_Page_Linear ;free page directory
popad
ret
.threadsexists: ;do nothing
popad ;last thread will free memory
ret
;-----------------------------------------------------------------------------
mem_alloc_specified_region:
;eax - linear directory address
;ebx - start address (aligned to 4096 bytes)
;ecx - size in pages
;result:
; eax=1 - ok
; eax=0 - failed
;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval.
pushad
mov ebp,ebx ;save start address for recoil
mov esi,eax
.gen_loop:
;esi = linear directory address
;ebx = current address
;ecx = remaining size in pages
mov edx,ebx
shr edx,22
mov edi,[esi+4*edx] ;find directory entry for current address
test edi,edi
jnz .table_exists ;check if page table allocated
call MEM_Alloc_Page ;alloc page table
test eax,eax
jz .failed
mov [esi+4*edx],eax
add dword [esi+4*edx],7 ;write it address with flags
call MEM_Get_Linear_Address
call mem_fill_page ;clear page table
jmp .table_linear
.table_exists:
;calculate linear address of page table
mov eax,edi
and eax,not (4096-1) ;clear flags
call MEM_Get_Linear_Address
.table_linear:
;eax = linear address of page table
mov edx,ebx
shr edx,12
and edx,(1024-1) ;calculate index in page table
mov edi,eax
.loop:
;edi = linear address of page table
;edx = current page table index
;ecx = remaining size in pages
;ebx = current address
test ecx,ecx
jle .endloop1 ;all requested pages allocated
call MEM_Alloc_Page ;alloc new page
test eax,eax
jz .failed
mov [edi+4*edx],eax
add dword [edi+4*edx],7 ;write it address with flags
call MEM_Get_Linear_Address
call mem_fill_page ;clear new page
;go to next page table entry
dec ecx
add ebx,4096
inc edx
test edx,(1024-1)
jnz .loop
jmp .gen_loop
.endloop1:
popad
mov eax,1 ;ok
ret
.failed:
;calculate data for recoil
sub ebx,ebp
shr ebx,12
mov ecx,ebx ;calculate number of allocated pages
mov eax,esi ;restore linear address of page directory
mov ebx,ebp ;restore initial address
call mem_free_specified_region ;free all allocated pages
popad
xor eax,eax ;fail
ret
;-----------------------------------------------------------------------------
mem_fill_page:
;Input:
; eax - address
;result:
; none
;set to zero 4096 bytes at eax address.
push ecx
push edi
mov edi,eax
mov ecx,4096/4
xor eax,eax
rep stosd
lea eax,[edi-4096]
pop edi
pop ecx
ret
;-----------------------------------------------------------------------------
mem_free_specified_region:
;eax - linear page directory address
;ebx - start address (aligned to 4096 bytes)
;ecx - size in pages
;result - none
;Free pages in [ebx;ebx+4096*ecx) region.
pushad
mov esi,eax
xor ebp,ebp
.gen_loop:
;esi = linear page directory address
;ebx = current address
;ecx = remaining pages
;ebp = 0 for first page table
; 1 otherwise
mov edx,ebx
shr edx,22
mov eax,[esi+4*edx] ;find directory entry for current address
and eax,not (4096-1)
test eax,eax
jnz .table_exists
;skip absent page tables
mov edx,ebx
shr edx,12
and edx,(1024-1) ;edx - index of current page
add ebx,1 shl 22
add ecx,edx
and ebx,not ((1 shl 22)-1)
mov ebp,1 ;set flag
sub ecx,1024 ;ecx=ecx-(1024-edx)
jg .gen_loop
popad
ret
.table_exists:
call MEM_Get_Linear_Address
;eax - linear address of table
mov edx,ebx
shr edx,12
and edx,(1024-1) ;edx - index of current page
mov edi,eax
.loop:
;edi = linear address of page table entry
;edx = index of page table entry
;ecx = remaining pages
test ecx,ecx
jle .endloop1
mov eax,[edi+4*edx]
and eax,not (4096-1)
call MEM_Free_Page ;free page
mov dword [edi+4*edx],0 ;and clear page table entry
dec ecx
inc edx
cmp edx,1024
jl .loop
test ebp,ebp
jz .first_page
mov eax,edi
call MEM_Free_Page_Linear ;free page table
mov edx,ebx
shr edx,22
mov dword [esi+4*edx],0 ;and clear page directory entry
.first_page:
add ebx,1 shl 22
and ebx,not ((1 shl 22)-1) ;calculate new current address
mov ebp,1 ;set flag
jmp .gen_loop
.endloop1:
popad
ret
end if
/kernel/trunk/core/memmanag.inc
0,0 → 1,977
if ~defined memmanager_inc
memmanager_inc_fix:
memmanager_inc fix memmanager_inc_fix
;for testing in applications
if defined B32
iskernel=1
else
iskernel=0
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Memory allocator for MenuetOS kernel
;; Andrey Halyavin, halyavin@land.ru 2005
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; heap block structure -
;; you can handle several ranges of
;; pages simultaneosly.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.heap_linear_address equ 0
.heap_block_size equ 4
.heap_physical_address equ 8
.heap_reserved equ 12
.heap_block_info equ 16
max_heaps equ 8
.range_info equ 36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; memory manager data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_heap_block_ rd .heap_block_info*max_heaps/4
MEM_heap_block=MEM_heap_block_+second_base_address
MEM_heap_count_ rd 1
MEM_heap_count=MEM_heap_count_+second_base_address
if iskernel = 0
MEM_general_mutex rd 1
MEM_call_count rd 1
MEM_mutex_pid rd 1
MEM_mutex_count rd 1
else
MEM_cli_count_ rd 1
MEM_cli_count=MEM_cli_count_+second_base_address
MEM_cli_prev_ rd 1
MEM_cli_prev=MEM_cli_prev_+second_base_address
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Init
;;Initialize memory manager structures.
;;Must be called first.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Init:
push eax
xor eax,eax
if iskernel = 0
mov [MEM_heap_count],eax
mov [MEM_general_mutex],eax
mov [MEM_call_count],eax
mov [MEM_mutex_pid],eax
mov [MEM_mutex_count],eax
else
mov [MEM_cli_prev],eax ;init value = 0
dec eax
mov [MEM_cli_count],eax ;init value = -1
end if
pop eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;change_task
;;procedure for changing tasks.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if iskernel = 0
change_task:
push eax
push ebx
mov eax,5
xor ebx,ebx
inc ebx
int 0x40
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_get_pid
;;determine current pid
;;result:
;; eax - pid
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if iskernel = 0
MEM_get_pid:
push ebx
push ecx
sub esp,1024
mov eax,9
mov ebx,esp
mov ecx,-1
int 0x40
mov eax,[esp+30]
add esp,1024
pop ecx
pop ebx
ret
else
; pid_address dd 0x3000
;MEM_get_pid:
; mov eax,[pid_address]
; mov eax,[eax]
; ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Heap_Lock
;;Wait until all operations with heap will be finished.
;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations
;;with heap are forbidden.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Heap_Lock:
if iskernel = 0
push eax
inc dword [MEM_call_count]
MEM_Heap_Lock_wait:
mov eax,1
xchg [MEM_general_mutex],eax
test eax,eax
jz MEM_Heap_Lock_end
call MEM_get_pid
cmp [MEM_mutex_pid],eax
jz MEM_Heap_Lock_end1
call change_task
jmp MEM_Heap_Lock_wait
MEM_Heap_Lock_end1:
inc dword [MEM_mutex_count]
pop eax
ret
MEM_Heap_Lock_end:
call MEM_get_pid
mov [MEM_mutex_pid],eax
mov dword [MEM_mutex_count],1
pop eax
ret
else
pushfd
cli
inc dword [MEM_cli_count]
jz MEM_Heap_First_Lock
add esp,4
ret
MEM_Heap_First_Lock: ;save interrupt flag
shr dword [esp],9
and dword [esp],1
pop dword [MEM_cli_prev]
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Heap_UnLock
;;After this routine operations with heap are allowed.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Heap_UnLock:
if iskernel = 0
push eax
xor eax,eax
dec dword [MEM_mutex_count]
jnz MEM_Heap_UnLock_No_Wait1
dec dword [MEM_call_count]
mov [MEM_mutex_pid],eax
mov [MEM_general_mutex],eax;release mutex BEFORE task switching
jz MEM_Heap_UnLock_No_Wait
call change_task ;someone want to use heap - switch tasks
MEM_Heap_UnLock_No_Wait:
pop eax
ret
MEM_Heap_UnLock_No_Wait1:
dec dword [MEM_call_count]
jz MEM_Heap_UnLock_No_Wait2
call change_task
MEM_Heap_UnLock_No_Wait2:
pop eax
ret
else
dec dword [MEM_cli_count]
js MEM_Heap_UnLock_last
ret
MEM_Heap_UnLock_last:
cmp dword [MEM_cli_prev],0 ;restore saved interrupt flag
jz MEM_Heap_UnLock_No_sti
sti
MEM_Heap_UnLock_No_sti:
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Heap
;;Add new range to memory manager.
;;eax - linear address
;;ebx - size in pages
;;ecx - physical address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Add_Heap:
push edx
call MEM_Heap_Lock
mov edx,[MEM_heap_count]
cmp edx,max_heaps
jz MEM_Add_Heap_Error
inc dword [MEM_heap_count]
shl edx,4
mov [MEM_heap_block+edx+.heap_linear_address],eax
mov [MEM_heap_block+edx+.heap_block_size],ebx
shl dword [MEM_heap_block+edx+.heap_block_size],12
mov [MEM_heap_block+edx+.heap_physical_address],ecx
lea edx,[4*ebx+.range_info+4095] ;calculate space for page info table
and edx,0xFFFFF000
mov [eax],eax
add [eax],edx ;first 4 bytes - pointer to first free page
;clean page info area
push edi
lea edi,[eax+4]
mov ecx,edx
shr ecx,2
push eax
xor eax,eax
rep stosd
pop eax
pop edi
;create free pages list.
mov ecx,[eax]
shl ebx,12
add eax,ebx ;eax - address after block
MEM_Add_Heap_loop:
add ecx,4096
mov [ecx-4096],ecx ;set forward pointer
cmp ecx,eax
jnz MEM_Add_Heap_loop
mov dword [ecx-4096],0 ;set end of list
MEM_Add_Heap_ret:
call MEM_Heap_UnLock
pop edx
ret
MEM_Add_Heap_Error:
xor eax,eax
jmp MEM_Add_Heap_ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Physical_Address
;;Translate linear address to physical address
;;Parameters:
;; eax - linear address
;;Result:
;; eax - physical address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Physical_Address
MEM_Get_Physical_Address:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Physical_Address_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
jl MEM_Get_Physical_Address_next
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jge MEM_Get_Physical_Address_next
add eax,[MEM_heap_block+ecx+.heap_physical_address]
jmp MEM_Get_Physical_Address_loopend
MEM_Get_Physical_Address_next:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Get_Physical_Address_loop
xor eax,eax ;address not found
MEM_Get_Physical_Address_loopend:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Linear_Address
;;Translate physical address to linear address.
;;Parameters:
;; eax - physical address
;;Result:
;; eax - linear address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Linear_Address
MEM_Get_Linear_Address:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Linear_Address_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
jl MEM_Get_Linear_Address_Next
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jge MEM_Get_Linear_Address_Next
add eax,[MEM_heap_block+ecx+.heap_linear_address]
call MEM_Heap_UnLock
pop ecx
ret
MEM_Get_Linear_Address_Next:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Get_Linear_Address_loop
call MEM_Heap_UnLock
pop ecx
xor eax,eax ;address not found
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Page
;;Allocate and add reference to page
;;Result:
;; eax<>0 - physical address of page
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Page
MEM_Alloc_Page:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Page_loop:
push ecx
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [ecx],0
jz MEM_Alloc_Page_loopend
mov eax,[ecx]
push dword [eax]
pop dword [ecx]
sub eax,ecx
push eax
shr eax,10
mov word [ecx+.range_info+eax],1
pop eax
pop ecx
add eax,[MEM_heap_block+ecx+.heap_physical_address]
jmp MEM_Alloc_Page_ret
MEM_Alloc_Page_loopend:
pop ecx
sub ecx,16
jns MEM_Alloc_Page_loop
xor eax,eax
MEM_Alloc_Page_ret:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Page_Linear
;;Allocate and add reference to page
;;Result:
;; eax<>0 - linear address of page
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Page_Linear
MEM_Alloc_Page_Linear:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Page_Linear_loop:
push ecx
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [ecx],0
jz MEM_Alloc_Page_Linear_loopend
mov eax,[ecx]
push dword [eax]
pop dword [ecx]
push eax
sub eax,ecx
shr eax,10
mov word [ecx+.range_info+eax],1
pop eax
pop ecx
jmp MEM_Alloc_Page_Linear_ret
MEM_Alloc_Page_Linear_loopend:
pop ecx
sub ecx,16
jns MEM_Alloc_Page_Linear_loop
xor eax,eax
MEM_Alloc_Page_Linear_ret:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Page
;;Remove reference and free page if number of
;;references is equal to 0
;;Parameters:
;; eax - physical address of page
;;Result:
;; eax - 1 success
;; eax - 0 failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Page
MEM_Free_Page:
test eax,eax
jz MEM_Free_Page_Zero
test eax,0xFFF
jnz MEM_Free_Page_Not_Aligned
push ebx
push ecx
push edx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Free_Page_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
js MEM_Free_Page_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Free_Page_Heap_loopend
MEM_Free_Page_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Free_Page_Heap_loop
xor eax,eax
inc eax
jmp MEM_Free_Page_ret
MEM_Free_Page_Heap_loopend:
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov ebx,eax
add eax,ecx
shr ebx,10
mov edx,[ecx+.range_info+ebx]
test edx,0x80000000
jnz MEM_Free_Page_Bucket
test dx,dx
jz MEM_Free_Page_Error
dec word [ecx+.range_info+ebx]
jnz MEM_Free_Page_OK
MEM_Free_Page_Bucket:
push dword [ecx]
mov [ecx],eax
pop dword [eax]
mov dword [ecx+.range_info+ebx],0
MEM_Free_Page_OK:
mov eax,1
MEM_Free_Page_ret:
call MEM_Heap_UnLock
pop edx
pop ecx
pop ebx
ret
MEM_Free_Page_Error:
xor eax,eax
jmp MEM_Free_Page_ret
MEM_Free_Page_Zero:
inc eax
ret
MEM_Free_Page_Not_Aligned:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Page_Linear
;;Remove reference and free page if number of
;;references is equal to 0
;;Parameters:
;; eax - linear address of page
;;Result:
;; eax - 1 success
;; eax - 0 failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Page_Linear
MEM_Free_Page_Linear:
test eax,eax
jz MEM_Free_Page_Linear_Zero
test eax,0xFFF
jnz MEM_Free_Page_Linear_Not_Aligned
push ebx
push ecx
push edx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Free_Page_Linear_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
js MEM_Free_Page_Linear_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Free_Page_Linear_Heap_loopend
MEM_Free_Page_Linear_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Free_Page_Linear_Heap_loop
xor eax,eax
inc eax
jmp MEM_Free_Page_Linear_ret
MEM_Free_Page_Linear_Heap_loopend:
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov ebx,eax
add eax,ecx
shr ebx,10
mov edx,[ecx+.range_info+ebx]
test edx,0x80000000
jnz MEM_Free_Page_Linear_Bucket
test dx,dx
jz MEM_Free_Page_Linear_Error
dec word [ecx+.range_info+ebx]
jnz MEM_Free_Page_Linear_OK
MEM_Free_Page_Linear_Bucket:
mov edx,[ecx]
mov [eax],edx
mov dword [eax+4],0
mov [ecx],eax
test edx,edx
jz MEM_Free_Page_No_Next
mov [edx+4],eax
MEM_Free_Page_No_Next:
mov dword [ecx+.range_info+ebx],0
MEM_Free_Page_Linear_OK:
xor eax, eax
inc eax
MEM_Free_Page_Linear_ret:
call MEM_Heap_UnLock
pop edx
pop ecx
pop ebx
ret
MEM_Free_Page_Linear_Error:
xor eax,eax
jmp MEM_Free_Page_Linear_ret
MEM_Free_Page_Linear_Zero:
inc eax
ret
MEM_Free_Page_Linear_Not_Aligned:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Pages
;;Allocates set of pages.
;;Parameters:
;; eax - number of pages
;; ebx - buffer for physical addresses
;;Result:
;; eax - number of allocated pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Pages
MEM_Alloc_Pages:
push eax
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Alloc_Pages_ret
MEM_Alloc_Pages_loop:
call MEM_Alloc_Page
test eax,eax
jz MEM_Alloc_Pages_ret
mov [ebx],eax
add ebx,4
dec ecx
jnz MEM_Alloc_Pages_loop
MEM_Alloc_Pages_ret:
sub [esp+8],ecx
pop ecx
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Pages_Linear
;;Allocates set of pages.
;;Parameters:
;; eax - number of pages
;; ebx - buffer for linear addresses
;;Result:
;; eax - number of allocated pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Pages_Linear
MEM_Alloc_Pages_Linear:
push eax
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Alloc_Pages_Linear_ret
MEM_Alloc_Pages_Linear_loop:
call MEM_Alloc_Page_Linear
test eax,eax
jz MEM_Alloc_Pages_Linear_ret
mov [ebx],eax
add ebx,4
dec ecx
jnz MEM_Alloc_Pages_Linear_loop
MEM_Alloc_Pages_Linear_ret:
sub [esp+8],ecx
pop ecx
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Pages
;;Parameters:
;; eax - number of pages
;; ebx - array of addresses
;;Result:
;; eax=1 - succcess
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Pages
MEM_Free_Pages:
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Free_Pages_ret
MEM_Free_Pages_loop:
mov eax,[ebx]
call MEM_Free_Page
add ebx,4
test eax,eax
jz MEM_Free_Pages_ret
dec ecx
jnz MEM_Free_Pages_loop
MEM_Free_Pages_ret:
pop ecx
pop ebx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Pages_Linear
;;Parameters:
;; eax - number of pages
;; ebx - array of addresses
;;Result:
;; eax=1 - succcess
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Pages_Linear
MEM_Free_Pages_Linear:
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Free_Pages_Linear_ret
MEM_Free_Pages_Linear_loop:
mov eax,[ebx]
call MEM_Free_Page_Linear
add ebx,4
test eax,eax
jz MEM_Free_Pages_Linear_ret
dec ecx
jnz MEM_Free_Pages_Linear_loop
MEM_Free_Pages_Linear_ret:
pop ecx
pop ebx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Heap_Number
;;Calculate number of heap which pointer belongs to.
;;Parameter:
;; eax - address
;;Result:
;; ecx - number of heap*16.
;; eax=0 if address not found.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Heap_Number
MEM_Get_Heap_Number:
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
jl MEM_Get_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Get_Heap_loopend
MEM_Get_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Get_Heap_loop
call MEM_Heap_UnLock
xor eax,eax
ret
MEM_Get_Heap_loopend:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
call MEM_Heap_UnLock
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Heap_Number_Linear
;;Calculate number of heap which pointer belongs to.
;;Parameter:
;; eax - address
;;Result:
;; ecx - number of heap*16.
;; eax=0 if address not found.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Heap_Number_Linear
MEM_Get_Heap_Number_Linear:
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Heap_Linear_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
jl MEM_Get_Heap_Linear_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Get_Heap_Linear_loopend
MEM_Get_Heap_Linear_loopnext:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Get_Heap_Linear_loop
call MEM_Heap_UnLock
xor eax,eax
ret
MEM_Get_Heap_Linear_loopend:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
call MEM_Heap_UnLock
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc
;;Allocate small region.
;;Parameters:
;; eax - size (0<eax<=4096)
;;Result:
;; eax - linear address
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc
MEM_Alloc:
;find chain
test eax,eax
jng MEM_Alloc_Wrong_Size
cmp eax,4096
jg MEM_Alloc_Wrong_Size
push ebx
push ecx
push edx
push esi
dec eax
shr eax,4
xor edx,edx
MEM_Alloc_Find_Size:
add edx,4
shr eax,1
jnz MEM_Alloc_Find_Size
MEM_Alloc_Size_Found:
mov ecx,edx
shr ecx,2
add ecx,4
mov eax,1
shl eax,cl
mov esi,eax
;esi - block size
;edx - offset
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Find_Heap:
mov eax,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [eax+edx],0
jnz MEM_Alloc_Use_Existing
sub ecx,16
jns MEM_Alloc_Find_Heap
;create new bucket page
call MEM_Alloc_Page_Linear
call MEM_Get_Heap_Number_Linear
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov [ecx+edx],eax
lea ebx,[eax+4096]
MEM_Alloc_List_loop:
mov [eax],eax
mov [eax+4],eax
add [eax],esi
sub [eax+4],esi
add eax,esi
cmp eax,ebx
jnz MEM_Alloc_List_loop
sub ebx,esi
mov dword [ebx],0
sub eax,4096
mov dword [eax+4],0
mov eax,ecx
MEM_Alloc_Use_Existing:
mov ebx,eax
mov eax,[eax+edx]
mov ecx,[eax]
mov [ebx+edx],ecx
test ecx,ecx
jz MEM_Alloc_Became_Empty
mov dword [ecx+4],0
MEM_Alloc_Became_Empty:
mov ecx,eax
sub ecx,ebx
shr ecx,10
and ecx,0xFFFFFFFC
inc byte [ebx+.range_info+ecx+2]
shr edx,2
add edx,128
dec edx
mov [ebx+.range_info+ecx+3],dl
MEM_Alloc_ret:
call MEM_Heap_UnLock
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Alloc_Wrong_Size:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free
;;Parameters:
;; eax - linear address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free
MEM_Free:
test eax,eax
jz MEM_Free_Zero
push ebx
push ecx
push edx
push esi
push edi
push ebp
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Free_ret
mov edx,eax
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub edx,ecx
shr edx,10
and edx,0xFFFFFFFC
mov ebx,[ecx+.range_info+edx]
mov esi,ebx
shr esi,24
sub esi,128
mov edi,[ecx+4+4*esi]
mov [eax],edi
mov dword [eax+4],0
test edi,edi
jz MEM_Free_Empty_List
mov [edi+4],eax
MEM_Free_Empty_List:
mov [ecx+4+4*esi],eax
sub ebx,0x10000
mov [ecx+.range_info+edx],ebx
test ebx,0xFF0000
jnz MEM_Free_ret
;delete empty blocks on the page
lea edx,[esi+5]
and eax,0xFFFFF000
mov edi,eax
mov eax,1
xchg ecx,edx
shl eax,cl
mov ecx,edx
mov edx,eax
;edx - size of block
;edi - start of page
mov eax,edi
lea ebx,[eax+4096]
MEM_Free_Block_loop:
cmp dword [eax+4],0
jnz MEM_Free_Block_Not_First
mov ebp,dword [eax]
mov [ecx+4+4*esi],ebp
test ebp,ebp
jz MEM_Free_Block_Last
mov dword [ebp+4],0
MEM_Free_Block_Last:
jmp MEM_Free_Block_loop_end
MEM_Free_Block_Not_First:
mov ebp,dword [eax]
push ebp
mov ebp,dword [eax+4]
pop dword [ebp]
mov ebp,dword [eax]
test ebp,ebp
jz MEM_Free_Block_loop_end
push dword [eax+4]
pop dword [ebp+4]
; jmp MEM_Free_Block_loop_end
MEM_Free_Block_loop_end:
add eax,edx
cmp eax,ebx
jnz MEM_Free_Block_loop
mov eax,edi
call MEM_Free_Page_Linear
MEM_Free_ret:
call MEM_Heap_UnLock
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Free_Zero:
inc eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference
;; eax - physical address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference
MEM_Add_Reference:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number
test eax,eax
jz MEM_Add_Reference_ret
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_failed
inc dword [ecx+eax+.range_info]
MEM_Add_Reference_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_failed:
xor eax,eax
jmp MEM_Add_Reference_ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference_Linear
;; eax - linear address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference_Linear
MEM_Add_Reference_Linear:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Add_Reference_Linear_ret
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub eax,ecx
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_Linear_failed
inc dword [ecx+eax+.range_info]
mov eax,1
MEM_Add_Reference_Linear_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_Linear_failed:
xor eax,eax
jmp MEM_Add_Reference_Linear_ret
end if
end if ;memmanager.inc
/kernel/trunk/core/newproce.inc
0,0 → 1,1321
if ~defined newprocess_inc
newprocess_inc_fix:
newprocess_inc fix newprocess_inc_fix
include "mem.inc"
include "memmanag.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Working with new types of processes.
;;Author: Khalyavin Andrey halyavin@land.ru
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
new_process_loading db 'K : New Process - loading',13,10,0
new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
endg
;-----------------------------------------------------------------------------
find_new_process_place:
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [0x3004]!
mov eax,0x3000+second_base_address
push ebx
mov ebx,[0x3004]
inc ebx
shl ebx,5
add ebx,eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax,ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax,0x20
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx,eax
sub eax,0x3000+second_base_address
shr eax,5 ;calculate slot index
cmp eax,256
jge .failed ;it should be <256
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary)
mov [new_process_place],eax ;save process slot
pop ebx
ret
.failed:
xor eax,eax
pop ebx
ret
;-----------------------------------------------------------------------------
 
new_start_application_floppy:
;input:
; eax - pointer to filename
; ebx - parameters to pass
;result:
; eax - pid of new process
; or 0 if call fails.
pushad
mov esi,new_process_loading
call sys_msg_board_str ;write to debug board
;wait application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
jz .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
;we can change system tables now
push edi
push ebx
push eax
call find_new_process_place ;find empty process slot
sti
test eax,eax
jz .failed
 
mov edi,eax
shl edi,8
add edi,0x80000
mov ecx,256/4
xor eax,eax
cld
rep stosd ;clean extended information about process
;set new process name
mov eax,[esp+8]
.find_last_byte:
cmp byte [eax],0
jz .find_last_byte_end
inc eax
jmp .find_last_byte
.find_last_byte_end:
sub eax,11 ;last 11 bytes = application name
; mov eax,[esp] ;eax - pointer to file name
mov ebx,[new_process_place]
shl ebx,8
add ebx,0x80000
mov ecx,11
call memmove
;read header of file
mov eax,[esp]
mov ebx,1 ;index of first block
mov ecx,2 ;number of blocks
mov edx,0x90000 ;temp area
mov esi,12 ;file name length
mov edi,[esp+8]
; cli
call floppy_fileread ;read file from FD
; sti
cmp eax,0
jne .cleanfailed
;check MENUET signature
cmp [0x90000],dword 'MENU'
jnz .cleanfailed
cmp [0x90004],word 'ET'
jnz .cleanfailed
call get_app_params ;parse header fields
cmp esi,0
jz .cleanfailed
mov eax,[new_process_place]
call create_app_cr3_table ;create page directory for new process
test eax,eax
jz .cleanfailed_mem
call MEM_Get_Linear_Address ;calculate linear address of it
mov ebx,std_application_base_address
mov ecx,[app_mem]
add ecx,4095
shr ecx,12
mov edx,eax
call mem_alloc_specified_region ;allocate memory for application
test eax,eax
jz .cleanfailed_mem
mov eax,[edx+(std_application_base_address shr 20)]
and eax,not (4096-1) ;eax - physical address of first (for application memory) page table
call MEM_Get_Linear_Address
mov edx,eax
;read file
mov ebx,1
mov esi,12 ;length of file name
.loop1:
;edx = linear address of current page table entry
;ebx = index of current block in file
push edx
mov eax,[edx]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov edx,eax ;read file block to current page
mov eax,[esp+4] ;restore pointer to file name
mov ecx,8 ;number of blocks read
push ebx
mov edi,[esp+16]
; cli
call floppy_fileread
;ebx=file size
; sti
pop ecx
shr ebx,9
cmp ecx,ebx
jg .endloop1 ;if end of file?
mov ebx,ecx
test eax,eax
jnz .endloop1 ;check io errors
pop edx
add ebx,8 ;go to next page
add edx,4
jmp .loop1
.endloop1:
add esp,8+4 ;pop linear address of page table entry and pointer to file name
call new_start_application_fl.add_app_parameters
mov [esp+28],eax
popad
ret
.cleanfailed_mem:
mov esi,start_not_enough_memory
call sys_msg_board_str
.cleanfailed: ;clean process name
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov ecx,11
mov eax,' '
cld
rep stosb
.failed:
add esp,8+4
mov [application_table_status],0
popad
sti
mov eax,-1
ret
 
;-----------------------------------------------------------------------------
new_start_application_fl:
;input:
; eax - pointer to filename
; ebx - parameters to pass
;result:
; eax - pid of new process
; or 0 if call fails.
pushad
mov esi,new_process_loading
call sys_msg_board_str ;write to debug board
;wait application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
jz .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
;we can change system tables now
push ebx
push eax
call find_new_process_place ;find empty process slot
sti
test eax,eax
jz .failed
 
mov edi,eax
shl edi,8
add edi,0x80000
mov ecx,256/4
xor eax,eax
cld
rep stosd ;clean extended information about process
;set new process name
mov eax,[esp] ;eax - pointer to file name
mov ebx,[new_process_place]
shl ebx,8
add ebx,0x80000
mov ecx,11
call memmove
;read header of file
mov ebx,1 ;index of first block
mov ecx,2 ;number of blocks
mov edx,0x90000 ;temp area
mov esi,12 ;file name length
cli
call fileread ;read file from RD
sti
cmp eax,0
jne .cleanfailed
;check MENUET signature
cmp [0x90000],dword 'MENU'
jnz .cleanfailed
cmp [0x90004],word 'ET'
jnz .cleanfailed
call get_app_params ;parse header fields
cmp esi,0
jz .failed
mov eax,[new_process_place]
call create_app_cr3_table ;create page directory for new process
test eax,eax
jz .cleanfailed_mem
call MEM_Get_Linear_Address ;calculate linear address of it
mov ebx,std_application_base_address
mov ecx,[app_mem]
add ecx,4095
shr ecx,12
mov edx,eax
call mem_alloc_specified_region ;allocate memory for application
test eax,eax
jz .cleanfailed_mem
mov eax,[edx+(std_application_base_address shr 20)]
and eax,not (4096-1) ;eax - physical address of first (for application memory) page table
call MEM_Get_Linear_Address
mov edx,eax
;read file
mov ebx,1
mov esi,12 ;length of file name
.loop1:
;edx = linear address of current page table entry
;ebx = index of current block in file
push edx
mov eax,[edx]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov edx,eax ;read file block to current page
mov eax,[esp+4] ;restore pointer to file name
mov ecx,8 ;number of blocks read
push ebx
cli
call fileread
;ebx=file size
sti
pop ecx
shr ebx,9
cmp ecx,ebx
jg .endloop1 ;if end of file?
mov ebx,ecx
test eax,eax
jnz .endloop1 ;check io errors
pop edx
add ebx,8 ;go to next page
add edx,4
jmp .loop1
.endloop1:
add esp,8 ;pop linear address of page table entry and pointer to file name
call .add_app_parameters
mov [esp+28],eax
popad
ret
.cleanfailed_mem:
mov esi,start_not_enough_memory
call sys_msg_board_str
.cleanfailed: ;clean process name
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov ecx,11
mov eax,' '
cld
rep stosb
.failed:
add esp,8
mov [application_table_status],0
popad
sti
mov eax,-1
ret
.add_app_parameters:
;input:
; [esp] - pointer to parameters
; [esp+4]-[esp+36] pushad registers.
;result
; eax - pid of new process
; or zero if failed
cli
mov ebx,[new_process_place]
cmp ebx,[0x3004]
jle .noinc
inc dword [0x3004] ;update number of processes
.noinc:
 
; mov ebx,[new_process_place]
;set 0x8c field of extended information about process
;(size of application memory)
shl ebx,8
mov eax,[app_mem]
mov [second_base_address+0x80000+0x8c+ebx],eax
;set 0x10 field of information about process
;(application base address)
; mov ebx,[new_process_place]
; shl ebx,5
shr ebx,3
mov dword [second_base_address+0x3000+ebx+0x10],std_application_base_address
 
;add command line parameters
.add_command_line:
mov edx,[app_i_param]
test edx,edx
jz .no_command_line ;application don't need parameters
mov eax,[esp+4]
test eax,eax
jz .no_command_line ;no parameters specified
;calculate parameter length
mov esi,eax
xor ecx,ecx
.command_line_len:
cmp byte [esi],0
jz .command_line_len_end
inc esi
inc ecx
cmp ecx,256
jl .command_line_len
.command_line_len_end:
;ecx - parameter length
;edx - address of parameters in new process address space
mov ebx,eax ;ebx - address of parameters in our address space
mov eax,[new_process_place]
call write_process_memory ;copy parameters to new process address space
.no_command_line:
mov ebx,[new_process_place]
mov eax,ebx
shl ebx,5
add ebx,0x3000 ;ebx - pointer to information about process
mov [ebx+0xe],al ;set window number on screen = process slot
mov [ebx],dword 1+2+4 ;set default event flags (see 40 function)
inc dword [process_number]
mov eax,[process_number]
mov [ebx+4],eax ;set PID
mov ecx,ebx
add ecx,draw_data-0x3000 ;ecx - pointer to draw data
;set draw data to full screen
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[0xfe00]
mov [ecx+8],eax
mov eax,[0xfe04]
mov [ecx+12],eax
;set cr3 register in TSS of application
mov ecx,[new_process_place]
shl ecx,8
mov eax,[0x800B8+ecx]
add eax,8+16 ;add flags
mov [l.cr3],eax
;write cr3 in TSS of System Call Handler
mov ecx,[new_process_place]
shl ecx,7
mov [0x298000+ecx+l.cr3-tss_sceleton],eax ;write directy to TSS
mov eax,[app_start]
mov [l.eip],eax ;set eip in TSS
mov eax,[app_esp]
mov [l.esp],eax ;set stack in TSS
;gdt
mov ebx,[new_process_place]
shl ebx,3
mov ax,app_code ;ax - selector of code segment
add ax,bx
mov [l.cs],ax
mov ax,app_data
add ax,bx ;ax - selector of data segment
mov [l.ss],ax
mov [l.ds],ax
mov [l.es],ax
mov [l.fs],ax
mov ax,graph_data ;ax - selector of graphic segment
mov [l.gs],ax
mov [l.io],word 128
mov [l.eflags],dword 0x11202
mov [l.ss0],os_data
mov [l.esp0],0x55000
; mov [l.esp1],0x56000
; mov [l.esp2],0x57000
 
;copy tss to it place
mov eax,tss_sceleton
mov ebx,[new_process_place]
imul ebx,tss_step
add ebx,tss_data ;ebx - address of application TSS
mov ecx,120
call memmove
;Add IO access table - bit array of permitted ports
or eax,-1
mov edi,[new_process_place]
imul edi,tss_step
add edi,tss_data+128
mov ecx,2048
cld
rep stosd ;full access to 2048*8=16384 ports
mov ecx,ebx ;ecx - address of application TSS
mov edi,[new_process_place]
shl edi,3
;set TSS descriptor
mov [edi+gdts+tss0+0],word tss_step ;limit (size)
mov [edi+gdts+tss0+2],cx ;part of offset
mov eax,ecx
shr eax,16
mov [edi+gdts+tss0+4],al ;part of offset
mov [edi+gdts+tss0+7],ah ;part of offset
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
;set code and data segments
mov eax,[new_process_place]
shl eax,3
;set base address of code segment
mov word [eax+gdts+app_code-3+2],0
mov byte [eax+gdts+app_code-3+4],0
mov byte [eax+gdts+app_code-3+7],std_application_base_address shr 24
;set limit of code segment
; mov ebx,[app_mem]
; add ebx,4095
; shr ebx,12
mov ebx,(0x80000000-std_application_base_address) shr 12
mov [eax+gdts+app_code-3+0],bx
mov [eax+gdts+app_code-3+5],word 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28)
;set base address of data segment
mov word [eax+gdts+app_data-3+2],0
mov byte [eax+gdts+app_data-3+4],0
mov byte [eax+gdts+app_data-3+7],std_application_base_address shr 24
;set limit of data segment
mov [eax+gdts+app_data-3+0],bx
mov [eax+gdts+app_data-3+5],word 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28)
 
;flush keyboard and buttons queue
mov [0xf400],byte 0
mov [0xf500],byte 0
 
mov edi,[new_process_place]
shl edi,5
add edi,window_data
mov ebx,[new_process_place]
movzx esi,word [0xC000+ebx*2]
lea esi,[0xC400+esi*2]
call windowactivate ;gui initialization
 
mov ebx,[new_process_place]
shl ebx,5
mov [0x3000+ebx+0xa],byte 0 ;set process state - running
mov esi,new_process_running
call sys_msg_board_str ;output information about succefull startup
; add esp,4 ;pop pointer to parameters
; popad
mov eax,[process_number] ;set result
mov [application_table_status],0 ;unlock application_table_status mutex
sti
ret 4
;-----------------------------------------------------------------------------
new_sys_threads:
;eax=1 - create thread
; ebx=thread start
; ecx=thread stack value
;result:
; eax=pid
pushad
cmp eax,1
jnz .ret ;other subfunctions
mov esi,new_process_loading
call sys_msg_board_str
;lock application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
je .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
;find free process slot
 
call find_new_process_place
test eax,eax
jz .failed
;set parameters for thread
xor eax,eax
mov [app_i_param],eax
mov [app_i_icon],eax
mov [app_start],ebx
mov [app_esp],ecx
 
mov esi,[0x3000]
shl esi,8
add esi,0x80000
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
rep stosd ;clean extended information about new thread
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov eax,[ebx+0x8c]
mov [app_mem],eax ;set memory size
mov eax,[ebx+0xb8]
mov [edx+0xb8],eax ;copy page directory
; mov eax,[new_process_place]
; mov ebx,[0x3000]
; call addreference_app_cr3_table
 
push 0 ;no parameters
call new_start_application_fl.add_app_parameters ;start thread
mov [esp+28],eax
popad
ret
.failed:
sti
popad
mov eax,-1
ret
.ret:
popad
ret
;-----------------------------------------------------------------------------
new_mem_resize:
;input:
; ebx - new size
;result:
; [esp+36]:=0 - normal
; [esp+36]:=1 - error
;This function set new application memory size.
mov esi,ebx ;save new size
add ebx,4095
and ebx,not (4096-1) ;round up size
mov ecx,[0x3000]
shl ecx,8
mov edx,[0x8008C+ecx]
add edx,4095
and edx,not (4096-1) ;old size
mov eax,[0x800B8+ecx]
call MEM_Get_Linear_Address
;eax - linear address of page directory
call MEM_Heap_Lock ;guarantee that two threads willn't
;change memory size simultaneously
cmp ebx,edx
; mov esi,ebx ;save new size
jg .expand
.free:
sub edx,ebx
jz .unlock ;do nothing
mov ecx,edx
shr ecx,12
add ebx,std_application_base_address
call mem_free_specified_region ;free unnecessary pages
jmp .unlock
 
.expand:
sub ebx,edx
mov ecx,ebx
shr ecx,12
mov ebx,edx
add ebx,std_application_base_address
call mem_alloc_specified_region ;alloc necessary pages
test eax,eax
jz .failed ;not enough memory
.unlock:
mov ebx,esi
mov eax,[0x3000]
shl eax,8
mov [eax+0x8008c],ebx ;write new memory size
;search threads and update
;application memory size infomation
mov ecx,[eax+0x800b8]
mov eax,2
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax,[0x3004]
jg .search_threads_end
mov edx,eax
shl edx,5
cmp word [0x3000+edx+0xa],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [edx+0x800b8],ecx ;if it is our thread?
jnz .search_threads_next
mov [edx+0x8008c],ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
 
call MEM_Heap_UnLock
mov dword [esp+36],0
ret
.failed:
call MEM_Heap_UnLock
mov dword [esp+36],1
ret
;-----------------------------------------------------------------------------
pid_to_slot:
;Input:
; eax - pid of process
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx,[0x3004]
shl ebx,5
mov ecx,2*32
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [second_base_address+0x3000+ecx+0xa],9
jz .endloop ;skip empty slots
cmp [second_base_address+0x3000+ecx+0x4],eax ;check PID
jz .pid_found
.endloop:
add ecx,32
cmp ecx,ebx
jle .loop
pop ecx
pop ebx
xor eax,eax
ret
.pid_found:
shr ecx,5
mov eax,ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
;-----------------------------------------------------------------------------
is_new_process:
;Input:
; eax - process slot
;Output:
; eax=1 - it is new process
; eax=0 - it is old process
; shl eax,5
; mov eax,[second_base_address+0x3000+eax+0x10]
; cmp eax,std_application_base_address ;check base address of application
; jz .new_process
; xor eax,eax
; ret
;.new_process:
mov eax,1
ret
;-----------------------------------------------------------------------------
write_process_memory:
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes written
pushad
shl eax,8
mov eax,[0x80000+eax+0xB8]
call MEM_Get_Linear_Address
mov ebp,eax
;ebp=linear address of page directory of other process.
add edx,std_application_base_address ;convert to linear address
test ecx,ecx
jle .ret
.write_loop:
;ebx = current buffer address
;ecx>0 = current size
;edx = current address in other process
;ebp = linear address of page directory
 
call MEM_Heap_Lock ;cli
mov esi,edx
shr esi,22
mov eax,[ebp+4*esi] ;find page directory entry
and eax,not (4096-1) ;clear flags
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page table
test eax,eax
jz .page_not_found
mov esi,edx
shr esi,12
and esi,1023
mov eax,[eax+4*esi] ;find page table entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page
test eax,eax
jz .page_not_found
mov edi,eax
call MEM_Add_Reference_Linear;guarantee that page willn't disappear
call MEM_Heap_UnLock ;sti
mov esi,edx
and esi,4095
add edi,esi ;add offset in page
;edi = linear address corresponding edx in other process
sub esi,4096
neg esi ;esi - number of remaining bytes in page
cmp esi,ecx
jl .min_ecx
mov esi,ecx
.min_ecx: ;esi=min(ecx,esi) - number of bytes to write
sub ecx,esi
push ecx
mov ecx,esi ;ecx - number of bytes to write
mov esi,ebx ;esi - source, edi - destination
add edx,ecx ;move pointer in address space of other process
push edi
;move ecx bytes
test ecx,3
jnz .not_aligned
shr ecx,2
rep movsd
jmp .next_iter
.not_aligned:
rep movsb
.next_iter:
 
pop eax
and eax,not (4096-1) ;eax - linear address of current page
call MEM_Free_Page_Linear ;free reference
mov ebx,esi ;new pointer to buffer - movsb automaticaly advance it.
pop ecx ;restore number of remaining bytes
test ecx,ecx
jnz .write_loop
.ret:
popad
mov eax,ecx
ret
.page_not_found:
call MEM_Heap_UnLock ;error has appeared in critical region
sub ecx,[esp+24] ;[esp+24]<-->ecx
neg ecx ;ecx=number_of_written_bytes
mov [esp+28],ecx ;[esp+28]<-->eax
popad
ret
;-----------------------------------------------------------------------------
syscall_test:
;for testing memory manager from applications.
mov edx,ecx
mov ecx,ebx
call trans_address
mov ebx,eax
mov eax,[0x3000]
call read_process_memory
ret
;-----------------------------------------------------------------------------
read_process_memory:
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes read.
pushad
shl eax,8
mov eax,[0x80000+eax+0xB8]
call MEM_Get_Linear_Address
mov ebp,eax
add edx,std_application_base_address
.read_loop:
;ebx = current buffer address
;ecx>0 = current size
;edx = current address in other process
;ebp = linear address of page directory
 
call MEM_Heap_Lock ;cli
mov esi,edx
shr esi,22
mov eax,[ebp+4*esi] ;find page directory entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address
test eax,eax
jz .page_not_found
mov esi,edx
shr esi,12
and esi,1023
mov eax,[eax+4*esi] ;find page table entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page
test eax,eax
jz .page_not_found
mov esi,eax
call MEM_Add_Reference_Linear;guarantee that page willn't disappear
call MEM_Heap_UnLock ;sti
mov edi,edx
and edi,4095
add esi,edi ;add offset in page
;esi = linear address corresponding edx in other process
sub edi,4096
neg edi
;edi=min(edi,ecx) - number of bytes to copy
cmp edi,ecx
jl .min_ecx
mov edi,ecx
.min_ecx:
 
sub ecx,edi ;update size of remaining bytes
add edx,edi ;update current pointer in other address space.
push ecx
mov ecx,edi ;ecx - number of bytes to read
mov edi,ebx ;esi - source, edi - destination
push esi
;move ecx bytes
test ecx,3
jnz .not_aligned
shr ecx,2
rep movsd
jmp .next_iter
.not_aligned:
rep movsb
.next_iter:
pop eax
and eax,not (4096-1) ;eax - linear address of current page
call MEM_Free_Page_Linear ;free reference
mov ebx,edi ;new pointer to buffer - movsb automaticaly advance it.
pop ecx ;restore number of remaining bytes
test ecx,ecx
jnz .read_loop
popad
mov eax,ecx
ret
.page_not_found:
call MEM_Heap_UnLock ;error has appeared in critical region
sub ecx,[esp+24] ;[esp+24]<-->ecx
neg ecx ;ecx=number_of_read_bytes
mov [esp+28],ecx ;[esp+28]<-->eax
popad
ret
;-----------------------------------------------------------------------------
check_region:
;input:
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax,[0x3000]
jmp check_process_region
;-----------------------------------------------------------------------------
check_process_region:
;input:
; eax - slot
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
test ecx,ecx
jle .ok
shl eax,5
cmp word [0x3000+eax+0xa],0
jnz .failed
shl eax,3
mov eax,[0x80000+eax+0xb8]
test eax,eax
jz .failed
call MEM_Get_Linear_Address
push ebx
push ecx
push edx
mov edx,ebx
and edx,not (4096-1)
sub ebx,edx
add ecx,ebx
mov ebx,edx
add ecx,(4096-1)
and ecx,not (4096-1)
.loop:
;eax - linear address of page directory
;ebx - current page
;ecx - current size
mov edx,ebx
shr edx,22
mov edx,[eax+4*edx]
and edx,not (4096-1)
test edx,edx
jz .failed1
push eax
mov eax,edx
call MEM_Get_Linear_Address
mov edx,ebx
shr edx,12
and edx,(1024-1)
mov eax,[eax+4*edx]
and eax,not (4096-1)
test eax,eax
pop eax
jz .failed1
add ebx,4096
sub ecx,4096
jg .loop
pop edx
pop ecx
pop ebx
.ok:
mov eax,1
ret
.failed1:
pop edx
pop ecx
pop ebx
.failed:
xor eax,eax
ret
;-----------------------------------------------------------------------------
new_sys_ipc:
;input:
; eax=1 - set ipc buffer area
; ebx=address of buffer
; ecx=size of buffer
; eax=2 - send message
; ebx=PID
; ecx=address of message
; edx=size of message
cmp eax,1
jnz .no_ipc_def
;set ipc buffer area
mov edi,[0x3000]
shl edi,8
add edi,0x80000
cli
mov [edi+0xA0],ebx ;set fields in extended information area
mov [edi+0xA4],ecx
sti
mov [esp+36],dword 0 ;success
ret
.no_ipc_def:
cmp eax,2
jnz .no_ipc_send
;send message
cli
;obtain slot from PID
mov eax,ebx
call pid_to_slot
test eax,eax
jz .no_pid
mov ebp,eax
;ebp = slot of other process
shl eax,8
mov edi,[eax+0x80000+0xa0] ;is ipc area defined?
test edi,edi
jz .no_ipc_area
mov esi,[eax+0x80000+0xa4] ;esi - size of buffer
push dword -1 ;temp variable for read_process_memory
mov ebx,esp
push ecx
push edx
mov ecx,4 ;read 4 bytes
mov eax,ebp
mov edx,edi ;from beginning of buffer.
call read_process_memory
mov eax,[esp+8]
test eax,eax
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
add edx,4 ;move to next 4 bytes
mov eax,ebp
call read_process_memory ;read size of occupied space in buffer
sub esi,8
sub esi,[esp]
sub esi,[esp+8] ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
js .buffer_overflow ;esi<0 - not enough memory in buffer
mov esi,[esp+8] ;previous offset
add dword [esp+8],8
mov edi,[esp]
add [esp+8],edi ;add (size of message)+(size of header of message) to [buffer+4]
mov eax,ebp
call write_process_memory
add edx,esi
sub edx,4 ;move to beginning of place for our message
mov eax,[second_base_address+0x3010]
mov eax,[eax+0x4] ;eax - our PID
mov [esp+8],eax
mov eax,ebp
call write_process_memory ;write PID
mov ebx,esp ;address of size of message
mov eax,ebp
add edx,4
call write_process_memory ;write size of message
add edx,4
pop ecx ;ecx - size of message
pop eax
call trans_address
mov ebx,eax ;ebx - linear address of message
add esp,4 ;pop temporary variable
mov eax,ebp
call write_process_memory ;write message
sti
;awake other process
shl ebp,8
mov eax,ebp
or [eax+0x800A8],dword 0x40
cmp dword [check_idle_semaphore],20
jge .ipc_no_cis
mov dword [check_idle_semaphore],5
.ipc_no_cis:
mov dword [esp+36],0
ret
.no_ipc_send:
mov dword [esp+36],-1
ret
.no_pid:
sti
mov dword [esp+36],4
ret
.no_ipc_area:
sti
mov dword [esp+36],1
ret
.ipc_blocked:
sti
add esp,12
mov dword [esp+36],2
ret
.buffer_overflow:
sti
add esp,12
mov dword [esp+36],3
ret
;-----------------------------------------------------------------------------
trans_address:
;Input
; eax - application address
;Output
; eax - linear address for kernel
add eax,std_application_base_address
ret
;-----------------------------------------------------------------------------
new_start_application_hd:
;eax - file name (kernel address)
;ebx - file name length
;ecx - work area (kernel address)
;ebp - parameters
pushad
mov esi,new_process_loading
call sys_msg_board_str ;write message to message board
;lock application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
jz .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
push ebp
push ebx
push eax
push ecx
call find_new_process_place ;find new process slot
sti
test eax,eax
jz .failed
;write application name
mov eax,[esp+4]
.find_last_byte:
cmp byte [eax],0
jz .find_last_byte_end
inc eax
jmp .find_last_byte
.find_last_byte_end:
lea esi,[eax-11] ;last 11 bytes = application name
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov ecx,11
cld
rep movsb ;copy name to extended information about process
;read header
mov eax,[esp+4] ;file name
mov esi,[esp] ;work area
mov ecx,1 ;read from first block
mov edx,1 ;read 1 block
call read_hd_file
test eax,eax
jnz .cleanfailed
 
mov esi,[esp]
;check menuet signature
cmp [esi+1024+0],dword 'MENU' ;read_hd_file function write file to +1024 offset
jnz .cleanfailed
cmp [esi+1024+4],word 'ET'
jnz .cleanfailed
add esi,1024
mov edi,0x90000
mov ecx,512/4
cld
rep movsd ;copy first block to 0x90000 address for get_app_params function
call get_app_params
test esi,esi
jz .cleanfailed
mov eax,[new_process_place]
call create_app_cr3_table ;create page directory
test eax,eax
jz .cleanfailed_mem
call MEM_Get_Linear_Address
mov ebx,std_application_base_address
mov ecx,[app_mem]
add ecx,4096-1
shr ecx,12
mov edx,eax ;edx - linear address of page directory
call mem_alloc_specified_region ;allocate memory for application
test eax,eax
jz .cleanfailed_mem
add edx,(std_application_base_address shr 20)
mov eax,[edx]
and eax,not (4096-1)
call MEM_Get_Linear_Address
push edx ;save pointer to first page table
mov edx,eax
;read file
mov ecx,1
xor ebp,ebp
.loop1:
;[esp] - pointer to current page directory entry
;edx - pointer to current page table
;ebp - offset in page
;ecx - current cluster
push edx
mov eax,[esp+12] ;file name
mov ebx,[esp+16] ;file name length
mov esi,[esp+8] ;work area
mov edx,1 ;number of blocks to read
push ecx
push ebp
cli
call read_hd_file
sti
pop ebp
test eax,eax
jnz .endloop1 ;check io errors
mov esi,[esp+8+4] ;work area
add esi,1024
mov eax,[esp+4] ;current page table
mov eax,[eax]
and eax,not (4096-1)
call MEM_Get_Linear_Address;calculate linear page address
lea edi,[eax+ebp] ;add page offset
mov ecx,512/4
cld
rep movsd ;copy data
pop ecx
inc ecx ;next block
mov eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096
add eax,512-1
shr eax,9 ;calculate application image size
cmp ecx,eax
jg .endloop11
pop edx
add ebp,512 ;new offset
test ebp,4096
jz .loop1
xor ebp,ebp
add edx,4 ;go to next page
test edx,(4096-1)
jnz .loop1
add dword [esp],4 ;go to next directory entry
mov eax,[esp]
mov eax,[eax]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov edx,eax
jmp .loop1
.endloop1:
add esp,4 ;pop ecx
.endloop11:
add esp,4+4 ;pop edx, pop edx
;add_app_parameters
add esp,12 ;now pointer to parameters is on the top of the stack
call new_start_application_fl.add_app_parameters ;start process
mov [esp+28],eax
popad
ret
.cleanfailed_mem:
mov esi,start_not_enough_memory
call sys_msg_board_str
.cleanfailed: ;clean process name
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov ecx,11
mov eax,' '
cld
rep stosb
.failed:
add esp,16
popad
mov eax,-1
mov [application_table_status],0
sti
ret
end if
/kernel/trunk/core/physmem.inc
0,0 → 1,218
virtual at 0
physical_mem_block:
.start rd 1
.size rd 1
.flags rd 1 ;0-free, pid-used.
.sizeof:
end virtual
max_physical_mem_blocks = 24
uglobal
num_physical_mem_blocks rd 1
physical_mem_blocks rd 3*max_physical_mem_blocks
endg
Init_Physical_Memory_Manager:
pushad
mov edi,physical_mem_blocks
mov ecx,3*max_physical_mem_blocks
xor eax,eax
cld
rep stosd
mov dword [num_physical_mem_blocks],2
mov [physical_mem_blocks+physical_mem_block.start],0x60000
mov [physical_mem_blocks+physical_mem_block.size],0x20000 ;128Kb
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.start],0x780000
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.size],0x80000 ;512Kb
popad
ret
Insert_Block:
;input:
; eax - handle
;output:
; none
push eax ecx esi edi
sub eax,[num_physical_mem_blocks]
neg eax
mov edi,physical_mem_block.sizeof
imul eax,edi
shr eax,2
mov ecx,eax
mov esi,[num_physical_mem_blocks]
imul esi,edi
add esi,physical_mem_blocks
lea edi,[esi+physical_mem_block.sizeof]
std
rep movsd
pop edi esi ecx eax
ret
Delete_Block:
;input:
; eax - handle
;output:
; none
pushad
mov edi,eax
sub eax,[num_physical_mem_blocks]
neg eax
dec eax
mov esi,physical_mem_block.sizeof
imul eax,esi
imul edi,esi
add edi,physical_mem_blocks
lea esi,[edi+physical_mem_block.sizeof]
mov ecx,eax
shr ecx,2
cld
rep movsd
popad
ret
Allocate_Physical_Block:
;input:
; eax - size
;output:
; eax - address or 0 if not enough memory.
pushad
cmp [num_physical_mem_blocks],max_physical_mem_blocks
jge .error
mov ebx,eax
xor eax,eax
mov esi,physical_mem_blocks
.loop:
cmp dword [esi+physical_mem_block.flags],0
jnz .next
cmp [esi+physical_mem_block.size],ebx
jg .addblock
jz .noaddblock
.next:
inc eax
add esi,physical_mem_block.sizeof
cmp eax,[num_physical_mem_blocks]
jl .loop
.error:
popad
xor eax,eax
ret
.noaddblock:
mov eax,[esi+physical_mem_block.start]
mov [esp+28],eax
mov eax,[0x3010]
mov eax,[eax+0x4]
mov [esi+physical_mem_block.flags],eax
popad
ret
.addblock:
call Insert_Block
inc dword [num_physical_mem_blocks]
mov eax,[esi+physical_mem_block.start]
mov [esp+28],eax
mov ecx,[0x3010]
mov ecx,[ecx+0x4]
mov [esi+physical_mem_block.flags],ecx
mov ecx,[esi+physical_mem_block.size]
mov [esi+physical_mem_block.size],ebx
sub ecx,ebx
mov [esi+physical_mem_block.sizeof+physical_mem_block.size],ecx
add ebx,[esi+physical_mem_block.start]
mov [esi+physical_mem_block.sizeof+physical_mem_block.start],ebx
mov dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0
popad
ret
Free_Physical_Block:
;input:
; eax - address
;output:
; none
pushad
test eax,eax
jz .ret
mov ebx,eax
xor eax,eax
mov esi,physical_mem_blocks
.loop:
cmp ebx,[esi+physical_mem_block.start]
jz .endloop
inc eax
add esi,physical_mem_block.sizeof
cmp eax,[num_physical_mem_blocks]
jl .loop
jmp .ret
.endloop:
mov dword [esi+physical_mem_block.flags],0
test eax,eax
jz .no_union_previous
cmp dword [esi-physical_mem_block.sizeof+physical_mem_block.flags],0
jnz .no_union_previous
mov ebx,[esi-physical_mem_block.sizeof+physical_mem_block.start]
add ebx,[esi-physical_mem_block.sizeof+physical_mem_block.size]
cmp ebx,[esi+physical_mem_block.start]
jnz .no_union_previous
mov ebx,[esi+physical_mem_block.size]
add [esi-physical_mem_block.sizeof+physical_mem_block.size],ebx
call Delete_Block
dec eax
dec [num_physical_mem_blocks]
.no_union_previous:
inc eax
cmp eax,[num_physical_mem_blocks]
jge .no_union_next
cmp dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0
jnz .no_union_next
mov ebx,[esi+physical_mem_block.start]
add ebx,[esi+physical_mem_block.size]
cmp ebx,[esi+physical_mem_block.sizeof+physical_mem_block.start]
jnz .no_union_next
mov ebx,[esi+physical_mem_block.sizeof+physical_mem_block.size]
add [esi+physical_mem_block.size],ebx
call Delete_Block
dec [num_physical_mem_blocks]
.no_union_next:
.ret:
popad
ret
sys_allocate_physical_block:
;eax - subfunction number
mov eax,ebx
call Allocate_Physical_Block
mov [esp+36],eax
ret
sys_free_physical_block:
;eax - subfunction number
mov eax,ebx
call Free_Physical_Block
ret
sys_set_buffer:
add ecx,std_application_base_address
isys_set_buffer: ;for using in kernel
;eax - subfunction number
;ebx - physical address
;ecx - buffer start
;edx - buffer size
lea edi,[ebx+second_base_address]
mov esi,ecx
mov ecx,edx
rep movsb
ret
sys_get_buffer:
add ecx,std_application_base_address
isys_get_buffer: ;for using in kernel
;eax - subfunction number
;ebx - physical address
;ecx - buffer start
;edx - buffer size
mov edi,ecx
lea esi,[ebx+second_base_address]
mov ecx,edx
rep movsb
ret
sys_internal_services:
cmp eax,4
jle sys_sheduler
cmp eax,5
jz sys_allocate_physical_block
cmp eax,6
jz sys_free_physical_block
cmp eax,7
jz sys_set_buffer
cmp eax,8
jz sys_get_buffer
ret
/kernel/trunk/core/sched.inc
0,0 → 1,286
label next_usage_update dword at 0xB008
label timer_ticks dword at 0xFDF0
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
irq0:
 
cmp [error_interrupt],-1
je no_error_in_previous_process
 
mov edi,[error_interrupt]
shl edi, 3
mov [edi+tss0i_l +5], word 01010000b *256 +11101001b
 
mov edi,[error_interrupt]
shl edi,7
add edi,0x290000
mov esi,[error_interrupt_entry]
mov [edi+l.eip-tss_sceleton],esi
mov [edi+l.eflags-tss_sceleton],dword 0x11002
 
mov [0xffff],byte 0
 
mov [error_interrupt],-1
 
no_error_in_previous_process:
 
mov edi,[0x3000]
shl edi, 3
; fields of TSS descriptor:
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
inc dword [timer_ticks]
 
mov eax, [timer_ticks]
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
call playNote ; <<<--- INSERT THIS LINE !!!!!!!!!!
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
cmp eax,[next_usage_update]
jb .nocounter
add eax,100
mov [next_usage_update],eax
call updatecputimes
.nocounter:
 
mov edi, [0x3010]
 
mov ebx, [edi+0x18] ; time stamp counter add
call _rdtsc
sub eax, ebx
add eax, [edi+0x14] ; counter sum
mov [edi+0x14], eax
 
mov ebx,[0x3000]
 
cmp [0xffff], byte 1 ;1
je do_not_change_task ;je
 
.waiting_for_termination:
.waiting_for_reuse:
.waiting_on_queue:
add edi,0x20
inc ebx
 
mov al, byte [edi+0xA]
cmp al, 3
je .waiting_for_termination
cmp al, 4
je .waiting_for_termination
cmp al, 9
je .waiting_for_reuse
cmp al, 16
je .waiting_on_queue
cmp al, 17
je .waiting_on_queue
 
cmp ebx,[0x3004]
jbe nsched0
mov ebx,1
mov edi,0x3020
 
nsched0:
 
mov [0x3000],ebx
mov [0x3010],edi
 
do_not_change_task:
 
mov edx,[0x3000]
lea edx,[tss0sys+8*edx]
;mov [8*0x40+idts+8+0], word 0
mov [8*0x40+idts+8+2],dx
;mov [8*0x40+idts+8+4],word 11100101b*256
;mov [8*0x40+idts+8+6], word 0
 
call _rdtsc
mov [edi+0x18],eax
 
cmp [0xffff],byte 0
je nodecffff
dec byte [0xffff]
nodecffff:
 
 
shl ebx, 3
xor eax, eax
add ebx, tss0
mov word [0xB004], bx ; selector ;mov [tss_s],bx
mov dword [0xB000], eax ; offset
 
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
.switch:
jmp pword [0xB000]
inc [context_counter] ;noname & halyavin
jmp irq0
 
iglobal
context_counter dd 0 ;noname & halyavin
endg
 
 
align 4
change_task:
 
mov [0xffff],byte 2
 
dec dword [timer_ticks] ; because irq0 will increase it
 
int 0x20 ; irq0 handler
 
ret
 
 
 
align 4
updatecputimes:
 
mov eax,[idleuse]
mov [idleusesec],eax
mov [idleuse],dword 0
mov ecx, [0x3004]
mov edi, 0x3020
.newupdate:
mov ebx,[edi+0x14]
mov [edi+0x1c],ebx
mov [edi+0x14],dword 0
add edi,0x20
dec ecx
jnz .newupdate
 
ret
 
 
 
;
; Wait queue is 16 bytes
; dd return code +12
; dd pointer to process +8
; dd prev +4
; dd next +0
;
; eax - pointer to pointer to the wait queue
; return:
; ecx - return code
sleep_on_queue:
sub esp,16 ; reserve space for wait node
mov ecx,esp ; ecx=this_node, [eax]=queue
 
pusha
 
mov ebx,[0x3010] ; get pointer to the current process
mov [ecx+8],ebx
 
pushf
cli ; adding element to the wait queue must be atomic
 
mov edi,[eax] ; edi=queue
and edi,edi ; check if queue is empty
jz .is_empty
 
; add element at the end of wait queue
 
mov edx,[edi+4] ; get pointer to prev edx=queue->prev
mov [ecx+4],edx ; this_node->prev=queue->prev
mov [ecx+0],edi ; this_node->next=queue
mov [edx+0],ecx ; this_node->prev->next=this_node
mov [edi+4],ecx ; queue->prev=this_node
jmp .added_ok
.is_empty:
; set this element as first in the queue
mov [ecx+0],ecx ; this_node->next=this_node
mov [ecx+4],ecx ; this_node->prev=this_node
mov [eax],ecx ; [queue]=this_node
.added_ok:
 
popf ; we can safely restore interrupts
 
mov [ebx+0xa],byte 17 ; set current task state as sleeping
call change_task ; schedule new thread
 
; someone has called wake_up_queue
 
pushf ; disable interrupts
cli
 
mov edx,[ecx+0] ; edx=this_node->next
mov esi,[ecx+4] ; esi=this_node->prev
 
; check if we need to remove this node from head
cmp [eax],ecx
jne .no_head
 
cmp [ecx+0],ecx ; check if queue is empty
jne .not_empty
 
mov [eax],dword 0
jmp .no_head
 
.not_empty:
mov [eax],edx
 
; remove our node from the queue (this must be atomic)
.no_head:
mov [edx+4],esi ; this_node->next->prev=this_node->prev
mov [esi+0],edx ; this_node->prev->next=this_node->next
 
popf
popa
add esp,12
pop ecx
ret
 
; eax - pointer to the wait queue
; ebx - wake up all (1=yes, 0=no)
; ecx - return code
; return:
; ebx - number of processes woken
wake_up_queue:
and eax,eax
jnz .nz
ret
.nz:
push eax
push ebx
push ecx
push edx
push esi
 
pushf
cli
 
xor ebx,ebx
mov edx,eax
.wake_loop:
 
mov [edx+12],ecx
mov esi,[edx+8]
mov byte [esi+0xa],0
inc ebx
 
mov edx,[edx+0]
cmp edx,eax
jne .wake_loop
 
and ebx,ebx
jz .wake_up_1
 
.return_it:
popf
pop esi
pop edx
pop ecx
add esp,4
pop eax
ret
.wake_up_1:
mov [eax+12],ecx
mov ecx,[eax+8]
mov byte [ecx+0xa],0
jmp .return_it
/kernel/trunk/core/sync.inc
0,0 → 1,111
if ~defined sync_inc
sync_inc_fix:
sync_inc fix sync_inc_fix
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Synhronization for MenuetOS. ;;
;;Author: Halyavin Andrey, halyavin@land.ru ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;simplest mutex.
macro SimpleMutex name
{
; iglobal
name dd 0
name#.type = 1
; endg
}
macro WaitSimpleMutex name
{
local start_wait,ok
start_wait=$
cli
cmp [name],dword 0
jz ok
sti
call change_task
jmp start_wait
ok=$
push eax
mov eax,dword [0x3010+second_base_address]
mov eax,[eax+0x4]
mov [name],eax
pop eax
sti
}
macro ReleaseSimpleMutex name
{
mov [name],dword 0
}
macro TryWaitSimpleMutex name ;result in eax and in flags
{
local ok,try_end
cmp [name],dword 0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
macro SimpleCriticalSection name
{
; iglobal
name dd 0
dd 0
name#.type=2
; endg
}
macro WaitSimpleCriticalSection name
{
local start_wait,first_wait,inc_counter,end_wait
push eax
mov eax,[0x3010+second_base_address]
mov eax,[eax+0x4]
start_wait=$
cli
cmp [name],dword 0
jz first_wait
cmp [name],eax
jz inc_counter
sti
call change_task
jmp start_wait
first_wait=$
mov [name],eax
mov [name+4],dword 1
jmp end_wait
inc_counter=$
inc dword [name+4]
end_wait=$
sti
pop eax
}
macro ReleaseSimpleCriticalSection name
{
local release_end
dec dword [name+4]
jnz release_end
mov [name],dword 0
release_end=$
}
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
{
local ok,try_end
mov eax,[0x3000+second_base_address]
mov eax,[eax+0x4]
cmp [name],eax
jz ok
cmp [name],0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
_cli equ call MEM_HeapLock
_sti equ call MEM_HeapUnLock
end if
 
/kernel/trunk/core/sys32.inc
0,0 → 1,2301
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; MenuetOS process management, protected ring3 ;;
;; ;;
;; Distributed under GPL. See file COPYING for details. ;;
;; Copyright 2003 Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
 
; GDT TABLE
 
gdts:
 
dw gdte-$-1
dd gdts
dw 0
 
int_code_l:
os_code_l:
 
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10011010b
db 0x00
 
int_data_l:
os_data_l:
 
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10010010b
db 0x00
 
graph_data_l:
 
dw 0x3ff
dw 0x0000
db 0x00
dw 11010000b *256 +11110010b
db 0x00
 
tss0_l:
times (max_processes+10) dd 0,0
 
tss0i_l:
times 0x41 dq 0 ;(256+10) dd 0,0
 
app_code_l:
times (max_processes+10) dd 0,0
 
app_data_l:
times (max_processes+10) dd 0,0
 
tss0sys_l:
times (max_processes+10) dd 0,0
 
gdte:
 
 
 
; <IP 05.02.2005>
idtreg:
dw 8*0x41-1
dd idts+8
 
label idts at 0xB100-8
;idte = idts + 8 + 0x60
 
; </IP> ; old code below:
 
 
;align 32
 
;idts:
; dw idte-$-1
; dd idts+8
; dw 0
 
; times 0x62 dd 0,0
 
;idte:
 
build_process_gdt_tss_pointer:
 
mov ecx,tss_data
mov edi,0
setgdtl2:
mov [edi+gdts+ tss0 +0], word tss_step
mov [edi+gdts+ tss0 +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0 +4], al
mov [edi+gdts+ tss0 +7], ah
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
add ecx,tss_step
add edi,8
cmp edi,8*(max_processes+5)
jbe setgdtl2
 
ret
 
;build_process_gdt_gate_pointer:
 
; mov edi,0
; mov dx,tss0
; setidtl1:
; mov ecx,[esi]
; mov [edi+gdts+ tss0t +0], word 0
; mov [edi+gdts+ tss0t +2], dx
; mov [edi+gdts+ tss0t +4], word 11100101b*256
; mov [edi+gdts+ tss0t +6], word 0
; add dx,8
; add edi,8
; cmp edi,8*(max_processes+5)
; jb setidtl1
 
; ret
 
build_interrupt_table:
 
mov [l.eflags],dword 0x11002
mov [l.ss0], int_data
;mov [l.ss1], ring1_data
;mov [l.ss2], ring2_data
mov [l.esp0], 0x52000
mov [l.esp1], 0x53000
mov [l.esp2], 0x54000
 
mov eax,cr3
mov [l.cr3],eax
mov [l.cs],int_code
mov [l.ss],int_data
mov [l.ds],int_data
mov [l.es],int_data
mov [l.fs],int_data
mov [l.gs],int_data
 
mov eax,sys_int
mov [l.esp],0x720000
mov edi,0x290000
 
newint:
push edi
mov ebx,[eax]
mov [l.eip],ebx
mov esi,tss_sceleton
mov ecx,120/4
cld
rep movsd
pop edi
 
add edi,128
add [l.esp],1024
add eax,4
 
cmp eax,sys_int+4*0x40 ;0x60
jbe newint ;jb
 
;;
 
mov esi,boot_sched_3_2
call boot_log
 
mov ecx,0x290000
mov edi,0
setgdtl2i:
mov [edi+gdts+ tss0i +0], word 128
mov [edi+gdts+ tss0i +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0i +4], al
mov [edi+gdts+ tss0i +7], ah
mov [edi+gdts+ tss0i +5], word 01010000b *256 +11101001b
add ecx,128
add edi,8
cmp edi,8*0x40 ;0x60
jbe setgdtl2i
 
;;
 
mov esi,boot_sched_3_3
call boot_log
 
mov edi,0
mov edx,tss0i
setidtl2:
mov [edi+idts+ 8 +0], word 0
mov [edi+idts+ 8 +2], dx
mov [edi+idts+ 8 +4], word 10000101b*256 ; task gate DPL=0
; cmp edi,0x40*8
; jne no_sw_int
; mov [edi+idts+ 8 +4], word 11100101b*256 ; task gate DPL=3
; no_sw_int:
mov [edi+idts+ 8 +6], word 0
add edx,8
add edi,8
 
cmp edi,8*0x40 ;0x60
jbe setidtl2 ;jb
 
; <Ivan Poddubny 06.02.2005>
; THIS CODE WON'T WORK ;-(
; because each process's 0-level stack points to the same area
; and if task switch occurs and another process is being interrupted
; a stack overflow happens
; The only way to solve that problem is to disable interrupts
; while 0x40-handler is working
; Then we have to make all entries in the IDT INTERRUPT gates, not TASK
; mov edi, idts+8
; mov esi, sys_int
; mov ecx, 32
; @@:
; mov eax, [esi]
; mov [edi], ax ; lower part of offset
; mov [edi+2], word os_code ; segment selector
; shr eax, 16
; mov [edi+4], word 10001110b shl 8 ; interrupt descriptor
; mov [edi+6], ax
; add esi, 4
; add edi, 8
; dec ecx
; jnz @b
; </Ivan Poddubny>
 
ret
 
build_syscall_interrupt_table:
 
mov [l.eflags],dword 0x11002
mov [l.ss0], int_data ;code
;mov [l.ss1], ring1_data ;code
;mov [l.ss2], ring2_data ;code
mov [l.esp0], 0x52000
mov [l.esp1], 0x53000
mov [l.esp2], 0x54000
 
mov eax,cr3
mov [l.cr3],eax
mov [l.cs],int_code
mov [l.ss],int_data
mov [l.ds],int_data
mov [l.es],int_data
mov [l.fs],int_data
mov [l.gs],int_data
 
mov [l.esp],sysint_stack_data
mov edi,0x298000
 
newint2:
push edi
mov ebx,i40
mov [l.eip],ebx
mov esi,tss_sceleton
mov ecx,120/4
cld
rep movsd
pop edi
 
add [l.esp],4096
add edi,128
;add eax,4
 
cmp edi,0x298000+128*(max_processes+5)
jb newint2
 
;;
 
mov ecx,0x298000
mov edi,0
setgdtl2i2:
mov [edi+gdts+ tss0sys +0], word 128
mov [edi+gdts+ tss0sys +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0sys +4], al
mov [edi+gdts+ tss0sys +7], ah
mov [edi+gdts+ tss0sys +5], word 01010000b *256 +11101001b
add ecx,128
add edi,8
cmp edi,8*(max_processes+5)
jbe setgdtl2i2
 
;;
 
;mov dx,tss0sys
mov edi,8*0x40+idts+8
mov [edi + 0], word 0
mov [edi + 2], word tss0sys ;dx
mov [edi + 4], word 11100101b*256
mov [edi + 6], word 0
 
mov edi,8*0x38+idts+8
mov eax, i38
mov [edi], ax ; lower part of offset
mov [edi+2], word os_code ; segment selector
shr eax, 16
mov [edi+4], word 11101110b shl 8 ; 32-bit interrupt gate, DPL 3
mov [edi+6], ax
 
ret
 
 
align 4
i38:
; load data selectors
pushfd
push ds es
push eax
mov ax, os_data
mov ds, ax
mov es, ax
pop eax
 
pushad
push edi
mov edi, eax
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov esi, [esp]
and edi, 0xFF
call dword [servetable+edi*4]
add esp, 4
popad
pop es ds
popfd
iret
 
 
iglobal
sys_int:
dd s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sa,sb,sc,sd,se,sf
 
dd s10 ,s11 ; ,i_unknown12,i_unknown13
; dd i_unknown14,i_unknown15,i_unknown16,i_unknown17
; dd i_unknown18,i_unknown19,i_unknown1a,i_unknown1b
; dd i_unknown1c,i_unknown1d,i_unknown1e,i_unknown1f
times 14 dd unknown_interrupt
 
dd irq0 ,irq1 ,p_irq2 ,p_irq3 ,p_irq4 ,p_irq5,p_irq6 ,p_irq7
dd p_irq8,p_irq9,p_irq10,p_irq11,p_irq12,irqD ,p_irq14,p_irq15
 
;dd i_unknown30,i_unknown31,i_unknown32,i_unknown33
;dd i_unknown34,i_unknown35,i_unknown36,i_unknown37
;dd i_unknown38,i_unknown39,i_unknown3a,i_unknown3b
;dd i_unknown3c,i_unknown3d,i_unknown3e,i_unknown3f
times 16 dd unknown_interrupt
 
dd i40
endg
 
uglobal
tss_sceleton:
l.back dw 0,0
l.esp0 dd 0
l.ss0 dw 0,0
l.esp1 dd 0
l.ss1 dw 0,0
l.esp2 dd 0
l.ss2 dw 0,0
l.cr3 dd 0
l.eip dd 0
l.eflags dd 0
l.eax dd 0
l.ecx dd 0
l.edx dd 0
l.ebx dd 0
l.esp dd 0
l.ebp dd 0
l.esi dd 0
l.edi dd 0
l.es dw 0,0
l.cs dw 0,0
l.ss dw 0,0
l.ds dw 0,0
l.fs dw 0,0
l.gs dw 0,0
l.ldt dw 0,0
l.trap dw 0
l.io dw 0
endg
 
s0:
cli
 
mov [error_interrupt],0x0
mov [error_interrupt_entry],dword s0
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
 
s1:
cli
 
mov [error_interrupt],0x1
mov [error_interrupt_entry],dword s1
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s2:
cli
 
mov [error_interrupt],0x2
mov [error_interrupt_entry],dword s2
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s3:
cli
 
mov [error_interrupt],0x3
mov [error_interrupt_entry],dword s3
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s4:
cli
 
mov [error_interrupt],0x4
mov [error_interrupt_entry],dword s4
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s5:
cli
 
mov [error_interrupt],0x5
mov [error_interrupt_entry],dword s5
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s6:
cli
 
mov [error_interrupt],0x6
mov [error_interrupt_entry],dword s6
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
 
;;;;;;;;;;;;;;;;;;;;;;;
;; FPU ERROR HANDLER ;;
;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
s7:
; <IP 05.02.2004>
cli
; </IP>
mov edi, 7*8
mov [edi+gdts+ tss0i +5], word 01010000b *256 +11101001b
 
mov edi,[0x3000]
shl edi, 3
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
 
; save a copy of current task's TSS to fpu_tss
mov esi,[0x3000]
imul esi,tss_step
add esi,tss_data
mov edi,fpu_tss
mov ecx,120/4
cld
rep movsd
 
; get base address of our TSS and...
mov esi,[0x3000]
imul esi,tss_step
add esi,tss_data
 
; ...init segments, stack, eip, flags
mov word [esi+l.cs-tss_sceleton],int_code
mov word [esi+l.ss-tss_sceleton],int_data
mov word [esi+l.ds-tss_sceleton],int_data
mov word [esi+l.es-tss_sceleton],int_data
mov word [esi+l.fs-tss_sceleton],int_data
mov word [esi+l.gs-tss_sceleton],int_data
mov dword [esi+l.esp-tss_sceleton],fpu_stack+4*8
mov dword [esi+l.eip-tss_sceleton],fpu_handler
mov dword [esi+l.eflags-tss_sceleton],0x11002
 
; then execute this task
mov ebx, [0x3000]
shl ebx,3
add ebx, tss0 ;t
mov [0xB004], bx
 
jmp pword [0xB000]
 
jmp s7
 
s8:
cli
 
mov [error_interrupt],0x8
mov [error_interrupt_entry],dword s8
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s9:
cli
 
mov [error_interrupt],0x9
mov [error_interrupt_entry],dword s9
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sa:
cli
 
mov [error_interrupt],0xa
mov [error_interrupt_entry],dword sa
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sb:
cli
 
mov [error_interrupt],0xb
mov [error_interrupt_entry],dword sb
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sc:
cli
 
mov [error_interrupt],0xc
mov [error_interrupt_entry],dword sc
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sd:
cli
 
mov [error_interrupt],0xd
mov [error_interrupt_entry],dword sd
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
se:
cli
 
mov [error_interrupt],0xe
mov [error_interrupt_entry],dword se
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sf:
cli
 
mov [error_interrupt],0xf
mov [error_interrupt_entry],dword sf
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s10:
cli
 
mov [error_interrupt],0x10
mov [error_interrupt_entry],dword s10
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s11:
cli
 
mov [error_interrupt],0x11
mov [error_interrupt_entry],dword s11
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
writehex:
 
pusha
 
mov ecx,eax
mov ax,word [printerrorat]
shl eax,16
mov ax,[esp+32+4]
sub ax,60
mov edx,1
mov esi,8
mov ebx,0xffffff
whl1:
push ecx
and ecx,0xf
add ecx,hexletters
mov edi,1
 
mov cl,[ecx]
mov edi,[write_error_to]
mov [edi],cl
dec [write_error_to]
 
pop ecx
shr ecx,4
sub eax,6*65536
dec esi
jnz whl1
 
popa
ret
 
iglobal
hexletters db '0123456789ABCDEF'
 
error_interrupt dd -1
error_interrupt_entry dd -1
 
printerrorat dd 300
 
process_error db 'K : Process - forced terminate INT: 00000000',13,10,0
process_pid db 'K : Process - forced terminate PID: 00000000',13,10,0
process_eip db 'K : Process - forced terminate EIP: 00000000',13,10,0
system_error db 'K : Kernel error',13,10,0
endg
 
uglobal
write_error_to dd 0x0
endg
 
show_error_parameters:
mov [write_error_to],process_pid+43
mov eax,[0x3000]
shl eax, 5
mov eax,[0x3000+4+eax]
call writehex
mov [write_error_to],process_error+43
mov eax,[error_interrupt]
call writehex
mov eax,[0x3000]
shl eax,8
cmp [0x80000+eax+0xB0],dword 0
jnz .system_error
 
mov eax,[0x3000]
imul eax,tss_step
mov eax,[eax+tss_data+l.eip-tss_sceleton]
.out_eip:
mov [write_error_to],process_eip+43
call writehex
 
mov esi,process_error
call sys_msg_board_str
 
mov esi,process_pid
call sys_msg_board_str
 
mov esi,process_eip
call sys_msg_board_str
 
ret
.system_error:
mov esi,system_error
call sys_msg_board_str
mov eax,[0x3000]
shl eax,7
mov eax,[eax+0x298000+l.eip-tss_sceleton]
jmp .out_eip
 
 
irq5:
 
call restore_caller
 
mov dx,word [sb16]
add dx,0xe
in al,dx
 
; mov byte [SB16_Status],0
 
mov [check_idle_semaphore],5
 
mov al,0x20
out 0x20,al
 
call return_to_caller
 
jmp irq5
 
irqD:
 
call restore_caller
 
mov dx,0xf0
mov al,0
out dx,al
 
mov dx,0xa0
mov al,0x20
out dx,al
mov dx,0x20
out dx,al
 
mov ds,cx
mov es,cx
mov fs,cx
 
call return_to_caller
 
jmp irqD
 
p_irq2:
 
call restore_caller
 
mov edi,2 ; 1
call irqhandler ; 2/5
 
call return_to_caller
 
jmp p_irq2
 
p_irq3:
 
call restore_caller
 
mov edi,3
call irqhandler
 
call return_to_caller
 
jmp p_irq3
 
p_irq4:
 
call restore_caller
 
mov edi,4
call irqhandler
 
call return_to_caller
 
jmp p_irq4
 
p_irq5:
 
call restore_caller
 
mov edi,5
call irqhandler
 
call return_to_caller
 
jmp p_irq5
 
p_irq6:
 
call restore_caller
 
call fdc_irq
 
mov edi,6
call irqhandler
 
call return_to_caller
 
jmp p_irq6
 
p_irq7:
 
call restore_caller
 
mov edi,7
call irqhandler
 
call return_to_caller
 
jmp p_irq7
 
p_irq8:
 
call restore_caller
 
mov edi,8
call irqhandler
 
call return_to_caller
 
jmp p_irq8
 
p_irq9:
 
call restore_caller
 
mov edi,9
call irqhandler
 
call return_to_caller
 
jmp p_irq9
 
p_irq10:
 
call restore_caller
 
mov edi,10
call irqhandler
 
call return_to_caller
 
jmp p_irq10
 
p_irq11:
 
call restore_caller
 
mov edi,11
call irqhandler
 
call return_to_caller
 
jmp p_irq11
 
p_irq12:
 
call restore_caller
 
mov edi,12
call irqhandler
 
call return_to_caller
 
jmp p_irq12
 
p_irq13:
 
call restore_caller
 
mov edi,13
call irqhandler
 
call return_to_caller
 
jmp p_irq13
 
p_irq14:
 
call restore_caller
mov edi,14
call irqhandler
 
call return_to_caller
 
jmp p_irq14
 
p_irq15:
 
call restore_caller
 
mov edi,15
call irqhandler
 
call return_to_caller
 
jmp p_irq15
 
 
 
align 4
restore_caller:
 
mov edi,[0x3000]
shl edi, 3
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
ret
 
align 4
return_to_caller:
 
mov ebx,[0x3000]
shl bx,3
add bx,tss0;t
mov [tss_irq12],bx
 
db 0xea
dd 0
tss_irq12 dw tss0;t
 
ret
 
uglobal
irqh dd 0x0
endg
 
irqhandler:
 
push edi
 
mov esi,edi ; 1
shl esi,6 ; 1
add esi,irq00read ; 1
shl edi,12 ; 1
add edi,0x2E0000
 
mov [check_idle_semaphore],5
 
irqnewread:
 
mov dx,[esi] ; 2+
 
cmp dx,0 ; 1
jz irqover
cmp [esi+3],byte 1 ; 2 ; byte read
jne noirqbyte ; 4-11
 
in al,dx
 
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],al
inc edx
mov [edi],edx
 
add esi,4
jmp irqnewread
 
noirqbyte:
 
 
cmp [esi+3],byte 2 ; word read
jne noirqword
 
in ax,dx
 
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],ax
add edx,2
mov [edi],edx
add esi,4
jmp irqnewread
 
noirqword:
irqfull:
irqover:
 
mov al,0x20 ; ready for next irq
out 0x20,al
 
pop ebx
cmp ebx,7
jbe noa0
out 0xa0,al
noa0:
 
ret
 
 
; this code should never get control!
; applications can use only 0x40 interrupt
unknown_interrupt:
@@: call change_task
jmp @b
 
 
 
compare_to_thread:
 
push ebx
 
mov eax,edx
shl eax, 3
add eax,gdts+ app_code-3
mov ebx,[eax]
cmp ebx,[old_code_0]
jne ctt0
mov ebx,[eax+4]
cmp ebx,[old_code_1]
jne ctt0
 
pop ebx
mov eax,1
ret
 
ctt0:
 
pop ebx
mov eax,0
ret
 
 
 
check_for_thread_mem:
 
pusha
 
mov ecx,[0x3004]
cftm0:
mov eax,ecx
shl eax, 8
add eax,gdts+ app_code-3
mov ebx,[eax]
cmp ebx,[old_code_0]
jne cftm1
mov ebx,[eax+4]
cmp ebx,[old_code_1]
jne cftm1
 
mov eax,ecx ; new code segments
shl eax, 3 ;imul eax,8
add eax,gdts+ app_code-3
 
mov ebx,[new_code_0]
mov [eax],ebx
mov ebx,[new_code_1]
mov [eax+4],ebx
 
mov eax,ecx ; new data segments
shl eax, 3
 
add eax,gdts+ app_data-3
 
mov ebx,[new_data_0]
mov [eax],ebx
mov ebx,[new_data_1]
mov [eax+4],ebx
 
cmp [new_pos],0 ; new memory position segments
je no_new_postition_for_thread
mov eax,ecx
shl eax, 5
add eax,0x3000
mov ebx,[new_pos]
mov [eax+0x10],ebx
no_new_postition_for_thread:
 
mov eax,ecx ; new amount of memory
shl eax, 8
add eax,0x80000
mov ebx,[new_amount]
mov [eax+0x8C],ebx
 
cftm1:
 
dec ecx
jnz cftm0
 
popa
 
ret
 
 
save_for_thread_check:
 
; save for thread check
 
pusha
mov esi,[0x3000]
;imul esi,8
shl esi, 3
add esi,gdts+ app_code-3 +0
mov edi,old_code_0
mov ecx,8
cld
rep movsb
popa
 
ret
 
 
save_new_position_for_threads:
 
; new code segment for thread check
pusha
mov esi,[0x3000]
;imul esi,8
shl esi, 3
add esi,gdts+ app_code-3 +0
mov edi,new_code_0
mov ecx,8
cld
rep movsb
popa
 
; new data segment for thread check
pusha
mov esi,[0x3000]
;imul esi,8
shl esi, 3
add esi,gdts+ app_data-3 +0
mov edi,new_data_0
mov ecx,8
cld
rep movsb
popa
 
ret
 
set_application_table_status:
push eax
 
mov eax,[0x3000]
;imul eax,32
shl eax, 5
add eax,0x3000+4
mov eax,[eax]
 
mov [application_table_status],eax
 
pop eax
 
ret
 
 
clear_application_table_status:
push eax
 
mov eax,[0x3000]
;imul eax,32
shl eax, 5
add eax,0x3000+4
mov eax,[eax]
 
cmp eax,[application_table_status]
jne apptsl1
mov [application_table_status],0
apptsl1:
 
pop eax
 
ret
 
uglobal
old_code_0 dd 0x0
old_code_1 dd 0x0
 
;
 
new_code_0 dd 0x0
new_code_1 dd 0x0
 
new_data_0 dd 0x0
new_data_1 dd 0x0
 
new_pos dd 0x0
new_amount dd 0x0
endg
 
 
sys_resize_app_memory:
; eax = 1 - resize
; ebx = new amount of memory
 
cmp eax,1
jne no_application_mem_resize
mov eax,[0x3010]
cmp dword [eax+0x10],std_application_base_address
jz new_mem_resize ;resize for new type of processes
 
add ebx,4095
shr ebx,12
shl ebx,12
mov ebp,ebx
 
; wait for process table to be free
 
rsm0:
 
cli
cmp [application_table_status],0
je rsm1
sti
call change_task
jmp rsm0
 
rsm1:
 
call set_application_table_status
sti
 
cmp ebx,0 ; other than zero
je mem_resize_unsuccess
 
call save_for_thread_check
 
; find a free place
 
mov esi,[0xfe84] ; application memory start
mov edi,ebp
add edi,esi
dec edi
 
rfgdt:
 
mov edx,2
 
rfindgdtl1:
 
call compare_to_thread
cmp eax,1
je rfindfl3
 
mov ecx,edx
shl ecx,3
 
; eax run base -> ebx limit
 
mov al,[ecx+gdts+ app_code-3 +4]
mov ah,[ecx+gdts+ app_code-3 +7]
shl eax,16
mov ax,[ecx+gdts+ app_code-3 +2]
;!!mem
cmp eax,std_application_base_address
jz rfindfl3
;!!mem
 
movzx ebx,word [ecx+gdts+ app_code-3 +0]
shl ebx,12
add ebx,eax
 
cmp eax,edi
jg rfindfl3
cmp ebx,esi
jb rfindfl3
 
add esi,4096
add edi,4096
 
cmp edi,[0xfe8c] ; < c_memory
jbe rfgdt
 
jmp rfind_free_ret_2 ;; not enough memory
 
rfindfl3:
 
inc edx
cmp edx,[0x3004]
jbe rfindgdtl1
 
rfindfl1:
rthread_c:
 
mov ecx,[0x3000]
shl ecx,3
 
inc edi
sub edi,esi
add edi,4095
shr edi,12
dec edi
 
; code
 
mov eax,esi
mov ebx,edi
 
mov [ecx+gdts+ app_code-3 +2], ax ; base 0:15
shr eax,16
mov [ecx+gdts+ app_code-3 +4], al ; base 23:16
mov [ecx+gdts+ app_code-3 +7], ah ; base 31:24
mov [ecx+gdts+ app_code-3 +0], bx ; limit
 
; data
 
mov eax,esi
mov [ecx+gdts+ app_data-3 +2], ax ; base 0:15
shr eax,16
mov [ecx+gdts+ app_data-3 +4], al ; base 23:16
mov [ecx+gdts+ app_data-3 +7], ah ; base 31:24
 
movzx edx,word [ecx+gdts+ app_code-3 +0] ; save limit
 
mov [ecx+gdts+ app_data-3 +0], bx ; limit
 
and ebx,0xffff
 
cmp ebx,edx ; copy smaller from memory sizes
jge noedxebxxchg
mov edx,ebx
noedxebxxchg:
 
movzx ecx,dx
shl ecx,12
add ecx,4096
 
mov edi,esi
 
mov eax,[0x3010]
mov esi,[eax+0x10]
 
mov [eax+0x10],edi ; new memory position
 
mov eax,[0x3000] ; new memory size
shl eax,8
add eax,0x80000
mov [eax+0x8c],ebp
 
mov [new_pos],edi ; new position for threads
mov [new_amount],ebp ; new amount of mem for threads
 
cmp esi,edi
je no_app_move
 
cld
rep movsb ; move the app image to the new position
 
no_app_move:
 
call save_new_position_for_threads
call check_for_thread_mem
 
mov [application_table_status],0
 
mov [esp+36],dword 0 ; eax <- 0 ; successfull
 
ret
 
rfind_free_ret_2:
 
mem_resize_unsuccess:
 
mov [application_table_status],0
 
mov [esp+36],dword 1 ; eax <- 1 ; unsuccessfull
 
ret
 
no_application_mem_resize:
 
 
ret
 
 
align 4
find_free_mem:
 
push eax
push ebx
push ecx
push edx
push edi
 
call find_free_process_slot
mov eax,[new_process_place]
 
cmp eax,max_processes
jg find_free_ret_2
 
cmp [thread_create],1
je thread_c
 
mov esi,[0xfe84]
add edi,esi
dec edi
 
mov eax,2
cmp dword [0x3004],1
je findf4
 
fgdt:
 
mov edx,2
 
findgdtl1:
 
mov ecx,edx
shl ecx,3
 
; eax run base -> ebx limit
 
mov al,[ecx+gdts+ app_code-3 +4]
mov ah,[ecx+gdts+ app_code-3 +7]
shl eax,16
mov ax,[ecx+gdts+ app_code-3 +2]
;!!mem
cmp eax,std_application_base_address
jz findfl3
;!!mem
 
movzx ebx,word [ecx+gdts+ app_code-3 +0]
shl ebx,12
add ebx,eax
 
cmp eax,edi
jg findfl3
cmp ebx,esi
jb findfl3
 
add esi,4096
add edi,4096
 
cmp edi,[0xfe8c] ; < c_memory
jbe fgdt
 
jmp find_free_ret_2
 
findfl3:
 
inc edx
cmp edx,[check_processes]
jbe findgdtl1
 
findfl1:
thread_c:
 
mov eax,[new_process_place]
 
findf4:
 
mov [first_gdt_search],eax
mov [gdt_place],eax
 
mov ecx,eax
shl ecx,3
 
inc edi
sub edi,esi
add edi,4095
shr edi,12
dec edi
 
; code
 
mov eax,esi
mov ebx,edi
 
mov [ecx+gdts+ app_code-3 +2], ax ; base 0:15
shr eax,16
mov [ecx+gdts+ app_code-3 +4], al ; base 23:16
mov [ecx+gdts+ app_code-3 +7], ah ; base 31:24
mov [ecx+gdts+ app_code-3 +0], bx ; limit
mov [ecx+gdts+ app_code-3 +5], word 11010000b *256 +11111010b
 
; data
 
mov eax,esi
mov [ecx+gdts+ app_data-3 +2], ax ; base 0:15
shr eax,16
mov [ecx+gdts+ app_data-3 +4], al ; base 23:16
mov [ecx+gdts+ app_data-3 +7], ah ; base 31:24
mov [ecx+gdts+ app_data-3 +0], bx ; limit
mov [ecx+gdts+ app_data-3 +5], word 11010000b *256 +11110010b
 
push esi
mov esi,process_loading
call sys_msg_board_str
pop esi
 
find_free_ret:
 
pop edi
pop edx
pop ecx
pop ebx
pop eax
ret
 
find_free_ret_2:
 
cmp [dec3004],0
je no3004inc
dec dword [0x3004]
no3004inc:
 
pop edi
pop edx
pop ecx
pop ebx
pop eax
mov esi,0
ret
 
 
get_app_params:
 
push eax
 
cmp [0x90000+6],word '00'
jne no_00_header
 
mov eax,[0x90000+12]
mov [app_start],eax
mov eax,[0x90000+16]
mov [app_i_end],eax
mov eax,[0x90000+20]
mov [app_mem],eax
shr eax,1
sub eax,0x10
mov [app_esp],eax
mov eax,[0x90000+24]
mov [app_i_param],eax
mov [app_i_icon],dword 0
 
pop eax
mov esi,1
ret
 
no_00_header:
 
 
cmp [0x90000+6],word '01'
jne no_01_header
 
mov eax,[0x90000+12]
mov [app_start],eax
mov eax,[0x90000+16]
mov [app_i_end],eax
mov eax,[0x90000+20]
mov [app_mem],eax
mov eax,[0x90000+24]
mov [app_esp],eax
mov eax,[0x90000+28]
mov [app_i_param],eax
mov eax,[0x90000+32]
mov [app_i_icon],eax
 
pop eax
mov esi,1
ret
 
no_01_header:
 
pop eax
mov esi,0
ret
 
 
start_application_fl:
jmp new_start_application_fl
 
;************************************************************************
 
start_application_floppy:
jmp new_start_application_floppy
 
;********************************************************************
 
start_application_hd:
jmp new_start_application_hd
 
uglobal
threadstring dd 0x0
new_process_place dd 0x0
check_processes dd 0x0
dec3004 db 0x0
app_start dd 0x0
app_i_end dd 0x0
app_mem dd 0x0
app_esp dd 0x0
app_i_param dd 0x0
app_i_icon dd 0x0
app_mem_pos dd 0x0
thread_create dd 0x0
gdt_place dd 0x0
endg
 
iglobal
hd_app_string db 'HDAPP '
process_loading db 'K : Process - loading ',13,10,0
process_running db 'K : Process - done',13,10,0
first_gdt_search dd 0x2
endg
 
 
sys_threads:
 
; eax=1 create thread
;
; ebx=thread start
; ecx=thread stack value
;
; on return : eax = pid
jmp new_sys_threads
cli
cmp [application_table_status],0
je stth9
sti
call change_task
jmp sys_threads
stth9:
 
call set_application_table_status
 
sti
 
cmp eax,1
jne no_sys_thread_create
cli
 
mov eax,[0x3010]
mov eax,[eax+0x10]
mov [app_mem_pos],eax
 
mov [app_i_param],0
mov [app_i_icon],0
 
mov [app_start],ebx
mov [app_esp],ecx
 
mov ebx,[0x3000]
shl ebx,8
add ebx,0x80000
mov [threadstring],ebx
mov ebx,[ebx+0x8c]
mov [app_mem],ebx
 
mov esi,[app_mem_pos]
mov edi,[app_mem]
add edi,esi
dec edi
mov [thread_create],1
call find_free_mem
cmp esi,0
jne th_cr1
mov [application_table_status],0
mov eax,1 ; no free memory
sti
ret
th_cr1:
push dword 0
push dword [threadstring]
jmp add_app_parameters
no_sys_thread_create:
 
mov eax,-1
mov [application_table_status],0
ret
 
 
find_free_process_slot:
 
pusha
 
mov ebx,[0x3004]
mov [check_processes],ebx
inc ebx
mov [new_process_place],ebx
 
mov ebx,2
 
newfps:
 
mov eax,ebx
;imul eax,0x20
shl eax, 5
add eax,0x3000+0xa
cmp [eax],byte 9
je ffpl
 
inc ebx
cmp ebx,[0x3004]
jbe newfps
 
;mov [dec3004],0
mov [dec3004],1
shl ebx,5
mov [0x3000+0xa+ebx],byte 9
inc dword [0x3004]
 
popa
ret
 
ffpl:
 
;mov [dec3004],1
;dec dword [0x3004]
mov [dec3004],0
mov [new_process_place],ebx
 
popa
ret
 
 
add_app_parameters:
; returns: eax = pid or -1 if unsuccesfull
cmp [app_i_param],dword 0 ; parameter
jz no_app_params
xor eax, eax
mov edi,[app_i_param]
add edi,[app_mem_pos]
mov ecx,256/4
cld
rep stosd
mov esi,[esp+4]
test esi, esi
jz no_app_params
mov eax,[app_i_param]
add eax,[app_mem_pos]
mov edi,eax
mov ecx,256
cld
app_new_param:
cmp [esi],byte 0
jz no_app_params
movsb
loop app_new_param
no_app_params:
 
;inc dword [0x3004] ; increase number of processes
mov ebx,[new_process_place]
 
mov edi,ebx ; clear 0x80000 (256 bytes)
shl edi,8
add edi,0x80000
mov ecx,256 / 4
mov eax,0
cld
rep stosd
 
shl ebx,5 ; * 32 +0x3000
add ebx,0x3000
 
mov al,byte [new_process_place] ; screen id ?
mov [ebx+0xe],al
 
mov [ebx],dword 1+2+4 ; report events: windowdraw, key, button
 
inc dword [process_number] ; process id number
mov eax,[process_number]
mov [ebx+4],eax
 
mov ecx,ebx ; set draw limits
add ecx,draw_data-0x3000
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[0xfe00]
mov [ecx+8],eax
mov eax,[0xfe04]
mov [ecx+12],eax
 
mov eax,[app_mem_pos] ; position in memory
mov [ebx+0x10],eax
 
; TSS
xor ebx,ebx
cmp [thread_create],ebx
jnz clone_cr3_table
mov eax,[new_process_place]
call create_app_cr3_table
jmp set_cr3
clone_cr3_table:
; mov eax,[new_process_place]
; mov ebx,[0x3000]
; call addreference_app_cr3_table
mov eax,[0x3000]
call get_cr3_table
set_cr3:
add eax,8+16
mov [l.cr3],eax
mov eax,[app_start]
mov [l.eip],eax
mov eax,[app_esp]
mov [l.esp],eax
 
mov ebx,[new_process_place] ; gdt's
shl ebx,3
 
mov ax,app_code
add ax,bx
mov [l.cs],ax
mov ax,app_data
add ax,bx
mov [l.ss],ax
mov [l.ds],ax
mov [l.es],ax
mov [l.fs],ax
mov ax,graph_data
mov [l.gs],ax
mov [l.io],word 128
mov [l.eflags],dword 0x11202
mov [l.ss0], os_data
;mov [l.ss1], ring1_data
;mov [l.ss2], ring2_data
; [Ivan 07.03.2005]
mov [l.esp0], 0x8000 ;0x55000 ; used by i38 handler
; [/Ivan 07.03.2005]
mov [l.esp1], 0x56000
mov [l.esp2], 0x57000
 
mov eax,tss_sceleton ; move tss to tss_data+
mov ebx,[new_process_place]
imul ebx,tss_step
add ebx,tss_data
mov ecx,120
call memmove
 
 
; Add IO access table
 
or eax, -1
mov edi, [new_process_place]
imul edi, tss_step
add edi, tss_data + 128
mov ecx, 2048 ; for 2048 * 4 * 8 bits = 65536 ports
cld
rep stosd
 
; make sure gdt is pointing to the process
; and not to i40 handler
 
mov ecx,ebx
mov edi,[new_process_place]
; imul edi,8
shl edi, 3
 
mov [edi+gdts+ tss0 +0], word tss_step ; limit 0:15
mov [edi+gdts+ tss0 +2], cx ; base 0:15
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0 +4], al ; base 23:16
mov [edi+gdts+ tss0 +7], ah ; base 31:24
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
pop eax
pop ebx
 
mov ebx,[new_process_place] ; save name of the process
shl ebx,8
add ebx,0x80000
mov ecx,11
call memmove
 
mov ebx,[new_process_place] ; save image size
shl ebx,8
add ebx,0x80000+0x8C
mov eax,[app_mem]
mov [ebx],eax
 
mov [0xf400],byte 0 ; empty keyboard buffer
mov [0xf500],byte 0 ; empty button buffer
 
mov [application_table_status],0
mov eax,[process_number]
 
mov ebx,[new_process_place]
shl ebx, 5 ;imul ebx,0x20
mov [0x3000+ebx+0xa],byte 0
 
mov edi,[new_process_place]
shl edi,5
add edi,window_data
 
mov ebx,[new_process_place]
movzx esi, word [0xC000 + ebx*2]
lea esi, [0xC400 + esi*2]
call windowactivate
 
sti
 
push esi
mov esi,process_running
call sys_msg_board_str
pop esi
 
ret
 
iglobal
process_terminating db 'K : Process - terminating',13,10,0
process_terminated db 'K : Process - done',13,10,0
endg
 
 
terminate: ; terminate application
push esi
mov esi,process_terminating
call sys_msg_board_str
pop esi
;start memory manager code
; mov eax,esi
; call MEM_Heap_Clean
;end memory manager code
 
cli
cmp [application_table_status],0
je term9
sti
call change_task
jmp terminate
term9:
 
call set_application_table_status
mov eax,esi
call dispose_app_cr3_table
 
mov [first_gdt_search],0x2 ; start gdt search from beginning
 
cmp [prev_user_of_fpu],esi ; if user fpu last -> fpu user = 1
jne fpu_ok_1
mov [prev_user_of_fpu],1
fpu_ok_1:
 
mov [0xf400],byte 0 ; empty keyboard buffer
mov [0xf500],byte 0 ; empty button buffer
 
mov ecx,esi ; clear memory reserv.
shl ecx,3
mov [ecx+gdts+ app_code-3 +0],dword 0
mov [ecx+gdts+ app_code-3 +4],dword 0
mov [ecx+gdts+ app_data-3 +0],dword 0
mov [ecx+gdts+ app_data-3 +4],dword 0
 
mov edi, esi
; shl edi, 5
; add edi, 0x3000
; cmp [edi+0xa],byte 3 ; if normal terminate then clear int40 handler
; jne nocl40
 
; mov edi,esi ; free the used interrupt 0x40 handler
; shl edi, 8 ;imul edi,256
; mov eax,[edi+0x80000+0xb0]
 
; cmp eax,0 ; is application using a systemcall interrupt ?
; je nocl40
 
mov [usedi40+eax],byte 0
 
; mov edi,8
; imul edi,eax
mov edi, eax
shl edi, 3
mov [edi+tss0sys_l +5], word 01010000b *256 +11101001b
 
; mov edi,128
; imul edi,eax
mov edi, eax
shl edi, 7
mov [edi+0x298000+l.eip-tss_sceleton],dword i40
mov [edi+0x298000+l.eflags-tss_sceleton],dword 0x11002
 
mov ebx,eax
shl ebx, 12 ;imul ebx,4096
add ebx,sysint_stack_data
mov [edi+0x298000+l.esp-tss_sceleton],ebx
 
nocl40:
 
mov ecx,esi ; remove buttons
bnewba2:
mov edi,[0xfe88]
mov eax,edi
cld
movzx ebx,word [edi]
inc bx
bnewba:
dec bx
jz bnmba
add eax,0x10
cmp cx,[eax]
jnz bnewba
pusha
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popa
jmp bnewba2
bnmba:
 
pusha ; save window coordinates for window restoring
cld
shl esi,5
add esi,window_data
mov ax,[esi+0]
mov word [dlx],ax
mov bx,[esi+8]
add ax,bx
mov word [dlxe],ax
mov ax,[esi+4]
mov word [dly],ax
mov bx,[esi+12]
add ax,bx
mov word [dlye],ax
mov [esi+0],word 0
mov [esi+8],word 5
mov ax,[0xFE04]
mov [esi+4],ax
mov [esi+12],word 5
xor eax, eax
mov [esi+16],eax;dword 0
mov [esi+20],eax;dword 0
mov [esi+24],eax;dword 0
mov [esi+28],eax;dword 0
popa
 
pusha
mov edi,esi
shl edi,5
add edi,window_data
mov ecx,32/4
xor eax, eax
; cld
rep stosd
 
mov eax,[0xFE04] ; set window to start from maxy+1
add eax,2
 
mov edi,esi
shl edi,5
add edi,window_data
mov [edi+4],eax
 
popa
 
pusha
mov edi,esi
shl edi,5
add edi,draw_data
mov ecx,32/4
xor eax, eax
; cld
rep stosd
popa
 
pusha ; at 0x80000+
mov edi,esi
shl edi,8
add edi,0x80000
mov ecx,256/4
xor eax, eax
; cld
rep stosd
popa
 
pusha ; name to spaces
mov edi,esi
shl edi,8
add edi,0x80000
mov ecx,11
mov eax,' '
; cld
rep stosb
popa
 
pusha ; C000 --> C400
mov eax, 0xc000
mov esi, 0
nlc40:
add eax, 2
inc esi
cmp esi, [0x3004]
jae nlc41
movzx ecx, word [eax]
mov [0xC400 + ecx*2], si
jmp nlc40
nlc41:
; ivan 08.12.2004 begin
;mov ebx, [0x3004]
;dec ebx
;lea esi, [0xC400 + ebx*2]
;call windowactivate
; ivan 08.12.2004 end
popa
 
pusha ; remove hd1 reservation
mov edx,esi
shl edx, 5 ;imul edx,0x20
add edx,0x3000
mov edx,[edx+4]
cmp [hd1_status],edx
jne no_hd1_s_remove
mov [hd1_status],0
no_hd1_s_remove:
popa
 
pusha ; remove all irq reservations
mov edx,esi
shl edx, 5 ;imul edx,0x20
add edx,0x3000
mov edx,[edx+4]
mov edi,irq_owner
mov ecx,16
newirqfree:
cmp [edi],edx
jne nofreeirq
mov [edi],dword 0
nofreeirq:
add edi,4
loop newirqfree
popa
 
 
pusha ; remove all port reservations
 
mov edx,esi
shl edx, 5 ;imul edx,0x20
add edx,0x3000
mov edx,[edx+4]
 
rmpr0:
 
mov esi,[0x2d0000]
 
cmp esi,0
je rmpr9
 
rmpr3:
 
mov edi,esi
shl edi,4
add edi,0x2d0000
 
cmp edx,[edi]
je rmpr4
 
dec esi
jnz rmpr3
 
jmp rmpr9
 
rmpr4:
 
mov ecx,256
sub ecx,esi
shl ecx,4
 
mov esi,edi
add esi,16
cld
rep movsb
 
dec dword [0x2d0000]
 
jmp rmpr0
 
rmpr9:
 
popa
mov edi,esi ; do not run this process slot
shl edi, 5 ;imul edi,0x20
; add edi,0x3000
mov [edi+0x300A],byte 9
; call systest
sti ; .. and life goes on
 
; movzx eax,word [dlx]
; movzx ebx,word [dly]
; movzx ecx,word [dlxe]
; movzx edx,word [dlye]
call calculatescreen
 
xor eax, eax
xor esi, esi
call redrawscreen
 
mov [0xfff4],byte 0 ; no mouse background
mov [0xfff5],byte 0 ; draw mouse
 
mov [application_table_status],0
 
mov esi,process_terminated
call sys_msg_board_str
 
;* start code - fix error redraw for terminate (2) - Mario79
; cmp [draw_present],1
; je no_draw_background_temp
; mov [0xfff0],byte 1
;no_draw_background_temp:
; mov [draw_present],0
ret
;draw_present db 0
;* end code - fix error redraw for terminate (2) - Mario79
 
iglobal
boot_sched_1 db 'Building gdt tss pointer',0
;boot_sched_2 db 'Building gdt gate pointer',0
boot_sched_3 db 'Building interrupt table - TSS',0
boot_sched_3_2 db 'Building interrupt table - GDT',0
boot_sched_3_3 db 'Building interrupt table - IDT',0
boot_sched_4 db 'Building syscall interrupt table',0
endg
 
 
build_scheduler:
; { Ivan 06.03.2005
mov edi, usedi40
mov ecx, 256/4
xor eax, eax
rep stosd
; } Ivan 06.03.2005
 
mov esi,boot_sched_1
call boot_log
call build_process_gdt_tss_pointer
 
; mov esi,boot_sched_2
; call boot_log
; call build_process_gdt_gate_pointer
 
mov esi,boot_sched_3
call boot_log
call build_interrupt_table
 
mov esi,boot_sched_4
call boot_log
call build_syscall_interrupt_table
 
ret
 
/kernel/trunk/core/syscall.inc
0,0 → 1,238
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSTEM CALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
i40:
cli
 
mov edi,[0x3000]
mov eax,edi
shl edi, 3
;clear busy flag in application's TSS
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
;save GDT TSS entry
mov edx,[edi+tss0_l]
mov [reg1+eax*4],edx
mov edx,[edi+tss0_l+4]
mov [reg2+eax*4],edx
;and then write there i40's descriptor
mov edx,[tss0sys_l+edi]
mov [edi+tss0_l],edx
mov edx,[tss0sys_l+edi+4]
mov [edi+tss0_l+4],edx
 
 
shl edi,5
mov [edi+0x80000+0xB0],eax ; used i40 handler
 
; for syscall trace function
call save_registers
 
mov esi, [0x3000]
imul esi, tss_step
add esi, tss_data
; esi holds address of TSS of interupted program
; load first 3 registers
mov eax,[esi+l.eax-tss_sceleton]
mov ebx,[esi+l.ebx-tss_sceleton]
mov ecx,[esi+l.ecx-tss_sceleton]
 
; save current registers
; stack may be modified by a system function to return some value to caller!
pushad
 
; load all registers from TSS of the application, in crossed order (why?)
mov edi,[esi+l.eax-tss_sceleton]
mov eax,[esi+l.ebx-tss_sceleton]
mov ebx,[esi+l.ecx-tss_sceleton]
mov ecx,[esi+l.edx-tss_sceleton]
mov edx,[esi+l.esi-tss_sceleton]
mov esi,[esi+l.edi-tss_sceleton]
 
; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler
sti
; eax doesn't need to be saved, but...
push eax
and edi,0xff
call dword [servetable+edi*4]
pop eax
cli
; return saved and probably even changed regs
popad
 
; <Ivan 05.03.2005> esi already loaded - look above "pusha"
;mov esi,[0x3000]
;imul esi,tss_step
;add esi,tss_data
; </Ivan 05.03.2005>
 
; modify 3 program's registers (in its TSS)
mov [esi+l.eax-tss_sceleton], eax
mov [esi+l.ebx-tss_sceleton], ebx
mov [esi+l.ecx-tss_sceleton], ecx
 
; calculate app's TSS address
mov ebx, [0x3000]
shl ebx, 3
add ebx, tss0_l
 
mov ecx, [0x3000]
 
; restore saved TSS descriptor
mov eax, [reg1+ecx*4]
mov [ebx], eax
mov eax, [reg2+ecx*4]
mov [ebx+4], eax
 
xor eax, eax
mov edi, [0x3000] ; no syscall interrupt in use anymore
shl edi, 8
mov [edi+0x80000+0xB0],eax
 
; clear busy flag in TSS of this handler
mov edi, [0x3000]
shl edi, 3
mov [edi+tss0sys_l +5], word 01010000b *256 +11101001b
 
add edi,tss0
mov [0xB004], di
 
jmp pword [0xB000]
 
jmp i40
 
label reg1 dword at 0x6000
label reg2 dword at 0x6400
label usedi40 byte at 0x6800
 
uglobal
schd dd 0x0
endg
 
align 4
save_registers:
 
mov esi,[0x3000]
imul esi,tss_step
add esi,tss_data
 
mov eax,[esi+l.eax-tss_sceleton]
mov ebx,[esi+l.ebx-tss_sceleton]
mov ecx,[esi+l.ecx-tss_sceleton]
mov edx,[esi+l.edx-tss_sceleton]
mov edi,[esi+l.edi-tss_sceleton]
mov ebp,[esi+l.ebp-tss_sceleton]
 
mov esi,[esi+l.esi-tss_sceleton]
 
push eax ecx esi edi
mov esi,[0x3010]
mov eax,[esi+0x4]
mov esi,esp
inc [save_syscall_count]
mov edi,[save_syscall_count]
and edi,0xF
shl edi,6
add edi,save_syscall_data+32
mov [edi-32],eax
mov ecx,32 / 4
cld
rep movsd
pop edi esi ecx eax
ret
 
uglobal
save_syscall_count dd 0x0
endg
 
label save_syscall_data dword at 0x5000
 
 
iglobal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYSTEM FUNCTIONS TABLE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
servetable:
 
dd sys_drawwindow ; 0-DrawWindow
dd syscall_setpixel ; 1-SetPixel
dd sys_getkey ; 2-GetKey
dd sys_clock ; 3-GetTime
dd syscall_writetext ; 4-WriteText
dd delay_hs ; 5-DelayHs
dd syscall_openramdiskfile ; 6-OpenRamdiskFile
dd syscall_putimage ; 7-PutImage
dd sys_button ; 8-DefineButton
dd sys_cpuusage ; 9-GetProcessInfo
dd sys_waitforevent ; 10-WaitForEvent
dd sys_getevent ; 11-CheckForEvent
dd sys_redrawstat ; 12-BeginDraw and EndDraw
dd syscall_drawrect ; 13-DrawRect
dd syscall_getscreensize ; 14-GetScreenSize
dd sys_background ; 15-bgr
dd sys_cachetodiskette ; 16-FlushFloppyCache
dd sys_getbutton ; 17-GetButton
dd syscall_system ; 18-Shutdown,KillApp,WindowActivate
dd syscall_startapp ; 19-StartApp
dd sys_midi ; 20-ResetMidi and OutputMidi
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,.
dd sys_settime ; 22-setting date,time,clock and alarm-clock
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist
dd sys_sb16 ; 25-SetSb16
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
dd sys_wss ; 27-SetWssMainVol and SetWssCdVol
dd sys_sb16II ; 28-SetSb16
dd sys_date ; 29-GetDate
dd syscall_readhd ; 30-ReadHd
dd syscall_starthdapp ; 31-StartHdApp
dd syscall_delramdiskfile ; 32-DelRamdiskFile
dd syscall_writeramdiskfile; 33-WriteRamdiskFile
dd read_floppy_file ; 34-ReadFloppyDrive
dd syscall_getpixel ; 35-GetPixel
dd syscall_readstring ; 36-ReadString (not yet ready)
dd readmousepos ; 37-GetMousePosition_ScreenRelative,.
dd syscall_drawline ; 38-DrawLine
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,.
dd set_app_param ; 40-WantEvents
dd syscall_getirqowner ; 41-GetIrqOwner
dd get_irq_data ; 42-ReadIrqData
dd sys_outport ; 43-SendDeviceData
dd sys_programirq ; 44-ProgramIrqs
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea
dd display_number ; 47-WriteNum
dd display_settings ; 48-SetRedrawType and SetButtonType
dd syscall_appints ; 49-AppInts
dd random_shaped_window ; 50-Window shape & scale
dd syscall_threads ; 51-Threads
dd stack_driver_stat ; 52-Stack driver status
dd socket ; 53-Socket interface
dd user_events ; 54-User events
dd sound_interface ; 55-Sound interface
dd write_to_hd ; 56-Write a file to hd
dd delete_from_hd ; 57-Delete a file from hd
dd file_system ; 58-Common file system interface
dd sys_trace ; 59-System call trace
dd new_sys_ipc ; 60-Inter Process Communication
dd sys_gs ; 61-Direct graphics access
dd sys_pci ; 62-PCI functions
dd sys_msg_board ; 63-System message board
dd sys_resize_app_memory ; 64-Resize application memory usage
dd undefined_syscall ; 65-UTF
dd sys_process_def ; 66-Process definitions - keyboard
dd sys_window_move ; 67-Window move or resize
dd sys_internal_services ; 68-Some internal services
 
times 255 - ( ($-servetable) /4 ) dd undefined_syscall
 
dd sys_end ; -1-end application
endg
 
/kernel/trunk/detect/commouse.inc
0,0 → 1,121
;**************************************************
;* ÏÎÈÑÊ ÌÛØÈ ÏÎ ÏÎÑËÅÄÎÂÀÒÅËÜÍÛÌ ÏÎÐÒÀÌ *
;* Ïðîöåäóðà ïîäãîòàâëèâàåò ãëîáàëüíûå ïåðåìåííûå *
;* COMPortNum è COMPortBaseAddr äëÿ ïîäïðîãðàììû *
;* óñòàíîâêè îáðàáîò÷èêà ïðåðûâàíèÿ *
;**************************************************
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; Àäàïòàöèÿ è äîðàáîòêà Mario79
 
MSMouseSearch:
pusha
; Çàïðåòèòü ïðåðûâàíèå COM1 è COM2
cli
in AL,21h ;ïðî÷èòàòü ìàñêó ïðåðûâàíèé
or AL,18h ;çàïðåòèòü IRQ3 è IRQ4
out 21h,AL ;çàìåíèòü ìàñêó
sti
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ
MouseSearch:
; Óñòàíàâëèâàåì ñêîðîñòü
; ïðèåìà/ïåðåäà÷è 1200 áîä
mov DX,[COMPortBaseAddr]
add DX,3
in AL,DX
or AL,80h ;óñòàíîâèòü áèò DLAB
out DX,AL
mov DX,[COMPortBaseAddr]
mov AL,60h ;1200 áîä
out DX,AL
inc DX
mov AL,0
out DX,AL
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò,
; ÷åòíîñòü íå êîíòðîëèðîâàòü
mov DX,[COMPortBaseAddr]
add DX,3
mov AL,00000010b
out DX,AL
; Çàïðåòèòü âñå ïðåðûâàíèÿ
mov DX,[COMPortBaseAddr]
inc DX
mov AL,0
out DX,AL
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñÿ
; ìûøüþ òèïà MSMouse
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíèÿ
mov DX,[COMPortBaseAddr]
add DX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2
out DX,AL
; Îæèäàòü 5 "òèêîâ" (0,2 ñ)
mov ecx,0xffff
dT_1:
dec ecx
cmp ecx,0
jne dT_1
mov ecx,0xffff
; Âêëþ÷èòü ïèòàíèå ìûøè
mov AL,11b ;óñòàíîâèòü DTR è RTS
out DX,AL
; Î÷èñòèòü ðåãèñòð äàííûõ
mov DX,[COMPortBaseAddr]
in AL,DX
; Öèêë îïðîñà ïîðòà
WaitData:
; Îæèäàòü åùå 10 "òèêîâ"
dec ecx
cmp ecx,0
je NoMouse
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà
mov DX,[COMPortBaseAddr]
add DX,5
in AL,DX
test AL,1 ;Äàííûå ãîòîâû?
jz WaitData
; Ââåñòè äàííûå
mov DX,[COMPortBaseAddr]
in AL,DX
; Óñòðîéñòâî ÿâëÿåòñÿ ìûøüþ?
cmp AL,'M'
je EndDetect
NoMouse:
inc [COMPortNum]
cmp [COMPortNum],1
ja EndDetect
sub [COMPortBaseAddr],100h
jmp MouseSearch
 
iglobal
COMPortBaseAddr dw 3F8h
COMPortNum dw 0
endg
 
iglobal
boot_setmouse_type db 'No COM mouse, set PS2',0
db 'Detected - COM1 mouse',0
db 'Detected - COM2 mouse',0
endg
 
EndDetect:
cmp [COMPortNum],0 ;íîìåð ïîðòà ìåíüøå 0?
jl ComMouseNotFound ;ìûøü íå íàéäåíà
cmp [COMPortNum],1 ;íîìåð ïîðòà áîëüøå 1?
ja ComMouseNotFound ;ìûøü íå íàéäåíà
mov ax,[COMPortNum]
add al,2
jmp set_detecting_mouse
ComMouseNotFound:
mov al,1
set_detecting_mouse:
mov [0xF604],al
dec al
movzx eax,al
imul eax,22
mov esi,boot_setmouse_type
add esi,eax
call boot_log
popa
 
 
/kernel/trunk/detect/dev_fd.inc
0,0 → 1,20
;***************************************************
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD
; àâòîð Mario79
;***************************************************
xor eax,eax
mov edi,0x40000
mov ecx,16384
cld
rep stosd
 
mov al,0x10
out 0x70,al
mov cx,0xff
wait_cmos:
dec cx
cmp cx,0
jne wait_cmos
in al,0x71
mov [0x40000],al
/kernel/trunk/detect/dev_hdcd.inc
0,0 → 1,374
;******************************************************
; ïîèñê ïðèâîäîâ HDD è CD
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; àäàïòàöèÿ è äîðàáîòêà Mario79
;******************************************************
 
;****************************************************
;* ÏÎÈÑÊ HDD è CD *
;****************************************************
FindHDD:
mov [ChannelNumber],1
mov [DiskNumber],0
call FindHDD_3
; mov ax,[Sector512+176]
; mov [0x40006],ax
; mov ax,[Sector512+126]
; mov [0x40008],ax
; mov ax,[Sector512+128]
; mov [0x40008],ax
mov [DiskNumber],1
call FindHDD_3
; mov al,[Sector512+176]
; mov [0x40007],al
inc [ChannelNumber]
mov [DiskNumber],0
call FindHDD_3
; mov al,[Sector512+176]
; mov [0x40008],al
mov [DiskNumber],1
call FindHDD_1
; mov al,[Sector512+176]
; mov [0x40009],al
jmp EndFindHDD
 
FindHDD_1:
call ReadHDD_ID
cmp [DevErrorCode],0
jne FindHDD_2
cmp [Sector512+6],word 16
ja FindHDD_2
cmp [Sector512+12],word 255
ja FindHDD_2
inc byte [0x40001]
jmp FindHDD_2_2
FindHDD_2:
call DeviceReset
cmp [DevErrorCode],0
jne FindHDD_2_2
call ReadCD_ID
cmp [DevErrorCode],0
jne FindHDD_2_2
inc byte [0x40001]
inc byte [0x40001]
FindHDD_2_2:
ret
 
FindHDD_3:
call FindHDD_1
shl byte [0x40001],2
ret
 
 
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA
SectorAddress DD ?
 
;*************************************************
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà íà êàíàëå (0 èëè 1). *
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ *
;* â ìàññèâ Sector512. *
;*************************************************
ReadHDD_ID:
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà
mov [ATAFeatures],0
mov [ATAHead],0
mov [ATACommand],0ECh
call SendCommandToHDD
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jne @@End ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
mov DX,[ATABasePortAddr]
add DX,7 ;àäðåñ ðåãèñòðà ñîñòîÿíèÿ
mov ecx,0xffff
@@WaitCompleet:
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
dec ecx
cmp ecx,0
je @@Error1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitCompleet
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Error6
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitCompleet
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
; mov AX,DS
; mov ES,AX
mov EDI,Sector512 ;offset Sector512
mov DX,[ATABasePortAddr] ;ðåãèñòð äàííûõ
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ
rep insw ;ïðèíÿòü áëîê äàííûõ
jmp @@End
; Çàïèñàòü êîä îøèáêè
@@Error1:
mov [DevErrorCode],1
jmp @@End
@@Error6:
mov [DevErrorCode],6
@@End: ret
 
 
 
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2
StandardATABases DW 1F0h, 170h
; Íîìåð êàíàëà
ChannelNumber DW ?
; Íîìåð äèñêà
DiskNumber DB ?
; Áàçîâûé àäðåñ ãðóïïû ïîðòîâ êîíòðîëëåðà ATA
ATABasePortAddr DW ?
; Ïàðàìåòðû ATA-êîìàíäû
ATAFeatures DB ? ;îñîáåííîñòè
ATASectorCount DB ? ;êîëè÷åñòâî îáðàáàòûâàåìûõ ñåêòîðîâ
ATASectorNumber DB ? ;íîìåð íà÷àëüíîãî ñåêòîðà
ATACylinder DW ? ;íîìåð íà÷àëüíîãî öèëèíäðà
ATAHead DB ? ;íîìåð íà÷àëüíîé ãîëîâêè
ATAAddressMode DB ? ;ðåæèì àäðåñàöèè (0 - CHS, 1 - LBA)
ATACommand DB ? ;êîä êîìàíäû, ïîäëåæàùåé âûïîëíåíèþ
; Êîä îøèáêè (0 - íåò îøèáîê, 1 - ïðåâûøåí äîïóñòèìûé
; èíòåðâàë îæèäàíèÿ, 2 - íåâåðíûé êîä ðåæèìà àäðåñàöèè,
; 3 - íåâåðíûé íîìåð êàíàëà, 4 - íåâåðíûé íîìåð äèñêà,
; 5 - íåâåðíûé íîìåð ãîëîâêè, 6 - îøèáêà ïðè âûïîëíåíèè
; êîìàíäû)
DevErrorCode DB ?
 
;****************************************************
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà (0 èëè 1); *
;* ATAFeatures - "îñîáåííîñòè"; *
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; *
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; *
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; *
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; *
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); *
;* ATACommand - êîä êîìàíäû. *
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: *
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; *
;* â DevErrorCode - íîëü. *
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò *
;* âîçâðàùåí êîä îøèáêè. *
;****************************************************
SendCommandToHDD:
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
cmp [ATAAddressMode],1
ja @@Err2
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
mov BX,[ChannelNumber]
cmp BX,1
jb @@Err3
cmp BX,2
ja @@Err3
; Óñòàíîâèòü áàçîâûé àäðåñ
dec BX
shl BX,1
movzx ebx,bx
mov AX,[ebx+StandardATABases]
mov [ATABasePortAddr],AX
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû
; Âûáðàòü íóæíûé äèñê
mov DX,[ATABasePortAddr]
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL,[DiskNumber]
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà
ja @@Err4
shl AL,4
or AL,10100000b
out DX,AL
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ
inc DX
mov ecx,0xfff
; mov eax,[timer_ticks]
; mov [TickCounter_1],eax
@@WaitHDReady:
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
dec ecx
cmp ecx,0
je @@Err1
; mov eax,[timer_ticks]
; sub eax,[TickCounter_1]
; cmp eax,300 ;îæèäàòü 300 òèêîâ
; ja @@Err1 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
in AL,DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
test AL,80h
jnz @@WaitHDReady
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
test AL,08h
jnz @@WaitHDReady
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
cli
mov DX,[ATABasePortAddr]
inc DX ;ðåãèñòð "îñîáåííîñòåé"
mov AL,[ATAFeatures]
out DX,AL
inc DX ;ñ÷åò÷èê ñåêòîðîâ
mov AL,[ATASectorCount]
out DX,AL
inc DX ;ðåãèñòð íîìåðà ñåêòîðà
mov AL,[ATASectorNumber]
out DX,AL
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò)
mov AX,[ATACylinder]
out DX,AL
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò)
mov AL,AH
out DX,AL
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà
mov AL,[DiskNumber]
shl AL,4
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè
ja @@Err5
or AL,[ATAHead]
or AL,10100000b
mov AH,[ATAAddressMode]
shl AH,6
or AL,AH
out DX,AL
; Ïîñëàòü êîìàíäó
mov AL,[ATACommand]
inc DX ;ðåãèñòð êîìàíä
out DX,AL
sti
; Ñáðîñèòü ïðèçíàê îøèáêè
mov [DevErrorCode],0
jmp @@End_2
; Çàïèñàòü êîä îøèáêè
@@Err1: mov [DevErrorCode],1
jmp @@End_2
@@Err2: mov [DevErrorCode],2
jmp @@End_2
@@Err3: mov [DevErrorCode],3
jmp @@End_2
@@Err4: mov [DevErrorCode],4
jmp @@End_2
@@Err5: mov [DevErrorCode],5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
@@End_2:
ret
 
;*************************************************
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÓÑÒÐÎÉÑÒÂÀ ATAPI *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ *
;* â ìàññèâ Sector512. *
;*************************************************
ReadCD_ID:
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
mov [ATACylinder],0
mov [ATAHead],0
mov [ATACommand],0A1h
call SendCommandToHDD
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jne @@End_1 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov ecx,0xffff
@@WaitCompleet_1:
; Ïðîâåðèòü âðåìÿ
dec ecx
cmp ecx,0
je @@Error1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitCompleet_1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Error6_1
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitCompleet_1
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
; mov AX,DS
; mov ES,AX
mov EDI,Sector512 ;offset Sector512
mov DX,[ATABasePortAddr] ;ïîðò 1x0h
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ
rep insw
jmp @@End_1
; Çàïèñàòü êîä îøèáêè
@@Error1_1:
mov [DevErrorCode],1
jmp @@End_1
@@Error6_1:
mov [DevErrorCode],6
@@End_1:
ret
 
;*************************************************
;* ÑÁÐÎÑ ÓÑÒÐÎÉÑÒÂÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà (0 èëè 1). *
;*************************************************
DeviceReset:
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
mov BX,[ChannelNumber]
cmp BX,1
jb @@Err3_2
cmp BX,2
ja @@Err3_2
; Óñòàíîâèòü áàçîâûé àäðåñ
dec BX
shl BX,1
movzx ebx,bx
mov DX,[ebx+StandardATABases]
mov [ATABasePortAddr],DX
; Âûáðàòü íóæíûé äèñê
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL,[DiskNumber]
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà
ja @@Err4_2
shl AL,4
or AL,10100000b
out DX,AL
; Ïîñëàòü êîìàíäó "Ñáðîñ"
mov AL,08h
inc DX ;ðåãèñòð êîìàíä
out DX,AL
mov ecx,0xffff
@@WaitHDReady_1:
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
dec ecx
cmp ecx,0
je @@Err1_2 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
in AL,DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
test AL,80h
jnz @@WaitHDReady_1
; Ñáðîñèòü ïðèçíàê îøèáêè
mov [DevErrorCode],0
jmp @@End_3
; Îáðàáîòêà îøèáîê
@@Err1_2: mov [DevErrorCode],1
jmp @@End_3
@@Err3_2: mov [DevErrorCode],3
jmp @@End_3
@@Err4_2: mov [DevErrorCode],4
; Çàïèñàòü êîä îøèáêè
@@End_3:
ret
 
EndFindHDD:
 
/kernel/trunk/detect/disks.inc
0,0 → 1,4
include 'dev_fd.inc'
include 'dev_hdcd.inc'
include 'sear_par.inc'
 
/kernel/trunk/detect/sear_par.inc
0,0 → 1,116
;****************************************************
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû
; àâòîð Mario79
;****************************************************
mov [transfer_adress],0x4000a
search_partitions_ide0:
test [0x40001],byte 0x40
jz search_partitions_ide1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [fat32part],1
search_partitions_ide0_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide1
inc byte [0x40002]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide0_1
 
search_partitions_ide1:
test [0x40001],byte 0x10
jz search_partitions_ide2
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [fat32part],1
search_partitions_ide1_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide2
inc byte [0x40003]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide1_1
 
search_partitions_ide2:
test [0x40001],byte 0x4
jz search_partitions_ide3
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [fat32part],1
search_partitions_ide2_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide3
inc byte [0x40004]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide2_1
 
search_partitions_ide3:
test [0x40001],byte 0x1
jz end_search_partitions_ide
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [fat32part],1
search_partitions_ide3_1:
call set_FAT32_variables
cmp [problem_partition],0
jne end_search_partitions_ide
inc byte [0x40005]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide3_1
 
partition_data_transfer:
mov edi,[transfer_adress]
mov esi,PARTITION_START
xor ecx,ecx
mov cx,69 ;100
rep movsb
ret
transfer_adress dd 0
partition_data_transfer_1:
cli
mov edi,PARTITION_START
mov esi,[transfer_adress]
xor ecx,ecx
mov cx,69 ;100
rep movsb
sti
ret
 
end_search_partitions_ide:
 
;PARTITION_START dd 0x3f
;PARTITION_END dd 0
;SECTORS_PER_FAT dd 0x1f3a
;NUMBER_OF_FATS dd 0x2
;SECTORS_PER_CLUSTER dd 0x8
;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
;ROOT_CLUSTER dd 2 ; first rootdir cluster
;FAT_START dd 0 ; start of fat table
;ROOT_START dd 0 ; start of rootdir (only fat16)
;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
;DATA_START dd 0 ; start of data area (=first cluster 2)
;LAST_CLUSTER dd 0 ; last availabe cluster
;ADR_FSINFO dd 0 ; used only by fat32
;
;fatRESERVED dd 0x0FFFFFF6
;fatBAD dd 0x0FFFFFF7
;fatEND dd 0x0FFFFFF8
;fatMASK dd 0x0FFFFFFF
;
;fat_type db 0 ; 0=none, 16=fat16, 32=fat32
 
/kernel/trunk/fs/fat12.inc
0,0 → 1,1084
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; FAT12.INC ;;
;; (C) 2005 Mario79, License: GPL ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
n_sector dd 0 ; temporary save for sector value
flp_status dd 0
clust_tmp_flp dd 0 ; used by analyze_directory and analyze_directory_to_write
path_pointer_flp dd 0
pointer_file_name_flp dd 0
save_root_flag db 0
save_flag db 0
root_read db 0 ; 0-necessary to load root, 1-not to load root
flp_fat db 0 ; 0-necessary to load fat, 1-not to load fat
flp_number db 0 ; 1- Floppy A, 2-Floppy B
old_track db 0 ; old value track
flp_label rb 15 ; Label and ID of inserted floppy disk
 
reserve_flp:
 
cli
cmp [flp_status],0
je reserve_flp_ok
 
sti
call change_task
jmp reserve_flp
 
reserve_flp_ok:
 
push eax
mov eax,[0x3000]
shl eax,5
mov eax,[eax+0x3000+4]
mov [flp_status],eax
pop eax
sti
ret
 
floppy_free_space:
;---------------------------------------------
;
; returns free space in edi
;
;---------------------------------------------
push eax ebx ecx
call read_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_2
mov eax,0x282000
xor edi,edi
mov ecx,2847 ;1448000/512
rdfs1_1:
mov ebx,[eax]
and ebx,4095
cmp ebx,0
jne rdfs2_1
add edi,512
rdfs2_1:
add eax,2
loop rdfs1_1
fdc_status_error_2:
pop ecx ebx eax
ret
 
 
floppy_fileread:
;----------------------------------------------------------------
;
; fileread - sys floppy
;
; eax points to filename 11 chars - for root directory
; ebx first wanted block ; 1+ ; if 0 then set to 1
; ecx number of blocks to read ; 1+ ; if 0 then set to 1
; edx mem location to return data
; esi length of filename 12*X
; edi pointer to path /fd/1/...... - for all files in nested directories
;
; ret ebx = size or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
; 10 = access denied
;--------------------------------------------------------------
 
mov [save_flag],0
mov [path_pointer_flp],edi
cmp esi,0 ; return ramdisk root
jne fr_noroot_1
cmp ebx,224/16
jbe fr_do_1
mov eax,5
mov ebx,0
mov [flp_status],0
ret
 
fr_do_1:
push ebx ecx edx
call read_flp_root
pop edx ecx ebx
cmp [FDC_Status],0
jne fdc_status_error_1
mov edi,edx
dec ebx
shl ebx,9
mov esi,0x8000
add esi,ebx
shl ecx,9
cld
rep movsb
mov eax,0 ; ok read
mov ebx,0
mov [flp_status],0
ret
fdc_status_error_1:
mov [flp_status],0
mov eax,10
mov ebx,-1
ret
 
fr_noroot_1:
sub esp,32
call expand_filename
frfloppy_1:
cmp ebx,0
jne frfl5_1
mov ebx,1
frfl5_1:
cmp ecx,0
jne frfl6_1
mov ecx,1
frfl6_1:
dec ebx
push eax
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
call SeekTrack
mov dh,14
l.20_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov dl,16
mov edi,0xD000
inc [FDD_Sector]
l.21_1:
mov esi,eax ;Name of file we want
mov ecx,11
cld
rep cmpsb ;Found the file?
je fifound_1 ;Yes
add ecx,21
add edi, ecx ;Advance to next entry
dec dl
cmp dl,0
jne l.21_1
dec dh
cmp dh,0
jne l.20_1
fdc_status_error_3:
mov eax,5 ; file not found ?
mov ebx,-1
add esp,32+28
mov [flp_status],0
ret
fdc_status_error_3_2:
cmp [FDC_Status],0
je fdc_status_error_3
fdc_status_error_3_1:
add esp,32+28
jmp fdc_status_error_1
 
fifound_1:
mov eax,[path_pointer_flp]
cmp [eax+36],byte 0
je fifound_2
add edi,0xf
mov eax,[edi]
and eax,65535
mov ebx,[path_pointer_flp]
add ebx,36
call get_cluster_of_a_path_flp
jc fdc_status_error_3_2
mov ebx,[ebx-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
jmp fifound_3
fifound_2:
mov ebx,[edi-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
add edi,0xf
mov eax,[edi]
fifound_3:
and eax,65535
mov [n_sector],eax ;eax=cluster
frnew_1:
add eax,31 ;bootsector+2*fat+filenames
cmp [esp+16],dword 0 ; wanted cluster ?
jne frfl7_1
call read_chs_sector
cmp [FDC_Status],0
jne fdc_status_error_5
mov edi,[esp+8]
call give_back_application_data_1
add [esp+8],dword 512
dec dword [esp+12] ; last wanted cluster ?
cmp [esp+12],dword 0
je frnoread_1
jmp frfl8_1
frfl7_1:
dec dword [esp+16]
frfl8_1:
mov edi,[n_sector]
shl edi,1 ;find next cluster from FAT
add edi,0x282000
mov eax,[edi]
and eax,4095
mov edi,eax
mov [n_sector],edi
cmp edi,4095 ;eof - cluster
jz frnoread2_1
cmp [esp+24],dword 512 ;eof - size
jb frnoread_1
sub [esp+24],dword 512
jmp frnew_1
 
read_chs_sector:
call calculate_chs
call ReadSectWithRetr
ret
 
frnoread2_1:
cmp [esp+16],dword 0 ; eof without read ?
je frnoread_1
mov [fdc_irq_func],fdc_null
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,6 ; end of file
mov [flp_status],0
ret
 
frnoread_1:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,0
mov [flp_status],0
ret
 
fdc_status_error_5:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
jmp fdc_status_error_1
 
read_flp_root:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_root_read
cmp [root_read],1
je unnecessary_root_read
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,0x8000
call SeekTrack
read_flp_root_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_root_read
push edi
call give_back_application_data_1
pop edi
add edi,512
inc [FDD_Sector]
cmp [FDD_Sector],16
jne read_flp_root_1
mov [root_read],1
unnecessary_root_read:
popa
ret
 
 
read_flp_fat:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_flp_fat
cmp [flp_fat],1
je unnecessary_flp_fat
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,0x8000
call SeekTrack
read_flp_fat_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat
push edi
call give_back_application_data_1
pop edi
add edi,512
inc [FDD_Sector]
cmp [FDD_Sector],19
jne read_flp_fat_1
mov [FDD_Sector],1
mov [FDD_Head],1
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat
call give_back_application_data_1
call calculatefatchain_flp
mov [root_read],0
mov [flp_fat],1
unnecessary_flp_fat:
popa
ret
 
calculatefatchain_flp:
pushad
 
mov esi,0x8000
mov edi,0x282000
 
fcnew_1:
mov eax,dword [esi]
mov ebx,dword [esi+4]
mov ecx,dword [esi+8]
mov edx,ecx
shr edx,4 ;8 ok
shr dx,4 ;7 ok
xor ch,ch
shld ecx,ebx,20 ;6 ok
shr cx,4 ;5 ok
shld ebx,eax,12
and ebx,0x0fffffff ;4 ok
shr bx,4 ;3 ok
shl eax,4
and eax,0x0fffffff ;2 ok
shr ax,4 ;1 ok
mov dword [edi],eax
add edi,4
mov dword [edi],ebx
add edi,4
mov dword [edi],ecx
add edi,4
mov dword [edi],edx
add edi,4
add esi,12
 
cmp edi,0x282000+2856*2 ;2849 clusters
jnz fcnew_1
 
popad
ret
check_label:
pushad
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],1 ; Ñåêòîð
call SetUserInterrupts
call FDDMotorON
call RecalibrateFDD
cmp [FDC_Status],0
jne fdc_status_error
call SeekTrack
cmp [FDC_Status],0
jne fdc_status_error
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error
mov esi,flp_label
mov edi,0xD000+39
mov ecx,15
cld
rep cmpsb
je same_label
mov [root_read],0
mov [flp_fat],0
same_label:
mov esi,0xD000+39
mov edi,flp_label
mov ecx,15
cld
rep movsb
popad
ret
fdc_status_error:
popad
ret
 
save_flp_root:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_root_save
cmp [root_read],0
je unnecessary_root_save
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,0x8000
call SeekTrack
save_flp_root_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_root_save
inc [FDD_Sector]
cmp [FDD_Sector],16
jne save_flp_root_1
unnecessary_root_save:
mov [fdc_irq_func],fdc_null
popa
ret
save_flp_fat:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
cmp [flp_fat],0
je unnecessary_flp_fat_save
call restorefatchain_flp
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,0x8000
call SeekTrack
save_flp_fat_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
inc [FDD_Sector]
cmp [FDD_Sector],19
jne save_flp_fat_1
mov [FDD_Sector],1
mov [FDD_Head],1
call take_data_from_application_1
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
mov [root_read],0
unnecessary_flp_fat_save:
mov [fdc_irq_func],fdc_null
popa
ret
 
restorefatchain_flp: ; restore fat chain
pushad
 
mov esi,0x282000
mov edi,0x8000
 
fcnew2_1:
mov eax,dword [esi]
mov ebx,dword [esi+4]
shl ax,4
shl eax,4
shl bx,4
shr ebx,4
shrd eax,ebx,8
shr ebx,8
mov dword [edi],eax
add edi,4
mov word [edi],bx
add edi,2
add esi,8
 
cmp edi,0x8000+0x1200 ;4274 bytes - all used FAT
jb fcnew2_1
 
mov esi,0x8000 ; duplicate fat chain
mov edi,0x8000+0x1200
mov ecx,0x1200/4
cld
rep movsd
 
popad
ret
 
 
floppy_filedelete:
;--------------------------------------------
;
; filedelete - sys floppy
; in:
; eax - filename 11 chars - for root directory
; edi pointer to path /fd/1/...... - for all files in nested directories
;
; out:
; eax - 0 = successful, 1 = file not found, 10 = access denied
;
;--------------------------------------------
mov [path_pointer_flp],edi
mov [save_flag],0
mov ebp,1 ; file not found as default
filedelete_newtry_1:
sub esp,32
call expand_filename
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status],0
jne frnoreadd_1
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
call SeekTrack
mov dh,14
l.20_2:
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_4
mov dl,16
mov edi,0xD000
inc [FDD_Sector]
l.21_2:
mov esi,eax ;Name of file we want
mov ecx,11
cld
rep cmpsb ;Found the file?
je fifoundd_1 ;Yes
add ecx,21
add edi, ecx ;Advance to next entry
dec dl
cmp dl,0
jne l.21_2
dec dh
cmp dh,0
jne l.20_2
jmp frnoreadd_1
 
fdc_status_error_4:
pop edi esi edx ecx ebx eax
add esp,32
jmp fdc_status_error_1
 
fifoundd_1:
mov eax,[path_pointer_flp]
cmp [eax+36],byte 0
je fifoundd_2
add edi,0xf
mov eax,[edi]
and eax,65535
mov ebx,[path_pointer_flp]
add ebx,36
call get_cluster_of_a_path_flp
jc frnoreadd_1_1
mov edi,ebx
add edi,11
jmp fifoundd_2_1
fifoundd_2:
dec [FDD_Sector]
fifoundd_2_1:
mov [edi-11],byte 0xE5 ;mark filename deleted
add edi,0xf
mov eax,[edi]
and eax,65535
mov edi,eax ;edi = cluster
frnewd_1:
shl edi,1 ;find next cluster from FAT
add edi,0x282000
mov eax,[edi]
mov [edi],word 0x0 ;clear fat chain cluster
and eax,4095
mov edi,eax
cmp edi,dword 4095 ;last cluster ?
jz frnoreadd2_1
jmp frnewd_1
 
frnoreadd2_1:
call WriteSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_4
call save_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_4
; pop edi esi edx ecx ebx eax
; add esp,32
mov ebp,0 ; file found
; jmp filedelete_newtry_1
jmp frnoreadd_1
 
frnoreadd_1_1:
cmp [FDC_Status],0
jne fdc_status_error_4
frnoreadd_1:
pop edi esi edx ecx ebx eax
add esp,32
mov eax,ebp
ret
 
floppy_filesave:
;----------------------------------------------------------
;
; filesave - sys floppy
;
; eax ; pointer to file name 11 chars - for root directory
; ebx ; buffer
; ecx ; count to write in bytes
; edx ; 0 create new , 1 append
; edi pointer to path /fd/1/...... - for all files in nested directories
;
; output : eax = 0 - ok
; 5 - file not found / directory not found
; 8 - disk full
; 10 - access denied
;-----------------------------------------------------------
mov [path_pointer_flp],edi
sub esp,32
call expand_filename
cmp edx,0
jnz fsdel_1
pusha
call floppy_filedelete
cmp [FDC_Status],0
jne fdc_status_error_6
popa
mov [save_flag],1
fsdel_1:
call floppy_free_space
cmp [FDC_Status],0
jne fdc_status_error_6
cmp ecx,edi
jb rd_do_save_1
add esp,32
mov eax,8 ; not enough free space
mov [flp_status],0
ret
 
fdc_status_error_6:
popa
add esp,32
jmp fdc_status_error_1
rd_do_save_1:
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_7
push eax
mov eax,[path_pointer_flp]
cmp [eax+36],byte 0
jne fifoundds_2
pop eax
mov [save_root_flag],1
call read_flp_root
cmp [FDC_Status],0
jne fdc_status_error_7
mov edi,0x8000 ;Point at directory
mov edx,224 +1
; find an empty spot for filename in the root dir
l20ds_1:
sub edx,1
cmp edx,0
jnz l21ds_1
jmp frnoreadds_1
l21ds_1:
cmp [edi],byte 0xE5
jz fifoundds_1
cmp [edi],byte 0x0
jz fifoundds_1
add edi,32 ; Advance to next entry
jmp l20ds_1
 
fifoundds_2:
pop eax
mov [save_root_flag],0
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
call SeekTrack
mov dh,14
l.20_3:
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_7
mov dl,16
mov edi,0xD000
inc [FDD_Sector]
l.21_3:
mov esi,eax ;Name of file we want
mov ecx,11
cld
rep cmpsb ;Found the file?
je fifoundds_3 ;Yes
add ecx,21
add edi, ecx ;Advance to next entry
dec dl
cmp dl,0
jne l.21_3
dec dh
cmp dh,0
jne l.20_3
fdc_status_error_8:
pop edi esi edx ecx ebx eax
mov eax,5 ; file not found ?
mov ebx,-1
add esp,32
mov [flp_status],0
ret
 
fifoundds_3:
add edi,0xf
mov eax,[edi]
and eax,65535
mov ebx,[path_pointer_flp]
add ebx,36
call get_cluster_of_a_path_flp
jc fdc_status_error_7_1
found_directory_for_writing_flp:
call analyze_directory_to_write_flp
jc fdc_status_error_7_1
mov edi,ebx
fifoundds_1:
push edi ; move the filename to root dir
mov esi,[esp+4+20]
cmp [save_root_flag],0
jne fifoundds_4
mov esi,[pointer_file_name_flp]
fifoundds_4:
mov ecx,11
cld
rep movsb
pop edi
mov edx,edi
add edx,11+0xf ; edx <- cluster save position
mov ebx,[esp+12] ; save file size
mov [edi+28],ebx
mov [edi+11],byte 0x20 ; attribute
call get_date_for_file ; from FAT32.INC
mov [edi+24],ax ; date
mov [edi+18],ax ; date
call get_time_for_file ; from FAT32.INC
mov [edi+22],ax ; time
xor ax,ax
mov [edi+20],ax
mov ebx,1 ; first cluster
cmp [save_root_flag],0
jne frnewds_1
call frnewds_2
pusha
call WriteSectWithRetr
popa
cmp [FDC_Status],0
jne fdc_status_error_7
jmp frnewds_3
 
frnewds_1:
call frnewds_2
frnewds_3:
pusha ; move save to floppy cluster
add ebx,31
mov eax,ebx
mov esi,[esp+32+16]
call take_data_from_application_1
call save_chs_sector
cmp [FDC_Status],0
jne fdc_status_error_7
popa
mov eax,[esp+12]
cmp eax,512
jb flnsa_1
sub eax,512
mov [esp+12],eax
mov eax,[esp+16]
add eax,512
mov [esp+16],eax
jmp frnewds_1
 
frnewds_2:
add ebx,1
mov edi,ebx ; find free cluster in FAT
shl edi,1
add edi,0x282000
mov eax,[edi]
and eax,4095
cmp eax,0x0
jnz frnewds_2
mov [edx],bx ; save next cluster pos. to prev cl.
mov edx,edi ; next save pos abs mem add
ret
 
flnsa_1:
mov [edi],word 4095 ; mark end of file - last cluster
cmp [save_root_flag],1
jne flnsa_2
call save_flp_root
cmp [FDC_Status],0
jne fdc_status_error_7
flnsa_2:
call save_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_7
frnoreadds_1:
pop edi esi edx ecx ebx eax
add esp,32
mov eax,0
mov [flp_status],0
ret
 
fdc_status_error_7_1:
cmp [FDC_Status],0
je fdc_status_error_8
fdc_status_error_7:
pop edi esi edx ecx ebx eax
add esp,32
jmp fdc_status_error_1
 
save_chs_sector:
call calculate_chs
call WriteSectWithRetr
ret
calculate_chs:
mov bl,[FDD_Track]
mov [old_track],bl
mov ebx,18
xor edx,edx
div ebx
inc edx
mov [FDD_Sector],dl
xor edx,edx
mov ebx,2
div ebx
mov [FDD_Track],al
mov [FDD_Head],0
cmp edx,0
je no_head_2
inc [FDD_Head]
no_head_2:
mov dl,[old_track]
cmp dl,[FDD_Track]
je no_seek_track_1
call SeekTrack
no_seek_track_1:
ret
 
get_cluster_of_a_path_flp:
;---------------------------------------------------------
; input : EBX = pointer to a path string
; (example: the path "/files/data/document" become
; "files......data.......document...0"
; '.' = space char
; '0' = char(0) (ASCII=0) !!! )
; output : if (CARRY=1) -> ERROR in the PATH
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
 
push edx
mov edx,ebx
 
search_end_of_path_flp:
cmp [save_flag],0
jne search_end_of_path_flp_1
cmp byte [edx],0
je found_end_of_path_flp
jmp search_end_of_path_flp_2
search_end_of_path_flp_1:
cmp byte [edx+12],0
je found_end_of_path_flp
search_end_of_path_flp_2:
inc edx ; '/'
call analyze_directory_flp
jc directory_not_found_flp
 
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
mov ax,[ebx+26] ; read the LOW 16bit cluster field
and eax,0xfff ;[fatMASK]
add edx,11 ; 8+3 (name+extension)
jmp search_end_of_path_flp
 
found_end_of_path_flp:
inc edx
mov [pointer_file_name_flp],edx
pop edx
clc ; no errors
ret
 
directory_not_found_flp:
pop edx
stc ; errors occour
ret
analyze_directory_flp:
;--------------------------------
; input : EAX = first cluster of the directory
; EBX = pointer to filename
; output : IF CARRY=0 EAX = sector where th file is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,EDI,EDI not changed
; IF CARRY=1
;--------------------------------
push ebx ;[esp+16]
push ecx
push edx
push esi
push edi
adr56_flp:
mov [clust_tmp_flp],eax
add eax,31
pusha
call read_chs_sector
popa
cmp [FDC_Status],0
jne not_found_file_analyze_flp
 
mov ecx,512/32
mov ebx,0xD000
adr1_analyze_flp:
mov esi,edx ;[esp+16]
mov edi,ebx
cld
push ecx
mov ecx,11
rep cmpsb
pop ecx
je found_file_analyze_flp
add ebx,32
loop adr1_analyze_flp
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,0x282000
mov eax,[eax]
and eax,4095
cmp eax,0x0ff8
jb adr56_flp
not_found_file_analyze_flp:
pop edi
pop esi
pop edx
pop ecx
add esp,4
stc ;file not found
ret
found_file_analyze_flp:
pop edi
pop esi
pop edx
pop ecx
add esp,4
clc ;file found
ret
analyze_directory_to_write_flp:
;--------------------------------
; input : EAX = first cluster of the directory
; output : IF CARRY=0 EAX = sector where the file is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,EDI,EDI not changed
; IF CARRY=1
;--------------------------------
push ecx
push edx
push esi
adr561:
mov [clust_tmp_flp],eax
add eax,31
pusha
call read_chs_sector
popa
cmp [FDC_Status],0
jne error_found_file_analyze1
 
mov ecx,512/32
mov ebx,0xD000
adr1_analyze1:
cmp byte [ebx],0x00
je found_file_analyze1
cmp byte [ebx],0xe5
je found_file_analyze1
avanti:
add ebx,32
loop adr1_analyze1
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,0x282000
mov eax,[eax]
and eax,4095
cmp eax,0x0ff8
jb adr561
call get_free_FAT ;this block of code add a new cluster
;for the directory because the directory
;is full
 
mov [edi],word 0x0fff
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,0x282000
sub edi,0x282000
mov [eax],di
 
pusha
mov ecx,512/4
xor eax,eax
mov edi,0xD000
cld
rep stosd
popa
 
mov eax,edi
add eax,31
pusha
call save_chs_sector
popa
cmp [FDC_Status],0
jne error_found_file_analyze1
mov ebx,0xD000
 
found_file_analyze1:
pop esi
pop edx
pop ecx
clc ;file found
ret
 
error_found_file_analyze1:
pop esi
pop edx
pop ecx
stc
ret
get_free_FAT_flp:
;------------------------------------------
; input : EAX = # cluster for start the searching
; output : EAX = # first cluster found free
;-------------------------------------------
push ebx
mov ebx,1
check_new_flp:
add ebx,1
mov edi,ebx ; find free cluster in FAT
shl edi,1
add edi,0x282000
mov eax,[edi]
and eax,4095
cmp eax,0x0
jnz check_new_flp
 
pop ebx
ret
/kernel/trunk/fs/fat32.inc
0,0 → 1,2827
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; FAT32.INC ;;
;; ;;
;; FAT16/32 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; 15.01.2005 get file size/attr/date, file_append - ATV ;;
;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;;
;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;;
;; 23.11.2004 don't allow overwrite dir with file - ATV ;;
;; 18.11.2004 get_disk_info and more error codes - ATV ;;
;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;;
;; 10.11.2004 removedir clear whole directory structure - ATV ;;
;; 08.11.2004 rename - ATV ;;
;; 30.10.2004 file_read return also dirsize in bytes - ATV ;;
;; 20.10.2004 Makedir/Removedir - ATV ;;
;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;;
;; 06.9.2004 Fix free space by Mario79 added - MH ;;
;; 24.5.2004 Write back buffer for File_write -VT ;;
;; 20.5.2004 File_read function to work with syscall 58 - VT ;;
;; 30.3.2004 Error parameters at function return - VT ;;
;; 01.5.2002 Bugfix in device write - VT ;;
;; 20.5.2002 Hd status check - VT ;;
;; 29.6.2002 Improved fat32 verification - VT ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00
 
ERROR_DISK_BASE equ 1
ERROR_UNSUPPORTED_FS equ 2
ERROR_UNKNOWN_FS equ 3
ERROR_PARTITION equ 4
ERROR_FILE_NOT_FOUND equ 5
ERROR_END_OF_FILE equ 6
ERROR_MEMORY_POINTER equ 7
ERROR_DISK_FULL equ 8
ERROR_FAT_TABLE equ 9
ERROR_ACCESS_DENIED equ 10
 
PUSHAD_EAX equ [esp+28]
PUSHAD_ECX equ [esp+24]
PUSHAD_EDX equ [esp+20]
PUSHAD_EBX equ [esp+16]
PUSHAD_EBP equ [esp+8]
PUSHAD_ESI equ [esp+4]
PUSHAD_EDI equ [esp+0]
 
align 4
;******************************************************
; Please do not change this place - variables in text
; Mario79
; START place
;******************************************************
PARTITION_START dd 0x3f
PARTITION_END dd 0
SECTORS_PER_FAT dd 0x1f3a
NUMBER_OF_FATS dd 0x2
SECTORS_PER_CLUSTER dd 0x8
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
ROOT_CLUSTER dd 2 ; first rootdir cluster
FAT_START dd 0 ; start of fat table
ROOT_START dd 0 ; start of rootdir (only fat16)
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
DATA_START dd 0 ; start of data area (=first cluster 2)
LAST_CLUSTER dd 0 ; last availabe cluster
ADR_FSINFO dd 0 ; used only by fat32
 
fatRESERVED dd 0x0FFFFFF6
fatBAD dd 0x0FFFFFF7
fatEND dd 0x0FFFFFF8
fatMASK dd 0x0FFFFFFF
 
fat_type db 0 ; 0=none, 16=fat16, 32=fat32
;***************************************************************************
; End place
; Mario79
;***************************************************************************
cluster dd 0 ; used by file_write,makedir,append
partition_count dd 0 ; partitions found by set_FAT32_variables
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous
longname_sec2 dd 0 ; directory sectors for delete long filename
 
hd_error dd 0 ; set by wait_for_sector_buffer
hd_setup dd 0
hd_wait_timeout dd 0
 
cluster_tmp dd 0 ; used by analyze_directory
; and analyze_directory_to_write
 
file_size dd 0 ; used by file_read
 
sector_tmp dd 0 ; used by rename,append,file_write
entry_pos dd 0 ; used by rename,append,file_write
 
old_filesize dd 0 ; used by append
new_filepos dd 0 ; used by append
bytes2write dd 0 ; used by append
 
cache_search_start dd 0 ; used by find_empty_slot
 
fat_in_cache dd -1
fat_cache: times 512 db 0
 
uglobal
Sector512: ; label for dev_hdcd.inc
buffer: times 512 db 0
deltree_buffer: times 512 db 0
endg
 
iglobal
NewDirEntry1 db ". ",0x10
times 20 db 0
NewDirEntry2 db ".. ",0x10
times 20 db 0
endg
 
uglobal
dir_entry: times 32 db 0
 
startpath: times 255 db 0
 
fat16_root db 0 ; flag for fat16 rootdir
f_del db 0 ; 1=overwrite fat entry
fat_change db 0 ; 1=fat has changed
 
endg
 
iglobal
partition_types: ; list of fat16/32 partitions
db 0x04 ; DOS: fat16 <32M
db 0x06 ; DOS: fat16 >32M
db 0x0b ; WIN95: fat32
db 0x0c ; WIN95: fat32, LBA-mapped
db 0x0e ; WIN95: fat16, LBA-mapped
db 0x14 ; Hidden DOS: fat16 <32M
db 0x16 ; Hidden DOS: fat16 >32M
db 0x1b ; Hidden WIN95: fat32
db 0x1c ; Hidden WIN95: fat32, LBA-mapped
db 0x1e ; Hidden WIN95: fat16, LBA-mapped
db 0xc4 ; DRDOS/secured: fat16 <32M
db 0xc6 ; DRDOS/secured: fat16 >32M
db 0xcb ; DRDOS/secured: fat32
db 0xcc ; DRDOS/secured: fat32, LBA-mapped
db 0xce ; DRDOS/secured: fat16, LBA-mapped
db 0xd4 ; Old Multiuser DOS secured: fat16 <32M
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M
partition_types_end:
 
 
extended_types: ; list of extended partitions
db 0x05 ; DOS: extended partition
db 0x0f ; WIN95: extended partition, LBA-mapped
db 0xc5 ; DRDOS/secured: extended partition
db 0xd5 ; Old Multiuser DOS secured: extended partition
extended_types_end:
 
endg
 
 
reserve_hd1:
 
cli
cmp [hd1_status],0
je reserve_ok1
 
sti
call change_task
jmp reserve_hd1
 
reserve_ok1:
 
push eax
mov eax,[0x3000]
shl eax,5
mov eax,[eax+0x3000+4]
mov [hd1_status],eax
pop eax
sti
ret
 
 
clear_hd_cache:
 
push eax ecx edi
mov edi,0x600000
mov ecx,16384
xor eax,eax
cld
rep stosd ; clear hd cache with 0
mov [cache_search_start],eax
mov [fat_in_cache],-1
mov [fat_change],0
pop edi ecx eax
ret
 
problem_partition db 0 ; used for partitions search
 
; Partition chain used:
; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4
;==========================================================
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +--
; extended --+ extended --+ extended --+ extended --+
; 0 0 0 0
; 0 0 0 0
; Notes:
; - extended partition need to be in second entry on table
; - it will skip over removed partitions
 
set_FAT32_variables:
mov [0xfe10],dword 0 ; entries in hd cache
mov [problem_partition],0
call reserve_hd1
call clear_hd_cache
 
cmp dword [hdpos],0
je problem_hd
 
pushad
xor ecx,ecx ; partition count
mov edx,-1 ; flag for partition
xor eax,eax ; read MBR
xor ebp,ebp ; extended partition start
 
new_partition:
test ebp,ebp ; is there extended partition?
jnz extended_already_set ; yes
xchg ebp,eax ; no. set it now
 
extended_already_set:
add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start
mov ebx,buffer
call hd_read
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz end_partition_chain
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition
jz next_partition
 
push eax ecx
mov edi,partition_types
mov ecx,partition_types_end-partition_types
mov al,[ebx+0x1be+4] ; get partition type
cld
repne scasb ; is partition type ok?
pop ecx eax
jnz next_partition ; no. skip over
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_partition ; no
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8] ; add relative start
 
next_partition:
push ecx
mov edi,extended_types
mov ecx,extended_types_end-extended_types
mov al,[ebx+0x1be+4+16] ; get second partition type
cld
repne scasb ; is it extended partition?
pop ecx
jnz end_partition_chain ; no. end chain
 
mov eax,[ebx+0x1be+8+16] ; get start of extended partition
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
 
end_partition_chain:
mov [partition_count],ecx
 
cmp edx,-1 ; found wanted partition?
jnz hd_and_partition_ok ; yes. install it
jmp problem_partition_or_fat
 
problem_fat_dec_count: ; bootsector is missing or another problem
dec [partition_count] ; remove it from partition_count
 
problem_partition_or_fat:
popad
 
problem_hd:
mov [fat_type],0
mov [hd1_status],0 ; free
mov [problem_partition],1
ret
 
hd_and_partition_ok:
mov eax,edx
mov [PARTITION_START],eax
 
mov [hd_setup],1
mov ebx,buffer
call hd_read ; read boot sector of partition
mov [hd_setup],0
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz problem_fat_dec_count
 
movzx eax,word [ebx+0xe] ; sectors reserved
add eax,[PARTITION_START]
mov [FAT_START],eax ; fat_start = partition_start + reserved
 
movzx eax,byte [ebx+0xd] ; sectors per cluster
mov [SECTORS_PER_CLUSTER],eax
 
movzx ecx,word [ebx+0xb] ; bytes per sector
mov [BYTES_PER_SECTOR],ecx
 
movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32)
mov edx,32
mul edx
dec ecx
add eax,ecx ; round up if not equal count
inc ecx ; bytes per sector
div ecx
mov [ROOT_SECTORS],eax ; count of rootdir sectors
 
movzx eax,word [ebx+0x16] ; sectors per fat <65536
test eax,eax
jnz fat16_fatsize
mov eax,[ebx+0x24] ; sectors per fat
fat16_fatsize:
mov [SECTORS_PER_FAT],eax
 
movzx eax,byte [ebx+0x10] ; number of fats
test eax,eax ; if 0 it's not fat partition
jz problem_fat_dec_count
mov [NUMBER_OF_FATS],eax
imul eax,[SECTORS_PER_FAT]
add eax,[FAT_START]
mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count
add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32
mov [DATA_START],eax ; data area = rootdir + rootdir_size
 
movzx eax,word [ebx+0x13] ; total sector count <65536
test eax,eax
jnz fat16_total
mov eax,[ebx+0x20] ; total sector count
fat16_total:
add eax,[PARTITION_START]
dec eax
mov [PARTITION_END],eax
inc eax
sub eax,[DATA_START] ; eax = count of data sectors
xor edx,edx
div dword [SECTORS_PER_CLUSTER]
inc eax
mov [LAST_CLUSTER],eax
dec eax ; cluster count
 
; limits by Microsoft Hardware White Paper v1.03
cmp eax,4085 ; 0xff5
jb problem_fat_dec_count ; fat12 not supported
cmp eax,65525 ; 0xfff5
jb fat16_partition
 
fat32_partition:
mov eax,[ebx+0x2c] ; rootdir cluster
mov [ROOT_CLUSTER],eax
movzx eax,word [ebx+0x30] ; fs info sector
add eax,[PARTITION_START]
mov [ADR_FSINFO],eax
 
popad
 
mov [fatRESERVED],0x0FFFFFF6
mov [fatBAD],0x0FFFFFF7
mov [fatEND],0x0FFFFFF8
mov [fatMASK],0x0FFFFFFF
mov [fat_type],32 ; Fat32
mov [hd1_status],0 ; free
ret
 
fat16_partition:
xor eax,eax
mov [ROOT_CLUSTER],eax
 
popad
 
mov [fatRESERVED],0x0000FFF6
mov [fatBAD],0x0000FFF7
mov [fatEND],0x0000FFF8
mov [fatMASK],0x0000FFFF
mov [fat_type],16 ; Fat16
mov [hd1_status],0 ; free
ret
 
 
set_FAT:
;--------------------------------
; input : EAX = cluster
; EDX = value to save
; output : EDX = old value
;--------------------------------
push eax ebx esi
 
cmp eax,2
jb sfc_error
cmp eax,[LAST_CLUSTER]
ja sfc_error
cmp [fat_type],16
je sfc_1
add eax,eax
sfc_1:
add eax,eax
mov esi,511
and esi,eax ; esi = position in fat sector
shr eax,9 ; eax = fat sector
add eax,[FAT_START]
mov ebx,fat_cache
 
cmp eax,[fat_in_cache] ; is fat sector already in memory?
je sfc_in_cache ; yes
 
cmp [fat_change],0 ; is fat changed?
je sfc_no_change ; no
call write_fat_sector ; yes. write it into disk
 
sfc_no_change:
mov [fat_in_cache],eax ; save fat sector
call hd_read
 
sfc_in_cache:
cmp [fat_type],16
jne sfc_test32
 
cmp [f_del],1 ; overwrite previous value?
je sfc_set16 ; yes
cmp word [ebx+esi],0 ; is cluster free?
je sfc_set16 ; yes
mov dword [8*0x100000],0xffffff
mov edx,[ebx+esi] ; get old value
jmp sfc_nonzero
 
sfc_set16:
xchg [ebx+esi],dx ; save new value and get old value
jmp sfc_write
 
sfc_test32:
mov eax,[fatMASK]
cmp [f_del],1 ; overwrite previous value?
je sfc_set32 ; yes
test eax,[ebx+esi] ; is cluster free?
je sfc_set32 ; yes
mov dword [8*0x100000],0xffffff
mov edx,[ebx+esi] ; get old value
jmp sfc_nonzero
 
sfc_set32:
and edx,eax
xor eax,-1 ; mask for high bits
and eax,[ebx+esi] ; get high 4 bits
or eax,edx
mov edx,[ebx+esi] ; get old value
mov [ebx+esi],eax ; save new value
 
sfc_write:
mov [fat_change],1 ; fat has changed
 
sfc_nonzero:
and edx,[fatMASK]
 
sfc_error:
pop esi ebx eax
ret
 
 
get_FAT:
;--------------------------------
; input : EAX = cluster
; output : EAX = next cluster
;--------------------------------
push ebx esi
 
cmp [fat_type],16
je gfc_1
add eax,eax
gfc_1:
add eax,eax
mov esi,511
and esi,eax ; esi = position in fat sector
shr eax,9 ; eax = fat sector
add eax,[FAT_START]
mov ebx,fat_cache
 
cmp eax,[fat_in_cache] ; is fat sector already in memory?
je gfc_in_cache
 
cmp [fat_change],0 ; is fat changed?
je gfc_no_change ; no
call write_fat_sector ; yes. write it into disk
 
gfc_no_change:
mov [fat_in_cache],eax
call hd_read
 
gfc_in_cache:
mov eax,[ebx+esi]
and eax,[fatMASK]
pop esi ebx
ret
 
 
get_free_FAT:
;-----------------------------------------------------------
; input : EAX = # cluster for start the searching
; output : if CARRY=0 EAX = # first cluster found free
; if CARRY=1 disk full
; Note : for more speed need to use fat_cache directly
;-----------------------------------------------------------
push ecx
mov ecx,[LAST_CLUSTER] ; counter for full disk
sub ecx,2
 
gff_test:
cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2
jbe gff_in_range
mov eax,2
 
gff_in_range:
push eax
call get_FAT ; get cluster state
test eax,eax ; is it free?
pop eax
je gff_found ; yes
inc eax ; next cluster
dec ecx ; is all checked?
jns gff_test ; no
 
gff_not_found:
pop ecx ; yes. disk is full
stc
ret
 
gff_found:
pop ecx
clc
ret
 
 
write_fat_sector:
;-----------------------------------------------------------
; write changed fat to disk
;-----------------------------------------------------------
push eax ebx ecx
 
mov [fat_change],0
mov eax,[fat_in_cache]
cmp eax,-1
jz write_fat_not_used
mov ebx,fat_cache
mov ecx,[NUMBER_OF_FATS]
 
write_next_fat:
call hd_write
add eax,[SECTORS_PER_FAT]
dec ecx
jnz write_next_fat
 
write_fat_not_used:
pop ecx ebx eax
ret
 
 
analyze_directory:
;-----------------------------------------------------------
; input : EAX = first cluster of the directory
; EBX = pointer to filename
; output : IF CARRY=0 EAX = sector where th file is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,ESI,EDI not changed
; IF CARRY=1 filename not found
; Note : if cluster=0 it's changed to read rootdir
; save 2 previous directory sectors in longname_sec
;-----------------------------------------------------------
push ecx edx esi edi ebx ; ebx = [esp+0]
mov [longname_sec1],0
mov [longname_sec2],0
 
adr_new_cluster:
mov [cluster_tmp],eax
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja adr_not_found ; too big cluster number, something is wrong
cmp eax,2
jnb adr_data_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fat_type],16
jne adr_data_cluster
mov eax,[ROOT_START]
mov edx,[ROOT_SECTORS]
mov [fat16_root],1 ; flag for fat16 rootdir
jmp adr_new_sector
 
adr_data_cluster:
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
 
adr_new_sector:
mov ebx,buffer
call hd_read
mov ecx,512/32 ; count of dir entrys per sector = 16
 
adr_analyze:
mov edi,[ebx+11] ; file attribute
and edi,0xf
cmp edi,0xf
je adr_long_filename
test edi,0x8 ; skip over volume label
jne adr_long_filename ; Note: label can be same name as file/dir
 
mov esi,[esp+0] ; filename need to be uppercase
mov edi,ebx
push ecx
mov ecx,11
cld
rep cmpsb ; compare 8+3 filename
pop ecx
je adr_found
 
adr_long_filename:
add ebx,32 ; position of next dir entry
dec ecx
jnz adr_analyze
 
mov ecx,[longname_sec1] ; save 2 previous directory sectors
mov [longname_sec1],eax ; for delete long filename
mov [longname_sec2],ecx
inc eax ; next sector
dec edx
jne adr_new_sector
cmp [fat16_root],1 ; end of fat16 rootdir
je adr_not_found
 
adr_next_cluster:
mov eax,[cluster_tmp]
call get_FAT ; get next cluster
cmp eax,2 ; incorrect fat chain?
jb adr_not_found ; yes
cmp eax,[fatRESERVED] ; is it end of directory?
jb adr_new_cluster ; no. analyse it
 
adr_not_found:
pop edi edi esi edx ecx ; first edi will remove ebx
stc ; file not found
ret
 
adr_found:
pop edi edi esi edx ecx ; first edi will remove ebx
clc ; file found
ret
 
 
analyze_directory_to_write:
;-----------------------------------------------------------
; input : EAX = first cluster of the directory
; output : IF CARRY=0 EAX = sector where the empty pos is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,ESI,EDI not changed
; IF CARRY=1 disk full or fat corrupted
; Note : if cluster=0 it's changed to read rootdir
;-----------------------------------------------------------
push ecx edx edi
 
adw_new_cluster:
mov [cluster_tmp],eax
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja adw_not_found ; too big cluster number, something is wrong
cmp eax,2
jnb adw_data_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fat_type],16
jne adw_data_cluster
mov eax,[ROOT_START]
mov edx,[ROOT_SECTORS]
mov [fat16_root],1 ; flag for fat16 rootdir
jmp adw_new_sector
 
adw_data_cluster:
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
 
adw_new_sector:
mov ebx,buffer
call hd_read
mov ecx,512/32 ; count of dir entrys per sector = 16
 
adw_analyze:
cmp byte [ebx],0x00 ; is free entry?
je adw_found ; yes
cmp byte [ebx],0xe5 ; is deleted entry?
je adw_found ; yes
add ebx,32 ; position of next dir entry
dec ecx
jnz adw_analyze
 
inc eax ; next sector
dec edx
jne adw_new_sector
cmp [fat16_root],1 ; end of fat16 rootdir
je adw_not_found
 
mov eax,[cluster_tmp]
call get_FAT ; get next cluster
cmp eax,2 ; incorrect fat chain?
jb adw_not_found ; yes
cmp eax,[fatRESERVED] ; is it end of directory?
jb adw_new_cluster ; no. analyse it
 
mov eax,2 ; this block of code add a new cluster
call get_free_FAT ; for the directory because the directory
jc adw_not_found ; is full
 
mov edx,[fatEND] ; new end for directory
call set_FAT
 
push eax ; save new cluster
mov edx,eax
mov eax,[cluster_tmp] ; change last cluster to point new cluster
mov [f_del],1
call set_FAT
mov [f_del],0
 
mov ecx,-1 ; remove 1 cluster from free disk space
call add_disk_free_space
 
mov ecx,512/4
xor eax,eax
mov edi,buffer
cld
rep stosd ; clear new directory cluster
pop eax
 
sub eax,2
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
mov ebx,buffer
push eax ; save sector number
 
adw_set_empty_directory:
call hd_write
inc eax ; next sector
dec ecx
jnz adw_set_empty_directory
 
pop eax
 
adw_found:
pop edi edx ecx
clc ; free space found
ret
 
adw_not_found:
pop edi edx ecx
stc ; free space not found
ret
 
 
get_data_cluster:
;-----------------------------------------------------------
; input : EAX = cluster
; EBX = pointer to buffer
; EDX = # blocks to read in buffer
; ESI = # blocks to skip over
; output : if CARRY=0 ok EBX/EDX/ESI updated
; if CARRY=1 cluster out of range
; Note : if cluster=0 it's changed to read rootdir
;-----------------------------------------------------------
push eax ecx
 
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja gdc_error ; too big cluster number, something is wrong
cmp eax,2
jnb gdc_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fat_type],16
jne gdc_cluster
mov eax,[ROOT_START]
mov ecx,[ROOT_SECTORS] ; Note: not cluster size
mov [fat16_root],1 ; flag for fat16 rootdir
jmp gdc_read
 
gdc_cluster:
sub eax,2
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
 
gdc_read:
test esi,esi ; first wanted block
je gdcl1 ; yes, skip count is 0
dec esi
jmp gdcl2
 
gdcl1:
call hd_read
add ebx,512 ; update pointer
dec edx
 
gdcl2:
test edx,edx ; is all read?
je out_of_read
 
inc eax ; next sector
dec ecx
jnz gdc_read
 
out_of_read:
pop ecx eax
clc
ret
 
gdc_error:
pop ecx eax
stc
ret
 
 
set_data_cluster:
;-----------------------------------------------------------
; input : EAX = cluster
; EBX = pointer to buffer
; output : if CARRY=0 ok
; if CARRY=1 cluster out of range
;-----------------------------------------------------------
push eax ebx edx
 
cmp eax,[LAST_CLUSTER]
ja sdc_error ; too big cluster number, something is wrong
sub eax,2
jb sdc_error ; don't allow rootdir write
 
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
 
sdc_write:
call hd_write
add ebx,512 ; update pointer
inc eax
dec edx
jnz sdc_write
pop edx ebx eax
clc
ret
 
sdc_error:
pop edx ebx eax
stc
ret
 
 
get_cluster_of_a_path:
;---------------------------------------------------------
; input : EBX = pointer to a path string
; (example: the path "/files/data/document" become
; "files......data.......document...0"
; '.' = space char
; '0' = char(0) (ASCII=0) !!! )
; output : if (CARRY=1) -> ERROR in the PATH
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
push ebx edx
 
mov eax,[ROOT_CLUSTER]
mov edx,ebx
 
search_end_of_path:
cmp byte [edx],0
je found_end_of_path
 
inc edx ; '/'
mov ebx,edx
call analyze_directory
jc directory_not_found
 
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
mov ax,[ebx+26] ; read the LOW 16bit cluster field
and eax,[fatMASK]
add edx,11 ; 8+3 (name+extension)
jmp search_end_of_path
 
found_end_of_path:
pop edx ebx
clc ; no errors
ret
 
directory_not_found:
pop edx ebx
stc ; errors occour
ret
 
 
bcd2bin:
;----------------------------------
; input : AL=BCD number (eg. 0x11)
; output : AH=0
; AL=decimal number (eg. 11)
;----------------------------------
xor ah,ah
shl ax,4
shr al,4
aad
ret
 
 
get_date_for_file:
;-----------------------------------------------------
; Get date from CMOS and pack day,month,year in AX
; DATE bits 0..4 : day of month 0..31
; 5..8 : month of year 1..12
; 9..15 : count of years from 1980
;-----------------------------------------------------
mov al,0x7 ;day
out 0x70,al
in al,0x71
call bcd2bin
ror eax,5
 
mov al,0x8 ;month
out 0x70,al
in al,0x71
call bcd2bin
ror eax,4
 
mov al,0x9 ;year
out 0x70,al
in al,0x71
call bcd2bin
add ax,20 ;because CMOS return only the two last
;digit (eg. 2000 -> 00 , 2001 -> 01) and we
rol eax,9 ;need the difference with 1980 (eg. 2001-1980)
ret
 
 
get_time_for_file:
;-----------------------------------------------------
; Get time from CMOS and pack hour,minute,second in AX
; TIME bits 0..4 : second (the low bit is lost)
; 5..10 : minute 0..59
; 11..15 : hour 0..23
;-----------------------------------------------------
mov al,0x0 ;second
out 0x70,al
in al,0x71
call bcd2bin
ror eax,6
 
mov al,0x2 ;minute
out 0x70,al
in al,0x71
call bcd2bin
ror eax,6
 
mov al,0x4 ;hour
out 0x70,al
in al,0x71
call bcd2bin
rol eax,11
ret
 
 
set_current_time_for_entry:
;-----------------------------------------------------
; Set current time/date for file entry
; input : ebx = file entry pointer
;-----------------------------------------------------
push eax
call get_time_for_file ; update files date/time
mov [ebx+22],ax
call get_date_for_file
mov [ebx+24],ax
pop eax
ret
 
 
makedir:
;-----------------------------------------------------
; input : eax = directory name
; edx = path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 8 - disk full
; 10 - access denied
; Note : can only make one directory at time
;-----------------------------------------------------
cmp [fat_type],0
jnz make_dir_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
make_dir_fat_ok:
; call reserve_hd1
 
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jnc make_dir_found_path
 
make_dir_path_not_found:
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
mov eax,ERROR_FILE_NOT_FOUND
ret
 
make_dir_disk_full:
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
mov eax,ERROR_DISK_FULL
ret
 
make_dir_already_exist:
mov eax,[cluster] ; directory cluster
xor edx,edx ; free
mov [f_del],1
call set_FAT
mov [f_del],0
 
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
make_dir_found_path:
cmp eax,[ROOT_CLUSTER]
jnz make_dir_not_root
xor eax,eax
 
make_dir_not_root:
mov ecx,eax ; directorys start cluster
mov word [NewDirEntry2+26],cx ; 16 bits low of cluster
shr ecx,16
mov word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16)
 
push eax ; save parent directory cluster
mov eax,2
call get_free_FAT
mov [cluster],eax ; first free cluster
pop eax
jc make_dir_disk_full
 
push eax
mov eax,[cluster] ; directory cluster
mov edx,[fatEND] ; end for directory
call set_FAT
pop eax
 
mov ebx,PUSHAD_EAX ; dir name
push eax
call analyze_directory ; check if directory already exist
pop eax
jnc make_dir_already_exist ; need to free allocated cluster!
 
call analyze_directory_to_write
jc make_dir_already_exist ; need to free allocated cluster!
 
mov esi,PUSHAD_EAX ; dir name
mov edi,ebx ; pointer in buffer
mov ecx,11
cld
rep movsb
 
mov dword [ebx+28],0 ; dir size is always 0
mov ecx,[cluster]
mov [ebx+26],cx ; 16 bits low of cluster
mov word [NewDirEntry1+26],cx
shr ecx,16
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
mov word [NewDirEntry1+20],cx
mov byte [ebx+11],0x10 ; attribute = directory
 
call set_current_time_for_entry
mov ecx,[ebx+22]
mov dword [NewDirEntry1+22],ecx
mov dword [NewDirEntry2+22],ecx
 
mov ebx,buffer ; save the directory name,length,cluster
call hd_write
 
mov ecx,512/4
xor eax,eax
mov edi,buffer
cld
rep stosd ; clear new directory cluster
 
mov eax,[cluster] ; new directory cluster
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
mov ebx,buffer
add eax,edx ; start from last sector
 
dir_set_empty_directory:
dec eax ; next sector
cmp edx,1 ; is first directory sector?
jnz not_first_sector ; no. write empty sector
mov esi,NewDirEntry1
mov edi,buffer
mov ecx,64/4
cld
rep movsd ; copy 2 first directory entrys "." and ".."
 
not_first_sector:
call hd_write
dec edx
jnz dir_set_empty_directory
 
mov ecx,-1 ; remove 1 cluster from free disk space
call add_disk_free_space
 
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
xor eax,eax
ret
 
 
removedir:
;-----------------------------------------------------
; input : eax = file/directory name
; edx = path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 10 - access denied
;-----------------------------------------------------
cmp [fat_type],0
jnz remove_dir_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
remove_dir_fat_ok:
; call reserve_hd1
 
push edi
mov edi,1 ; allow directory remove
call file_delete
pop edi
 
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
ret
 
 
add_disk_free_space:
;-----------------------------------------------------
; input : ecx = cluster count
; Note : negative = remove clusters from free space
; positive = add clusters to free space
;-----------------------------------------------------
test ecx,ecx ; no change
je add_dfs_no
cmp [fat_type],32 ; free disk space only used by fat32
jne add_dfs_no
 
push eax ebx
mov eax,[ADR_FSINFO]
mov ebx,buffer
call hd_read
cmp dword [ebx+0x1fc],0xaa550000 ; check sector id
jne add_not_fs
 
add [ebx+0x1e8],ecx
call hd_write
 
add_not_fs:
pop ebx eax
 
add_dfs_no:
ret
 
 
file_append:
;-----------------------------------------------------
; input : eax = file name
; edx = path
; ecx = pointer to buffer
; ebx = bytes to write (0 = truncate file)
; esi = start position (-1 = end of file)
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 6 - end of file
; 8 - disk full
; 9 - fat table corrupted
; 10 - access denied
; ebx = bytes written
;-----------------------------------------------------
cmp [fat_type],0
jnz append_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
append_fat_ok:
; call reserve_hd1
 
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jc append_not_found
 
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc append_not_found
 
mov [sector_tmp],eax
mov [entry_pos],ebx
 
test byte [ebx+11],0x10 ; is it directory?
jnz append_access ; yes
 
mov ecx,[ebx+28] ; file size
mov edi,PUSHAD_ESI ; write position
cmp edi,-1 ; -1 = eof
jnz append_inside_file
mov edi,ecx ; file size
 
append_inside_file:
cmp edi,ecx ; start above old file size?
ja append_eof ; yes
 
mov [old_filesize],ecx
mov [new_filepos],edi
 
mov ecx,PUSHAD_EBX ; bytes to write
test ecx,ecx ; truncate?
jz append_truncate ; yes
 
mov [bytes2write],ecx ; bytes to write
mov esi,PUSHAD_ECX ; pointer to buffer
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
jnz append_find_pos ; first cluster <> 0
 
mov eax,2
call get_free_FAT
jc append_disk_full
mov ecx,eax ; set files first cluster
mov [ebx+26],cx ; 16 bits low of cluster
shr ecx,16
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
mov edx,[fatEND] ; new end for cluster chain
call set_FAT
 
push eax ; save first cluster
mov eax,[sector_tmp]
mov ebx,buffer
call hd_write ; write new file entry back to disk
pop eax
 
append_remove_free:
mov ecx,-1 ; remove 1 cluster from free disk space
call add_disk_free_space ; Note: uses buffer
 
append_found_cluster:
mov [cluster],eax
sub eax,2
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
xor edi,edi
 
append_new_sector:
push ecx
mov ecx,[bytes2write] ; bytes left in buffer
mov ebx,512
sub ebx,edi ; bytes left in sector
cmp ecx,ebx
jb append_bytes_ok
mov ecx,ebx
 
append_bytes_ok:
cmp ecx,512 ; overwrite full sector?
jz append_full_sector ; yes
mov ebx,buffer ; overwrite part of sector
call hd_read ; read old sector
 
append_full_sector:
sub [bytes2write],ecx
add [new_filepos],ecx
add edi,buffer
cld
rep movsb
pop ecx
 
mov ebx,buffer
call hd_write
cmp [bytes2write],0 ; is all done?
jz append_done
xor edi,edi
inc eax
dec ecx
jnz append_new_sector
 
mov eax,[cluster]
call get_FAT
cmp eax,2
jb append_fat
cmp eax,[LAST_CLUSTER]
jbe append_found_cluster
 
append_alloc_cluster:
mov eax,2 ; ToDo: use temp array to keep track
call get_free_FAT ; of last free cluster
jc append_disk_full
push eax ; save new cluster
mov edx,[fatEND] ; new end for cluster chain
call set_FAT
mov edx,eax
mov eax,[cluster]
mov [f_del],1
call set_FAT ; update previous cluster
mov [f_del],0
pop eax
jmp append_remove_free
 
append_find_pos:
call find_filepos
mov [cluster],ebx
jnc append_new_sector
test edi,edi
jz append_alloc_cluster
 
append_fat:
mov eax,ERROR_FAT_TABLE
jmp append_ret_code
 
append_disk_full:
mov eax,ERROR_DISK_FULL
jmp append_ret_code
 
append_done:
xor eax,eax
 
append_ret_code:
mov PUSHAD_EAX,eax ; return code
 
mov eax,[sector_tmp] ; update directory entry
mov ebx,buffer
call hd_read
mov ebx,[entry_pos]
mov ecx,[new_filepos]
cmp ecx,[old_filesize] ; is file pos above old size?
jbe append_size_ok ; no
mov [ebx+28],ecx ; new file size
 
append_size_ok:
call set_current_time_for_entry
mov ebx,buffer
call hd_write ; write new file entry back to disk
 
sub ecx,PUSHAD_ESI ; start position
mov PUSHAD_EBX,ecx ; bytes written
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
ret
 
append_eof:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_END_OF_FILE
ret
 
append_not_found:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
 
append_access:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_ACCESS_DENIED
ret
 
append_truncate:
mov edx,[ebx+20-2] ; FAT entry
mov dx,[ebx+26]
and edx,[fatMASK]
mov [ebx+28],edi ; set new file size
test edi,edi ; 0 length file?
jnz truncate_save_size ; no
mov [ebx+20],di ; FAT entry = 0
mov [ebx+26],di
 
truncate_save_size:
call set_current_time_for_entry
mov ebx,buffer
call hd_write
mov eax,edx ; first cluster
test edi,edi ; 0 length file?
jz truncate_clear_chain
 
imul esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes
 
truncate_new_cluster:
cmp eax,2 ; incorrect fat chain?
jb truncate_eof ; yes
cmp eax,[fatRESERVED] ; is it end of file?
jnb truncate_eof ; yes
sub edi,esi
jbe truncate_pos_found
call get_FAT ; get next cluster
jmp truncate_new_cluster
 
truncate_pos_found:
mov edx,[fatEND] ; new end for cluster chain
mov [f_del],1
call set_FAT
mov [f_del],0
mov eax,edx ; clear rest of chain
 
truncate_clear_chain:
call clear_cluster_chain
 
truncate_eof:
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
xor ebx,ebx
xor eax,eax
ret
 
 
find_filepos:
;-----------------------------------------------------
; input : eax = first cluster
; edi = bytes to skip over (start position)
; output : if CARRY=0 file position found
; if CARRY=1 end of file found
; eax = current file sector
; ebx = last cluster
; ecx = sector count in last cluster
; edi = bytes to skip over (sector position)
;-----------------------------------------------------
push esi
mov ecx,[SECTORS_PER_CLUSTER]
imul esi,ecx,512 ; esi = cluster size in bytes
mov ebx,eax
 
filepos_new_cluster:
cmp eax,2 ; incorrect fat chain?
jb filepos_eof ; yes
cmp eax,[fatRESERVED] ; is it end of file?
jnb filepos_eof ; yes
 
mov ebx,eax
cmp edi,esi ; skip over full cluster?
jb filepos_cluster_ok ; no
 
sub edi,esi
call get_FAT ; get next cluster
jmp filepos_new_cluster
 
filepos_cluster_ok:
sub eax,2
imul eax,ecx
add eax,[DATA_START]
 
filepos_new_sector:
cmp edi,512 ; skip over full sector?
jb filepos_sector_ok ; no
sub edi,512
inc eax
dec ecx
jnz filepos_new_sector
 
filepos_eof:
pop esi
stc
ret
 
filepos_sector_ok:
pop esi
clc
ret
 
 
file_write:
;--------------------------------------------------------------------------
; INPUT : user-reg register-in-this meaning symbol-in-this-routine
;
; EAX EDI system call to write /
; EBX EAX (PAR0) pointer to file-name PAR0
; EDX ECX (PAR1) pointer to buffer PAR1
; ECX EBX (PAR2) file size PAR2
; ESI EDX (PAR3) pointer to path PAR3
;
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 8 - disk full
; 10 - access denied
;--------------------------------------------------------------------------
cmp [fat_type],0
jnz fat_ok_for_writing
mov eax,ERROR_UNKNOWN_FS
ret
 
fat_ok_for_writing:
; call reserve_hd1
 
pushad
 
xor edi,edi ; don't allow directory remove
call file_delete ; try to delete the file first
test eax,eax
jz old_deleted ; deleted ok
cmp eax,ERROR_FILE_NOT_FOUND
jnz exit_write_access ; it exist but can't delete
 
old_deleted:
mov ebx,PUSHAD_EDX
call get_cluster_of_a_path
jnc found_directory_for_writing
 
exit_writing_with_error:
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
mov eax,ERROR_FILE_NOT_FOUND
ret
 
exit_writing_disk_full_clear:
mov eax,[sector_tmp]
mov ebx,buffer
call hd_read ; read directory sector
mov edx,[entry_pos]
mov byte [edx],0xe5 ; mark as deleted
call hd_write
mov eax,[edx+20-2] ; FAT entry
mov ax,[edx+26]
and eax,[fatMASK]
call clear_cluster_chain
 
exit_writing_disk_full:
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
mov eax,ERROR_DISK_FULL
ret
 
exit_write_access:
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
found_directory_for_writing:
call analyze_directory_to_write
jc exit_writing_disk_full
 
mov [sector_tmp],eax
mov [entry_pos],ebx
push eax ; save directory sector
mov eax,2
call get_free_FAT
mov [cluster],eax ; first free cluster
pop eax
jc exit_writing_disk_full
 
mov esi,PUSHAD_EAX ; file name
mov edi,ebx ; pointer in buffer
mov ecx,11
cld
rep movsb
 
mov esi,PUSHAD_EBX ; file size (bytes left)
mov [ebx+28],esi ; file size
mov ecx,[cluster]
mov [ebx+26],cx ; 16 bits low of cluster
shr ecx,16
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
mov byte [ebx+11],0x20 ; attribute = archive
 
call set_current_time_for_entry
 
mov ebx,buffer ; save the directory name,length,cluster
call hd_write
 
imul edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes
xor ecx,ecx ; cluster count
mov ebx,PUSHAD_ECX ; ebx = buffer
 
hd_new_block_write:
 
mov eax,[cluster] ; eax = block
call set_data_cluster
 
sub esi,edi ; sub wrote bytes
jbe file_saved_OK ; end if all done
add ebx,edi ; update buffer position
 
inc eax
call get_free_FAT ; next free in FAT
jc exit_writing_disk_full_clear
 
mov edx,eax
xchg eax,[cluster] ; get old cluster and save new cluster
call set_FAT ; add it in cluster chain
dec ecx ; update cluster count
jmp hd_new_block_write
 
file_saved_OK:
 
mov edx,[fatEND] ; new end for cluster chain
call set_FAT
dec ecx ; update cluster count
 
call add_disk_free_space ; remove clusters from free disk space
 
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
xor eax,eax
ret
 
 
file_read:
;--------------------------------------------------------------------------
; INPUT : user-register register-in-this meaning symbol-in-this
;
; EAX EDI system call to write /
; EBX EAX (PAR0) pointer to file-name PAR0
; EDX ECX (PAR1) pointer to buffer PAR1
; ECX EBX (PAR2) vt file blocks to read PAR2
; ESI EDX (PAR3) pointer to path PAR3
; EDI ESI vt first 512 block to read
; EDI if 0 - read root
;
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 6 - end of file
; 9 - fat table corrupted
; ebx = size of file/directory
;--------------------------------------------------------------------------
cmp [fat_type],0
jnz fat_ok_for_reading
xor ebx,ebx
mov eax,ERROR_UNKNOWN_FS
ret
 
fat_ok_for_reading:
; call reserve_hd1
 
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jc file_to_read_not_found
 
test edi,edi ; read rootdir
jne no_read_root
 
xor eax,eax
call get_dir_size ; return rootdir size
mov [file_size],eax
mov eax,[ROOT_CLUSTER]
jmp file_read_start
 
no_read_root:
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc file_to_read_not_found
 
mov eax,[ebx+28] ; file size
test byte [ebx+11],0x10 ; is it directory?
jz read_set_size ; no
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
call get_dir_size
 
read_set_size:
mov [file_size],eax
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
 
file_read_start:
mov ebx,PUSHAD_ECX ; pointer to buffer
mov edx,PUSHAD_EBX ; file blocks to read
mov esi,PUSHAD_ESI ; first 512 block to read
 
file_read_new_cluster:
call get_data_cluster
jc file_read_eof ; end of file or cluster out of range
 
test edx,edx ; is all read?
je file_read_OK ; yes
 
call get_FAT ; get next cluster
cmp eax,[fatRESERVED] ; end of file
jnb file_read_eof
cmp eax,2 ; incorrect fat chain
jnb file_read_new_cluster
 
popad
mov [hd1_status],0
mov ebx,[file_size]
mov eax,ERROR_FAT_TABLE
ret
 
file_read_eof:
popad
mov [hd1_status],0
mov ebx,[file_size]
mov eax,ERROR_END_OF_FILE
ret
 
file_read_OK:
popad
mov [hd1_status],0
mov ebx,[file_size]
xor eax,eax
ret
 
file_to_read_not_found:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
 
 
get_dir_size:
;-----------------------------------------------------
; input : eax = first cluster (0=rootdir)
; output : eax = directory size in bytes
;-----------------------------------------------------
push edx
xor edx,edx ; count of directory clusters
test eax,eax
jnz dir_size_next
 
mov eax,[ROOT_SECTORS]
shl eax,9 ; fat16 rootdir size in bytes
cmp [fat_type],16
je dir_size_ret
mov eax,[ROOT_CLUSTER]
 
dir_size_next:
cmp eax,2 ; incorrect fat chain
jb dir_size_end
cmp eax,[fatRESERVED] ; end of directory
ja dir_size_end
call get_FAT ; get next cluster
inc edx
jmp dir_size_next
 
dir_size_end:
imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
imul eax,edx
 
dir_size_ret:
pop edx
ret
 
 
file_delete:
;-----------------------------------------------------
; input : eax = file/directory name
; edx = path
; edi = 1 - allow directory remove else don't remove directory
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 10 - access denied
;-----------------------------------------------------
cmp [fat_type],0
jnz file_del_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
file_del_fat_ok:
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jc file_to_delete_not_found
 
mov ebx,PUSHAD_EAX ; file/directory name
call analyze_directory
jc file_to_delete_not_found
 
test byte [ebx+11],0x10 ; is it directory?
jz delete_notdir ; no. it's file
cmp edi,1 ; allow directory remove
jnz delete_no_access ; no
 
push eax ; save directory sector
mov eax,[ebx+20-2] ; first cluster of file
mov ax,[ebx+26] ; 0 length files start cluster = 0
and eax,[fatMASK]
xor ebp,ebp ; counter for directory deepnes
call clear_directory
pop eax
jc delete_no_access
 
push ebx ; save directory pointer in buffer
mov ebx,buffer
call hd_read ; read directory sector
pop ebx
 
delete_notdir:
call delete_entry_name
mov eax,ecx ; first cluster of file
call clear_cluster_chain
popad
xor eax,eax
ret
 
delete_no_access:
popad
mov eax,ERROR_ACCESS_DENIED
ret
 
file_to_delete_not_found:
popad
mov eax,ERROR_FILE_NOT_FOUND
ret
 
 
clear_cluster_chain:
;-----------------------------------------------------
; input : eax = first cluster
;-----------------------------------------------------
push eax ecx edx
xor ecx,ecx ; cluster count
mov [f_del],1 ; delete on
 
clean_new_chain:
cmp eax,[LAST_CLUSTER] ; end of file
ja delete_OK
cmp eax,2 ; unfinished fat chain or zero length file
jb delete_OK
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
jz delete_OK
 
xor edx,edx
call set_FAT ; clear fat entry
inc ecx ; update cluster count
mov eax,edx ; old cluster
jmp clean_new_chain
 
delete_OK:
call add_disk_free_space ; add clusters to free disk space
mov [f_del],0
pop edx ecx eax
ret
 
 
clear_directory:
;-----------------------------------------------------
; input : eax = directory cluster
; ebp = directory deepnes
; Note : use recursive call
;-----------------------------------------------------
pushad
inc ebp
cmp ebp,64 ; if over 63 directory deep
jnb clear_error ; something must be wrong
 
clear_new_cluster:
cmp eax,[LAST_CLUSTER]
ja clear_end
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
jz clear_end
mov esi,eax ; esi = current directory cluster
sub eax,2
jb clear_end
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
 
clear_new_sector:
mov edi,eax ; edi = current directory sector
mov ebx,deltree_buffer
call hd_read
mov edx,512/32 ; count of dir entrys per sector = 16
 
clear_analyze:
mov al,[ebx+11] ; file attribute
and al,0xf
cmp al,0xf
je clear_long_filename
 
cmp byte [ebx],'.' ; parent or current directory
je clear_next_entry
cmp byte [ebx],0xe5 ; deleted
je clear_next_entry
cmp byte [ebx],0 ; empty
je clear_write_last
;je clear_next_entry
 
mov eax,[ebx+20-2] ; first cluster of entry
mov ax,[ebx+26]
and eax,[fatMASK]
 
test byte [ebx+11],0x10 ; is it directory?
jz clear_file ; no
 
push eax ebx
mov eax,edi
mov ebx,deltree_buffer ; save buffer over recursive call
call hd_write ; write directory sector to disk
pop ebx eax
 
call clear_directory ; recursive call !!!
jc clear_error ; exit if error found
 
push eax ebx
mov eax,edi
mov ebx,deltree_buffer
call hd_read ; read directory sector again
pop ebx eax
 
clear_file:
call clear_cluster_chain
 
clear_long_filename:
mov byte [ebx],0xe5
 
clear_next_entry:
add ebx,32 ; position of next dir entry
dec edx
jnz clear_analyze
 
mov eax,edi
mov ebx,deltree_buffer
call hd_write ; write directory sector to disk
 
inc eax ; next sector
dec ecx
jnz clear_new_sector
 
mov eax,esi
call get_FAT ; get next cluster
jmp clear_new_cluster ; clear it
 
clear_write_last:
mov eax,edi
mov ebx,deltree_buffer
call hd_write ; write directory sector to disk
 
clear_end:
popad
clc
ret
 
clear_error:
popad
stc
ret
 
 
delete_entry_name:
;-----------------------------------------------------
; input : eax = directory sector
; ebx = directory pointer in buffer
; longname_sec = 2 previous directory sectors
; output : ecx = first cluster
; change : eax,ebx,edx
;-----------------------------------------------------
mov byte [ebx],0xe5
mov ecx,[ebx+20-2] ; first cluster of file
mov cx,[ebx+26] ; 0 length files start cluster = 0
and ecx,[fatMASK]
 
delete_empty:
sub ebx,32
cmp ebx,buffer
jnb delete_test_long
 
mov ebx,buffer
call hd_write ; write directory sector back
xor eax,eax
xchg eax,[longname_sec2]
xchg eax,[longname_sec1]
test eax,eax ; is there previous directory sector?
jz delete_name_end ; no
 
mov ebx,buffer
call hd_read ; read previous sector
mov ebx,buffer+0x1e0 ; start from last entry
 
delete_test_long:
mov dh,[ebx+11] ; file attribute
and dh,0xf
cmp dh,0xf
jne delete_write_buffer
 
cmp byte [ebx],0x40 ; end of long dir entry?
mov byte [ebx],0xe5
jb delete_empty
 
delete_write_buffer:
mov ebx,buffer
call hd_write ; write directory sector back
 
delete_name_end:
ret
 
 
rename:
;-----------------------------------------------------------
; input : eax = source directory name
; edx = source path
; ebx = dest directory name
; edi = dest path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 8 - disk full
; 10 - access denied
;-----------------------------------------------------------
cmp [fat_type],0
jnz fat_ok_for_rename
mov eax,ERROR_UNKNOWN_FS
ret
 
fat_ok_for_rename:
; call reserve_hd1
 
pushad
 
mov ebx,edx ; source path
call get_cluster_of_a_path
jc rename_entry_not_found
 
mov ebx,PUSHAD_EAX ; source directory name
call analyze_directory
jc rename_entry_not_found
 
mov [sector_tmp],eax ; save source sector
mov [entry_pos],ebx
mov esi,ebx
mov edi,dir_entry
mov ecx,32/4
cld
rep movsd ; save entry
 
mov ebx,PUSHAD_EDI ; dest path
call get_cluster_of_a_path
jc rename_entry_not_found
 
mov edx,eax ; save dest directory cluster
mov ebx,PUSHAD_EBX ; dest directory name
push [longname_sec1]
push [longname_sec2]
call analyze_directory ; check if entry already exist
pop [longname_sec2]
pop [longname_sec1]
jnc rename_entry_already_exist
 
mov eax,edx
call analyze_directory_to_write
jc rename_disk_full
 
mov esi,dir_entry
mov edi,ebx
mov ecx,32/4
cld
rep movsd ; copy entry
mov esi,PUSHAD_EBX ; dest directory name
mov edi,ebx
mov ecx,11
rep movsb ; copy name
 
mov ebx,buffer ; save the directory name,length,cluster
call hd_write
 
test byte [dir_entry+11],0x10 ; is it directory?
jz rename_not_dir ; no
mov eax,[dir_entry+20-2] ; FAT entry
mov ax,[dir_entry+26]
and eax,[fatMASK]
call change_2dot_cluster
 
rename_not_dir:
mov eax,[sector_tmp]
mov ebx,buffer
call hd_read ; read source directory sector
 
mov ebx,[entry_pos]
call delete_entry_name
 
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
xor eax,eax
ret
 
rename_entry_not_found:
popad
mov [hd1_status],0
mov eax,ERROR_FILE_NOT_FOUND
ret
 
rename_entry_already_exist:
popad
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
rename_disk_full:
popad
mov [hd1_status],0
mov eax,ERROR_DISK_FULL
ret
 
 
change_2dot_cluster:
;-----------------------------------------------------------
; input : eax = directory cluster
; edx = value to save
; change : eax,ebx,edx
;-----------------------------------------------------------
cmp eax,[LAST_CLUSTER]
ja not_2dot ; too big cluster number, something is wrong
sub eax,2
jb not_2dot
 
imul eax,[SECTORS_PER_CLUSTER]
add eax,[DATA_START]
mov ebx,buffer
call hd_read
 
cmp dword [ebx+32],'.. '
jnz not_2dot
 
cmp edx,[ROOT_CLUSTER] ; is rootdir cluster?
jne not_2dot_root
xor edx,edx ; yes. set it zero
 
not_2dot_root:
mov [ebx+32+26],dx ; 16 bits low of cluster
shr edx,16
mov [ebx+32+20],dx ; 16 bits high of cluster (=0 fat16)
call hd_write
 
not_2dot:
ret
 
 
get_filesize:
;-----------------------------------------------------------
; input : eax = file name
; edx = path
; edi = if 0 - read rootdir else normal dir/file size
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; ebx = file size
;-----------------------------------------------------------
cmp [fat_type],0
jnz get_filesize_fat_ok
xor ebx,ebx
mov eax,ERROR_UNKNOWN_FS
ret
 
get_filesize_fat_ok:
; call reserve_hd1
 
pushad
xor eax,eax
test edi,edi ; is read rootdir?
je get_filesize_dirsize ; yes
 
get_filesize_no_root:
mov ebx,edx
call get_cluster_of_a_path
jc get_filesize_not_found
 
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc get_filesize_not_found
 
mov eax,[ebx+28] ; file size
test byte [ebx+11],0x10 ; is it directory?
jz get_filesize_set_size ; no
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
 
get_filesize_dirsize:
call get_dir_size
 
get_filesize_set_size:
mov PUSHAD_EBX,eax
popad
mov [hd1_status],0
xor eax,eax
ret
 
get_filesize_not_found:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
 
 
get_fileattr:
;-----------------------------------------------------------
; input : eax = file name
; edx = path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; ebx = file attribute
;-----------------------------------------------------------
cmp [fat_type],0
jnz get_fileattr_fat_ok
xor ebx,ebx
mov eax,ERROR_UNKNOWN_FS
ret
 
get_fileattr_fat_ok:
; call reserve_hd1
 
pushad
mov ebx,edx
call get_cluster_of_a_path
jc get_fileattr_not_found
 
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc get_fileattr_not_found
 
movzx eax,byte [ebx+11] ; file attribute
mov PUSHAD_EBX,eax
popad
mov [hd1_status],0
xor eax,eax
ret
 
get_fileattr_not_found:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
 
 
get_filedate:
;-----------------------------------------------------------
; input : eax = file name
; edx = path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; ebx = file date/time
; bits 31..25 = year-1980
; bits 24..21 = month
; bits 20..16 = day
; bits 15..11 = hour
; bits 10..5 = minute
; bits 4..0 = second/2
;-----------------------------------------------------------
cmp [fat_type],0
jnz get_filedate_fat_ok
xor ebx,ebx
mov eax,ERROR_UNKNOWN_FS
ret
 
get_filedate_fat_ok:
; call reserve_hd1
 
pushad
mov ebx,edx
call get_cluster_of_a_path
jc get_filedate_not_found
 
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc get_filedate_not_found
 
mov eax,[ebx+22] ; file date/time
mov PUSHAD_EBX,eax
popad
mov [hd1_status],0
xor eax,eax
ret
 
get_filedate_not_found:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
 
 
get_hd_info:
;-----------------------------------------------------------
; output : eax = 0 - ok
; 3 - unknown FS
; edx = cluster size in bytes
; ebx = total clusters on disk
; ecx = free clusters on disk
;-----------------------------------------------------------
cmp [fat_type],0
jnz info_fat_ok
xor edx,edx
xor ebx,ebx
xor ecx,ecx
mov eax,ERROR_UNKNOWN_FS
ret
 
info_fat_ok:
; call reserve_hd1
 
xor ecx,ecx ; count of free clusters
mov eax,2
mov ebx,[LAST_CLUSTER]
 
info_cluster:
push eax
call get_FAT ; get cluster info
test eax,eax ; is it free?
jnz info_used ; no
inc ecx
 
info_used:
pop eax
inc eax
cmp eax,ebx ; is above last cluster?
jbe info_cluster ; no. test next cluster
 
dec ebx ; cluster count
imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
mov [hd1_status],0
xor eax,eax
ret
 
 
update_disk:
;-----------------------------------------------------------
; write changed fat and cache to disk
;-----------------------------------------------------------
cmp [fat_change],0 ; is fat changed?
je upd_no_change
 
call write_fat_sector
 
upd_no_change:
 
call write_cache
ret
 
 
;**************************************************************************
;
; 0x600008 - first entry in cache list
;
; +0 - lba sector
; +4 - state of cache sector
; 0 = empty
; 1 = used for read ( same as in hd )
; 2 = used for write ( differs from hd )
;
; +65536 - cache entries
;
;**************************************************************************
 
 
hd_read:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
push ecx esi edi ; scan cache
 
mov ecx,cache_max ; entries in cache
mov esi,0x600000+8
mov edi,1
 
hdreadcache:
 
cmp dword [esi+4],0 ; empty
je nohdcache
 
cmp [esi],eax ; correct sector
je yeshdcache
 
nohdcache:
 
add esi,8
inc edi
dec ecx
jnz hdreadcache
 
call find_empty_slot ; ret in edi
 
call wait_for_hd_idle
push eax edx
 
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al ; ATAFeatures ðåãèñòð "îñîáåííîñòåé"
inc edx
inc eax
out dx,al ; ATASectorCount ñ÷åò÷èê ñåêòîðîâ
inc edx
mov eax,[esp+4]
out dx,al ; ATASectorNumber ðåãèñòð íîìåðà ñåêòîðà
shr eax,8
inc edx
out dx,al ; ATACylinder íîìåð öèëèíäðà (ìëàäøèé áàéò)
shr eax,8
inc edx
out dx,al ; íîìåð öèëèíäðà (ñòàðøèé áàéò)
shr eax,8
inc edx
and al,1+2+4+8
add al,byte [hdid]
add al,128+64+32
out dx,al ; íîìåð ãîëîâêè/íîìåð äèñêà
inc edx
mov al,20h
out dx,al ; ATACommand ðåãèñòð êîìàíä
sti
 
call wait_for_sector_buffer
 
cmp [hd_error],0
jne hd_read_error
 
cli
push edi
shl edi,9
add edi,0x600000+65536
mov ecx,256
mov edx,[hdbase]
cld
rep insw
pop edi
sti
 
pop edx eax
blok_read_2:
lea esi,[edi*8+0x600000]
mov [esi],eax ; sector number
mov dword [esi+4],1 ; hd read - mark as same as in hd
 
yeshdcache:
 
mov esi,edi
shl esi,9
add esi,0x600000+65536
mov edi,ebx
mov ecx,512/4
cld
rep movsd ; move data
; blok_read_2:
pop edi esi ecx
ret
 
hd_write:
;-----------------------------------------------------------
; input : eax = block
; ebx = pointer to memory
;-----------------------------------------------------------
push ecx esi edi
 
; check if the cache already has the sector and overwrite it
 
mov ecx,cache_max
mov esi,0x600000+8
mov edi,1
 
hdwritecache:
 
cmp dword [esi+4],0 ; if cache slot is empty
je not_in_cache_write
 
cmp [esi],eax ; if the slot has the sector
je yes_in_cache_write
 
not_in_cache_write:
 
add esi,8
inc edi
dec ecx
jnz hdwritecache
 
; sector not found in cache
; write the block to a new location
 
call find_empty_slot ; ret in edi
 
lea esi,[edi*8+0x600000]
mov [esi],eax ; sector number
 
yes_in_cache_write:
 
mov dword [esi+4],2 ; write - differs from hd
 
shl edi,9
add edi,0x600000+65536
mov esi,ebx
mov ecx,512/4
cld
rep movsd ; move data
 
pop edi esi ecx
ret
 
 
write_cache:
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
push eax ecx edx esi edi
 
; write difference ( 2 ) from cache to hd
 
mov ecx,cache_max
mov esi,0x600000+8
mov edi,1
 
write_cache_more:
 
cmp dword [esi+4],2 ; if cache slot is not different
jne does_not_need_writing
 
mov dword [esi+4],1 ; same as in hd
mov eax,[esi] ; eax = sector to write
 
cmp eax,[PARTITION_START]
jb danger
cmp eax,[PARTITION_END]
ja danger
 
call wait_for_hd_idle
 
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
inc eax
out dx,al
inc edx
mov eax,[esi] ; eax = sector to write
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
and al,1+2+4+8
add al,byte [hdid]
add al,128+64+32
out dx,al
inc edx
mov al,30h
out dx,al
sti
 
call wait_for_sector_buffer
 
cmp [hd_error],0
jne hd_write_error
 
push ecx esi
 
cli
mov esi,edi
shl esi,9
add esi,0x600000+65536 ; esi = from memory position
mov ecx,256
mov edx,[hdbase]
cld
rep outsw
sti
 
pop esi ecx
 
danger:
does_not_need_writing:
 
add esi,8
inc edi
dec ecx
jnz write_cache_more
 
pop edi esi edx ecx eax
ret
 
 
find_empty_slot:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
; output : edi = cache slot
;-----------------------------------------------------------
push ecx esi
 
search_again:
 
mov ecx,cache_max*10/100
mov edi,[cache_search_start]
 
search_for_empty:
 
inc edi
cmp edi,cache_max
jbe inside_cache
mov edi,1
 
inside_cache:
 
cmp dword [edi*8+0x600000+4],2 ; get cache slot info
jb found_slot ; it's empty or read
dec ecx
jnz search_for_empty
 
call write_cache ; no empty slots found, write all
jmp search_again ; and start again
 
found_slot:
 
mov [cache_search_start],edi
 
pop esi ecx
ret
 
 
save_hd_wait_timeout:
 
push eax
mov eax,[timer_ticks];[0xfdf0]
add eax,300 ; 3 sec timeout
mov [hd_wait_timeout],eax
pop eax
ret
 
 
check_hd_wait_timeout:
 
push eax
mov eax,[hd_wait_timeout]
cmp [timer_ticks], eax ;[0xfdf0],eax
jg hd_timeout_error
pop eax
ret
 
iglobal
hd_timeout_str db 'K : FS - HD timeout',13,10,0
hd_read_str db 'K : FS - HD read error',13,10,0
hd_write_str db 'K : FS - HD write error',13,10,0
endg
 
hd_timeout_error:
 
call clear_hd_cache
call clear_application_table_status
mov esi,hd_timeout_str
call sys_msg_board_str
jmp $
 
 
hd_read_error:
 
call clear_hd_cache
call clear_application_table_status
mov esi,hd_read_str
call sys_msg_board_str
jmp $
 
hd_write_error:
 
call clear_hd_cache
call clear_application_table_status
mov esi,hd_write_str
call sys_msg_board_str
jmp $
 
 
 
 
wait_for_hd_idle:
 
push eax edx
 
call save_hd_wait_timeout
 
mov edx,[hdbase]
add edx,0x7
 
wfhil1:
 
call check_hd_wait_timeout
 
in al,dx
test al,128
jnz wfhil1
 
pop edx eax
ret
 
 
wait_for_sector_buffer:
 
push eax edx
 
mov edx,[hdbase]
add edx,0x7
 
call save_hd_wait_timeout
 
hdwait_sbuf: ; wait for sector buffer to be ready
 
call check_hd_wait_timeout
 
in al,dx
test al,8
jz hdwait_sbuf
 
mov [hd_error],0
 
cmp [hd_setup],1 ; do not mark error for setup request
je buf_wait_ok
 
test al,1 ; previous command ended up with an error
jz buf_wait_ok
mov [hd_error],1
 
buf_wait_ok:
 
pop edx eax
ret
 
 
 
read_hd_file:
;-----------------------------------------------------------------
;
; Converting old reading function for hd-application start.
;
; IN:
;
; eax - pointer to file (0 = read only first sector of drive: eg 'label')
; ebx - file lenght
; ecx - start 512 byte block number
; edx - number of blocks to read
; esi - pointer to return/work area (atleast 20 000 bytes)
;
; For new read function
;
; EAX (PAR0) pointer to file-name
; ECX (PAR1) pointer to buffer
; EBX (PAR2) vt file blocks to read
; EDX (PAR3) pointer to path
; ESI vt first 512 block to read
; EDI if 0 - return root
;--------------------------------------------------------------------------
 
push ecx esi edi
mov esi,eax
mov edi,startpath
mov ecx,250
cld
rep movsb
pop edi esi ecx
 
mov eax,startpath
mov [eax+ebx-12],byte 0
 
push eax ebx ecx edx esi
 
pop ecx ; pointer to buffer
add ecx,1024
pop ebx ; number of blocks to read
pop esi ; first block to read
dec esi
pop eax ; file length
pop edx ; pointer to path
 
mov edi,12
lea eax,[eax+edx-12+1]
call file_read
 
ret
 
/kernel/trunk/fs/fs.inc
0,0 → 1,1095
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; System service for filesystem call ;;
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; ;;
;; 15.01.2005 get file size/attr/date, file_append (only for hd) - ATV ;;
;; 23.11.2004 test if hd/partition is set - ATV ;;
;; 18.11.2004 get_disk_info and more error codes - ATV ;;
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;;
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
iglobal
dir0: db 'HARDDISK '
db 'RAMDISK '
db 'FLOPPYDISK '
db 0
 
dir1: db 'FIRST '
db 'SECOND '
db 'THIRD '
db 'FOURTH '
db 0
 
not_select_IDE db 0
 
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10
dd 0x170,0x00,0x170,0x10
endg
 
file_system:
; IN:
;
; eax = 0 ; read file /RamDisk/First 6 /HardDisk/First 30
; eax = 1 ; write file /RamDisk/First 33 /HardDisk/First 56
; eax = 2 ; delete file /RamDisk/First 32 /HardDisk/First 57
; eax = 3 ; append to a file /RamDisk/First ?? /HardDisk/First ??
; eax = 4 ; makedir
; eax = 5 ; rename file/directory
; eax = 8 ; lba read