Kolibri 5 initial checkout

git-svn-id: svn://kolibrios.org@1 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
ha 2005-10-06 17:56:22 +00:00
commit d8e9ce1559
67 changed files with 40886 additions and 0 deletions

261
trunk/blkdev/cdrom.inc Normal file
View File

@ -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

369
trunk/blkdev/fdc.inc Normal file
View File

@ -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

685
trunk/blkdev/flp_drv.inc Normal file
View File

@ -0,0 +1,685 @@
;**********************************************************
; <EFBFBD>¥¯®á।á⢥­­ ï à ¡®â  á ª®­â஫«¥à®¬ £¨¡ª®£® ¤¨áª 
;**********************************************************
; €¢â®à ¨á室­®£® ⥪áâ  Šã« ª®¢ ‚« ¤¨¬¨à ƒ¥­­ ¤ì¥¢¨ç.
; €¤ ¯â æ¨ï ¨ ¤®à ¡®âª  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:
; “áâ ­®¢¨âì ­®¢ë© ®¡à ¡®â稪 ¯à¥à뢠­¨ï <EFBFBD>ƒŒ„
call SetUserInterrupts
; ‚ª«îç¨âì ¬®â®à ¤¨áª®¢®¤ 
call FDDMotorON
; ˆ­¨æ¨ «¨§¨à®¢ âì ¯¥à¥¬¥­­ë¥
; mov [FDD_Track],0
; mov [FDD_Head],0
; mov [FDD_Sector],1
; <EFBFBD>஢¥á⨠४ «¨¡à®¢ªã ¨ ¯®¨áª ­ã«¥¢®© ¤®à®¦ª¨
call RecalibrateFDD
call SeekTrack
ret
flp_readsector:
call flp_initialization
; <EFBFBD>à®ç¨â âì ᥪâ®à
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 ?
; Š®¤ § ¢¥à襭¨ï ®¯¥à æ¨¨ á ª®­â஫«¥à®¬ <EFBFBD>ƒŒ„
FDC_Status DB ?
; ”« £ ¯à¥à뢠­¨ï ®â <EFBFBD>ƒŒ„
FDD_IntFlag DB ?
; Œ®¬¥­â ­ ç «  ¯®á«¥¤­¥© ®¯¥à æ¨¨ á <EFBFBD>ƒŒ„
FDD_Time DD ?
; <EFBFBD>®¬¥à ¤¨áª®¢®¤ 
FDD_Type db 0
; Š®®à¤¨­ âë ᥪâ®à 
FDD_Track DB ?
FDD_Head DB ?
FDD_Sector DB ?
; <EFBFBD>«®ª १ã«ìâ â  ®¯¥à æ¨¨
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
;*************************************
;* ˆ<EFBFBD>ˆˆˆ‡€ˆŸ <EFBFBD>…†ˆŒ€ <EFBFBD><EFBFBD> „‹Ÿ <EFBFBD>ƒŒ„ *
;*************************************
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
;***********************************
;* ‡€<EFBFBD>ˆœ <EFBFBD>€‰ <EFBFBD>Ž<EFBFBD> „€<EFBFBD><EFBFBD> FDC *
;* <EFBFBD> à ¬¥âàë: *
;* AL - ¢ë¢®¤¨¬ë© ¡ ©â. *
;***********************************
FDCDataOutput:
; pusha
push ax cx dx
mov AH,AL ;§ ¯®¬­¨âì ¡ ©â ¢ AH
; ‘¡à®á¨âì ¯¥à¥¬¥­­ãî á®áâ®ï­¨ï ª®­â஫«¥à 
mov [FDC_Status],FDC_Normal
; <EFBFBD>஢¥à¨âì £®â®¢­®áâì ª®­â஫«¥à  ª ¯à¨¥¬ã ¤ ­­ëå
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
;******************************************
;* <EFBFBD><EFBFBD>Ž—ˆœ <EFBFBD>€‰ ˆ‡ <EFBFBD>Ž<EFBFBD> „€<EFBFBD><EFBFBD> FDC *
;* <EFBFBD>à®æ¥¤ãà  ­¥ ¨¬¥¥â ¢å®¤­ëå ¯ à ¬¥â஢. *
;* ‚ë室­ë¥ ¤ ­­ë¥: *
;* AL - áç¨â ­­ë© ¡ ©â. *
;******************************************
FDCDataInput:
push ECX
push DX
; ‘¡à®á¨âì ¯¥à¥¬¥­­ãî á®áâ®ï­¨ï ª®­â஫«¥à 
mov [FDC_Status],FDC_Normal
; <EFBFBD>஢¥à¨âì £®â®¢­®áâì ª®­â஫«¥à  ª ¯¥à¥¤ ç¥ ¤ ­­ëå
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
;*********************************************
;* Ž<EFBFBD><EFBFBD><EFBFBD>ŽˆŠ <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˆŸ Ž’ ŠŽ<EFBFBD><EFBFBD>Ž<EFBFBD> <EFBFBD>ƒŒ„ *
;*********************************************
FDCInterrupt:
; <EFBFBD> §à¥è¨âì ¯à¥à뢠­¨ï
; sti
; push AX
; “áâ ­®¢¨âì ä« £ ¯à¥à뢠­¨ï
mov [FDD_IntFlag],1
; <EFBFBD>®á« âì ª®¬ ­¤ã EOI ª®­â஫«¥àã ¯à¥à뢠­¨©
; mov AL,20h
; out 20h,AL
; pop AX
ret
;******************************************
;* <EFBFBD>Žˆœ <EFBFBD>Ž Ž<EFBFBD><EFBFBD><EFBFBD>ŽˆŠ <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˆ *
;* <EFBFBD>ƒŒ„ *
;******************************************
SetUserInterrupts:
mov [fdc_irq_func],FDCInterrupt
ret
;*******************************************
;* Ž†ˆ„€<EFBFBD>ˆ <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˆŸ Ž’ ŠŽ<EFBFBD><EFBFBD>Ž<EFBFBD> <EFBFBD>ƒŒ„ *
;*******************************************
WaitFDCInterrupt:
pusha
; ‘¡à®á¨âì ¡ ©â á®áâ®ï­¨ï ®¯¥à æ¨¨
mov [FDC_Status],FDC_Normal
; ‘¡à®á¨âì ä« £ ¯à¥à뢠­¨ï
mov [FDD_IntFlag],0
; Ž¡­ã«¨âì áç¥â稪 ⨪®¢
mov eax,[timer_ticks]
mov [TickCounter],eax
; Ž¦¨¤ âì ãáâ ­®¢ª¨ ä« £  ¯à¥à뢠­¨ï <EFBFBD>ƒŒ„
@@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
;*********************************
;* ‚Š‹ž—ˆ’œ ŒŽŽ<EFBFBD> „ˆ‘ŠŽ‚Ž„€ "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
; <EFBFBD>ந§¢¥á⨠á¡à®á ª®­â஫«¥à  <EFBFBD>ƒŒ„
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
;*****************************************
;* Ž•<EFBFBD><EFBFBD><EFBFBD>ˆ “Š€‡€’…‹Ÿ <EFBFBD>…Œ…<EFBFBD>ˆ *
;*****************************************
save_timer_fdd_motor:
mov eax,[timer_ticks]
mov [timer_fdd_motor],eax
ret
;*****************************************
;* <EFBFBD><EFBFBD>Ž<EFBFBD>Š€ ‡€„…<EFBFBD>†Šˆ Šž—…<EFBFBD>ˆŸ ŒŽŽ<EFBFBD> *
;*****************************************
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
;**********************************
;* ‚›Š‹ž—ˆ’œ ŒŽŽ<EFBFBD> „ˆ‘ŠŽ‚Ž„€ *
;**********************************
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
;*******************************
;* <EFBFBD>…Š€ˆ<EFBFBD><EFBFBD>ŽŠ€ „ˆ‘ŠŽ‚Ž„€ "A:" *
;*******************************
RecalibrateFDD:
pusha
call save_timer_fdd_motor
; <EFBFBD>®¤ âì ª®¬ ­¤ã "<EFBFBD>¥ª «¨¡à®¢ª "
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
;*****************************************************
;* <EFBFBD>ŽˆŠ „Ž<EFBFBD>Ž†Šˆ *
;* <EFBFBD> à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1). *
;* <EFBFBD>¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ FDC_Status. *
;*****************************************************
SeekTrack:
pusha
call save_timer_fdd_motor
; <EFBFBD>®¤ âì ª®¬ ­¤ã "<EFBFBD>®¨áª"
mov AL,0Fh
call FDCDataOutput
; <EFBFBD>¥à¥¤ âì ¡ ©â ­®¬¥à  £®«®¢ª¨/­ ª®¯¨â¥«ï
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
; <EFBFBD>¥à¥¤ âì ¡ ©â ­®¬¥à  ¤®à®¦ª¨
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
; <EFBFBD>஢¥à¨âì १ã«ìâ â ¯®¨áª 
; <EFBFBD>®¨áª § ¢¥à襭?
test [FDC_ST0],100000b
je @@Err
; ‡ ¤ ­­ë© â४ ­ ©¤¥­?
mov AL,[FDC_C]
cmp AL,[FDD_Track]
jne @@Err
; <EFBFBD>®¬¥à £®«®¢ª¨ ᮢ¯ ¤ ¥â á § ¤ ­­ë¬?
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
;*******************************************************
;* <EFBFBD>ˆ …ŠŽ<EFBFBD> „€<EFBFBD><EFBFBD> *
;* <EFBFBD> à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1); *
;* FDD_Sector - ­®¬¥à ᥪâ®à  (1-18). *
;* <EFBFBD>¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ 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
; <EFBFBD>®¤ âì ª®¬ ­¤ã "—⥭¨¥ ¤ ­­ëå"
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
;*******************************************************
;* <EFBFBD>ˆ …ŠŽ<EFBFBD> ( <EFBFBD>ŽŽ<EFBFBD><EFBFBD>ˆ…Œ Ž<EFBFBD><EFBFBD>ˆˆ <EFBFBD><EFBFBD>ˆ <EFBFBD>Ž…) *
;* <EFBFBD> à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1); *
;* FDD_Sector - ­®¬¥à ᥪâ®à  (1-18). *
;* <EFBFBD>¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ 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
;*******************************************************
;* ‡€<EFBFBD>ˆœ …ŠŽ<EFBFBD> „€<EFBFBD><EFBFBD> *
;* <EFBFBD> à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1); *
;* FDD_Sector - ­®¬¥à ᥪâ®à  (1-18). *
;* <EFBFBD>¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ 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
; <EFBFBD>®¤ âì ª®¬ ­¤ã "‡ ¯¨áì ¤ ­­ëå"
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
;*******************************************************
;* ‡€<EFBFBD>ˆœ …ŠŽ<EFBFBD> ( <EFBFBD>ŽŽ<EFBFBD><EFBFBD>ˆ…Œ Ž<EFBFBD><EFBFBD>ˆˆ <EFBFBD><EFBFBD>ˆ <EFBFBD>Ž…) *
;* <EFBFBD> à ¬¥âàë ¯¥à¥¤ îâáï ç¥à¥§ £«®¡ «ì­ë¥ ¯¥à¥¬¥­­ë¥: *
;* FDD_Track - ­®¬¥à ¤®à®¦ª¨ (0-79); *
;* FDD_Head - ­®¬¥à £®«®¢ª¨ (0-1); *
;* FDD_Sector - ­®¬¥à ᥪâ®à  (1-18). *
;* <EFBFBD>¥§ã«ìâ â ®¯¥à æ¨¨ § ­®á¨âáï ¢ 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
;*********************************************
;* <EFBFBD>Ž“—ˆœ ˆ<EFBFBD>”Ž<EFBFBD>Œ€ˆž Ž <EFBFBD>…‡“œ Ž<EFBFBD><EFBFBD>ˆˆ *
;*********************************************
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

446
trunk/blkdev/rd.inc Normal file
View File

@ -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

26
trunk/blkdev/rdsave.inc Normal file
View File

@ -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:

917
trunk/boot/bootcode.inc Normal file
View File

@ -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

109
trunk/boot/booteng.inc Normal file
View File

@ -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

110
trunk/boot/bootru.inc Normal file
View File

@ -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 '­â¨©; <20>®¤à®¡­¥¥ - á¬. 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," <20>à®á¬®âà¥âì ¦ãà­ « § £à㧪¨? [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," Žè¨¡ª  - <20>¥ ¬®£ã ®¯à¥¤¥«¨âì £«ã¡¨­ã 梥â .",0
fatalsel db 13,10,"Žè¨¡ª  - ‚ë¡à ­­ë© ¢¨¤¥®à¥¦¨¬ ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0
badsect db 13,10,186," Žè¨¡ª  - „¨áª¥â  ¯®¢à¥¦¤¥­ . <20>®¯à®¡ã©â¥ ¤àã£ãî. "
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

23
trunk/boot/preboot.inc Normal file
View File

@ -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

95
trunk/boot/rdload.inc Normal file
View File

@ -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:

92
trunk/boot/ru.inc Normal file
View File

@ -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

496
trunk/boot/shutdown.inc Normal file
View File

@ -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 "<EFBFBD>¥§®¯ á­®¥ ¢ëª«î祭¨¥ ª®¬¯ìîâ¥à  ¨«¨ "
db ' '
db '1) ‘®åà ­¨âì à ¬¤¨áª ­  ¤¨áª¥âã '
db '2) APM - ¢ëª«î祭¨¥ ¯¨â ­¨ï '
db '3) <20>¥à¥§ £à㧪  á¨á⥬ë '
db '4) <20>¥áâ àâ ï¤à  ¨§ Ž‡“ '
rosef:
db 'ROSE TXT'
endg

4
trunk/build_en.bat Normal file
View File

@ -0,0 +1,4 @@
@if not exist lang.inc (
@echo lang fix en >lang.inc
)
@fasm kernel.asm kernel.mnt

4
trunk/build_ru.bat Normal file
View File

@ -0,0 +1,4 @@
@if not exist lang.inc (
@echo lang fix ru >lang.inc
)
@fasm kernel.asm kernel.mnt

46
trunk/bus/pci/pci16.inc Normal file
View File

@ -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

358
trunk/bus/pci/pci32.inc Normal file
View File

@ -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

62
trunk/core/fpu.inc Normal file
View File

@ -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

473
trunk/core/mem.inc Normal file
View File

@ -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

977
trunk/core/memmanag.inc Normal file
View File

@ -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

1321
trunk/core/newproce.inc Normal file

File diff suppressed because it is too large Load Diff

218
trunk/core/physmem.inc Normal file
View File

@ -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

286
trunk/core/sched.inc Normal file
View File

@ -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

111
trunk/core/sync.inc Normal file
View File

@ -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

2301
trunk/core/sys32.inc Normal file

File diff suppressed because it is too large Load Diff

238
trunk/core/syscall.inc Normal file
View File

@ -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

121
trunk/detect/commouse.inc Normal file
View File

@ -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

20
trunk/detect/dev_fd.inc Normal file
View File

@ -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

374
trunk/detect/dev_hdcd.inc Normal file
View File

@ -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:

4
trunk/detect/disks.inc Normal file
View File

@ -0,0 +1,4 @@
include 'dev_fd.inc'
include 'dev_hdcd.inc'
include 'sear_par.inc'

116
trunk/detect/sear_par.inc Normal file
View File

@ -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

1084
trunk/fs/fat12.inc Normal file

File diff suppressed because it is too large Load Diff

2827
trunk/fs/fat32.inc Normal file

File diff suppressed because it is too large Load Diff

1095
trunk/fs/fs.inc Normal file

File diff suppressed because it is too large Load Diff

111
trunk/fs/fs_phys.inc Normal file
View File

@ -0,0 +1,111 @@
hd_phys_read:
;eax - sector number
;ebx - destination
pushad
call wait_for_hd_idle
popad
push edx
push eax
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
inc eax
out dx,al
inc edx
;write sector number.
mov eax,[esp]
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] ;+0 or +16
or al,32+64+128
out dx,al
inc edx
mov al,0x20
out dx,al
sti
call wait_for_sector_buffer
cmp [hd_error],0
jnz hd_read_error
cli
push edi
mov edi,ebx
mov ecx,256
mov edx,[hdbase]
cld
rep insw
pop edi
sti
pop edx
pop eax
ret
hd_phys_write:
;eax - sector number
;ebx - destination
cmp eax,[partition_start]
jb .ret
cmp eax,[partition_end]
ja .ret
pushad
call wait_for_hd_idle
popad
push edx
push eax
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
inc eax
out dx,al
;write sector number
inc edx
mov eax,[esp]
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] ;+0 or +16
or al,32+64+128
out dx,al
inc edx
mov al,0x30
out dx,al
sti
call wait_for_sector_buffer
cmp [hd_error],0
jnz hd_write_error
cli
push esi
mov esi,ebx
mov ecx,256
mov edx,[hdbase]
cld
rep outsw
pop esi
sti
pop edx
pop eax
.ret:
ret

551
trunk/gui/button.inc Normal file
View File

@ -0,0 +1,551 @@
max_buttons=4095
dececx:
push eax
push edx
push ecx
mov edx,1
dececl:
movzx eax,byte [esp+edx]
cmp eax,0x20
jge @f
mov [esp+edx],byte 0x20
@@:
sub [esp+edx],byte 0x20
add edx,1
cmp edx,4
jbe dececl
pop ecx
pop edx
pop eax
ret
drawbuttonframes:
push esi
push edi
push eax
push ebx
push ecx
push edx
shr eax,16
shr ebx,16
mov edx,[0x3010]
add eax,[edx-twdw]
add ebx,[edx-twdw+4]
mov cx,ax
mov dx,bx
shl eax,16
shl ebx,16
mov ax,cx
mov bx,dx
add ax,word [esp+12]
mov esi,ebx
mov edi,0
mov ecx,[esp+0]
add ecx,0x202020
call [draw_line]
movzx edx,word [esp+8]
add ebx,edx
shl edx,16
add ebx,edx
mov ecx,[esp+0]
call dececx
call [draw_line]
mov ebx,esi
push edx
mov edx,eax
shr edx,16
mov ax,dx
mov edx,ebx
shr edx,16
mov bx,dx
mov dx,[esp+8+4]
add bx,dx
pop edx
mov edi,0
mov ecx,[esp+0]
add ecx,0x202020
call [draw_line]
mov esi,edx
mov dx,[esp+12]
add ax,dx
shl edx,16
add eax,edx
add ebx,1*65536
mov edx,esi
mov ecx,[esp+0]
call dececx
call [draw_line]
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
ret
button_dececx:
cmp [buttontype],dword 1
jne .finish
; je bdece
; ret
; bdece:
push eax
mov eax,0x01
cmp edi,20
jg @f
mov eax,0x02
@@:
test ecx,0xff
jz @f
sub ecx,eax
@@:
shl eax,8
test ecx,0xff00
jz @f
sub ecx,eax
@@:
shl eax,8
test ecx,0xff0000
jz @f
sub ecx,eax
@@:
pop eax
.finish:
ret
sys_button:
test ecx,0x80000000
jnz remove_button
push esi
push edi
push eax
push ebx
push ecx
push edx
test ecx,0x40000000
jnz button_no_draw
pushad ; button body
push ebx
shr eax,16
shr ebx,16
mov edx,[0x3010]
mov esi,[edx-twdw]
mov edi,[edx-twdw+4]
add eax,esi
add ebx,edi
mov cx,ax
mov dx,bx
shl eax,16
shl ebx,16
mov ax,cx
mov bx,dx
movzx ecx,word [4+32+esp+12]
add eax,ecx
mov ecx,[4+32+esp+0]
cmp [buttontype],dword 0
je @f
add ecx,0x141414
@@:
movzx edi,word [esp]
; <Ivan Poddubny 15.08.2004>
pop edx
and edx, 0xFFFF
;;cli
.newline:
call button_dececx
push edi
xor edi, edi
call [draw_line]
pop edi
add ebx,1*65536+1 ; [ y start | y end ]
dec edx
jnz .newline
;;sti
;; pop ebx
; </Ivan Poddubny 15.08.2004>
popad
call drawbuttonframes
button_no_draw:
and ecx,0xffff
mov edi,[0x3010]
sub edi,twdw
mov edi,[0xfe88]
movzx eax,word [edi]
cmp eax,max_buttons
jge noaddbutt
inc eax
mov [edi],ax
shl eax,4
add eax,edi
mov bx,[0x3000]
mov [eax],bx
add eax,2 ; save button id number
mov ebx,[esp+4]
mov [eax],bx ; bits 0-15
shr ebx,16
mov [eax-2+0xc],bx; bits 16-31
add eax,2 ; x start
mov bx,[esp+12+2]
mov [eax],bx
add eax,2 ; x size
mov bx,[esp+12+0]
mov [eax],bx
add eax,2 ; y start
mov bx,[esp+8+2]
mov [eax],bx
add eax,2 ; y size
mov bx,[esp+8+0]
mov [eax],bx
noaddbutt:
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
ret
remove_button:
and ecx,0x7fffffff
rnewba2:
mov edi,[0xfe88]
mov eax,edi
movzx ebx,word [edi]
inc bx
rnewba:
dec bx
jz rnmba
add eax,0x10
mov dx,[0x3000]
cmp dx,[eax]
jnz rnewba
cmp cx,[eax+2]
jnz rnewba
pushad
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popad
jmp rnewba2
rnmba:
ret
find_pressed_button_frames:
pushad
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
movzx ecx,word [ebx+0] ; window x start
movzx edx,word [eax+4] ; button x start
add ecx,edx
push ecx
mov dx,[eax+6] ; button x size
add cx,dx
mov esi,ecx
inc esi
mov cx,[ebx+4] ; window y start
mov dx,[eax+8] ; button y start
add ecx,edx
mov ebx,ecx
mov dx,[eax+10] ; button y size
add dx,cx
inc dx
pop eax
; eax x beginning
; ebx y beginning
; esi x end
; edx y end
; ecx color
mov [pressed_button_eax],eax
mov [pressed_button_ebx],ebx
mov [pressed_button_ecx],ecx
mov [pressed_button_edx],edx
mov [pressed_button_esi],esi
popad
ret
uglobal
pressed_button_eax dd 0
pressed_button_ebx dd 0
pressed_button_ecx dd 0
pressed_button_edx dd 0
pressed_button_esi dd 0
endg
; negative button image
negativebutton:
; If requested, do not display button
; boarder on press.
test ebx,0x20000000
jz draw_negative_button
ret
draw_negative_button:
pushad
mov eax,[pressed_button_eax]
mov ebx,[pressed_button_ebx]
mov ecx,[pressed_button_ecx]
mov edx,[pressed_button_edx]
mov esi,[pressed_button_esi]
mov ecx,0x01000000
dec edx
push edx
inc edx
dec esi
push esi
inc esi
push eax
push ebx
push ecx
push edx
push edi
call [disable_mouse]
bdbnewline:
mov edi,1 ; force
cmp eax,[esp+16]
jz bneg
cmp eax,[esp+20]
jz bneg
cmp ebx,[esp+12]
jz bneg
cmp ebx,[esp+24]
jnz nbneg
; jz bneg
; jmp nbneg
bneg:
;;;call [disable_mouse]
call [putpixel]
nbneg:
inc eax
cmp eax,esi
jnz bdbnewline
mov eax,[esp+16]
inc ebx
cmp ebx,edx
jnz bdbnewline
add esp,28
popad
ret
; check buttons
; 0000 word process number
; 0002 word button id number : bits 0-15
; 0004 word x start
; 0006 word x size
; 0008 word y start
; 000A word y size
; 000C word button id number : bits 16-31
;
; button table in 0x10 increments
;
; first at 0x10
checkbuttons:
cmp [0xfb40],byte 0 ; mouse buttons pressed
jnz @f
ret
@@:
pushad
xor esi, esi
mov edi, [0xfe88]
movzx edx, word [edi]
test edx, edx
jne @f
popad
ret
@@:
push esi
inc edx
push edx
buttonnewcheck:
pop edx
pop esi
inc esi
cmp edx,esi
jge bch
popad ; no button pressed
ret
bch:
push esi
push edx
mov eax,esi
shl eax,4
add eax,edi
; check that button is at top of windowing stack
movzx ebx,word [eax]
movzx ecx,word [0xC000 + ebx * 2]
cmp ecx,[0x3004]
jne buttonnewcheck
; check that button start is inside window x/y end
movzx ebx,word [eax+0]
shl ebx,5
; add ebx,window_data
; mov ecx,[window_data+ebx+8] ; window end X
movzx edx,word [eax+4] ; button start X
cmp edx, [window_data+ebx+8] ;ecx
jge buttonnewcheck
; mov ecx,[window_data+ebx+12] ; window end Y
movzx edx, word [eax+8] ; button start Y
cmp edx, [window_data+ebx+12] ;ecx
jge buttonnewcheck
; check coordinates
; mouse x >= button x ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
movzx ecx,word [ebx+0] ; window x start
movzx edx,word [eax+4] ; button x start
add edx,ecx
mov cx,[0xfb0a]
cmp edx,ecx
jg buttonnewcheck
movzx ebx,word [eax+6] ; button x size
add edx,ebx
cmp ecx,edx
jg buttonnewcheck
; mouse y >= button y ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
movzx ecx,word [ebx+4] ; window y start
movzx edx,word [eax+8] ; button y start
add edx,ecx
mov cx,[0xfb0c]
cmp edx,ecx
jg buttonnewcheck
movzx ebx,word [eax+10] ; button y size
add edx,ebx
cmp ecx,edx
jg buttonnewcheck
; mouse on button
pop edx
pop esi
mov bx,[eax+0xc] ; button id : bits 16-31
shl ebx,16
mov bx,[eax+2] ; button id : bits 00-16
push ebx
mov [0xfb44],byte 1 ; no mouse down checks
call find_pressed_button_frames
call negativebutton
pushad
cbwaitmouseup:
call checkidle
call check_mouse_data
call [draw_pointer]
pushad
call stack_handler
popad
cmp [0xfb40],byte 0 ; mouse buttons pressed ?
jnz cbwaitmouseup
popad
call negativebutton
mov [0xfff4],byte 0 ; no mouse background
mov [0xfff5],byte 0 ; draw mouse
mov [0xf500],byte 1
pop ebx
mov [0xf501],ebx
mov [0xfb44],byte 0 ; mouse down checks
popad
ret

188
trunk/gui/event.inc Normal file
View File

@ -0,0 +1,188 @@
sys_getevent:
call get_event_for_app
mov [esp+36],eax
ret
align 4
sys_wait_event_timeout:
mov ebx,[timer_ticks];[0xfdf0]
add ebx,eax
cmp ebx,[timer_ticks];[0xfdf0]
jna .swfet2
.swfet1:
call get_event_for_app
test eax,eax
jne .eventoccur_time
call change_task
cmp ebx,[timer_ticks];[0xfdf0]
jg .swfet1
.swfet2:
xor eax,eax
.eventoccur_time:
mov [esp+36],eax
ret
align 4
sys_waitforevent:
call get_event_for_app
test eax,eax
jne eventoccur
newwait:
call change_task
call get_event_for_app
test eax,eax
je newwait
eventoccur:
mov [esp+36],eax
ret
get_event_for_app:
pushad
mov edi,[0x3010] ; WINDOW REDRAW
test [edi],dword 1
jz no_eventoccur1
mov edi,[0x3010]
cmp [edi-twdw+31],byte 0
je no_eventoccur1
popad
mov eax,1
ret
no_eventoccur1:
mov edi,[0x3010] ; KEY IN BUFFER
test [edi],dword 2
jz no_eventoccur2
mov ecx, [0x3000]
movzx edx,word [0xC000+ecx*2]
mov eax, [0x3004]
cmp eax,edx
jne no_eventoccur2
cmp [0xf400],byte 0
je no_eventoccur2
popad
mov eax,2
ret
no_eventoccur2:
mov edi,[0x3010] ; BUTTON IN BUFFER
test [edi],dword 4
jz no_eventoccur3
mov ecx, [0x3000]
movzx edx, word [0xC000+ecx*2]
mov eax, [0x3004]
cmp eax,edx
jnz no_eventoccur3
cmp [0xf500],byte 0
je no_eventoccur3
popad
mov eax,[0xf501]
cmp eax,65535
je no_event_1
mov eax,3
ret
no_event_1:
mov [window_minimize],1
mov [0xf500],byte 0
xor eax, eax
ret
no_eventoccur3:
mov edi,[0x3010] ; DESKTOP BACKGROUND REDRAW
test [edi],dword 16
jz no_eventoccur5
cmp [0xfff0],byte 2
jnz no_eventoccur5
popad
mov eax,5
ret
no_eventoccur5:
mov edi,[0x3010] ; mouse event
test [edi],dword 00100000b
jz no_mouse_event
mov edi,[0x3000]
shl edi,8
test [edi+0x80000+0xA8],dword 00100000b
jz no_mouse_event
and [edi+0x80000+0xA8],dword 0xffffffff-00100000b
popad
mov eax,6
ret
no_mouse_event:
mov edi,[0x3010] ; IPC
test [edi],dword 01000000b
jz no_ipc
mov edi,[0x3000]
shl edi,8
test [edi+0x80000+0xA8],dword 01000000b
jz no_ipc
and [edi+0x80000+0xA8],dword 0xffffffff-01000000b
popad
mov eax,7
ret
no_ipc:
mov edi,[0x3010] ; STACK
test [edi],dword 10000000b
jz no_stack_event
mov edi,[0x3000]
shl edi,8
test [edi+0x80000+0xA8],dword 10000000b
jz no_stack_event
and [edi+0x80000+0xA8],dword 0xffffffff-10000000b
popad
mov eax,7
ret
no_stack_event:
mov esi,0x2e0000 ; IRQ'S AND DATA
mov ebx,0x00010000
xor ecx, ecx
irq_event_test:
mov edi,[0x3010]
test [edi],ebx
jz no_irq_event
mov edi,ecx
shl edi,2
add edi,irq_owner
mov edx,[edi]
mov eax,[0x3010]
mov eax,[eax+0x4]
cmp edx,eax
jne no_irq_event
cmp [esi],dword 0
jz no_irq_event
mov eax,ecx
add eax,16
mov [esp+28],eax
popad
ret
no_irq_event:
add esi,0x1000
shl ebx,1
inc ecx
cmp ecx,16
jb irq_event_test
popad
xor eax, eax
ret

225
trunk/gui/font.inc Normal file
View File

@ -0,0 +1,225 @@
align 4
dtext:
; eax x & y
; ebx font ( 0xX0000000 ) & color ( 0x00RRGGBB )
; ecx start of text
; edx length
; edi 1 force
test ebx,0x10000000
jnz dtext2
pushad
mov esi, edx
and esi, 0xff
test esi, esi ; zero length ?
jnz @f
popad
ret
@@:
align 4
.letnew:
push eax ecx edx
movzx ebx,ax
shr eax,16
movzx edx,byte [ecx]
mov ecx,[esp+3*4+32-16]
call drawletter
pop edx ecx eax
add eax,6*65536
inc ecx
dec edx
jnz .letnew
popad
ret
align 4
drawletter:
; eax x
; ebx y
; ecx color
; edx letter
; esi shl size
; edi force
pushad
call [disable_mouse]
xor eax, eax
xor ebx, ebx ; 0x37000+eax+ebx*8
inc esi
align 4
chc:
push eax
push ebx
mov edx,ebx
shl edx,3
add edx,eax
add edx,0x37000+8
mov ecx,[esp+32-12+8]
imul ecx,8*10
add edx,ecx
cmp [edx],byte 'o'
jnz .nopix
mov eax,[esp+4]
mov ebx,[esp+0]
add eax,[esp+32+2*4-4]
add ebx,[esp+32+2*4-16]
mov ecx,[esp+32+2*4-8]
;;;call [disable_mouse]
call [putpixel]
.nopix:
pop ebx
pop eax
inc eax
cmp eax,5 ; ebp
jne chc
xor eax, eax
inc ebx
cmp ebx,9 ; ebp
jne chc
popad
ret
dtext2:
; eax x & y
; ebx color
; ecx start of text
; edx length
; edi 1 force
pushad
mov esi,edx
and esi,0xff
test esi,esi ; zero length ?
jnz @f
popad
ret
@@:
align 4
letnew2:
push eax
push ecx
push edx
movzx ebx,ax
shr eax,16
movzx edx,byte [ecx]
mov ecx,[esp+3*4+32-16]
call drawletter2
pop edx
pop ecx
pop eax
push edx
movzx edx,byte [ecx]
imul edx,10*10
add edx,0x30000
cmp [edx+6],byte ' '
jne nocharadd8
add eax,8*65536
jmp charaddok
nocharadd8:
movzx edx,byte [edx+6]
sub edx,47
shl edx,16
add eax,edx
charaddok:
pop edx
inc ecx
dec edx
jnz letnew2
popad
ret
align 4
drawletter2:
; eax x
; ebx y
; ecx color
; edx letter
; esi shl size
; edi force
pushad
call [disable_mouse]
xor eax, eax
xor ebx, ebx ; +eax+ebx*8
inc esi
align 4
chc2:
push eax
push ebx
; cmp esi,1
; je noldiv
; xor edx,edx
; div esi
; push eax
; xor edx,edx
; mov eax,ebx
; div esi
; mov ebx,eax
; pop eax
; noldiv:
mov edx,ebx
;shl edx,3
imul edx,10
add edx,eax
add edx,0x30000+8+2
mov ecx,[esp+32-12+8]
;shl ecx,6
imul ecx,10*10
add edx,ecx
cmp [edx],byte 'o'
jnz nopix2
mov eax,[esp+4]
mov ebx,[esp+0]
add eax,[esp+32+2*4-4]
add ebx,[esp+32+2*4-16]
mov ecx,[esp+32+2*4-8]
;;;call [disable_mouse]
call [putpixel]
nopix2:
pop ebx
pop eax
;mov ebp,7
;imul ebp,esi
inc eax
cmp eax,7 ;ebp
jnz chc2
xor eax, eax
;mov ebp,9
;imul ebp,esi
inc ebx
cmp ebx,9 ; ebp
jnz chc2
popad
ret

243
trunk/gui/mouse.inc Normal file
View File

@ -0,0 +1,243 @@
;mouseunder:
; times 16*24 dd 0
label mouseunder dword at 0x6900
iglobal
mousepointer:
db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f
db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79
db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57
db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71
db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50
db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70
db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f
db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70
db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e
db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a
db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66
db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e
db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39
db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66
db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c
db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff
db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68
db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d
db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00
db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e
db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e
db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00
db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64
db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d
db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d
db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14
db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a
db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c
db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52
db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77
db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00
db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25
db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54
db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d
db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52
db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33
db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64
db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d
db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a
db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff
db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35
db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70
db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77
db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68
db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41
db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f
db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79
db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e
db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52
db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77
db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c
db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f
db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00
db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56
db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d
db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e
db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76
db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56
db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b
db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f
db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76
db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77
db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71
db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b
db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c
db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a
db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f
db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e
db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e
db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80
db 0x80,0x80
mousepointer1:
db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a
db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16
db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e
db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f
db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47
db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23
db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c
db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c
db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c
db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37
db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31
db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49
db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78
db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16
db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33
db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08
db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e
db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e
db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00
db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00
db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff
db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50
db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00
db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56
db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a
db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05
db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49
db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d
db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00
db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27
db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06
db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00
endg

388
trunk/gui/skincode.inc Normal file
View File

@ -0,0 +1,388 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; WINDOW SKIN for MenuetOS ;;
;; ;;
;; entryway@bkg.lt ;;
;; ;;
;; Bugfixes & upgrades by ;;
;; Samuel Rodriguez Perez ;;
;; Xeoda@ciberirmandade.org ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include "SKINDATA.INC"
virtual at 0
bmp_header:
.type rw 1 ; "BM" signature
.filesize rd 1 ; size of the file
.reserved rd 1 ; zero
.offbits rd 1 ; pointer to image data
;----------------
.headsize rd 1 ; usually 40 bytes for image header
.width rd 1
.height rd 1
.planes rw 1 ; usually 1
.bitcount rw 1 ; currently 24 bits/pixel (0x18)
.compress rd 1 ; zero
.sizeimage rd 1 ; x*y*(bitcount/8)
.unused rd 4 ; these bits aren't used by MeOS
bmp_data:
end virtual
virtual at 0x778000
_bmp_bpl dd ? ; bytes per line
_bmp_dpl dd ? ; dwords per line
_bmp_zb dd ? ; bytes filled by zeroes at the end of a scanline
align 32
raw_data:
end virtual
bmp2raw:
; esi = to bmp data (source)
; edi = to raw data (destination)
cmp [esi+bmp_header.type],'BM' ; check if bmp file is really loaded
jne .finish
mov edx,esi
mov eax,[edx+bmp_header.width]
imul eax,3
push eax
test eax,11b
jz @f
add eax,4
@@:
shr eax,2
mov [_bmp_dpl],eax
shl eax,2
mov [_bmp_bpl],eax
pop ebx
sub eax,ebx
mov [_bmp_zb],eax
add esi,bmp_data
mov eax,[_bmp_bpl]
imul eax,[edx+bmp_header.height]
add esi,eax
mov ebx,[edx+bmp_header.height] ; ebx = y
cld
.y_begin:
sub esi,[_bmp_bpl]
push esi
mov ecx,[_bmp_dpl]
rep movsd
pop esi
sub edi,[_bmp_zb]
dec ebx
jne .y_begin
.finish:
ret
; BMP support by Ivan Poddubny
; 1) load LEFT.BMP
; a) _skinleftw = bmp_width
; b) _skinleft = 0
; c) _refleft = 0x778000
; d) convert
; 2) load BASE.BMP
; a) _skinbasew = bmp_width
; b) _skinbase = _skinleftw
; c) _refbase = _refleft+sizeof(left_raw_converted)
; d) convert
; 3) load OPER.BMP
; a) _skinoper = minus width from bmp file
; b) _skinoperw = width from bmp file
; c) _refoper = _refbase+sizeof(oper_raw_converted)
; d) convert
; 4) set height
load_bmp_file:
; eax = pointer to filename
mov ebx, 1
or ecx, -1
mov edx, 0x90000
mov esi, 12
call fileread
ret
load_default_skin:
pushad
mov eax, _fileleft
call load_bmp_file
mov eax, [0x90000+bmp_header.width]
mov [_skinleftw], eax
mov [_skinleft], 0
mov edi, raw_data
mov [_refleft], edi
mov esi, 0x90000
call bmp2raw
mov eax, [_bmp_bpl]
imul eax, [0x90000+bmp_header.height]
push eax
mov eax, _filebase
call load_bmp_file
mov eax, [0x90000+bmp_header.width]
mov [_skinbasew], eax
mov eax, [_skinleftw]
mov [_skinbase], eax
pop eax
add eax, [_refleft]
; align to 32-byte boundary
test eax, 11111b
jz @f
shr eax, 5
inc eax
shl eax, 5
@@:
; save base address
mov [_refbase], eax
; convert
mov edi, eax
mov esi, 0x90000
call bmp2raw
mov eax, [_bmp_bpl]
imul eax, [0x90000+bmp_header.height]
push eax
mov eax, _fileoper
call load_bmp_file
mov eax, [0x90000+bmp_header.width]
mov [_skinoperw], eax
neg eax
mov [_skinoper], eax
pop eax
add eax, [_refbase]
; align to 32-byte boundary
test eax, 11111b
jz @f
shr eax, 5
inc eax
shl eax, 5
@@:
mov [_refoper], eax
mov edi, eax
mov esi, 0x90000
call bmp2raw
; mov eax, [0x90000+bmp_header.height]
; imul eax, [0x90000+bmp_header.width]
; imul eax, 3
; add eax, raw_data ; now eax points to the last line of image
; mov ecx, [eax]
; mov [_coloroutborder], ecx
; mov [_colorborder], ecx
; sub eax, 2*3
; mov ecx, [eax]
; mov [_colorframe], ecx
mov eax, [0x90000+bmp_header.height]
mov [_skinh], eax
popad
ret
drawwindow_IV:
pusha
push edx
mov edi,[esp] ; RECTANGLE
mov eax,[edi+0]
shl eax,16
mov ax,[edi+0]
add ax,[edi+8]
mov ebx,[edi+4]
shl ebx,16
mov bx,[edi+4]
add bx,[edi+12]
; mov esi,[edi+24]
; shr esi,1
; and esi,0x007f7f7f
mov esi,[_coloroutborder]
call draw_rectangle
mov ecx,3
_dw3l:
add eax,1*65536-1
add ebx,1*65536-1
test ax,ax
js no_skin_add_button
test bx,bx
js no_skin_add_button
mov esi,[_colorframe] ;[edi+24]
call draw_rectangle
dec ecx
jnz _dw3l
mov esi,[_colorborder]
add eax,1*65536-1
add ebx,1*65536-1
test ax,ax
js no_skin_add_button
test bx,bx
js no_skin_add_button
call draw_rectangle
mov esi,[esp]
mov eax,[esi+8] ; window width
mov edx,[_skinleft]
shl edx,16
mov ecx,[_skinleftw]
shl ecx,16
add ecx,[_skinh]
mov ebx,[_refleft]
call sys_putimage
mov esi,[esp]
mov eax,[esi+8]
sub eax,[_skinleftw]
sub eax,[_skinoperw]
cmp eax,[_skinbase]
jng non_base
xor edx,edx
mov ebx,[_skinbasew]
div ebx
inc eax
mov ebx,[_refbase]
mov ecx,[_skinbasew]
shl ecx,16
add ecx,[_skinh]
mov edx,[_skinbase]
sub edx,[_skinbasew]
shl edx,16
baseskinloop:
shr edx,16
add edx,[_skinbasew]
shl edx,16
push eax ebx ecx edx
call sys_putimage
pop edx ecx ebx eax
dec eax
jnz baseskinloop
non_base:
mov esi,[esp]
mov edx,[esi+8]
sub edx,[_skinoperw]
inc edx
shl edx,16
mov ebx,[_refoper]
mov ecx,[_skinoperw]
shl ecx,16
add ecx,[_skinh]
call sys_putimage
mov esi,[esp]
mov edx,[esi+04] ; WORK AREA
add edx,21+5
mov ebx,[esi+04]
add ebx,[esi+12]
cmp edx,ebx
jg _noinside2
mov eax,5
mov ebx,[_skinh]
mov ecx,[esi+8]
mov edx,[esi+12]
sub ecx,4
sub edx,4
mov edi,[esi+16]
call [drawbar]
_noinside2:
mov edi,[0xfe88]
movzx eax,word [edi]
cmp eax,1000
jge no_skin_add_button
inc eax
mov [edi],ax
shl eax,4
add eax,edi
mov bx,[0x3000]
mov [eax],bx
add eax,2 ; save button id number
mov bx,1
mov [eax],bx
add eax,2 ; x start
mov ebx,[esp]
mov ebx,[ebx+8]
cmp [_buttonCx],0
jg _bCx_at_right
mov ebx,[_buttonCw] ; ebx will be 0 in next instruction
_bCx_at_right:
sub ebx,[_buttonCw]
sub ebx,[_buttonCx]
mov [eax],bx
add eax,2 ; x size
mov ebx,[_buttonCw]
mov [eax],bx
add eax,2 ; y start
mov ebx,[_buttonCy]
mov [eax],bx
add eax,2 ; y size
mov ebx,[_buttonCh]
mov [eax],bx
;* minimize button
mov edi,[0xfe88]
movzx eax,word [edi]
cmp eax,1000
jge no_skin_add_button
inc eax
mov [edi],ax
shl eax,4
add eax,edi
mov bx,[0x3000]
mov [eax],bx
add eax,2 ; save button id number
mov bx,65535 ;999
mov [eax],bx
add eax,2 ; x start
mov ebx,[esp]
mov ebx,[ebx+8]
cmp [_buttonMx],0
jg _bMx_at_right
mov ebx,[_buttonMw] ; ebx will be 0 in next instruction
_bMx_at_right:
sub ebx,[_buttonMw]
sub ebx,[_buttonMx]
mov [eax],bx
add eax,2 ; x size
mov ebx,[_buttonMw]
mov [eax],bx
add eax,2 ; y start
mov ebx,[_buttonMy]
mov [eax],bx
add eax,2 ; y size
mov ebx,[_buttonMh]
mov [eax],bx
;* minimize button
no_skin_add_button:
add esp,4
popa
ret

44
trunk/gui/skindata.inc Normal file
View File

@ -0,0 +1,44 @@
;
; WINDOW SKIN for MenuetOS
; ivan-yar@bk.ru
;
iglobal
_skinh dd 22
_skinleftw dd 10
_skinbase dd 10
_skinbasew dd 8
_skinoper dd -39 ;-21
_skinoperw dd 39 ;21
_buttonCx dd 5 ; close
_buttonCy dd 2
_buttonCw dd 15
_buttonCh dd 17
_buttonMx dd 23 ; minimize
_buttonMy dd 2
_buttonMw dd 15
_buttonMh dd 17
_colorframe dd 0x3a6cb6 ;0x586E93
_colorborder dd 0x00081D
_coloroutborder dd 0x00081D
_fileleft db 'LEFT.BMP '
_filebase db 'BASE.BMP '
_fileoper db 'OPER.BMP '
endg
uglobal
_refoper dd 0
_refbase dd 0
_refleft dd 0
_skinleft dd 0
_skinwinw dd 0
endg

1613
trunk/gui/window.inc Normal file

File diff suppressed because it is too large Load Diff

223
trunk/hid/keyboard.inc Normal file
View File

@ -0,0 +1,223 @@
;// mike.dld [
VKEY_LSHIFT = 0000000000000001b
VKEY_RSHIFT = 0000000000000010b
VKEY_LCONTROL = 0000000000000100b
VKEY_RCONTROL = 0000000000001000b
VKEY_LALT = 0000000000010000b
VKEY_RALT = 0000000000100000b
VKEY_CAPSLOCK = 0000000001000000b
VKEY_NUMLOCK = 0000000010000000b
VKEY_SCRLOCK = 0000000100000000b
VKEY_SHIFT = 0000000000000011b
VKEY_CONTROL = 0000000000001100b
VKEY_ALT = 0000000000110000b
uglobal
align 4
kb_state dd 0
ext_code db 0
keyboard_mode db 0
keyboard_data db 0
altmouseb db 0
ctrl_alt_del db 0
kb_lights db 0
endg
align 4
irq1:
call restore_caller
movzx eax,word[0x3004] ; top window process
movzx eax,word[0xC400+eax*2]
shl eax,8
mov al,[0x800B4+eax]
mov [keyboard_mode],al
in al,0x60
mov [keyboard_data],al
mov ch,al
cmp al,0xE0
je @f
cmp al,0xE1
jne .normal_code
@@: mov [ext_code],al
jmp .no_key.end
.normal_code:
mov cl,[ext_code]
mov [ext_code],0
and al,0x7F
@@: cmp al,0x2A
jne @f
cmp cl,0xE0
je .no_key.end
mov eax,VKEY_LSHIFT
jmp .no_key
@@: cmp al,0x36
jne @f
cmp cl,0xE0
je .no_key.end
mov eax,VKEY_RSHIFT
jmp .no_key
@@: cmp al,0x38
jne @f
cmp cl,0xE0
je .alt.r
mov eax,VKEY_LALT
jmp .no_key
.alt.r:
mov eax,VKEY_RALT
jmp .no_key
@@: cmp al,0x1D
jne @f
cmp cl,0
jne .ctrl.r
mov eax,VKEY_LCONTROL
jmp .no_key
.ctrl.r:
cmp cl,0xE1
jne .ctrl.r.2
mov [ext_code],cl
jmp .no_key.end
.ctrl.r.2:
mov eax,VKEY_RCONTROL
jmp .no_key
@@: cmp al,0x3A
jne @f
mov bl,4
mov eax,VKEY_CAPSLOCK
jmp .no_key.xor
@@: cmp al,0x45
jne @f
cmp cl,0
jne .no_key.end
mov bl,2
mov eax,VKEY_NUMLOCK
jmp .no_key.xor
@@: cmp al,0x46
jne @f
mov bl,1
mov eax,VKEY_SCRLOCK
jmp .no_key.xor
@@:
test ch,0x80
jnz .no_key.end
movzx eax,ch ; plain key
mov bl,[keymap+eax]
mov edx,[kb_state]
test dl,VKEY_CONTROL ; ctrl alt del
jz .noctrlaltdel
test dl,VKEY_ALT
jz .noctrlaltdel
cmp bl,134+48
jne .noctrlaltdel
mov [ctrl_alt_del],1
jmp .no_key.end
.noctrlaltdel:
test dl,VKEY_CONTROL ; ctrl on ?
jz @f
sub bl,0x60
@@: test dl,VKEY_SHIFT ; shift on ?
jz @f
mov bl,[keymap_shift+eax]
@@: test dl,VKEY_ALT ; alt on ?
jz @f
mov bl,[keymap_alt+eax]
; alt mouse ?
xor edx,edx
cmp bl,178
jnz .no_alt.up
mov edx,5*65536
jmp .mouse.change
.no_alt.up:
cmp bl,177
jnz .no_alt.down
mov edx,251*65536
jmp .mouse.change
.no_alt.down:
cmp bl,176
jnz .no_alt.left
mov edx,251*256
jmp .mouse.change
.no_alt.left:
cmp bl,179
jnz .no_alt.right
mov edx,5*256
jmp .mouse.change
.no_alt.right:
cmp bl,' '
jne @f
xor [altmouseb],1
.mouse.change:
mov byte[0xF604],1; ps2 data
mov byte[0xFB00],0; ps2 chunk count
mov word[0x2E0000+4096*12],3; mouse data count
mov dl,[altmouseb]
mov [0x2E0000+4096*12+0x10],edx
mov bl,0
@@:
cmp [keyboard_mode],0 ; return from keymap
jne .no_key.end
mov [keyboard_mode_sys],0
cmp bl,0
je .no_key.end
movzx eax,byte[0xF400]
cmp al,120
jae .no_key.end
inc al
mov [0xF400],al
mov [0xF400+eax],bl
jmp .no_key.end
.no_key:
test ch,0x80
jz .no_key.down
not eax
and [kb_state],eax
jmp .no_key.end
.no_key.xor:
test ch,0x80
jnz .no_key.end
xor [kb_state],eax
xor [kb_lights],bl
call set_lights
jmp .no_key.end
.no_key.down:
or [kb_state],eax
.no_key.end:
cmp [keyboard_mode],1 ; return scancode
jne .no_scancode
mov [keyboard_mode_sys],1
movzx eax,byte[0xF400]
cmp al,120
jae .no_scancode
inc al
mov [0xF400],al
mov [0xF400+eax],ch
.no_scancode:
.exit.irq1:
mov [check_idle_semaphore],5
mov al,0x20 ; ready for next irq
out 0x20,al
call return_to_caller
jmp irq1
set_lights:
mov al,0xED
call kb_write
mov al,[kb_lights]
call kb_write
ret
;// mike.dld ]

191
trunk/hid/set_dtc.inc Normal file
View File

@ -0,0 +1,191 @@
;setting date,time,clock and alarm-clock
;add sys_settime at servetable as for ex. 22 fcn:
; 22 - SETTING DATE TIME, CLOCK AND ALARM-CLOCK
; ebx =0 - set time ecx - 00SSMMHH
; ebx =1 - set date ecx=00DDMMYY
; ebx =2 - set day of week ecx- 1-7
; ebx =3 - set alarm-clock ecx - 00SSMMHH
; out: 0 -Ok 1 -wrong format 2 -battery low
sys_settime:
mov ecx,eax
cli
mov al,0x0d
out 0x70,al
in al,0x71
bt ax,7
jnc bat_low
cmp ecx,2 ;day of week
jne nosetweek
test ebx,ebx ;test day of week
je wrongtime
cmp ebx,7
ja wrongtime
mov dx,0x70
call startstopclk
dec edx
mov al,6
out dx,al
inc edx
mov al,bl
out dx,al
jmp endsettime
nosetweek: ;set date
cmp ecx,1
jne nosetdate
cmp bl,0x99 ;test year
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
cmp bh,0x99 ;test month
ja wrongtime
shr ebx,4
test bh,bh
je wrongtime
cmp bh,0x12
ja wrongtime
shl ebx,8
bswap ebx ;ebx=00YYMMDD
test bl,bl ;test day
je wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
shr ebx,4
cmp bh,2 ;February
jne testday
cmp bl,0x29
ja wrongtime
jmp setdate
testday:
cmp bh,8
jb testday1 ;Aug-Dec
bt bx,8
jnc days31
jmp days30
testday1:
bt bx,8 ;Jan-Jul ex.Feb
jnc days30
days31:
cmp bl,0x31
ja wrongtime
jmp setdate
days30:
cmp bl,0x30
ja wrongtime
setdate:
mov dx,0x70
call startstopclk
dec edx
mov al,7 ;set days
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,8 ;set months
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,9 ;set years
out dx,al
inc edx
shr ebx,8
mov al,bh
out dx,al
jmp endsettime
nosetdate: ;set time or alarm-clock
cmp ecx,3
ja wrongtime
cmp bl,0x23
ja wrongtime
cmp bh,0x59
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
cmp bh,0x92
ja wrongtime
shl ebx,4
bswap ebx ;00HHMMSS
cmp bl,0x59
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
shr ebx,4
mov dx,0x70
call startstopclk
dec edx
cmp ecx,3
je setalarm
xor eax,eax ;al=0-set seconds
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,2 ;set minutes
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,4 ;set hours
out dx,al
inc edx
shr ebx,8
mov al,bh
out dx,al
jmp endsettime
setalarm:
mov al,1 ;set seconds for al.
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,3 ;set minutes for al.
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,5 ;set hours for al.
out dx,al
inc edx
shr ebx,8
mov al,bh
out dx,al
dec edx
mov al,0x0b ;enable irq's
out dx,al
inc dx
in al,dx
bts ax,5 ;set bit 5
out dx,al
endsettime:
dec edx
call startstopclk
sti
mov [esp+36],dword 0
ret
bat_low:
sti
mov [esp+36],dword 2
ret
wrongtime:
sti
mov [esp+36],dword 1
ret
startstopclk:
mov al,0x0b
out dx,al
inc dx
in al,dx
btc ax,7
out dx,al
ret

5730
trunk/kernel.asm Normal file

File diff suppressed because it is too large Load Diff

31
trunk/kernel16.inc Normal file
View File

@ -0,0 +1,31 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; KERNEL16.INC ;;
;; ;;
;; Included 16 bit kernel files for MenuetOS ;;
;; ;;
;; This file is kept separate as it will be easier to ;;
;; maintain and compile with an automated SETUP program ;;
;; in the future. ;;
;; ;;
;; Copyright Ville Turjanmaa, see file COPYING for details. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;% +include
;!!!
if lang eq en
include "boot/booteng.inc" ; english system boot messages
else
include "boot/bootru.inc" ; russian system boot messages
;!!!
end if
include "boot/ru.inc" ; Russian font
include "boot/bootcode.inc" ; 16 bit system boot code
include "bus/pci/pci16.inc"
;% -include

105
trunk/kernel32.inc Normal file
View File

@ -0,0 +1,105 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; KERNEL32.INC ;;
;; ;;
;; Included 32 bit kernel files for MenuetOS ;;
;; ;;
;; This file is kept separate as it will be easier to ;;
;; maintain and compile with an automated SETUP program ;;
;; in the future. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; structure definition helper
macro struct name, [arg]
{
common
name@struct fix name
struc name arg {
}
macro struct_helper name
{
virtual at 0
name name
sizeof.#name = $ - name
name equ sizeof.#name
end virtual
}
ends fix } struct_helper name@struct
; Core functions
include "core/sync.inc"
include "core/sys32.inc" ; process management
include "core/sched.inc" ; process scheduling
include "core/fpu.inc" ; FPU handler
include "core/syscall.inc" ; system call
include "core/mem.inc" ; high-level memory management
include "core/newproce.inc" ;new process management
include "core/physmem.inc" ; access to physical memory for applications
include "core/sync.inc" ; macros for synhronization objects
; GUI stuff
include "gui/window.inc"
include "gui/event.inc"
include "gui/font.inc"
include "gui/button.inc"
; shutdown
include "boot/shutdown.inc" ; shutdown or restart
; file system
include "fs/fs.inc" ; syscall
include "fs/fat32.inc" ; read / write for fat32 filesystem
include "fs/fat12.inc" ; read / write for fat12 filesystem
include "blkdev/rd.inc" ; ramdisk read /write
; sound
include "sound/sb16.inc" ; playback for Sound Blaster 16
include "sound/playnote.inc" ; player Note for Speaker PC
; display
include "video/vesa12.inc" ; Vesa 1.2 functions
include "video/vesa20.inc" ; Vesa 2.0 functions
include "video/vga.inc" ; VGA 16 color functions
; Network Interface & TCPIP Stack
include "network/stack.inc"
; Mouse pointer
include "gui/mouse.inc"
; Window skinning
include "gui/skincode.inc"
; Pci functions
include "bus/pci/pci32.inc"
; Floppy drive controller
include "blkdev/fdc.inc"
include "blkdev/flp_drv.inc"
; CD drive controller
include "blkdev/cdrom.inc"
; Character devices
include "hid/keyboard.inc"
; setting date,time,clock and alarm-clock
include "hid/set_dtc.inc"
;% -include

50
trunk/kglobals.inc Normal file
View File

@ -0,0 +1,50 @@
;------------------------------------------------------------------
; use "iglobal" for inserting initialized global data definitions.
;------------------------------------------------------------------
macro iglobal {
IGlobals equ IGlobals,
macro __IGlobalBlock { }
;-------------------------------------------------------------
; use 'uglobal' for inserting uninitialized global definitions.
; even when you define some data values, these variables
; will be stored as uninitialized data.
;-------------------------------------------------------------
macro uglobal {
UGlobals equ UGlobals,
macro __UGlobalBlock { }
endg fix } ; Use endg for ending iglobal and uglobal blocks.
macro IncludeIGlobals{
macro IGlobals dummy,[n] \{ __IGlobalBlock
purge __IGlobalBlock \}
match I, IGlobals \{ I \} }
macro IncludeUGlobals{
macro UGlobals dummy,[n] \{
\common
\local begin, size
begin = $
virtual at $
\forward
__UGlobalBlock
purge __UGlobalBlock
\common
size = $ - begin
end virtual
rb size
\}
match U, UGlobals \{ U \} }
macro IncludeAllGlobals {
IncludeIGlobals
IncludeUGlobals
}
iglobal
endg
uglobal
endg

239
trunk/memmap.inc Normal file
View File

@ -0,0 +1,239 @@
;
; MEMORY MAP
;
; Boot:
;
; 0:9000 byte bits per pixel
; 0:9001 word scanline length
; 0:9008 word vesa video mode
; 0:900A word X res
; 0:900C word Y res
; 0:9010 byte mouse port - not used
; 0:9014 dword Vesa 1.2 pm bank switch
; 0:9018 dword Vesa 2.0 LFB address
; 0:901C byte 0 or 1 : enable MTRR graphics acceleration
; 0:901D byte not used anymore (0 or 1 : enable system log display)
; 0:901E byte 0 or 1 : enable direct lfb write, paging disabled
; 0:9020 8bytes pci data
; 0:9030 byte VRR start enabled 1, 2-no
; 0:9031 word IDEContrRegsBaseAddr
;
;
; Runtime:
;
; 0000 -> 2FFF window_data - 256 entries
;
; 0000 dword x start
; 0004 dword y start
; 0008 dword x size
; 000C dword y size
; 0010 dword color of work area
; 0014 dword color of grab bar
; 0018 dword color of frames
; 001C dword window flags, +30 = window drawn, +31 redraw flag
;
; 3000 -> 4FFF task list - 256 entries
;
; 00 dword process count
; 04 dword no of processes
; 10 dword base of running process at 0x3000+
;
; 20 dword application event mask
; 24 dword PID - process identification number
; 2a word 0, state 3=zombie, 4=terminate
; 2e byte window number on screen
; 30 dword exact position in memory
; 34 dword counter sum
; 38 dword time stamp counter add
; 3c dword cpu usage in cpu timer tics
;
; -> delete -> 5000 -> AFFF free
;
;!!!
; 5000 -> 5FFF save_syscall_data - syscall trace
; 6000 -> 63FF reg1 array - for i40 (first parts of saved TSS descriptor)
; 6400 -> 67FF reg2 array - same thing, second part
; 6800 -> 68FF used i40 (1 if used, 0 if free), first element not used
; 6900 -> 6EFF saved picture under mouse pointer
;
; 6F00 -> 7FFF i38 stack (4,25Kb)
;
; 8000 -> A3FF used FLOPPY driver
;
; A400 -> AFFF free
;
; B000 -> B005 jump address for irq0 (task switch)
; B008 -> B00B count of ticks remaining to updating CPU usage info
;
; B060 -> B07F fpu error handler's stack
; B080 -> B0FF fpu_tss -> temporary TSS for FPU context switching
; B100 -> B2FF IDT
; B300 -> BAFF tasknum array - for i40 handler
; BB00 -> BEFF free
;!!!
; BF00 -> BFFF bytes, 1 if process running/memory in use
; C000 -> C3FF window stack C000 no of windows - all in words
; C402 -> C7FF window position in stack
; D000 -> D1FF FDC controller
; D200 -> D3FF FDC controller for Fat12
; D400 -> DFFF free
; E000 byte multitasking started
; E004 dword save for boot mem 0x24
; E010 dword pm bank switch address
; E014 dword window multiplier
; E020 dword putpixel address
; E024 dword getpixel address
; E030 dword Vesa 1.2 pm bank switch address
; F000 dword hd partition 1 start
; F004 dword root start at partition 1
; F008 dword root start at hd
; F100 byte 1=only os draw on screen
; F200 dword mousepicture -pointer
; F204 dword mouse appearance counter
; F300 dword x & y temp for windowmove
; F400 byte no of keys in buffer
; F401 byte 'buffer'
; F402 -> F4FF reserved for keys
; F500 byte no of buttons in buffer
; F501 dword 'buffer'
; F502 -> F5FF reserved for buttons
; F600 dword tsc / second
; F604 byte mouse port: 1 ps2, 2 com1, 3 com2
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y
; FB10 -> FB17 mouse color mem
; FB21 x move
; FB22 y move
; FB28 high bits temp
; FB30 color temp
; FB40 byte buttons down
; FB44 byte 0 mouse down -> do not draw
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under
; FBF0 byte multiplied window
; FBF1 byte bits per pixel
; FC00 -> FCFE com1/ps2 buffer
; FCFF com1/ps2 buffer count starting from FC00
; FDF0 -> FDF3 timer tick inc every 1/100 sec 4 bytes
; FE00 dword screen x size
; FE04 dword screen y size
; FE08 dword screen y multiplier
; FE0C dword screen mode
; FE10 dword entries in hd cache
; FE80 dword address of LFB in physical
; FE84 dword address of applications memory start in physical
; FE88 dword address of button list
; FE8C dword memory to use
; FF00 byte 1 = system shutdown request
; FF01 dword if >1 then activate process
; FFF0 byte 1 = redraw background request from app
; FFF1 byte 1 = diskette int occur
; FFF2 write and read bank in screen
; FFF4 byte 0 if first mouse draw & do not return picture under
; FFF5 byte 1 do not draw pointer
; FFFF byte do not change task for 1/100 sec.
;
; 10000 -> 1FFFF 32 bit os
; 20000 -> 2FFFF 32 bit stack
; 30000 -> 36FFF basic text font II
; 37000 -> 3BFFF basic text font I
; 40000 -> 4FFFF data of retrieved disks and partitions (Mario79)
; 50000 -> 500FF TSS of scheduler
; 51000 -> 54000 esp0,esp1,esp2
; 5F000 -> 5FFFF schedulers stack
; 60000 -> 7FFFF paging tables
; 80000 -> 8FFFF additional app info, in 256 byte steps - 256 entries
;
; 00 11db name of app running
; 10 108db floating point unit save area
; 7f byte 0= no fpu saved , 1= fpu saved to 0x10 -> restore
; 80 dword address of random shaped window area
; 84 byte shape area scale
; 88 dword used GDT of TSS
; 8C dword application memory size
; 90 dword window X position save
; 94 dword window Y position save
; 98 dword window X size save
; 9C dword window Y size save
; A0 dword IPC memory start
; A4 dword IPC memory size
; A8 dword event bits: mouse, stack,..
;
; B0 dword int40 handler in use ; 0 if not in use
; B4 byte keyboard mode: 0 = keymap, 1 = scancodes
;
; 90000 -> 9FFFF tmp
; A0000 -> AFFFF screen access area
; B0000 -> FFFFF bios rest in peace -area
; 100000 -> 27FFFF diskette image
; 280000 -> 281FFF ramdisk fat
; 282000 -> 283FFF floppy fat
;
; 284000 -> 28FFFF free
;
; 290000 -> 297FFF TSS's of interrupts
; 298000 -> 29FFFF TSS's of SYSTEM interrupts - 256 entries
; 2A0000 -> 2B00ff wav device data
; 2C0000 -> 2C3fff button info
;
; 0000 word number of buttons
; first button entry at 0x10
; +0000 word process number
; +0002 word button id number : bits 00-15
; +0004 word x start
; +0006 word x size
; +0008 word y start
; +000A word y size
; +000C word button id number : bits 16-31
;
; 2D0000 -> 2DFFFF reserved port area
;
; 0000 dword no of port areas reserved
; 0010 dword process id
; dword start port
; dword end port
; dword 0
;
; 2E0000 -> 2EFFFF irq data area
; 2F0000 -> 2FFFFF low memory save
;
; 300000 -> 45FFFF background image, max 1 M
;
; 460000 -> 5FFFFF display info
;
; 600000 -> 6FFFFF hd cache
;
; 700000 -> 71ffff tcp memory (128 kb)
; 720000 -> 75ffff interrupt stacks (256 kpl * 1024)
;
; 760000 -> 76ffff !vrr driver
; 770000 -> 777fff tcp memory ( 32 kb)
;
; 778000 -> 77ffff window skinning ( 32 kb)
; 780000 -> 7fffff free
;
; 800000 -> BFFFFF mapped to LFB
;
; C00000 -> DFFFFF * Application information
;
; C00000 -> C01FFF draw_data - 256 entries
;
; 00 dword draw limit - x start
; 04 dword draw limit - y start
; 08 dword draw limit - x end
; 0C dword draw limit - y end
; 1C dword app int vector
;
; C03000 -> D11fff sysint_stack_data
; - system interrupt stacks
; - 256 entries * 4096 step
;
; D20000 -> DA8000 TSS and IO map for (2048*8)=16384 ports
; (128+2048)*256 = 557956 = 0x88000
;
; 1000000 -> 3FFFFFF for applications
;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,739 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; I8255X.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.3 11 August 2003 ;;
;; ;;
;; This driver is based on the eepro100 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett, ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;********************************************************************
; Interface
; I8255x_reset
; I8255x_probe
; I8255x_poll
; I8255x_transmit
;
; These functions are referenced in ethernet.inc
;
;********************************************************************
rxfd_status equ eth_data_start
rxfd_command equ eth_data_start + 2
rxfd_link equ eth_data_start + 4
rxfd_rx_buf_addr equ eth_data_start + 8
rxfd_count equ eth_data_start + 12
rxfd_size equ eth_data_start + 14
rxfd_packet equ eth_data_start + 16
uglobal
eeprom_data: times 16 dd 0
align 4
lstats:
tx_good_frames: dd 0
tx_coll16_errs: dd 0
tx_late_colls: dd 0
tx_underruns: dd 0
tx_lost_carrier: dd 0
tx_deferred: dd 0
tx_one_colls: dd 0
tx_multi_colls: dd 0
tx_total_colls: dd 0
rx_good_frames: dd 0
rx_crc_errs: dd 0
rx_align_errs: dd 0
rx_resource_errs: dd 0
rx_overrun_errs: dd 0
rx_colls_errs: dd 0
rx_runt_errs: dd 0
done_marker: dd 0
align 4
confcmd:
confcmd_status: dw 0
confcmd_command: dw 0
confcmd_link: dd 0
endg
iglobal
confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
db 0x80, 0x3f, 0x05
endg
uglobal
align 4
txfd:
txfd_status: dw 0
txfd_command: dw 0
txfd_link: dd 0
txfd_tx_desc_addr: dd 0
txfd_count: dd 0
txfd_tx_buf_addr0: dd 0
txfd_tx_buf_size0: dd 0
txfd_tx_buf_addr1: dd 0
txfd_tx_buf_size1: dd 0
align 4
hdr:
hdr_dst_addr: times 6 db 0
hdr_src_addr: times 6 db 0
hdr_type: dw 0
endg
;***************************************************************************
; Function
; wait_for_cmd_done
;
; Description
; waits for the hardware to complete a command
; port address in edx
;
; al destroyed
;***************************************************************************
wait_for_cmd_done:
in al, dx
cmp al, 0
jne wait_for_cmd_done
ret
;***************************************************************************
; Function
; mdio_read
;
; Description
; This probably reads a register in the "physical media interface chip"
; Phy_id in ebx
; location in ecx
;
; Data returned in eax
;
;***************************************************************************
mdio_read:
mov edx, [io_addr]
add edx, 16 ; SCBCtrlMDI
mov eax, 0x08000000
shl ecx, 16
or eax, ecx
shl ebx, 21
or eax, ebx
out dx, eax
mrlp:
call delay_us
in eax, dx
mov ecx, eax
and ecx, 0x10000000
jz mrlp
and eax, 0xffff
ret
;***************************************************************************
; Function
; mdio_write
;
; Description
; This probably writes a register in the "physical media interface chip"
; Phy_id in ebx
; location in ecx
; data in edx
; Data returned in eax
;
;***************************************************************************
mdio_write:
mov eax, 0x04000000
shl ecx, 16
or eax, ecx
shl ebx, 21
or eax, ebx
or eax, edx
mov edx, [io_addr]
add edx, 16 ; SCBCtrlMDI
out dx, eax
mwlp:
call delay_us
in eax, dx
mov ecx, eax
and ecx, 0x10000000
jz mwlp
and eax, 0xffff
ret
;/***********************************************************************/
;/* I82557 related defines */
;/***********************************************************************/
; Serial EEPROM section.
; A "bit" grungy, but we work our way through bit-by-bit :->.
; EEPROM_Ctrl bits.
EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock.
EE_CS equ 0x02 ; EEPROM chip select.
EE_DATA_WRITE equ 0x04 ; EEPROM chip data in.
EE_DATA_READ equ 0x08 ; EEPROM chip data out.
EE_WRITE_0 equ 0x4802
EE_WRITE_1 equ 0x4806
EE_ENB equ 0x4802
; The EEPROM commands include the alway-set leading bit.
EE_READ_CMD equ 6
; The SCB accepts the following controls for the Tx and Rx units:
CU_START equ 0x0010
CU_RESUME equ 0x0020
CU_STATSADDR equ 0x0040
CU_SHOWSTATS equ 0x0050 ; Dump statistics counters.
CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands.
CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters.
RX_START equ 0x0001
RX_RESUME equ 0x0002
RX_ABORT equ 0x0004
RX_ADDR_LOAD equ 0x0006
RX_RESUMENR equ 0x0007
INT_MASK equ 0x0100
DRVR_INT equ 0x0200 ; Driver generated interrupt.
;***************************************************************************
; Function
; do_eeprom_cmd
;
; Description
; writes a cmd to the ethernet cards eeprom, by bit bashing
; cmd in ebx
; cmd length in ecx
; return in eax
;***************************************************************************
do_eeprom_cmd:
mov edx, [io_addr] ; We only require the value in dx
add dx, 14 ; the value SCBeeprom
mov ax, EE_ENB
out dx, ax
call delay_us
mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK
out dx, ax
call delay_us
; dx holds ee_addr
; ecx holds count
; eax holds cmd
xor edi, edi ; this will be the receive data
dec_001:
mov esi, 1
dec ecx
shl esi, cl
inc ecx
and esi, ebx
mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags..
cmp esi,0
jz dec_002
mov eax, EE_WRITE_1
dec_002:
out dx, ax
call delay_us
or ax, EE_SHIFT_CLK
out dx, ax
call delay_us
shl edi,1
in ax, dx
and ax, EE_DATA_READ
cmp ax,0
jz dec_003
inc edi
dec_003:
loop dec_001
mov ax, EE_ENB
out dx, ax
call delay_us
mov ax, 0x4800
out dx, ax
call delay_us
mov eax, edi
ret
;***************************************************************************
; Function
; I8255x_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
I8255x_reset:
ret
;***************************************************************************
; Function
; I8255x_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
I8255x_probe:
mov eax, [io_addr]
mov ebx, [pci_bus]
mov ecx, [pci_dev]
mov edx, 0x04 ; PCI_COMMAND
call pcibios_read_config_word
or ax, 0x05
mov ebx, [pci_bus]
mov ecx, [pci_dev]
mov edx, 0x04 ; PCI_COMMAND
call pcibios_write_config_word
mov ebx, 0x6000000
mov ecx, 27
call do_eeprom_cmd
and eax, 0xffe0000
cmp eax, 0xffe0000
je bige
mov ebx, 0x1800000
mov ecx, 0x40
jmp doread
bige:
mov ebx, 0x6000000
mov ecx, 0x100
doread:
; do-eeprom-cmd will destroy all registers
; we have eesize in ecx
; read_cmd in ebx
; Ignore full eeprom - just load the mac address
mov ecx, 0
drlp:
push ecx ; save count
push ebx
mov eax, ecx
shl eax, 16
or ebx, eax
mov ecx, 27
call do_eeprom_cmd
pop ebx
pop ecx
mov edx, ecx
shl edx, 2
mov esi, eeprom_data
add esi, edx
mov [esi], eax
inc ecx
cmp ecx, 16
jne drlp
; OK, we have the MAC address.
; Now reset the card
mov edx, [io_addr]
add dx, 8 ; SCBPort
xor eax, eax ; The reset cmd == 0
out dx, eax
mov esi, 10
call delay_ms ; Give the card time to warm up.
mov eax, lstats
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0140 ; INT_MASK | CU_STATSADDR
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
mov eax, 0
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
; build rxrd structure
mov ax, 0x0001
mov [rxfd_status], ax
mov ax, 0x0000
mov [rxfd_command], ax
mov eax, rxfd_status
mov [rxfd_link], eax
mov eax, Ether_buffer
mov [rxfd_rx_buf_addr], eax
mov ax, 0
mov [rxfd_count], ax
mov ax, 1528
mov [rxfd_size], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
call wait_for_cmd_done
; start the reciver
mov ax, 0
mov [rxfd_status], ax
mov ax, 0xc000
mov [rxfd_command], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
; Init TX Stuff
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, 0
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE
out dx, ax
call wait_for_cmd_done
; Set TX Base address
; First, set up confcmd values
mov ax, 2
mov [confcmd_command], ax
mov eax, txfd
mov [confcmd_link], eax
mov ax, 1
mov [txfd_command], ax ; CmdIASetup
mov ax, 0
mov [txfd_status], ax
mov eax, confcmd
mov [txfd_link], eax
; ETH_ALEN is 6 bytes
mov esi, eeprom_data
mov edi, node_addr
mov ecx, 3
drp000:
mov eax, [esi]
mov [edi], al
shr eax, 8
inc edi
mov [edi], al
inc edi
add esi, 4
loop drp000
; Hard code your MAC address into node_addr at this point,
; If you cannot read the MAC address from the eeprom in the previous step.
; You also have to write the mac address into txfd_tx_desc_addr, rather
; than taking data from eeprom_data
mov esi, eeprom_data
mov edi, txfd_tx_desc_addr
mov ecx, 3
drp001:
mov eax, [esi]
mov [edi], al
shr eax, 8
inc edi
mov [edi], al
inc edi
add esi, 4
loop drp001
mov esi, eeprom_data + (6 * 4)
mov eax, [esi]
shr eax, 8
and eax, 0x3f
cmp eax, 4 ; DP83840
je drp002
cmp eax, 10 ; DP83840A
je drp002
jmp drp003
drp002:
mov ebx, [esi]
and ebx, 0x1f
push ebx
mov ecx, 23
call mdio_read
pop ebx
or eax, 0x0422
mov ecx, 23
mov edx, eax
call mdio_write
drp003:
mov ax, 0x4002 ; Cmdsuspend | CmdConfigure
mov [confcmd_command], ax
mov ax, 0
mov [confcmd_status], ax
mov eax, txfd
mov [confcmd_link], eax
mov ebx, confcmd_data
mov al, 0x88 ; fifo of 8 each
mov [ebx + 1], al
mov al, 0
mov [ebx + 4], al
mov al, 0x80
mov [ebx + 5], al
mov al, 0x48
mov [ebx + 15], al
mov al, 0x80
mov [ebx + 19], al
mov al, 0x05
mov [ebx + 21], al
mov eax, txfd
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0110 ; INT_MASK | CU_START
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
jmp skip
; wait for thing to start
drp004:
mov ax, [txfd_status]
cmp ax, 0
je drp004
skip:
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
I8255x_exit:
ret
;***************************************************************************
; Function
; I8255x_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
I8255x_poll:
mov ax, 0 ; assume no data
mov [eth_rx_data_len], ax
mov ax, [rxfd_status]
cmp ax, 0
je i8p_exit
mov ax, 0
mov [rxfd_status], ax
mov ax, 0xc000
mov [rxfd_command], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
call wait_for_cmd_done
mov esi, rxfd_packet
mov edi, Ether_buffer
mov ecx, 1518
cld
rep movsb
mov ax, [rxfd_count]
and ax, 0x3fff
mov [eth_rx_data_len], ax
i8p_exit:
ret
;***************************************************************************
; Function
; I8255x_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
I8255x_transmit:
mov [hdr_type], bx
mov eax, [edi]
mov [hdr_dst_addr], eax
mov ax, [edi+4]
mov [hdr_dst_addr+4], ax
mov eax, [node_addr]
mov [hdr_src_addr], eax
mov ax, [node_addr+4]
mov [hdr_src_addr+4], ax
mov edx, [io_addr]
in ax, dx
and ax, 0xfc00
out dx, ax
xor ax, ax
mov [txfd_status], ax
mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex
mov [txfd_command], ax
mov eax, txfd
mov [txfd_link], eax
mov eax, 0x02208000
mov [txfd_count], eax
mov eax, txfd_tx_buf_addr0
mov [txfd_tx_desc_addr], eax
mov eax, hdr
mov [txfd_tx_buf_addr0], eax
mov eax, 14 ; sizeof hdr
mov [txfd_tx_buf_size0], eax
; Copy the buffer address and size in
mov eax, esi
mov [txfd_tx_buf_addr1], eax
mov eax, ecx
mov [txfd_tx_buf_size1], eax
mov eax, txfd
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov ax, 0x0110 ; INT_MASK | CU_START
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
mov edx, [io_addr]
in ax, dx
I8t_001:
mov ax, [txfd_status]
cmp ax, 0
je I8t_001
mov edx, [io_addr]
in ax, dx
ret

View File

@ -0,0 +1,814 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCNET32.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 1.0 31 July 2004 ;;
;; ;;
;; This driver is based on the PCNet32 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2004 Jarek Pelczar, ;;
;; jpelczar@interia.pl ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;macro PutStr X
;{
; local .__xyz1
; local .__xyz2
; push esi
; mov esi,.__xyz1
; call sys_msg_board_str
; push eax
; mov eax,1
; call delay_hs
; pop eax
; jmp .__xyz2
;.__xyz1:
; db X
; db 13,10,0
;.__xyz2:
; pop esi
;}
PCNET32_PORT_AUI equ 0x00
PCNET32_PORT_10BT equ 0x01
PCNET32_PORT_GPSI equ 0x02
PCNET32_PORT_MII equ 0x03
PCNET32_PORT_PORTSEL equ 0x03
PCNET32_PORT_ASEL equ 0x04
PCNET32_PORT_100 equ 0x40
PCNET32_PORT_FD equ 0x80
PCNET32_DMA_MASK equ 0xffffffff
PCNET32_LOG_TX_BUFFERS equ 1
PCNET32_LOG_RX_BUFFERS equ 2
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS)
PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1)
PCNET32_TX_RING_LEN_BITS equ 0
PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS)
PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1)
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4)
PCNET32_PKT_BUF_SZ equ 1544
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8
pcnet32_txb equ (eth_data_start)
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_private:
.mode dw ?
.tlen_rlen dw ?
.phys_addr db ?,?,?,?,?,?
.reserved dw ?
.filter dd ?,?
.rx_ring dd ?
.tx_ring dd ?
.cur_rx dd ?
.cur_tx dd ?
.dirty_rx dd ?
.dirty_tx dd ?
.tx_full db ?
.options dd ?
.full_duplex db ?
.chip_version dd ?
.mii db ?
.ltint db ?
.dxsuflo db ?
.fset db ?
.fdx db ?
end virtual
virtual at 0
pcnet32_rx_head:
.base dd ?
.buf_length dw ?
.status dw ?
.msg_length dd ?
.reserved dd ?
end virtual
virtual at 0
pcnet32_tx_head:
.base dd ?
.length dw ?
.status dw ?
.misc dd ?
.reserved dd ?
end virtual
uglobal
pcnet32_access:
.read_csr dd ?
.write_csr dd ?
.read_bcr dd ?
.write_bcr dd ?
.read_rap dd ?
.write_rap dd ?
.reset dd ?
endg
iglobal
pcnet32_options_mapping:
dd PCNET32_PORT_ASEL ; 0 Auto-select
dd PCNET32_PORT_AUI ; 1 BNC/AUI
dd PCNET32_PORT_AUI ; 2 AUI/BNC
dd PCNET32_PORT_ASEL ; 3 not supported
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD
dd PCNET32_PORT_ASEL ; 5 not supported
dd PCNET32_PORT_ASEL ; 6 not supported
dd PCNET32_PORT_ASEL ; 7 not supported
dd PCNET32_PORT_ASEL ; 8 not supported
dd PCNET32_PORT_MII ; 9 MII 10baseT
dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD
dd PCNET32_PORT_MII ; 11 MII (autosel)
dd PCNET32_PORT_10BT ; 12 10BaseT
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD
dd PCNET32_PORT_ASEL ; 15 not supported
endg
PCNET32_WIO_RDP equ 0x10
PCNET32_WIO_RAP equ 0x12
PCNET32_WIO_RESET equ 0x14
PCNET32_WIO_BDP equ 0x16
PCNET32_DWIO_RDP equ 0x10
PCNET32_DWIO_RAP equ 0x14
PCNET32_DWIO_RESET equ 0x18
PCNET32_DWIO_BDP equ 0x1C
PCNET32_TOTAL_SIZE equ 0x20
; ebx - index
; return:
; eax - data
pcnet32_wio_read_csr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
mov ax,bx
out dx,ax
lea edx,[ebp+PCNET32_WIO_RDP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - data
; ebx - index
pcnet32_wio_write_csr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
xchg eax,ebx
out dx,ax
xchg eax,ebx
lea edx,[ebp+PCNET32_WIO_RDP]
out dx,ax
pop edx
ret
; ebx - index
; return:
; eax - data
pcnet32_wio_read_bcr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
mov ax,bx
out dx,ax
lea edx,[ebp+PCNET32_WIO_BDP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - data
; ebx - index
pcnet32_wio_write_bcr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
xchg eax,ebx
out dx,ax
xchg eax,ebx
lea edx,[ebp+PCNET32_WIO_BDP]
out dx,ax
pop edx
ret
pcnet32_wio_read_rap:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - val
pcnet32_wio_write_rap:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
out dx,ax
pop edx
ret
pcnet32_wio_reset:
push edx
push eax
lea edx,[ebp+PCNET32_WIO_RESET]
in ax,dx
pop eax
pop edx
ret
pcnet32_wio_check:
push edx
mov ax,88
lea edx,[ebp+PCNET32_WIO_RAP]
out dx,ax
nop
nop
in ax,dx
cmp ax,88
sete al
pop edx
ret
iglobal
pcnet32_wio:
dd pcnet32_wio_read_csr
dd pcnet32_wio_write_csr
dd pcnet32_wio_read_bcr
dd pcnet32_wio_write_bcr
dd pcnet32_wio_read_rap
dd pcnet32_wio_write_rap
dd pcnet32_wio_reset
endg
; ebx - index
; return:
; eax - data
pcnet32_dwio_read_csr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
mov ebx,eax
out dx,eax
lea edx,[ebp+PCNET32_DWIO_RDP]
in eax,dx
and eax,0xffff
pop edx
ret
; ebx - index
; eax - data
pcnet32_dwio_write_csr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
xchg eax,ebx
out dx,eax
lea edx,[ebp+PCNET32_DWIO_RDP]
xchg eax,ebx
out dx,eax
pop edx
ret
; ebx - index
; return:
; eax - data
pcnet32_dwio_read_bcr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
mov ebx,eax
out dx,eax
lea edx,[ebp+PCNET32_DWIO_BDP]
in eax,dx
and eax,0xffff
pop edx
ret
; ebx - index
; eax - data
pcnet32_dwio_write_bcr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
xchg eax,ebx
out dx,eax
lea edx,[ebp+PCNET32_DWIO_BDP]
xchg eax,ebx
out dx,eax
pop edx
ret
pcnet32_dwio_read_rap:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
in eax,dx
and eax,0xffff
pop edx
ret
; eax - val
pcnet32_dwio_write_rap:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
out dx,eax
pop edx
ret
pcnet32_dwio_reset:
push edx
push eax
lea edx,[ebp+PCNET32_DWIO_RESET]
in eax,dx
pop eax
pop edx
ret
pcnet32_dwio_check:
push edx
lea edx,[PCNET32_DWIO_RAP]
mov eax,88
out dx,eax
nop
nop
in eax,dx
and eax,0xffff
cmp eax,88
sete al
pop edx
ret
iglobal
pcnet32_dwio:
dd pcnet32_dwio_read_csr
dd pcnet32_dwio_write_csr
dd pcnet32_dwio_read_bcr
dd pcnet32_dwio_write_bcr
dd pcnet32_dwio_read_rap
dd pcnet32_dwio_write_rap
dd pcnet32_dwio_reset
endg
pcnet32_init_ring:
mov [pcnet32_private.tx_full],0
mov [pcnet32_private.cur_rx],0
mov [pcnet32_private.cur_tx],0
mov [pcnet32_private.dirty_rx],0
mov [pcnet32_private.dirty_tx],0
mov edi,pcnet32_rx_ring
mov ecx,PCNET32_RX_RING_SIZE
mov ebx,pcnet32_rxb
.rx_init:
mov [edi+pcnet32_rx_head.base],ebx
mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
mov [edi+pcnet32_rx_head.status],word 0x8000
add ebx,PCNET32_PKT_BUF_SZ
; inc ebx
add edi,16
loop .rx_init
mov edi,pcnet32_tx_ring
mov ecx,PCNET32_TX_RING_SIZE
.tx_init:
mov [edi+pcnet32_tx_head.base],dword 0
mov [edi+pcnet32_tx_head.status],word 0
add edi,16
loop .tx_init
mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
mov esi,node_addr
mov edi,pcnet32_private.phys_addr
cld
movsd
movsw
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
ret
pcnet32_reset:
; Reset PCNET32
mov ebp,[io_addr]
call dword [pcnet32_access.reset]
; set 32bit mode
mov ebx,20
mov eax,2
call dword [pcnet32_access.write_bcr]
; set/reset autoselect bit
mov ebx,2
call dword [pcnet32_access.read_bcr]
and eax,not 2
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L1
or eax,2
.L1:
call dword [pcnet32_access.write_bcr]
; Handle full duplex setting
cmp byte [pcnet32_private.full_duplex],0
je .L2
mov ebx,9
call dword [pcnet32_access.read_bcr]
and eax,not 3
test [pcnet32_private.options],PCNET32_PORT_FD
jz .L3
or eax,1
cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI
jne .L4
or eax,2
jmp .L4
.L3:
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L4
cmp [pcnet32_private.chip_version],0x2627
jne .L4
or eax,3
.L4:
mov ebx,9
call dword [pcnet32_access.write_bcr]
.L2:
; set/reset GPSI bit
mov ebx,124
call dword [pcnet32_access.read_csr]
mov ecx,[pcnet32_private.options]
and ecx,PCNET32_PORT_PORTSEL
cmp ecx,PCNET32_PORT_GPSI
jne .L5
or eax,0x10
.L5:
call dword [pcnet32_access.write_csr]
cmp [pcnet32_private.mii],0
je .L6
test [pcnet32_private.options],PCNET32_PORT_ASEL
jnz .L6
mov ebx,32
call dword [pcnet32_access.read_bcr]
and eax,not 0x38
test [pcnet32_private.options],PCNET32_PORT_FD
jz .L7
or eax,0x10
.L7:
test [pcnet32_private.options],PCNET32_PORT_100
jz .L8
or eax,0x08
.L8:
call dword [pcnet32_access.write_bcr]
jmp .L9
.L6:
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L9
mov ebx,32
; PutStr "ASEL, enable auto-negotiation"
call dword [pcnet32_access.read_bcr]
and eax,not 0x98
or eax,0x20
call dword [pcnet32_access.write_bcr]
.L9:
cmp [pcnet32_private.ltint],0
je .L10
mov ebx,5
call dword [pcnet32_access.read_csr]
or eax,(1 shl 14)
call dword [pcnet32_access.write_csr]
.L10:
mov eax,[pcnet32_private.options]
and eax,PCNET32_PORT_PORTSEL
shl eax,7
mov [pcnet32_private.mode],ax
mov [pcnet32_private.filter],dword 0xffffffff
mov [pcnet32_private.filter+4],dword 0xffffffff
call pcnet32_init_ring
mov ebx,1
mov eax,pcnet32_private
and eax,0xffff
call dword [pcnet32_access.write_csr]
mov eax,pcnet32_private
mov ebx,2
shr eax,16
call dword [pcnet32_access.write_csr]
mov ebx,4
mov eax,0x0915
call dword [pcnet32_access.write_csr]
mov ebx,0
mov eax,1
call dword [pcnet32_access.write_csr]
mov ecx,100
.L11:
xor ebx,ebx
call dword [pcnet32_access.read_csr]
test ax,0x100
jnz .L12
loop .L11
.L12:
; PutStr "hardware reset"
xor ebx,ebx
mov eax,0x0002
call dword [pcnet32_access.write_csr]
xor ebx,ebx
call dword [pcnet32_access.read_csr]
; PutStr "PCNET reset complete"
ret
pcnet32_adjust_pci_device:
;*******Get current setting************************
mov al, 2 ;read a word
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x04 ;from command Register
call pci_read_reg
;******see if its already set as bus master********
mov bx, ax
and bx,5
cmp bx,5
je pcnet32_adjust_pci_device_Latency
;******Make card a bus master*******
mov cx, ax ;value to write
mov bh, [pci_dev]
mov al, 2 ;write a word
or cx,5
mov ah, [pci_bus]
mov bl, 0x04 ;to command register
call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Latency:
;*******Get current latency setting************************
; mov al, 1 ;read a byte
; mov bh, [pci_dev]
; mov ah, [pci_bus]
; mov bl, 0x0D ;from Lantency Timer Register
; call pci_read_reg
;******see if its aat least 64 clocks********
; cmp ax,64
; jge pcnet32_adjust_pci_device_Done
;******Set latency to 32 clocks*******
; mov cx, 64 ;value to write
; mov bh, [pci_dev]
; mov al, 1 ;write a byte
; mov ah, [pci_bus]
; mov bl, 0x0D ;to Lantency Timer Register
; call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Done:
ret
pcnet32_probe:
mov ebp,[io_addr]
call pcnet32_wio_reset
xor ebx,ebx
call pcnet32_wio_read_csr
cmp eax,4
jne .try_dwio
call pcnet32_wio_check
and al,al
jz .try_dwio
; PutStr "Using WIO"
mov esi,pcnet32_wio
jmp .L1
.try_dwio:
call pcnet32_dwio_reset
xor ebx,ebx
call pcnet32_dwio_read_csr
cmp eax,4
jne .no_dev
call pcnet32_dwio_check
and al,al
jz .no_dev
; PutStr "Using DWIO"
mov esi,pcnet32_dwio
jmp .L1
.no_dev:
; PutStr "PCNET32 not found"
ret
.L1:
mov edi,pcnet32_access
mov ecx,7
cld
rep movsd
mov ebx,88
call dword [pcnet32_access.read_csr]
mov ecx,eax
mov ebx,89
call dword [pcnet32_access.read_csr]
shl eax,16
or eax,ecx
mov ecx,eax
and ecx,0xfff
cmp ecx,3
jne .no_dev
shr eax,12
and eax,0xffff
mov [pcnet32_private.chip_version],eax
; PutStr "PCNET32 chip version OK"
mov [pcnet32_private.fdx],0
mov [pcnet32_private.mii],0
mov [pcnet32_private.fset],0
mov [pcnet32_private.dxsuflo],0
mov [pcnet32_private.ltint],0
mov eax,[pcnet32_private.chip_version]
cmp eax,0x2420
je .L2
cmp eax,0x2430
je .L3
cmp eax,0x2621
je .L4
cmp eax,0x2623
je .L5
cmp eax,0x2624
je .L6
cmp eax,0x2625
je .L7
cmp eax,0x2626
je .L8
cmp eax,0x2627
je .L9
; PutStr "Invalid chip rev"
jmp .no_dev
.L2:
; PutStr "PCnet/PCI 79C970"
jmp .L10
.L3:
; PutStr "PCnet/PCI 79C970"
jmp .L10
.L4:
; PutStr "PCnet/PCI II 79C970A"
mov [pcnet32_private.fdx],1
jmp .L10
.L5:
; PutStr "PCnet/FAST 79C971"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
mov [pcnet32_private.ltint],1
jmp .L10
.L6:
; PutStr "PCnet/FAST+ 79C972"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
jmp .L10
.L7:
; PutStr "PCnet/FAST III 79C973"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
jmp .L10
.L8:
; PutStr "PCnet/Home 79C978"
mov [pcnet32_private.fdx],1
mov ebx,49
call dword [pcnet32_access.read_bcr]
call dword [pcnet32_access.write_bcr]
jmp .L10
.L9:
; PutStr "PCnet/FAST III 79C975"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
.L10:
cmp [pcnet32_private.fset],1
jne .L11
mov ebx,18
call dword [pcnet32_access.read_bcr]
or eax,0x800
call dword [pcnet32_access.write_bcr]
mov ebx,80
call dword [pcnet32_access.read_csr]
and eax,0xc00
or eax,0xc00
call dword [pcnet32_access.write_csr]
mov [pcnet32_private.dxsuflo],1
mov [pcnet32_private.ltint],1
.L11:
; read MAC
mov edi,node_addr
mov edx,ebp
mov ecx,6
.Lmac:
in al,dx
stosb
inc edx
loop .Lmac
; PutStr "MAC read"
call pcnet32_adjust_pci_device
; PutStr "PCI done"
mov eax,PCNET32_PORT_ASEL
mov [pcnet32_private.options],eax
mov [pcnet32_private.mode],word 0x0003
mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
mov esi,node_addr
mov edi,pcnet32_private.phys_addr
cld
movsd
movsw
mov [pcnet32_private.filter],dword 0
mov [pcnet32_private.filter+4],dword 0
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
; PutStr "Switching to 32"
mov ebx,20
mov eax,2
call dword [pcnet32_access.write_bcr]
mov ebx,1
mov eax,(pcnet32_private and 0xffff)
call dword [pcnet32_access.write_csr]
mov ebx,2
mov eax,(pcnet32_private shr 16) and 0xffff
call dword [pcnet32_access.write_csr]
mov ebx,0
mov eax,1
call dword [pcnet32_access.write_csr]
mov esi,1
call delay_ms
call pcnet32_reset
mov eax, [pci_data]
mov [eth_status], eax
ret
pcnet32_poll:
xor eax,eax
mov [eth_rx_data_len],ax
mov eax,[pcnet32_private.cur_rx]
and eax,PCNET32_RX_RING_MOD_MASK
mov ebx,eax
imul esi,eax,PCNET32_PKT_BUF_SZ
add esi,pcnet32_rxb
shl ebx,4
add ebx,pcnet32_rx_ring
mov cx,[ebx+pcnet32_rx_head.status]
test cx,0x8000
jnz .L1
cmp ch,3
jne .L1
; PutStr "PCNETRX"
mov ecx,[ebx+pcnet32_rx_head.msg_length]
and ecx,0xfff
sub ecx,4
mov [eth_rx_data_len],cx
push ecx
shr ecx,2
mov edi,Ether_buffer
cld
rep movsd
pop ecx
and ecx,3
rep movsb
mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
or [ebx+pcnet32_rx_head.status],word 0x8000
inc [pcnet32_private.cur_rx]
.L1:
ret
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
pcnet32_xmit:
push edi
push esi
push ebx
push ecx
; PutStr "PCNETTX"
mov esi,edi
mov edi,[pcnet32_private.cur_tx]
imul edi,PCNET32_PKT_BUF_SZ
add edi,pcnet32_txb ; edi=ptxb
mov eax,edi
cld ; copy MAC
movsd
movsw
mov esi,node_addr
cld
movsd
movsw
mov [edi],bx
add edi,2
mov esi,[esp+8]
mov ecx,[esp]
push ecx
shr ecx,2
cld
rep movsd
pop ecx
and ecx,3
rep movsb
; mov ecx,[esp]
; add ecx,14 ; ETH_HLEN
; xor eax,eax
; pad to min length (60=ETH_ZLEN)
; cmp ecx,60
; jae .L1
; sub ecx,60
; cld
; rep stosb
;.L1:
mov edi,pcnet32_tx_ring+0 ; entry=0
mov ecx,[esp]
add ecx,14
cmp cx,60
jae .L1
mov cx,60
.L1:
neg cx
mov [edi+pcnet32_tx_head.length],cx
mov [edi+pcnet32_tx_head.misc],dword 0
mov [edi+pcnet32_tx_head.base],eax
mov [edi+pcnet32_tx_head.status],word 0x8300
; trigger an immediate send poll
mov ebx,0
mov eax,0x0008 ; 0x0048
mov ebp,[io_addr]
call dword [pcnet32_access.write_csr]
mov dword [pcnet32_private.cur_tx],0
; wait for TX to complete
mov ecx,[timer_ticks];[0xfdf0]
add ecx,100
.L2:
mov ax,[edi+pcnet32_tx_head.status]
test ax,0x8000
jz .L3
cmp ecx,[timer_ticks];[0xfdf0]
jb .L4
mov esi,10
call delay_ms
jnz .L2
.L4:
; PutStr "PCNET: Send timeout"
.L3:
mov dword [edi+pcnet32_tx_head.base],0
pop ecx
pop ebx
pop esi
pop edi
ret

View File

@ -0,0 +1,955 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; RTL8029.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.2 31 July 2002 ;;
;; ;;
;; This driver is based on the ns8390 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett, ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; While this implementation handles only PCI bus RTL8029 ;;
;; hardware, it can be easily adapted to other NE2000 clone ;;
;; products. I just dont have any to try! ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;********************************************************************
; Interface
; rtl8029_reset
; rtl8029_probe
; rtl8029_poll
; rtl8029_transmit
;
;********************************************************************
;**************************************************************************
; 8390 Register Definitions
;**************************************************************************
D8390_P0_COMMAND equ 0x00
D8390_P0_PSTART equ 0x01
D8390_P0_PSTOP equ 0x02
D8390_P0_BOUND equ 0x03
D8390_P0_TSR equ 0x04
D8390_P0_TPSR equ 0x04
D8390_P0_TBCR0 equ 0x05
D8390_P0_TBCR1 equ 0x06
D8390_P0_ISR equ 0x07
D8390_P0_RSAR0 equ 0x08
D8390_P0_RSAR1 equ 0x09
D8390_P0_RBCR0 equ 0x0A
D8390_P0_RBCR1 equ 0x0B
D8390_P0_RSR equ 0x0C
D8390_P0_RCR equ 0x0C
D8390_P0_TCR equ 0x0D
D8390_P0_DCR equ 0x0E
D8390_P0_IMR equ 0x0F
D8390_P1_COMMAND equ 0x00
D8390_P1_PAR0 equ 0x01
D8390_P1_PAR1 equ 0x02
D8390_P1_PAR2 equ 0x03
D8390_P1_PAR3 equ 0x04
D8390_P1_PAR4 equ 0x05
D8390_P1_PAR5 equ 0x06
D8390_P1_CURR equ 0x07
D8390_P1_MAR0 equ 0x08
D8390_COMMAND_PS0 equ 0x0 ; Page 0 select
D8390_COMMAND_PS1 equ 0x40 ; Page 1 select
D8390_COMMAND_PS2 equ 0x80 ; Page 2 select
D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control
D8390_COMMAND_RD1 equ 0x10
D8390_COMMAND_RD0 equ 0x08
D8390_COMMAND_TXP equ 0x04 ; transmit packet
D8390_COMMAND_STA equ 0x02 ; start
D8390_COMMAND_STP equ 0x01 ; stop
D8390_COMMAND_RD2_STA equ 0x22
D8390_COMMAND_RD2_STP equ 0x21
D8390_COMMAND_RD1_STA equ 0x12
D8390_COMMAND_RD0_STA equ 0x0A
D8390_COMMAND_PS0_RD2_STP equ 0x21
D8390_COMMAND_PS1_RD2_STP equ 0x61
D8390_COMMAND_PS0_RD2_STA equ 0x22
D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26
D8390_RCR_MON equ 0x20 ; monitor mode
D8390_DCR_FT1 equ 0x40
D8390_DCR_LS equ 0x08 ; Loopback select
D8390_DCR_WTS equ 0x01 ; Word transfer select
D8390_DCR_FT1_LS equ 0x48
D8390_DCR_WTS_FT1_LS equ 0x49
D8390_ISR_PRX equ 0x01 ; successful recv
D8390_ISR_PTX equ 0x02 ; successful xmit
D8390_ISR_RXE equ 0x04 ; receive error
D8390_ISR_TXE equ 0x08 ; transmit error
D8390_ISR_OVW equ 0x10 ; Overflow
D8390_ISR_CNT equ 0x20 ; Counter overflow
D8390_ISR_RDC equ 0x40 ; Remote DMA complete
D8390_ISR_RST equ 0x80 ; reset
D8390_RSTAT_PRX equ 0x01 ; successful recv
D8390_RSTAT_CRC equ 0x02 ; CRC error
D8390_RSTAT_FAE equ 0x04 ; Frame alignment error
D8390_RSTAT_OVER equ 0x08 ; FIFO overrun
D8390_TXBUF_SIZE equ 6
D8390_RXBUF_END equ 32
D8390_PAGE_SIZE equ 256
ETH_ALEN equ 6
ETH_HLEN equ 14
ETH_ZLEN equ 60
ETH_FRAME_LEN equ 1514
FLAG_PIO equ 0x01
FLAG_16BIT equ 0x02
ASIC_PIO equ 0
VENDOR_NONE equ 0
VENDOR_WD equ 1
VENDOR_NOVELL equ 2
VENDOR_3COM equ 3
NE_ASIC_OFFSET equ 0x10
NE_RESET equ 0x0F ; Used to reset card
NE_DATA equ 0x00 ; Used to read/write NIC mem
MEM_8192 equ 32
MEM_16384 equ 64
MEM_32768 equ 128
ISA_MAX_ADDR equ 0x400
uglobal
eth_flags: db 0
eth_vendor: db 0
eth_nic_base: dw 0
eth_asic_base: dw 0
eth_memsize: db 0
eth_rx_start: db 0
eth_tx_start: db 0
eth_bmem: dd 0
eth_rmem: dd 0
romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
endg
iglobal
test_data: db 'NE*000 memory',0
test_buffer: db ' ',0
endg
uglobal
eth_type: dw 0
pkthdr: db 0,0,0,0 ; status, next, (short) len
pktoff: dw 0
eth_rx_data_ptr: dd 0
eth_tmp_len: dw 0
endg
;***************************************************************************
; Function
; eth_pio_read
;
; Description
; Read a frame from the ethernet card via Programmed I/O
; src in ebx
; cnt in ecx
; dst in edi
;***************************************************************************
eth_pio_read:
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epr_001
inc ecx
and ecx, 0xFFFFFFFE
epr_001:
mov al, D8390_COMMAND_RD2_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov al, cl
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR0
out dx, al
mov al, ch
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR1
out dx, al
mov al, bl
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR0
out dx, al
mov al, bh
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR1
out dx, al
mov al, D8390_COMMAND_RD0_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov dx, [eth_asic_base]
add dx, ASIC_PIO
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epr_003
shr ecx, 1
epr_002:
; 2 bytes at a time
in ax, dx
mov [edi], ax
add edi, 2
loop epr_002
ret
epr_003:
; 1 byte at a time
in al, dx
mov [edi], al
inc edi
loop epr_003
ret
;***************************************************************************
; Function
; eth_pio_write
;
; Description
; writes a frame to the ethernet card via Programmed I/O
; dst in ebx
; cnt in ecx
; src in esi
;***************************************************************************
eth_pio_write:
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epw_001
inc ecx
and ecx, 0xFFFFFFFE
epw_001:
mov al, D8390_COMMAND_RD2_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov al, D8390_ISR_RDC
mov dx, [eth_nic_base]
add dx, D8390_P0_ISR
out dx, al
mov al, cl
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR0
out dx, al
mov al, ch
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR1
out dx, al
mov al, bl
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR0
out dx, al
mov al, bh
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR1
out dx, al
mov al, D8390_COMMAND_RD1_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov dx, [eth_asic_base]
add dx, ASIC_PIO
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epw_003
shr ecx, 1
epw_002:
; 2 bytes at a time
mov ax, [esi]
add esi, 2
out dx, ax
loop epw_002
jmp epw_004
epw_003:
; 1 byte at a time
mov al, [esi]
inc esi
out dx, al
loop epw_003
epw_004:
mov dx, [eth_nic_base]
add dx, D8390_P0_ISR
epw_005:
in al, dx
and al, D8390_ISR_RDC
cmp al, D8390_ISR_RDC
jne epw_005
ret
;***************************************************************************
; Function
; rtl8029_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
rtl8029_reset:
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P0_DCR
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, FLAG_16BIT
jne nsr_001
mov al, 0x49
jmp nsr_002
nsr_001:
mov al, 0x48
nsr_002:
out dx, al
xor al, al
mov dx, bx
add dx, D8390_P0_RBCR0
out dx, al
mov dx, bx
add dx, D8390_P0_RBCR1
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, 0x20
out dx, al
mov dx, bx
add dx, D8390_P0_TCR
mov al, 2
out dx, al
mov dx, bx
add dx, D8390_P0_TPSR
mov al, [eth_tx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, [eth_rx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, [eth_memsize]
out dx, al
mov dx, bx
add dx, D8390_P0_BOUND
mov al, [eth_memsize]
dec al
out dx, al
mov dx, bx
add dx, D8390_P0_ISR
mov al, 0xff
out dx, al
mov dx, bx
add dx, D8390_P0_IMR
xor al, al
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS1_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P1_PAR0
mov esi, node_addr
mov ecx, ETH_ALEN
nsr_003:
mov al, [esi]
out dx, al
inc esi
inc dx
loop nsr_003
mov dx, bx
add dx, D8390_P1_MAR0
mov ecx, ETH_ALEN
mov al, 0xff
nsr_004:
out dx, al
inc dx
loop nsr_004
mov dx, bx
add dx, D8390_P1_CURR
mov al, [eth_rx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STA
out dx, al
mov dx, bx
add dx, D8390_P0_ISR
mov al, 0xff
out dx, al
mov dx, bx
add dx, D8390_P0_TCR
mov al, 0
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, 4
out dx, al
ret
;***************************************************************************
; Function
; rtl8029_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
rtl8029_probe:
mov eax, [io_addr]
mov [eth_nic_base], ax ; The IO address space is 16 bit only
mov al, VENDOR_NONE
mov [eth_vendor], al
mov al, [eth_vendor]
cmp al, VENDOR_NONE
jne ep_check_have_vendor
xor eax, eax
mov [eth_bmem], eax
mov al, FLAG_PIO
mov [eth_flags], al
mov ax, [eth_nic_base]
add ax, NE_ASIC_OFFSET
mov [eth_asic_base], ax
mov al, MEM_16384
mov [eth_memsize], al
mov al, 32
mov [eth_tx_start], al
add al, D8390_TXBUF_SIZE
mov [eth_rx_start], al
mov dx, [eth_asic_base]
add dx, NE_RESET
in al, dx
out dx, al
in al, 0x84
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, D8390_RCR_MON
out dx, al
mov dx, bx
add dx, D8390_P0_DCR
mov al, D8390_DCR_FT1_LS
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, MEM_8192
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, MEM_16384
out dx, al
mov esi, test_data
mov ebx, 8192
mov ecx, 14
call eth_pio_write
mov ebx, 8192
mov ecx, 14
mov edi, test_buffer
call eth_pio_read
mov esi, test_buffer
mov edi, test_data
mov ecx, 13
cld
rep cmpsb
je ep_set_vendor
mov al, [eth_flags]
or al, FLAG_16BIT
mov [eth_flags], al
mov al, MEM_32768
mov [eth_memsize], al
mov al, 64
mov [eth_tx_start], al
add al, D8390_TXBUF_SIZE
mov [eth_rx_start], al
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_DCR
mov al, D8390_DCR_WTS_FT1_LS
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, MEM_16384
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, MEM_32768
out dx, al
mov esi, test_data
mov ebx, 16384
mov ecx, 14
call eth_pio_write
mov ebx, 16384
mov ecx, 14
mov edi, test_buffer
call eth_pio_read
mov esi, test_buffer
mov edi, test_data
mov ecx, 13
cld
rep cmpsb
ep_set_vendor:
; this bit is odd - probably left over from my hacking
mov ax, [eth_nic_base]
cmp ax, 0
je rtl8029_exit
cmp ax, ISA_MAX_ADDR
jbe ep_001
mov al, [eth_flags]
or al, FLAG_16BIT
mov [eth_flags], al
ep_001:
mov al, VENDOR_NOVELL
mov [eth_vendor], al
mov ebx, 0
mov ecx, 16
mov edi, romdata
call eth_pio_read
mov ecx, ETH_ALEN
mov esi, romdata
mov edi, node_addr
mov bl, [eth_flags]
and bl, FLAG_16BIT
ep_002:
mov al, [esi]
mov [edi], al
inc edi
inc esi
cmp bl, FLAG_16BIT
jne ep_003
inc esi
ep_003:
loop ep_002
ep_check_have_vendor:
mov al, [eth_vendor]
cmp al, VENDOR_NONE
je rtl8029_exit
cmp al, VENDOR_3COM
je ep_reset_card
mov eax, [eth_bmem]
mov [eth_rmem], eax
ep_reset_card:
; Reset the card
call rtl8029_reset
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
rtl8029_exit:
ret
;***************************************************************************
; Function
; rtl8029_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
rtl8029_poll:
mov eax, Ether_buffer
mov [eth_rx_data_ptr], eax
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_RSR
in al, dx
and al, D8390_RSTAT_PRX
cmp al, D8390_RSTAT_PRX
jne nsp_exit
mov dx, bx
add dx, D8390_P0_BOUND
in al, dx
inc al
cmp al, [eth_memsize]
jb nsp_001
mov al, [eth_rx_start]
nsp_001:
mov ch, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS1
out dx, al
mov dx, bx
add dx, D8390_P1_CURR
in al, dx ; get current page
mov cl, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0
out dx, al
cmp cl, [eth_memsize]
jb nsp_002
mov cl, [eth_rx_start]
nsp_002:
cmp cl, ch
je nsp_exit
xor ax, ax
mov ah, ch
mov [pktoff], ax
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_003
movzx ebx, word [pktoff]
mov edi, pkthdr
mov ecx, 4
call eth_pio_read
jmp nsp_004
nsp_003:
mov edi, [eth_rmem]
movzx eax, word [pktoff]
add edi, eax
mov eax, [edi]
mov [pkthdr], eax
nsp_004:
mov ax, [pktoff]
add ax, 4
mov [pktoff], ax
mov ax, [pkthdr + 2]
sub ax, 4
mov [eth_tmp_len], ax
cmp ax, ETH_ZLEN
jb nsp_exit
cmp ax, ETH_FRAME_LEN
ja nsp_exit
mov al, [pkthdr]
and al, D8390_RSTAT_PRX
cmp al, D8390_RSTAT_PRX
jne nsp_exit
; Right, we can now get the data
mov ax, [eth_tmp_len]
mov [eth_rx_data_len], ax
xor ebx, ebx
mov bh, [eth_memsize]
sub bx, [pktoff]
cmp [eth_tmp_len], bx
jbe nsp_005
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_006
push ebx
mov ecx, ebx
xor ebx, ebx
mov bx, [pktoff]
mov edi, [eth_rx_data_ptr]
call eth_pio_read
pop ebx
jmp nsp_007
nsp_006:
; Not implemented, as we are using PIO mode on this card
nsp_007:
xor ax, ax
mov ah, [eth_rx_start]
mov [pktoff], ax
mov eax, [eth_rx_data_ptr]
add eax, ebx
mov [eth_rx_data_ptr], eax
mov ax, [eth_tmp_len]
sub ax, bx
mov [eth_tmp_len], ax
nsp_005:
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_008
xor ebx, ebx
mov bx, [pktoff]
xor ecx, ecx
mov cx, [eth_tmp_len]
mov edi, [eth_rx_data_ptr]
call eth_pio_read
jmp nsp_009
nsp_008:
; Not implemented, as we are using PIO mode on this card
nsp_009:
mov al, [pkthdr+1]
cmp al, [eth_rx_start]
jne nsp_010
mov al, [eth_memsize]
nsp_010:
mov dx, [eth_nic_base]
add dx, D8390_P0_BOUND
dec al
out dx, al
nsp_exit:
ret
;***************************************************************************
; Function
; rtl8029_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
rtl8029_transmit:
mov [eth_type], bx
pusha
mov esi, edi
xor bx, bx
mov bh, [eth_tx_start]
mov ecx, ETH_ALEN
call eth_pio_write
mov esi, node_addr
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_ALEN
mov ecx, ETH_ALEN
call eth_pio_write
mov esi, eth_type
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_ALEN
add bx, ETH_ALEN
mov ecx, 2
call eth_pio_write
popa
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_HLEN
push ecx
call eth_pio_write
pop ecx
add ecx, ETH_HLEN
cmp ecx, ETH_ZLEN
jae nst_001
mov ecx, ETH_ZLEN
nst_001:
push ecx
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STA
out dx, al
mov dx, bx
add dx, D8390_P0_TPSR
mov al, [eth_tx_start]
out dx, al
pop ecx
mov dx, bx
add dx, D8390_P0_TBCR0
mov al, cl
out dx, al
mov dx, bx
add dx, D8390_P0_TBCR1
mov al, ch
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_TXP_RD2_STA
out dx, al
ret

View File

@ -0,0 +1,595 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; RTL8139.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.2 11 August 2003 ;;
;; ;;
;; Driver for chips of RealTek 8139 family ;;
;; References: ;;
;; www.realtek.com.hw - data sheets ;;
;; rtl8139.c - linux driver ;;
;; 8139too.c - linux driver ;;
;; ethernet driver template by Mike Hibbett ;;
;; ;;
;; The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; Copyright 2003 Endre Kozma, ;;
;; endre.kozma@axelero.hu ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ETH_ALEN equ 6
ETH_HLEN equ (2 * ETH_ALEN + 2)
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
; mininmum 64bytes frame length
PCI_REG_COMMAND equ 0x04 ; command register
PCI_BIT_PIO equ 0 ; bit0: io space control
PCI_BIT_MMIO equ 1 ; bit1: memory space control
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master
RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0
RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4
RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor
RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor
RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address
RTL8139_REG_COMMAND equ 0x37 ; command register
RTL8139_REG_CAPR equ 0x38 ; current address of packet read
RTL8139_REG_IMR equ 0x3c ; interrupt mask register
RTL8139_REG_ISR equ 0x3e ; interrupt status register
RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register
RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0
RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1
RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2
RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3
RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0
RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0
RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1
RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2
RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3
RTL8139_REG_MPC equ 0x4c ; missed packet counter
RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register
RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1
RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4
RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register
RTL8139_REG_BMCR equ 0x62 ; basic mode control register
RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register
; 5.1 packet header
RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes
RTL8139_BIT_LONG equ 3 ; total packet length > 4k
RTL8139_BIT_CRC equ 2 ; crc error occured
RTL8139_BIT_FAE equ 1 ; frame alignment error occured
RTL8139_BIT_ROK equ 0 ; received packet is ok
; 5.4 command register
RTL8139_BIT_RST equ 4 ; reset bit
RTL8139_BIT_RE equ 3 ; receiver enabled
RTL8139_BIT_TE equ 2 ; transmitter enabled
RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored
; 5.6 interrupt status register
RTL8139_BIT_ISR_TOK equ 2 ; transmit ok
RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt
RTL8139_BIT_ISR_ROK equ 0 ; receive ok
; 5.7 transmit configyration register
RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst
RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16)
; 5.8 receive configuration register
RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold
RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator
RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst
RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping
RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356
RTL8139_BIT_AER equ 5 ; accept error packets
RTL8139_BIT_AR equ 4 ; accept runt packets
RTL8139_BIT_AB equ 3 ; accept broadcast packets
RTL8139_BIT_AM equ 2 ; accept multicast packets
RTL8139_BIT_APM equ 1 ; accept physical match packets
RTL8139_BIT_AAP equ 0 ; accept all packets
; 5.9 93C46/93C56 command register
RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1
RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0
RTL8139_BIT_93C46_EECS equ 3 ; chip select
RTL8139_BIT_93C46_EESK equ 2 ; serial data clock
RTL8139_BIT_93C46_EEDI equ 1 ; serial data input
RTL8139_BIT_93C46_EEDO equ 0 ; serial data output
; 5.11 configuration register 1
RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1
RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips
RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips
RTL8139_BIT_PMEn equ 0 ; power management enabled
; 5.14 configuration register 4
RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4
; 6.2 transmit status register
RTL8139_BIT_ERTXTH equ 16 ; early TX threshold
RTL8139_BIT_TOK equ 15 ; transmit ok
RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed
; 6.18 basic mode control register
RTL8139_BIT_ANE equ 12 ; auto negotiation enable
; 6.20 auto negotiation advertisement register
RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex
RTL8139_BIT_TX equ 7 ; 100base-T
RTL8139_BIT_10FD equ 6 ; 10base-T full duplex
RTL8139_BIT_10 equ 5 ; 10base-T
RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001
; RX/TX buffer size
RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k
RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN)
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC
RTL8139_NUM_TX_DESC equ 4
RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC)
RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16)
RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==2048
RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256
RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==unlimited
RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==no threshold
RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \
or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \
or (1 shl RTL8139_BIT_NOWRAP) \
or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \
or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \
or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \
or (1 shl RTL8139_BIT_AM))
RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout
EE_93C46_REG_ETH_ID equ 7 ; MAC offset
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address
EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address
EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address
EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress
VER_RTL8139 equ 1100000b
VER_RTL8139A equ 1110000b
; VER_RTL8139AG equ 1110100b
VER_RTL8139B equ 1111000b
VER_RTL8130 equ VER_RTL8139B
VER_RTL8139C equ 1110100b
VER_RTL8100 equ 1111010b
VER_RTL8100B equ 1110101b
VER_RTL8139D equ VER_RTL8100B
VER_RTL8139CP equ 1110110b
VER_RTL8101 equ 1110111b
IDX_RTL8139 equ 0
IDX_RTL8139A equ 1
IDX_RTL8139B equ 2
IDX_RTL8139C equ 3
IDX_RTL8100 equ 4
IDX_RTL8139D equ 5
IDX_RTL8139D equ 6
IDX_RTL8101 equ 7
; These two must be 4 byte aligned ( which they are )
rtl8139_rx_buff equ eth_data_start
rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE)
uglobal
align 4
rtl8139_rx_buff_offset: dd 0
curr_tx_desc: dd 0
endg
iglobal
hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C
db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101
HW_VER_ARRAY_SIZE = $-hw_ver_array
endg
uglobal
hw_ver_id: db 0
endg
;***************************************************************************
; Function
; rtl8139_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
rtl8139_probe:
; enable the device
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
call pci_read_reg
mov cx, ax
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO)
and cl, not (1 shl PCI_BIT_MMIO)
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
call pci_write_reg
; get chip version
mov edx, [io_addr]
add edx, RTL8139_REG_TXCONFIG_2
in ax, dx
shr ah, 2
shr ax, 6
and al, 01111111b
mov ecx, HW_VER_ARRAY_SIZE-1
.chip_ver_loop:
cmp al, [hw_ver_array+ecx]
je .chip_ver_found
dec ecx
jns .chip_ver_loop
xor cl, cl ; default RTL8139
.chip_ver_found:
mov [hw_ver_id], cl
; wake up the chip
mov edx, [io_addr]
add edx, RTL8139_REG_HLTCLK
mov al, 'R' ; run the clock
out dx, al
; unlock config and BMCR registers
add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0)
out dx, al
; enable power management
add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR
in al, dx
cmp byte [hw_ver_id], IDX_RTL8139B
jl .old_chip
; set LWAKE pin to active high (default value).
; it is for Wake-On-LAN functionality of some motherboards.
; this signal is used to inform the motherboard to execute a wake-up process.
; only at newer chips.
or al, (1 shl RTL8139_BIT_PMEn)
and al, not (1 shl RTL8139_BIT_LWACT)
out dx, al
add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1
in al, dx
and al, not (1 shl RTL8139_BIT_LWPTN)
out dx, al
jmp .finish_wake_up
.old_chip:
; wake up older chips
and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN))
out dx, al
.finish_wake_up:
; lock config and BMCR registers
xor al, al
mov edx, [io_addr]
add edx, RTL8139_REG_9346CR
out dx, al
;***************************************************************************
; Function
; rt8139_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
rtl8139_reset:
mov edx, [io_addr]
add edx, RTL8139_REG_COMMAND
mov al, 1 shl RTL8139_BIT_RST
out dx, al
mov cx, 1000 ; wait no longer for the reset
.wait_for_reset:
in al, dx
test al, 1 shl RTL8139_BIT_RST
jz .reset_completed ; RST remains 1 during reset
dec cx
jns .wait_for_reset
.reset_completed:
; get MAC (hardware address)
mov ecx, 2
.mac_read_loop:
lea eax, [EE_93C46_REG_ETH_ID+ecx]
push ecx
call rtl8139_read_eeprom
pop ecx
mov [node_addr+ecx*2], ax
dec ecx
jns .mac_read_loop
; unlock config and BMCR registers
mov edx, [io_addr]
add edx, RTL8139_REG_9346CR
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0)
out dx, al
; initialize multicast registers (no filtering)
mov eax, 0xffffffff
add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR
out dx, eax
add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0
out dx, eax
; enable Rx/Tx
mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE)
add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4
out dx, al
; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold
; accept broadcast packets, accept physical match packets
mov ax, RTL8139_RX_CONFIG
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND
out dx, ax
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \
or (RTL8139_TXRR shl RTL8139_BIT_TXRR)
add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG
out dx, ax
; enable auto negotiation
add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG
in ax, dx
or ax, (1 shl RTL8139_BIT_ANE)
out dx, ax
; set auto negotiation advertisement
add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR
in ax, dx
or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \
or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \
or (1 shl RTL8139_BIT_TXFD)
out dx, ax
; lock config and BMCR registers
xor eax, eax
add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR
out dx, al
; init RX/TX pointers
mov [rtl8139_rx_buff_offset], eax
mov [curr_tx_desc], eax
; clear missing packet counter
add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR
out dx, eax
; disable all interrupts
add edx, RTL8139_REG_IMR - RTL8139_REG_MPC
out dx, ax
; set RxBuffer address, init RX buffer offset, init TX ring
mov eax, rtl8139_rx_buff
add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR
out dx, eax
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
ret
;***************************************************************************
; Function
; rtl8139_read_eeprom
; Description
; reads eeprom type 93c46 and 93c56
; Parameters
; al - word to be read (6bit in case of 93c46 and 8bit otherwise)
; Return value
; ax - word read in
; Destroyed register(s)
; eax, cx, ebx, edx
;
;***************************************************************************
rtl8139_read_eeprom:
movzx ebx, al
mov edx, [io_addr]
add edx, RTL8139_REG_RXCONFIG
in al, dx
test al, (1 shl RTL8139_BIT_9356SEL)
jz .type_93c46
; and bl, 01111111b ; don't care first bit
or bx, EE_93C56_READ_CMD ; it contains start bit
mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter
jmp .read_eeprom
.type_93c46:
and bl, 00111111b
or bx, EE_93C46_READ_CMD ; it contains start bit
mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter
.read_eeprom:
add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0
; mov al, (1 shl RTL8139_BIT_93C46_EEM1)
; out dx, al
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom
out dx, al
.cmd_loop:
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS)
bt bx, cx
jnc .zero_bit
or al, (1 shl RTL8139_BIT_93C46_EEDI)
.zero_bit:
out dx, al
; push eax
; in eax, dx ; eeprom delay
; pop eax
or al, (1 shl RTL8139_BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
dec cx
jns .cmd_loop
; in eax, dx ; eeprom delay
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS)
out dx, al
mov cl, 0xf
.read_loop:
shl ebx, 1
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS) \
or (1 shl RTL8139_BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
in al, dx
and al, (1 shl RTL8139_BIT_93C46_EEDO)
jz .dont_set
inc ebx
.dont_set:
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS)
out dx, al
; in eax, dx ; eeprom delay
dec cl
jns .read_loop
xor al, al
out dx, al
mov ax, bx
ret
;***************************************************************************
; Function
; rtl8139_transmit
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
; Destroyed registers
; eax, edx, esi, edi
; ToDo
; for waiting of timeout the rtl8139 internal timer
; should be used
;
;***************************************************************************
rtl8139_transmit:
cmp ecx, MAX_ETH_FRAME_SIZE
jg .finish ; packet is too long
push ecx
; check descriptor
mov ecx, [curr_tx_desc]
mov edx, [io_addr]
lea edx, [edx+ecx*4+RTL8139_REG_TSD0]
push edx ebx
in ax, dx
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
jz .send_packet
test ax, 0x1fff ; or no size given
jz .send_packet
; wait for timeout
mov ebx, RTL8139_TX_TIMEOUT
mov eax, 0x5 ; delay x/100 secs
int 0x40
in ax, dx
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
jz .send_packet
; chip hung, reset it
call rtl8139_reset
; reset the card
.send_packet:
; calculate tx_buffer address
pop ebx
push esi
mov eax, MAX_ETH_FRAME_SIZE
mul dword [curr_tx_desc]
mov esi, edi
lea edi, [rtl8139_tx_buff+eax]
mov eax, edi
cld
; copy destination address
movsd
movsw
; copy source address
mov esi, node_addr
movsd
movsw
; copy packet type
mov [edi], bx
add edi, 2
; copy the packet data
pop esi edx ecx
push ecx
shr ecx, 2
rep movsd
pop ecx
push ecx
and ecx, 3
rep movsb
; set address
add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0
out dx, eax
; set size and early threshold
pop eax ; pick up the size
add eax, ETH_HLEN
cmp eax, ETH_ZLEN
jnc .no_pad
mov eax, ETH_ZLEN
.no_pad:
or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH)
add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0
out dx, eax
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
inc dword [curr_tx_desc]
and dword [curr_tx_desc], 3
.finish:
ret
;***************************************************************************
; Function
; rtl8139_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
; Destroyed register(s)
; eax, edx, ecx
;
;***************************************************************************
rtl8139_poll:
mov word [eth_rx_data_len], 0
mov edx, [io_addr]
add edx, RTL8139_REG_COMMAND
in al, dx
test al, (1 shl RTL8139_BIT_BUFE)
jnz .finish
; new packet received copy it from rx_buffer into Ether_buffer
mov eax, rtl8139_rx_buff
add eax, [rtl8139_rx_buff_offset]
; check if packet is ok
test byte [eax], (1 shl RTL8139_BIT_ROK)
jz .reset_rx
; packet is ok copy it into the Ether_buffer
movzx ecx, word [eax+2] ; packet length
sub ecx, 4 ; don't copy CRC
mov word [eth_rx_data_len], cx
push ecx
shr ecx, 2 ; first copy dword-wise
lea esi, [eax+4] ; don't copy the packet header
mov edi, Ether_buffer
cld
rep movsd ; copy the dwords
pop ecx
and ecx, 3
rep movsb ; copy the rest bytes
; update rtl8139_rx_buff_offset
movzx eax, word [eax+2] ; packet length
add eax, [rtl8139_rx_buff_offset]
add eax, 4+3 ; packet header is 4 bytes long + dword alignment
and eax, not 3 ; dword alignment
cmp eax, RTL8139_RX_BUFFER_SIZE
jl .no_wrap
sub eax, RTL8139_RX_BUFFER_SIZE
.no_wrap:
mov [rtl8139_rx_buff_offset], eax
; update CAPR register
sub eax, 0x10 ; value 0x10 is a constant for CAPR
add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND
out dx, ax
.finish:
; clear active interrupt sources
mov edx, [io_addr]
add edx, RTL8139_REG_ISR
in ax, dx
out dx, ax
ret
.reset_rx:
in al, dx ; read command register
push eax
and al, not (1 shl RTL8139_BIT_RE)
out dx, al
pop eax
out dx, al
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND
mov ax, RTL8139_RX_CONFIG
out dx, ax
ret

File diff suppressed because it is too large Load Diff

202
trunk/network/ip.inc Normal file
View File

@ -0,0 +1,202 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; IP.INC ;;
;; ;;
;; IP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;*******************************************************************
; Interface
;
; ip_rx processes all packets received by the network layer
; It calls the appropriate protocol handler
;
;
;
;*******************************************************************
;***************************************************************************
; Function
; ip_rx
;
; Description
; Handles received IP packets
; This is a kernel function, called by stack_handler
;
;***************************************************************************
ip_rx:
; Look for a buffer to tx
mov eax, IPIN_QUEUE
call dequeue
cmp ax, NO_BUFFER
je ipr_exit ; Exit if no buffer available
push eax
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov edx, eax ; Save the address in edx for use by future processes
; Validate the IP checksum
mov ebx, edx
mov ah, [ebx + 10]
mov al, [ebx + 11] ; Get the checksum in intel format
mov [ebx + 10], word 0 ; clear checksum field - need to when
; recalculating checksum
; this needs two data pointers and two size #.
; 2nd pointer can be of length 0
mov ebx, edx
mov [checkAdd1], ebx
mov [checkSize1], word 20
mov [checkAdd2], dword 0
mov [checkSize2], word 0
call checksum ; Recalculate IP checksum
cmp ax, [checkResult]
jnz ipr_dump
; If the IP address is 255.255.255.255, accept it
; - it is a broadcast packet, which we need for dhcp
mov eax, [edx + 16]
cmp eax, 0xffffffff
je ipr_p0
; Validate the IP address, if it isn't broadcast
cmp eax, [stack_ip]
jnz ipr_dump
ipr_p0:
mov al, [edx]
and al, 0x0f
cmp al, 0x05
jnz ipr_dump
cmp [edx+8], byte 0
jz ipr_dump
mov ax, [edx + 6]
and ax, 0xFFBF
cmp ax, 0
jnz ipr_dump
; Check the protocol, and call the appropriate handler
; Each handler will re-use or free the queue buffer as appropriate
mov al, [edx + 9]
cmp al , PROTOCOL_ICMP
jnz ipr_p1
pop eax
call icmp_rx
jmp ipr_exit
ipr_p1:
cmp al , PROTOCOL_TCP
jnz ipr_p2
pop eax
call tcp_rx
jmp ipr_exit
ipr_p2:
cmp al , PROTOCOL_UDP
jnz ipr_dump
pop eax
call udp_rx
jmp ipr_exit
ipr_dump:
; No protocol handler available, so
; silently dump the packet, freeing up the queue buffer
; inc dword [dumped_rx_count]
pop eax
call freeBuff
ipr_exit:
ret
;***************************************************************************
; Function
; icmp_rx
;
; Description
; ICMP protocol handler
; This is a kernel function, called by ip_rx
; edx contains the address of the buffer in use.
; This buffer must be reused or marked as empty afterwards
;
;***************************************************************************
icmp_rx:
cmp [edx + 20], byte 8 ; Is this an echo request? discard if not
jz icmp_echo
call freeBuff
jmp icmp_exit
icmp_echo:
push eax
mov [edx + 10], word 0 ; I think this was already done by IP rx
; swap the source and destination addresses
mov ecx, [edx + 16]
mov eax, [edx + 12]
mov [edx + 16], eax
mov [edx + 12], ecx
; recaluculate the IP header checksum
mov ebx, edx
mov [checkAdd1], ebx
mov [checkSize1], word 20
mov [checkAdd2], dword 0
mov [checkSize2], word 0
call checksum
mov ax, [checkResult]
mov [edx + 10], ah
mov [edx + 11], al ; ?? correct byte order?
mov [edx + 20], byte 0 ; change the request to a response
mov [edx + 22], word 0 ; clear ICMP checksum prior to re-calc
; Calculate the length of the ICMP data ( IP payload)
mov ah, [edx + 2]
mov al, [edx + 3]
sub ax, 20
mov [checkSize1], ax
mov ebx, edx
add ebx, 20
mov [checkAdd1], ebx
mov [checkAdd2], dword 0
mov [checkSize2], word 0
call checksum
mov ax, [checkResult]
mov [edx + 22], ah
mov [edx + 23], al
; Queue packet for transmission
pop ebx
mov eax, NET1OUT_QUEUE
call queue
icmp_exit:
ret

214
trunk/network/queue.inc Normal file
View File

@ -0,0 +1,214 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; QUEUE.INC ;;
;; ;;
;; Buffer queue management for Menuet OS TCP/IP Stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;*******************************************************************
; Interface
;
; queueInit Configures the queues to empty
; dequeue Removes a buffer pointer from a queue
; queue Inserts a buffer pointer into a queue
; freeBuff Adds the buffer pointer to the list of free buffers
; queueSize Returns the number of entries in a queue
;
; The various defines for queue names can be found in stack.inc
;
;*******************************************************************
;***************************************************************************
; Function
; freeBuff
;
; Description
; Adds a buffer number to the beginning of the free list.
; buffer number in eax ( ms word zeroed )
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
freeBuff:
push ebx
push ecx
mov ebx, EMPTY_QUEUE
shl ebx, 1
add ebx, queues
cli ; Ensure that another process does not interfer
movzx ecx, word [ebx]
mov [ebx], ax
shl eax, 1
add eax, queueList
mov [eax], cx
sti
pop ecx
pop ebx
ret
;***************************************************************************
; Function
; queueSize
;
; Description
; Counts the number of entries in a queue
; queue number in ebx ( ms word zeroed )
; Queue size returned in eax
; This always works, so no error returned
;***************************************************************************
queueSize:
xor eax, eax
shl ebx, 1
add ebx, queues
movzx ecx, word [ebx]
cmp cx, NO_BUFFER
je qs_exit
qs_001:
inc eax
shl ecx, 1
add ecx, queueList
movzx ecx, word [ecx]
cmp cx, NO_BUFFER
je qs_exit
jmp qs_001
qs_exit:
ret
;***************************************************************************
; Function
; queue
;
; Description
; Adds a buffer number to the *end* of a queue
; This is quite quick because these queues will be short
; queue number in eax ( ms word zeroed )
; buffer number in ebx ( ms word zeroed )
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
queue:
push ebx
shl ebx, 1
add ebx, queueList ; eax now holds address of queue entry
mov [ebx], word NO_BUFFER ; This buffer will be the last
cli
shl eax, 1
add eax, queues ; eax now holds address of queue
movzx ebx, word [eax]
cmp bx, NO_BUFFER
jne qu_001
pop ebx
; The list is empty, so add this to the head
mov [eax], bx
jmp qu_exit
qu_001:
; Find the last entry
shl ebx, 1
add ebx, queueList
mov eax, ebx
movzx ebx, word [ebx]
cmp bx, NO_BUFFER
jne qu_001
mov ebx, eax
pop eax
mov [ebx], ax
qu_exit:
sti
ret
;***************************************************************************
; Function
; dequeue
;
; Description
; removes a buffer number from the head of a queue
; This is fast, as it unlinks the first entry in the list
; queue number in eax ( ms word zeroed )
; buffer number returned in eax ( ms word zeroed )
; all other registers preserved
;
;***************************************************************************
dequeue:
push ebx
shl eax, 1
add eax, queues ; eax now holds address of queue
mov ebx, eax
cli
movzx eax, word [eax]
cmp ax, NO_BUFFER
je dq_exit
push eax
shl eax, 1
add eax, queueList ; eax now holds address of queue entry
mov ax, [eax]
mov [ebx], ax
pop eax
dq_exit:
sti
pop ebx
ret
;***************************************************************************
; Function
; queueInit
;
; Description
; Initialises the queues to empty, and creates the free queue
; list.
;
;***************************************************************************
queueInit:
mov esi, queues
mov ecx, NUMQUEUES
mov ax, NO_BUFFER
qi001:
mov [esi], ax
inc esi
inc esi
loop qi001
mov esi, queues + ( 2 * EMPTY_QUEUE )
; Initialise empty queue list
xor ax, ax
mov [esi], ax
mov ecx, NUMQUEUEENTRIES - 1
mov esi, queueList
qi002:
inc ax
mov [esi], ax
inc esi
inc esi
loop qi002
mov ax, NO_BUFFER
mov [esi], ax
ret

1784
trunk/network/stack.inc Normal file

File diff suppressed because it is too large Load Diff

1243
trunk/network/tcp.inc Normal file

File diff suppressed because it is too large Load Diff

137
trunk/network/udp.inc Normal file
View File

@ -0,0 +1,137 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; UDP.INC ;;
;; ;;
;; UDP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;*******************************************************************
; Interface
;
; udp_rx Handles received IP packets with the UDP protocol
;
;*******************************************************************
;***************************************************************************
; Function
; udp_rx
;
; Description
; UDP protocol handler
; This is a kernel function, called by ip_rx
; IP buffer address given in edx
; Free up (or re-use) IP buffer when finished
;
;***************************************************************************
udp_rx:
push eax
; First validate the header & checksum. Discard buffer if error
; Look for a socket where
; IP Packet UDP Destination Port = local Port
; IP Packet SA = Remote IP
movzx ebx, word [edx + 22] ; get the local port from
; the IP packet's UDP header
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
fs1:
sub eax, SOCKETBUFFSIZE
cmp [eax + sockets + 12], bx ; bx will hold the 'wrong' value,
; but the comparision is correct
loopnz fs1 ; Return back if no match
jz fs_done
; No match, so exit
jmp udprx_001
fs_done:
; For dhcp, we must allow any remote server to respond.
; I will accept the first incoming response to be the one
; I bind to, if the socket is opened with a destination IP address of
; 255.255.255.255
mov ebx, [eax + sockets + 16]
cmp ebx, 0xffffffff
je udprx_002
mov ebx, [edx + 12] ; get the Source address from the IP packet
cmp [eax + sockets + 16], ebx
jne udprx_001 ; Quit if the source IP is not valid
udprx_002:
; OK - we have a valid UDP packet for this socket.
; First, update the sockets remote port number with the incoming msg
; - it will have changed
; from the original ( 69 normally ) to allow further connects
movzx ebx, word [edx + 20] ; get the UDP source port
; ( was 69, now new )
mov [eax + sockets + 20], bx
; Now, copy data to socket. We have socket address as [eax + sockets].
; We have IP packet in edx
; get # of bytes in ecx
movzx ecx, byte [edx + 3] ; total length of IP packet. Subtract
mov ch, byte [edx + 2] ; 20 + 8 gives data length
sub ecx, 28
mov ebx, eax
add ebx, sockets ; ebx = address of actual socket
mov eax, [ebx+ 4] ; get socket owner PID
push eax
mov eax, [ebx + 24] ; get # of bytes already in buffer
add [ebx + 24], ecx ; increment the count of bytes in buffer
; point to the location to store the data
add ebx, eax
add ebx, SOCKETHEADERSIZE
; ebx = location for first byte, ecx has count,
; edx points to data
add edx, 28 ; edx now points to the data
mov edi, ebx
mov esi, edx
cld
rep movsb ; copy the data across
; flag an event to the application
pop eax
mov ecx,1
mov esi,0x3020+0x4
newsearch:
cmp [esi],eax
je foundPID
inc ecx
add esi,0x20
cmp ecx,[0x3004]
jbe newsearch
foundPID:
shl ecx,8
or dword [ecx+0x80000+0xA8],dword 10000000b ; stack event
mov [check_idle_semaphore],200
udprx_001:
pop eax
call freeBuff ; Discard the packet
ret

135
trunk/sound/playnote.inc Normal file
View File

@ -0,0 +1,135 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PLAYNOTE.INC version 1.1 22 November 2003 ;;
;; ;;
;; Player Notes for Speaker PC ;;
;; subfunction #55 from function #55 Menuet OS ;;
;; ;;
;; Copyright 2003 VaStaNi ;;
;; vastani@ukr.net ;;
;; >>>- SIMPLY - QUICKLY - SHORTLY -<<< ;;
;; ;;
;; Note: playnote.txt ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
kontrOctave dw 0x4742, 0x4342, 0x3F7C, 0x3BEC, 0x388F, 0x3562
dw 0x3264, 0x2F8F, 0x2CE4, 0x2A5F, 0x2802, 0x25BF
memAdrNote dd 0
pidProcessNote dd 0
slotProcessNote dd 0
count_timer_Note dd 1
mem8253r42 dw 0
countDelayNote db 0
playNote:
; jmp NotPlayNotes
mov esi, [memAdrNote]
or esi, esi ; ESI = 0 ? - OFF Notes Play ?
jz NotPlayNotes ; if ESI = 0 -> ignore play pocedure
cmp eax, [count_timer_Note]
jb NotPlayNotes
push eax
inc eax
mov [count_timer_Note], eax
mov al, [countDelayNote]
dec al ; decrement counter Delay for Playing Note
jz NewLoadNote@Delay
cmp al, 0xFF ; this is first Note Play ?
jne NextDelayNote
;This is FIRST Note, save counter channel 2 chip 8253
mov al, 0xB6 ; control byte to timer chip 8253
out 0x43, al ; Send it to the control port chip 8253
in al, 0x42 ; Read Lower byte counter channel 2 chip 8253
mov ah, al ; AH = Lower byte counter channel 2
in al, 0x42 ; Read Upper byte counter channel 2 chip 8253
mov [mem8253r42], ax ; Save counter channel 2 timer chip 8253
NewLoadNote@Delay:
cld
; lodsb ; load AL - counter Delay
call ReadNoteByte
or al, al ; THE END ?
jz EndPlayNote
cmp al, 0x81
jnc NoteforOctave
mov [countDelayNote], al
; lodsw ; load AX - counter for Note!
call ReadNoteByte
mov ah,al
call ReadNoteByte
xchg al,ah
jmp pokeNote
EndPlayNote: ; THE END Play Notes!
in al, 0x61 ; Get contents of system port B chip 8255
and al, 0xFC ; Turn OFF timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
mov ax, [mem8253r42] ; memorize counter channel 2 timer chip 8253
xchg al, ah ; reverse byte in word
out 0x42, al ; restore Lower byte counter channel 2
mov al, ah ; AL = Upper byte counter channel 2
out 0x42, al ; restore Upper byte channel 2
xor eax, eax ; EAX = 0
mov [memAdrNote], eax ; clear header control Delay-Note string
NextDelayNote:
mov [countDelayNote], al ; save new counter delay Note
pop eax
NotPlayNotes:
RET
NoteforOctave:
sub al, 0x81 ; correction value for delay Note
mov [countDelayNote], al ; save counter delay this new Note
; lodsb ; load pack control code
call ReadNoteByte
cmp al, 0xFF ; this is PAUSE ?
jne packCode ; no, this is PACK CODE
in al, 0x61 ; Get contents of system port B chip 8255
and al, 0xFC ; Turn OFF timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
jmp saveESI
packCode:
mov cl, al ; save code
and al, 0xF ; clear upper bits
dec al ; correction
add al, al ; transform number to offset constant
movsx eax, al ; EAX - offset
add eax, dword kontrOctave ; EAX - address from constant
mov ax, [eax] ; read constant
shr cl, 4 ; transform for number Octave
shr ax, cl ; calculate from Note this Octave!
pokeNote:
out 0x42, al ; Lower byte Out to channel 2 timer chip 8253
mov al, ah
out 0x42, al ; Upper byte Out to channel 2 timer chip 8253
in al, 0x61 ; Get contents of system port B chip 8255
or al, 3 ; Turn ON timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
saveESI:
; mov [memAdrNote], esi ; save new header control Delay-Note string
pop eax
RET
ReadNoteByte:
;result:
; al - note
push eax
push ebx
push ecx
push edx
mov eax,[pidProcessNote]
call pid_to_slot
test eax,eax
jz .failed
lea ebx,[esp+12]
mov ecx,1
mov edx,[memAdrNote]
inc [memAdrNote]
call read_process_memory
.failed:
pop edx
pop ecx
pop ebx
pop eax
ret
;------------------- END CODE -------------------

350
trunk/sound/sb16.inc Normal file
View File

@ -0,0 +1,350 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SB16.INC ;;
;; ;;
;; Sound Blaster 16 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; - 11.07.2002 8 bit stereo mode - Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SB16_load_music equ 0xc0000000
SB16_play_music equ 0xc0000001
DMAPage equ 0x2A
Rate equ 44100
SB16Buffer equ 0x2A0000
SB16_Status equ SB16Buffer+65536
iglobal
sound_data_format dd 0x1
sound_data_length dd 65536
sound_data_freq dd 44100
endg
sound_interface:
cmp eax,0 ; Load data
jne no_SB16_load_music
mov edi,[0x3010]
add edi,0x10
add ebx,[edi]
call code_SB16_load_music
ret
no_SB16_load_music:
cmp eax,1 ; Play data
jne no_SB16_play_music
call code_SB16_play_music
ret
no_SB16_play_music:
cmp eax,2 ; Set data formats
jne no_SB16_data_format
cmp ebx,0 ; ebx=0 play format
jne no_sound_format
mov [sound_data_format],ecx ; 1=8b mono, 2=8b stereo
ret
no_sound_format:
cmp ebx,1 ; ebx=1 data length
jne no_sound_length
mov [sound_data_length],ecx ;
ret
no_sound_length:
cmp ebx,2 ; ebx=2 sound data frequency
jne no_sound_freq
mov [sound_data_freq],ecx
ret
no_sound_freq:
ret
no_SB16_data_format:
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
cmp eax, edi ; this is subfunction #55 ?
jne retFunc55 ; if no then return.
cmp byte [sound_flag],0
jne retFunc55
movzx eax, byte [countDelayNote]
or al, al ; player is busy ?
jnz retFunc55 ; return counter delay Note
; mov eax, [0x3010]
; mov eax, [eax+0x10] ; address application im memory
; add eax, edx ; add offset Delay-Note string
; mov [memAdrNote], eax
mov [memAdrNote],edx
mov eax,[0x3010]
mov eax,[eax+4]
mov [pidProcessNote],eax
xor eax, eax ; Ok! EAX = 0
retFunc55:
mov [esp+36], eax ; return value EAX for application
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ret
code_SB16_play_music:
cmp [sound_data_format],1
jne no_sound_8bm
call sb_play_8b_mono
ret
no_sound_8bm:
cmp [sound_data_format],2
jne no_sound_8bs
call sb_play_8b_stereo
ret
no_sound_8bs:
ret
Blaster_command:
push eax
push ecx
push edx
mov dx,word [sb16]
add dx,0xc
mov cx,1000
bcl1:
in al,dx
and al,128
jz bcl2
loop bcl1
bcl2:
mov al,[esp+8]
mov dx,[esp+0]
add dx,word [sb16]
out dx,al
pop edx
pop ecx
pop eax
ret
sb_play_8b_stereo:
pusha
call sb_set_dma
call sb_set_stereo
mov dx,0xc
mov al,0xa8
call Blaster_command
mov al,0x40
call Blaster_command
mov al,245
call Blaster_command
mov al,0x48
call Blaster_command
mov al,0xff
call Blaster_command
call Blaster_command
mov al,0x91
call Blaster_command
popa
ret
sb_set_stereo:
push eax
push edx
call sb_wait
mov dx,word [sb16]
add dx,0x4
mov al,0xe
out dx,al
inc dx
in al,dx
and al,253
or al,2 ; stereo
out dx,al
pop edx
pop eax
ret
code_SB16_load_music:
cmp byte [SB16_Status],1
je nol
mov edi,SB16Buffer
mov esi,ebx
mov ecx,65536/4
cld
rep movsd
nol: ret
iglobal
dma_table db 0x87,0x83,0x81,0x82
endg
;--------------------------------
; program dma
;--------------------------------
sb_set_dma:
pusha
mov eax,[sound_dma]
add eax,4
out 0xa,al
mov al,0
out 0xc,al
mov eax,[sound_dma]
add eax,0x48
out 0xb,al
mov edx,[sound_dma]
shl edx,1
mov al,0
out dx,al
mov al,0
out dx,al
mov edx,[sound_dma]
add edx,dma_table
movzx edx,byte [edx]
mov al,DMAPage
out dx,al
mov edx,[sound_dma]
shl edx,1
inc edx
mov eax,[sound_data_length]
dec eax
and eax,0xff
; mov al,(DataLength-1) and 0xff
out dx,al
mov eax,[sound_data_length]
dec eax
shr eax,8
; mov al,(DataLength-1) shr 8
out dx,al
mov eax,[sound_dma] ; DMA
out 0xa,al
popa
ret
sb_play_8b_mono:
call sb_set_dma
cmp byte [SB16_Status],1
jne contsb16
jmp retserve
contsb16:
mov dx,word [sb16]
add dx,4
mov ecx,[sound_dma]
mov ax,0x01
shl ax,cl
shl ax,8
add ax,0x81
out dx,ax
mov ax,0f280h ;enable irq5
out dx,ax
adr1_SB: mov dx,word [sb16]
add dx,0ch
in al,dx
and al,080h
jnz adr1_SB
call sb_set_stereo
mov al,0d1h
out dx,al
mov dx,word [sb16]
add dx,0ch
call sb_wait
mov al,40h ; Rate
out dx,al
call sb_wait
mov al,256-1000000/Rate
out dx,al
call sb_wait
mov al,14h ; Datalength
out dx,al
call sb_wait
mov eax,[sound_data_length]
dec eax
and eax,0xff
;mov al,(DataLength-1) and 0xff
out dx,al
call sb_wait
mov eax,[sound_data_length]
dec eax
shr eax,8
;mov al,(DataLength-1) shr 8
out dx,al
retserve:
ret
sb_wait: in al,dx ;wait
and al,080h
jnz sb_wait
ret
;****************************************
; END CODE SB16 by Minazzi Paolo
;***************************************

973
trunk/video/vesa12.inc Normal file
View File

@ -0,0 +1,973 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; VESA12.INC ;;
;; ;;
;; Vesa 1.2 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Ville Turjanmaa ;;
;; ;;
;; quickcode@mail.ru - bankswitch for S3 cards ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; A complete video driver should include the following types of function
;
; Putpixel
; Getpixel
;
; Drawimage
; Drawbar
;
; Drawbackground
;
;
; Modifying the set_bank -function is mostly enough
; for different Vesa 1.2 setups.
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{
; set_bank modified by kmeaw
set_bank:
cli
cmp al,[0xfff2]
je retsb
mov [0xfff2],al
push ax
push dx
push cx
mov cl, al
mov dx, 0x3D4
mov al, 0x38
out dx, al ;CR38 Register Lock 1 ;Note: Traditionally 48h is used to
;unlock and 00h to lock
inc dx
mov al, 0x48
out dx, al ;3d5 -?
dec dx
mov al, 0x31
out dx, al ;CR31 Memory Configuration Register
;0 Enable Base Address Offset (CPUA BASE). Enables bank operation if set, ;disables if clear.
;4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 51h,
;for the 864/964 see index 69h.
inc dx
in al, dx
dec dx
mov ah, al
mov al, 0x31
out dx, ax
mov al, ah
or al, 9
inc dx
out dx, al
dec dx
mov al, 0x35
out dx, al ;CR35 CRT Register Lock
inc dx
in al, dx
dec dx
and al, 0xF0
mov ch, cl
and ch, 0x0F
or ch, al
mov al, 0x35
out dx, al
inc dx
mov al, ch
out dx, ax
dec dx
mov al, 0x51 ;Extended System Control 2 Register
out dx, al
inc dx
in al, dx
dec dx
and al, 0xF3
shr cl, 2
and cl, 0x0C
or cl, al
mov al, 0x51
out dx, al
inc dx
mov al, cl
out dx, al
dec dx
mov al, 0x38
out dx, al
inc dx
xor al, al
out dx, al
dec dx
pop cx
pop dx
pop ax
retsb:
sti
ret
;Set bank function for Intel 810/815 chipsets
; *****Modified by Protopopius, Russia.*****
; ********* http://menuetos.hut.ru **************
; ************************************************
;
;set_bank:
;cli
;cmp al,[0xfff2]
;je retsb
;mov [0xfff2],al
;push ax
;push dx
;mov dx,3CEh
;mov ah,al ; Save value for later use
;mov al,10h ; Index GR10 (Address Mapping)
;out dx,al ; Select GR10
;inc dl
;mov al,3 ; Set bits 0 and 1 (Enable linear page mapping)
;out dx,al ; Write value
;dec dl
;mov al,11h ; Index GR11 (Page Selector)
;out dx,al ; Select GR11
;inc dl
;mov al,ah ; Write address
;out dx,al ; Write the value
;pop dx
;pop ax
;retsb:
;sti
;ret
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
;set_bank:
; cli
; cmp al,[0xfff2]
; je retsb
; mov [0xfff2],al
; push ax
; push dx
; mov ah,al
; mov dx,0x03D4
; mov al,0x39
; out dx,al
; inc dl
; mov al,0xA5
; out dx,al
; dec dl
; mov al,6Ah
; out dx,al
; inc dl
; mov al,ah
; out dx,al
; dec dl
; mov al,0x39
; out dx,al
; inc dl
; mov al,0x5A
; out dx,al
; dec dl
; pop dx
; pop ax
;
; retsb:
; ret
vesa12_drawbackground:
call [disable_mouse]
push eax
push ebx
push ecx
push edx
xor edx,edx
mov eax,dword[WinMapAddress-8]
mov ebx,dword[WinMapAddress-4]
mul ebx
mov ebx,3
mul ebx
mov [imax],eax
mov eax,[draw_data+32+0]
mov ebx,[draw_data+32+4]
mov edi,0 ;no force
v12dp3:
push eax
push ebx
mov esi,0x300000
cmp [WinMapAddress-12],dword 1 ; tiled background
jne no_vesa12_tiled_bgr
push edx
xor edx,edx
mov ecx,[WinMapAddress-8]
div ecx
mov eax,edx
push eax
mov eax,ebx
xor edx,edx
mov ecx,[WinMapAddress-4]
div ecx
mov ebx,edx
pop eax
pop edx
no_vesa12_tiled_bgr:
cmp [WinMapAddress-12],dword 2 ; stretched background
jne no_vesa12_stretched_bgr
push edx
imul eax,dword [WinMapAddress-8]
xor edx,edx
mov ecx,[0xfe00]
inc ecx
div ecx
push eax
mov eax,ebx
imul eax,dword [WinMapAddress-4]
xor edx,edx
mov ecx,[0xfe04]
inc ecx
div ecx
mov ebx,eax
pop eax
pop edx
no_vesa12_stretched_bgr:
push eax
mov eax,ebx
xor edx,edx
mov ebx,[WinMapAddress-8]
add ebx,[WinMapAddress-8]
add ebx,[WinMapAddress-8]
mul ebx
mov esi,eax
pop eax
add esi,eax
add esi,eax
add esi,eax
add esi,0x300000
pop ebx
pop eax
v12di4:
mov ecx,[esi]
pusha
mov esi,eax
mov edi,ebx
mov eax,[0xfe00]
add eax,1
mul ebx
add eax,esi
add eax,WinMapAddress
cmp [eax],byte 1
jnz v12nbgp
mov eax,[0xfe08]
mov ebx,edi
mul ebx
add eax,esi
add eax,esi
add eax,esi
cmp [0xFBF1],byte 24
jz v12bgl3
add eax,esi
v12bgl3:
push ebx
push eax
sub eax,[0xfe80]
shr eax,16
call set_bank
pop eax
and eax,65535
add eax,0xa0000
pop ebx
mov [eax],cx
add eax,2
shr ecx,16
mov [eax],cl
sti
v12nbgp:
popa
add esi,3
inc eax
cmp eax,[draw_data+32+8]
jg v12nodp31
jmp v12dp3
v12nodp31:
mov eax,[draw_data+32+0]
inc ebx
cmp ebx,[draw_data+32+12]
jg v12dp4
jmp v12dp3
v12dp4:
pop edx
pop ecx
pop ebx
pop eax
ret
vesa12_drawbar:
call [disable_mouse]
;; mov [novesachecksum],dword 0
sub edx,ebx
sub ecx,eax
push esi
push edi
push eax
push ebx
push ecx
push edx
mov ecx,[0x3010]
add eax,[ecx-twdw]
add ebx,[ecx-twdw+4]
push eax
mov eax,ebx ; y
mov ebx,[0xfe08]
mul ebx
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start
jz dbpi2412
add eax,ecx
dbpi2412:
add eax,[0xfe80]
mov edi,eax
; x size
mov eax,[esp+4] ; [esp+6]
mov ecx,eax
add ecx,eax
add ecx,eax
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size
jz dbpi24312
add ecx,eax
dbpi24312:
mov ebx,[esp+0]
; check limits ?
push eax
push ecx
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+0]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+4]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+8]
cmp ecx,[0xfe00]
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+12]
cmp ecx,[0xfe04]
jnz dbcblimitlset12
pop ecx
pop eax
push dword 0
jmp dbcblimitlno12
dbcblimitlset12:
pop ecx
pop eax
push dword 1
dbcblimitlno12:
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ?
jz dbpi24bit12
jmp dbpi32bit12
; DRAWBAR 24 BBP
dbpi24bit12:
push eax
push ebx
push edx
mov eax,ecx
mov ebx,3
div ebx
mov ecx,eax
pop edx
pop ebx
pop eax
cld
dbnewpi12:
push ebx
push edi
push ecx
xor edx,edx
mov eax,edi
sub eax,[0xfe80]
mov ebx,3
div ebx
add eax,WinMapAddress
mov ebx,[0x3010]
movzx ebx,byte[ebx+0xe]
cld
dbnp2412:
mov dl,[eax]
push eax
push ecx
cmp dl,bl
jnz dbimp24no12
cmp [esp+5*4],dword 0
jz dbimp24yes12
; call dbcplimit
; jnz dbimp24no12
dbimp24yes12:
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov eax,[esp+8+3*4+16+4+4]
stosw
shr eax,16
stosb
sti
pop edi
add edi,3
pop ecx
pop eax
inc eax
loop dbnp2412
jmp dbnp24d12
dbimp24no12:
pop ecx
pop eax
cld
add edi,3
inc eax
loop dbnp2412
dbnp24d12:
mov eax,[esp+3*4+16+4]
test eax,0x80000000
jz nodbgl2412
cmp al,0
jz nodbgl2412
dec eax
mov [esp+3*4+16+4],eax
nodbgl2412:
pop ecx
pop edi
pop ebx
add edi,[0xfe08]
dec ebx
jz dbnonewpi12
jmp dbnewpi12
dbnonewpi12:
add esp,7*4
ret
; DRAWBAR 32 BBP
dbpi32bit12:
cld
shr ecx,2
dbnewpi3212:
push ebx
push edi
push ecx
mov eax,edi
sub eax,[0xfe80]
shr eax,2
add eax,WinMapAddress
mov ebx,[0x3010]
movzx ebx,byte[ebx+0xe]
cld
dbnp3212:
mov dl,[eax]
push eax
push ecx
cmp dl,bl
jnz dbimp32no12
cmp [esp+5*4],dword 0
jz dbimp32yes12
; call dbcplimit
; jnz dbimp32no12
dbimp32yes12:
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov eax,[esp+8+3*4+16+4+4]
stosw
shr eax,16
stosb
sti
pop edi
add edi,4
inc ebp
pop ecx
pop eax
inc eax
loop dbnp3212
jmp dbnp32d12
dbimp32no12:
pop ecx
pop eax
inc eax
add edi,4
inc ebp
loop dbnp3212
dbnp32d12:
mov eax,[esp+12+16+4]
test eax,0x80000000
jz nodbgl3212
cmp al,0
jz nodbgl3212
dec eax
mov [esp+12+16+4],eax
nodbgl3212:
pop ecx
pop edi
pop ebx
add edi,[0xfe08]
dec ebx
jz nodbnewpi3212
jmp dbnewpi3212
nodbnewpi3212:
add esp,7*4
ret
Vesa12_putpixel24:
mov edi,eax ; x
mov eax,ebx ; y
lea edi,[edi+edi*2]
mov ebx,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov eax,[esp+28]
stosw
shr eax,16
mov [edi],al
sti
ret
Vesa12_putpixel32:
mov edi,eax ; x
mov eax,ebx ; y
shl edi,2
mov ebx,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov ecx,[esp+28]
mov [edi],ecx
sti
ret
Vesa12_getpixel24:
mov edi,eax ; x
mov eax,ebx ; y
lea edi,[edi+edi*2]
mov ebx,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov ecx,[edi]
and ecx,255*256*256+255*256+255
sti
ret
Vesa12_getpixel32:
mov edi,eax ; x
mov eax,ebx ; y
shl edi,2
mov ebx,[0xfe08]
xor edx,edx
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov ecx,[edi]
and ecx,255*256*256+255*256+255
sti
ret
vesa12_putimage:
; mov ebx,image
; mov ecx,320*65536+240
; mov edx,20*65536+20
call [disable_mouse]
mov [novesachecksum],dword 0
push esi
push edi
push eax
push ebx
push ecx
push edx
movzx eax,word [esp+2]
movzx ebx,word [esp+0]
mov ecx,[0x3010]
add eax,[ecx-twdw]
add ebx,[ecx-twdw+4]
push eax
mov eax,ebx ; y
mov ebx,[0xfe08]
mul ebx
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start
jz pi2412
add eax,ecx
pi2412:
add eax,[0xfe80]
mov edi,eax
; x size
movzx eax,word [esp+6]
mov ecx,eax
add ecx,eax
add ecx,eax
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size
jz pi24312
add ecx,eax
pi24312:
mov esi,[esp+8]
movzx ebx,word [esp+4]
; check limits while draw ?
push eax
push ecx
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+0]
cmp ecx,0
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+4]
cmp ecx,0
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+8]
cmp ecx,[0xfe00]
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+12]
cmp ecx,[0xfe04]
jnz dbcblimitlset212
pop ecx
pop eax
push dword 0
jmp dbcblimitlno212
dbcblimitlset212:
pop ecx
pop eax
push dword 1
dbcblimitlno212:
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ?
jz pi24bit12
jmp pi32bit12
pi24bit12:
cld
push eax
push ebx
push edx
xor edx,edx
mov eax,ecx
mov ebx,3
div ebx
mov ecx,eax
pop edx
pop ebx
pop eax
newpi12:
push edi
push esi
push ecx
push ebx
xor edx,edx
mov eax,edi
sub eax,[0xfe80]
mov ebx,3
div ebx
add eax,WinMapAddress
mov ebx,[0x3010]
mov bl,[ebx+0xe]
mov bh,[esp+4*4]
np2412:
cmp bl,[eax]
jnz imp24no12
mov edx,[esi]
cmp bh,0
jz imp24yes12
; call dbcplimit
; jnz imp24no12
imp24yes12:
push eax
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov [edi],edx
shr edx,2
mov [edi+2],dl
sti
pop edi
pop eax
imp24no12:
inc eax
add esi,3
add edi,3
dec ecx
jnz np2412
np24d12:
pop ebx
pop ecx
pop esi
pop edi
add edi,[0xfe08]
xor eax,eax
mov ax,[esp+4+2+4]
lea eax,[eax+eax*2]
add esi,eax
dec ebx
jz nonewpi12
jmp newpi12
nonewpi12:
add esp,7*4
mov eax,0
ret
pi32bit12:
cld
shr ecx,2
newpi3212:
push edi
push esi
push ecx
push ebx
mov eax,edi
sub eax,[0xfe80]
shr eax,2
add eax,WinMapAddress
mov ebx,[0x3010]
mov bl,[ebx+0xe]
mov bh,[esp+4*4]
np3212:
cmp bl,[eax]
jnz imp32no12
mov edx,[esi]
cmp bh,0
jz imp32yes12
; call dbcplimit
; jnz imp32no12
imp32yes12:
push eax
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov [edi],edx
sti
pop edi
pop eax
imp32no12:
inc eax
add esi,3
add edi,4
dec ecx
jnz np3212
np32d12:
pop ebx
pop ecx
pop esi
pop edi
add edi,[0xfe08]
movzx eax,word [esp+4+2+4]
lea eax,[eax+eax*2]
add esi,eax
dec ebx
jz nonewpi3212
jmp newpi3212
nonewpi3212:
add esp,7*4
mov eax,0
ret
vesa12_read_screen_pixel:
and eax,0x3FFFFF
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ?
jz v12rsp24
mov edi,eax
shl edi,2
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov eax,[edi]
and eax,0x00ffffff
ret
v12rsp24:
imul eax,3
mov edi,eax
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov eax,[edi]
and eax,0x00ffffff
ret

1107
trunk/video/vesa20.inc Normal file

File diff suppressed because it is too large Load Diff

781
trunk/video/vga.inc Normal file
View File

@ -0,0 +1,781 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; VGA.INC ;;
;; ;;
;; 640x480 mode 0x12 VGA functions for MenuetOS ;;
;; ;;
;; Paul Butcher, paul.butcher@asa.co.uk ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
paletteVGA:
;16 colour palette
mov dx,0x3c8
mov al,0
out dx,al
mov ecx,16
mov dx,0x3c9
xor eax,eax
palvganew:
mov al,0
test ah,4
jz palvgalbl1
add al,31
test ah,8
jz palvgalbl1
add al,32
palvgalbl1:
out dx,al ; red 0,31 or 63
mov al,0
test ah,2
jz palvgalbl2
add al,31
test ah,8
jz palvgalbl2
add al,32
palvgalbl2:
out dx,al ; blue 0,31 or 63
mov al,0
test ah,1
jz palvgalbl3
add al,31
test ah,8
jz palvgalbl3
add al,32
palvgalbl3:
out dx,al ; green 0,31 or 63
add ah,1
loop palvganew
ret
vga_putimage:
push ebp ;
push esi ;
push edi ;
push eax ;
push ebx ; +8 [ptrImage]
push ecx ; +4 [BH]
push edx ; +0 [xy]
movzx eax,word [esp+2] ; eax:=x
movzx ebx,word [esp+0] ; ebx:=y
mov ecx,[0x3010] ;
add eax,[ecx-twdw] ; eax+=Xwin
add ebx,[ecx-twdw+4] ; ebx+=Ywin
mov ecx,ebx ; ecx = y+Ywin
mov edx,eax ; edx = x+Xwin
imul ebx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl eax,2 ; (x+Xwin)*BytesPerPixel
add eax,ebx ;
mov edi,eax ; store copy
add eax,[0xfe80] ; +AddrLFB
;entry point in LFB >> EAX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrLFB
shr edi,5 ; change from 4 to 1/8 BytesPerPixel
add edi,0xa0000 ; + VGABasePtr
;VGA start address >> EDI:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrVGA
mov ebx, [0xfe00] ; ScreenXSize
inc ebx ; +1
imul ebx,ecx ; *(y+Ywin)
mov ebp, ebx ;
add ebp, edx ; +(x+Xwin)
add ebp, WinMapAddress ; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
mov esi,[esp+8] ; esi:=AddrImg
movzx ecx,word [esp+6] ; ecx:=B
movzx ebx,word [esp+4] ; ebx:=H
; check limits while draw ?
push ecx ; B
push eax ; LFB address
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+0]
cmp ecx,0
jnz dbcblimitlset_vga
mov ecx,[eax+draw_data-0x3000+4]
cmp ecx,0
jnz dbcblimitlset_vga
mov ecx,[eax+draw_data-0x3000+8]
cmp ecx,[0xfe00] ; ecx <> Screen X size
jnz dbcblimitlset_vga
mov ecx,[eax+draw_data-0x3000+12]
cmp ecx,[0xfe04] ; ecx <> Screen Y size
jnz dbcblimitlset_vga
pop eax ; LFB address
pop ecx ; B
push dword 0
jmp pimvga
dbcblimitlset_vga:
pop eax ; LFB address
pop ecx ; B
push dword 1
pimvga:
push edi
push esi
push eax ; LFB address
push ecx ; B
push ebx ; H
push edx ; x+Xwin
mov ebx,[0x3010]
mov bl,[ebx+0xe]
mov bh,[esp+6*4]
cld
npvga:
cmp bl,[ds:ebp]
jnz impvgano
; cmp bh,0
; jz impvgayes
; call voodoodbcplimit
; jnz impvgano
; impvgayes:
push eax ; LFB address
push ebx ; app no.
push ecx ; B
push edx ; x+Xwin
mov edx,[esi] ; color
mov [eax],dx
shr edx,16
mov [eax+2],dl
mov eax,[esi] ; color
mov ecx,[esp] ; x+Xwin
and ecx,0x07 ; modulo 8
call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
pop edx
pop ecx
pop ebx
pop eax
impvgano:
add esi,3 ; esi+=3 ptrImage+=3
add eax,4 ; eax+=4 LFBaddr +=4
inc ebp
inc edx ; x+Xwin+n
test edx,0x07 ; test modulo 8
jnz impvgacont
inc edi
impvgacont:
dec ecx ; B--
jnz npvga
pop edx
pop ebx
pop ecx
pop eax
pop esi
pop edi
add edi,640/8 ; add one VGA line
add eax,640*4 ; add one LFB line
sub ebp, ecx ; -B
add ebp, [0xfe00] ;
inc ebp ; ptrBuffer:=ptrBuffer-B+Screen_Xsize+1
push ecx
lea ecx,[ecx+ecx*2] ;
add esi,ecx ; ptrImage:=ptrImage+B*3
pop ecx
dec ebx ; H--
jnz near pimvga
add esp,4 ; jump saved limit byte
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
pop ebp
ret
VGA_putpixel:
; eax = x
; ebx = y
mov ecx,eax
mov eax, [esp+32-8+4] ; color
imul ebx, 640*4 ; y*BytesPerLine (Vesa2.0 32)
lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32)
mov edi,edx
add edi, [0xfe80] ; + LFB address
mov [edi], eax ; write to LFB for Vesa2.0
shr edx,5 ; change BytesPerPixel to 1/8
mov edi,edx
add edi, 0x0a0000 ; address of pixel in VGA area
and ecx,0x07 ; bit no. (modulo 8)
setvgapixel:
; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8)
push eax
mov ebx,eax ; color
;mov al,0x08
;mov dx,0x03ce
;out dx,al ; select GDC bit mask register
inc cl
mov ax, 0x100
shr ax,cl
mov dx,0x03cf
out dx,al ; set bit mask for pixel
mov dl,0
mov eax,ebx
and eax,0x000000ff ; blue
cmp eax,85
jle p13green
or dl,0x01
cmp eax,170
jle p13green
or dl,0x08
p13green:
and ebx,0x0000ff00 ; green
cmp ebx,85*256
jle p13red
or dl,0x02
cmp ebx,170*256
jle p13red
or dl,0x08
p13red:
pop ebx
and ebx,0x00ff0000 ; red
cmp ebx,85*256*256
jle p13cont
or dl,0x04
cmp ebx,170*256*256
jle p13cont
or dl,0x08
p13cont:
mov al,[edi] ; dummy read
mov [edi],dl
ret
vga_drawbar:
sub edx,ebx ; edx:=Yend-Ystart=H
sub ecx,eax ; ecx:=Xend-Xstat=B
push ebp ; +24
push esi ; +20
push edi ; +16
push eax ; +12
push ebx ; +8
push ecx ; +4
push edx ; +0
mov ecx,[0x3010] ;
add eax,[ecx-twdw] ; eax:=Xwin+x
add ebx,[ecx-twdw+4] ; ebx:=Ywin+y
mov ecx, eax ; ecx:=(x+Xwin)
mov edx, ebx ; edx:=(y+Ywin)
imul ebx, 640/8 ;
mov edi, ebx ; edi:=BytesPerScanLine*(y+Ywin)
shr eax, 3 ;
add edi, eax ; + (x+Xwin)*BytesPerPixel
add edi,0xa0000 ; + VGAbaseaddress
mov eax, [0xfe00] ; ScreenXSize
inc eax ; +1
imul eax,edx ; *(y+Ywin)
mov ebp, eax ;
add ebp, ecx ; +(x+Win)
add ebp, WinMapAddress ; +AddrBuffer
mov eax, [0xfe08] ; BytesPerScanLine - LFB
mul edx ; *(y+Ywin)
mov esi,eax
add esi,ecx
add esi,ecx
add esi,ecx
add esi,ecx ; + 4*(x+Xwin)
add esi,[0xfe80] ; +AddrLFB
; edi:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel + AddrVGA
; esi:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel + AddrLFB
; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
; x size
mov eax,[esp+4] ; B [esp+4]
mov ebx,[esp+0] ; H
mov edx,[esp+16] ; color
test edx,0x80000000
jz nodbglvga
; no color glide for VGA - set to half glide
shr ebx,1 ; H/2
sub edx,ebx
mov [esp+16],edx
mov ebx,[esp+0] ; reset to H
nodbglvga:
; check limits ?
push eax
push ecx
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+0]
cmp ecx,0
jnz dbcblimitlset_vga2
mov ecx,[eax+draw_data-0x3000+4]
cmp ecx,0
jnz dbcblimitlset_vga2
mov ecx,[eax+draw_data-0x3000+8]
cmp ecx,[0xfe00]
jnz dbcblimitlset_vga2
mov ecx,[eax+draw_data-0x3000+12]
cmp ecx,[0xfe04]
jnz dbcblimitlset_vga2
pop ecx
pop eax
push dword 0
jmp dbnewpivga
dbcblimitlset_vga2:
pop ecx ; x+Xwin
pop eax ; B
push dword 1
dbnewpivga:
push eax; B
push ebx ; H
push edi
push esi
push ecx ; x+Xwin
mov ebx,[0x3010]
movzx ebx,byte[ebx+0xe]
cld
dbnpvga:
mov dl,[ds:ebp]
cmp dl,bl
jnz dbimpvgano
; mov edx,[esp+5*4] ; check limit?
; cmp edx,0
; jz dbimpvgayes
; call voodoodbcplimit
; jnz dbimpvgano
; dbimpvgayes:
push eax ; B
push ebx
push ecx ; x+Xwin
mov eax,[esp+12+20+16+4] ; color
mov ebx,eax
mov [esi],bx ; write LFB pixel
shr ebx,16
mov [esi+2],bl
and ecx,0x07 ; modulo 8
call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
pop ecx
pop ebx
pop eax
dbimpvgano:
add esi,4 ; ptrLFB+=4
inc ebp ; address buffer
inc ecx ; x posn++
test ecx,0x07 ; test modulo 8
jnz dbvgacont
inc edi ; VGA screen ptr++
dbvgacont:
dec eax ; B-- NB ecx in Vesa20 fn?
jnz dbnpvga
dbnpvgad:
pop ecx
pop esi
pop edi
pop ebx
pop eax
add esi,[0xfe08] ; ptrLFB+=BytesPerScanLine
add edi,640/8 ; ptrScreen+=BytesPerScanLine
add ebp,[0xfe00] ;
sub ebp, eax ; was ecx in vesa20 fn?
inc ebp ; ptrBuffer:=ptrBuffer-B+BytesPerLine+1
dec ebx ; H--
jz nodbnewpivga ; H<>0
jmp dbnewpivga
nodbnewpivga:
add esp,7*4 ; NB includes limit check flag
;pop ebx
;pop eax
;pop edi
;pop esi
pop ebp
;pop edx
;pop ecx
ret
vga_drawbackground_tiled:
push ebp
push eax
push ebx
push ecx
push edx
mov edx,dword [0x400000-8] ; B
add edx,dword [WinMapAddress-8] ; +B
add edx,dword [WinMapAddress-8] ; +B
push edx
mov eax,[draw_data+32+0] ; x start:=(x+Xwin)
mov ebx,[draw_data+32+4] ; y start:=(y+Ywin)
mov ecx,eax
mov edx,ebx
imul edx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl ecx,2 ; (x+Xwin)*BytesPerPixel
add ecx,edx ;
mov ebp,ecx ; store copy
add ecx,[0xfe80] ; +AddrLFB
;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
shr ebp,5 ; change from 4 to 1/8 BytesPerPixel
add ebp,0xa0000 ; + VGABasePtr
;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
call calculate_edi
dp3vga: ; MAIN LOOP
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1)
je ybgpvga
jmp nbgpvga
ybgpvga:
push eax ; x
push ebx ; y
push ecx ; LFB address
mov ecx,dword [WinMapAddress-8] ; B
xor edx,edx ; edx:=0
div ecx ; Xstart/B
; eax=Int(qn) edx:=Rem
lea esi,[edx+edx*2] ; esi:=edx*3
mov ecx,dword [WinMapAddress-4] ; ecx:=H
mov eax,[esp+4] ; eax:=Ystart
xor edx,edx ;
div ecx ; Ystart/H
mov eax,edx ; eax:=Rem
xor edx,edx ;
mov ebx,[esp+12] ; ebx:=B*3
mul ebx ;
add esi,eax ;
mov eax,[esi+0x300000] ; color
and eax,0xffffff
mov ecx, [esp] ; LFB address
mov ebx,eax ; copy color
mov [ecx],bx
shr ebx,16
mov [ecx+2],bl
xchg edi, ebp
mov ecx,[esp+8] ; x position
and ecx,0x07 ; x modulo 8
call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
xchg ebp, edi
pop ecx
pop ebx
pop eax
nbgpvga:
inc eax ; x++
cmp eax,[draw_data+32+8] ; X > xend?
jg nodp3vga
test eax,0x07 ; x test modulo 8
jnz hook1vga
inc ebp ; VGA address++
hook1vga:
add ecx,4 ; LFB address += 4
inc edi ; ptrBuffer++
add esi,3 ; ptrImage+=3
jmp dp3vga
nodp3vga:
mov eax,[draw_data+32+0] ; x+Xwin
inc ebx ; y position
mov ecx,eax
mov edx,ebx
imul edx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl ecx,2 ; (x+Xwin)*BytesPerPixel
add ecx,edx ;
mov ebp,ecx ; store copy
add ecx,[0xfe80] ; +AddrLFB
;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
shr ebp,5 ; change from 4 to 1/8 BytesPerPixel
add ebp,0xa0000 ; + VGABasePtr
;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
call calculate_edi
cmp ebx,[draw_data+32+12] ; Y > yend
jg dp4vga
jmp dp3vga
dp4vga:
add esp,4
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret
; ----------
vga_drawbackground_stretch:
push ebp
push eax
push ebx
push ecx
push edx
mov edx,dword [WinMapAddress-8] ; B
add edx,dword [WinMapAddress-8] ; +B
add edx,dword [WinMapAddress-8] ; +B
push edx
mov eax,[draw_data+32+0] ; x start:=(x+Xwin)
mov ebx,[draw_data+32+4] ; y start:=(y+Ywin)
mov ecx,eax
mov edx,ebx
imul edx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl ecx,2 ; (x+Xwin)*BytesPerPixel
add ecx,edx ;
mov ebp,ecx ; store copy
add ecx,[0xfe80] ; +AddrLFB
;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
shr ebp,5 ; change from 4 to 1/8 BytesPerPixel
add ebp,0xa0000 ; + VGABasePtr
;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+AddrV
call calculate_edi
sdp3vga: ; MAIN LOOP
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1)
je sybgpvga
jmp snbgpvga
sybgpvga:
push eax ; x
push ebx ; y
push ecx ; LFB address
mov eax,dword [WinMapAddress-8] ; B
xor edx,edx
mov ebx,[esp+8] ; Xstart
mul ebx ; B*Xstart
xor edx,edx
mov ebx,[0xfe00] ; x screen width
div ebx ; B*Xstart/xwidth
lea esi,[eax+eax*2] ; *3
mov eax,dword [WinMapAddress-4] ; H
xor edx,edx
mov ebx,[esp+4] ; Ystart
mul ebx ; H*Ystart
xor edx,edx
mov ebx,[0xfe04] ; y screen height
div ebx ; H*Ystart/yheight
xor edx,edx
mov ebx,[esp+12] ; B*3
mul ebx ;
add esi,eax
mov eax,[esi+0x300000] ; color
and eax,0xffffff
mov ecx, [esp] ; LFB address
mov ebx,eax ; copy color
mov [ecx],bx
shr ebx,16
mov [ecx+2],bl
xchg edi, ebp
mov ecx,[esp+8] ; x position
and ecx,0x07 ; x modulo 8
call setvgapixel ; eax=color, ecx=x%8, edi=VGA address
xchg ebp, edi ; ebp+=3
pop ecx
pop ebx
pop eax
snbgpvga:
inc eax ; x++
cmp eax,[draw_data+32+8] ; X > xend?
jg snodp3vga
test eax,0x07 ; x test modulo 8
jnz shook1vga
inc ebp ; VGA address++
shook1vga:
add ecx,4 ; LFB address += 4
inc edi ; ptrBuffer++
add esi,3 ; ptrImage+=3
jmp sdp3vga
snodp3vga:
mov eax,[draw_data+32+0] ; x+Xwin
inc ebx ; y position
mov ecx,eax
mov edx,ebx
imul edx, 640*4 ; (y+Ywin)*BytesPerScanLine
shl ecx,2 ; (x+Xwin)*BytesPerPixel
add ecx,edx ;
mov ebp,ecx ; store copy
add ecx,[0xfe80] ; +AddrLFB
;entry point in LFB >> ECX:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+Addr
shr ebp,5 ; change from 4 to 1/8 BytesPerPixel
add ebp,0xa0000 ; + VGABasePtr
;VGA start address >> EBP:=(y+Ywin)*BytesPerScanLine+X*BytesPerPixel+A
call calculate_edi
cmp ebx,[draw_data+32+12] ; Y > yend
jg sdp4vga
jmp sdp3vga
sdp4vga:
add esp,4
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret

20
trunk/vmodeint.inc Normal file
View File

@ -0,0 +1,20 @@
;
; Call of videomode driver's functions
;
; (Add in System function 21 (and/or 26) as a subfunction 13)
;
; Author: Trans
; Date: 19.07.2003
;
; Include in MeOS kernel and compile with FASM
;
cmp eax,13 ; CALL VIDEOMODE DRIVER FUNCTIONS
jne .no_vmode_drv_access
or eax,-1 ; If driver is absent then eax does not change
call 0x760100 ; Entry point of video driver
mov [esp+36],eax
mov [esp+24],ebx
mov [esp+32],ecx
; mov [esp+28],edx
ret
.no_vmode_drv_access:

27
trunk/vmodeld.inc Normal file
View File

@ -0,0 +1,27 @@
;
; Load of videomode driver in memory
;
; (driver is located at 0x760000-0x768000 - 32kb) // if this area not occuped anything
;
; Author: Trans
; Date: 19.07.2003
;
; Include in MeOS kernel and compile with FASM
;
;vmode db 'VMODE MDR' ; MDR - Menuet Driver
; must be located after fonts filenames in kernel.asm
; LOAD VIDEOMODE DRIVER
; If vmode.mdr file not found
or eax,-1 ; Driver ID = -1 (not present in system)
mov [0x760000],eax ;
mov [0x760100],byte 0xC3 ; Instruction RETN - driver loop
mov eax,vmode ; File name of driver
mov esi,12
mov ebx,0
mov ecx,26000
mov edx,0x760000 ; Memory position of driver
call fileread