Subversion Repositories Kolibri OS

Rev

Rev 6016 | Rev 8866 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5363 yogev_ezra 3
;; Copyright (C) KolibriOS team 2007-2015. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 6333 $
9
 
10
; Virtual-8086 mode manager
11
; diamond, 2007, 2008
12
 
13
DEBUG_SHOW_IO = 0
14
 
2384 hidnplayr 15
struct  V86_machine
2288 clevermous 16
; page directory
5130 serge 17
        process         dd ?
2288 clevermous 18
; mutex to protect all data from writing by multiple threads at one time
2384 hidnplayr 19
        mutex           dd ?
2288 clevermous 20
; i/o permission map
2384 hidnplayr 21
        iopm            dd ?
22
ends
2288 clevermous 23
 
24
; Create V86 machine
25
; in: nothing
26
; out: eax = handle (pointer to struc V86_machine)
27
;      eax = NULL => failure
28
; destroys: ebx, ecx, edx (due to malloc)
29
v86_create:
30
; allocate V86_machine structure
2384 hidnplayr 31
        mov     eax, sizeof.V86_machine
2288 clevermous 32
        call    malloc
33
        test    eax, eax
34
        jz      .fail
35
; initialize mutex
36
        and     dword [eax+V86_machine.mutex], 0
37
; allocate tables
38
        mov     ebx, eax
5130 serge 39
 
6333 serge 40
        stdcall create_process, 4096
5130 serge 41
        test    eax, eax
42
        jz      .fail2
43
 
44
        mov     [eax+PROC.mem_used], 4096
45
        mov     [ebx+V86_machine.process], eax
46
 
47
        push    2000h
2288 clevermous 48
        call    kernel_alloc
49
        test    eax, eax
50
        jz      .fail2
5130 serge 51
 
52
        mov     [ebx+V86_machine.iopm], eax
53
 
54
; initialize tables
55
        push    edi
2288 clevermous 56
        mov     edi, eax
5130 serge 57
        mov     eax, -1
2288 clevermous 58
        mov     ecx, 2000h/4
59
        rep stosd
60
 
5130 serge 61
        mov     eax, [ebx+V86_machine.process]
62
        mov     eax, [eax+PROC.pdt_0_phys]
2288 clevermous 63
 
5130 serge 64
        pushfd
65
        cli
66
        mov     cr3, eax
67
 
2288 clevermous 68
; now V86 specific: initialize known addresses in first Mb
5130 serge 69
 
2288 clevermous 70
; first page - BIOS data (shared between all machines!)
71
; physical address = 0
72
; linear address = OS_BASE
73
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
74
; physical address = 0x9C000
75
; linear address = 0x8009C000
76
; (I have seen one computer with EBDA segment = 0x9D80,
77
; all other computers use less memory)
5130 serge 78
 
5356 serge 79
        mov     eax, PG_UWR
5130 serge 80
        mov     [page_tabs], eax
81
        invlpg  [eax]
82
 
83
        mov     byte [0x500], 0xCD
84
        mov     byte [0x501], 0x13
85
        mov     byte [0x502], 0xF4
86
        mov     byte [0x503], 0xCD
87
        mov     byte [0x504], 0x10
88
        mov     byte [0x505], 0xF4
89
 
6016 clevermous 90
        mov     eax, 0x98000+PG_UWR
91
        mov     edi, page_tabs+0x98*4
5130 serge 92
        mov     edx, 0x1000
6016 clevermous 93
        mov     ecx, 8
2288 clevermous 94
@@:
95
        stosd
5130 serge 96
        add     eax, edx
2288 clevermous 97
        loop    @b
5130 serge 98
 
2288 clevermous 99
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
100
; physical address = 0xC0000
5130 serge 101
 
5356 serge 102
        mov     eax, 0xC0000+PG_UWR
5130 serge 103
        mov     edi, page_tabs+0xC0*4
104
        mov     ecx, 64
2288 clevermous 105
@@:
5130 serge 106
        stosd
107
        add     eax, edx
108
        loop    @b
109
 
6333 serge 110
        mov     eax, [sys_proc+PROC.pdt_0_phys]
111
        mov     cr3, eax
5130 serge 112
        popfd
113
 
114
        pop     edi
115
 
2288 clevermous 116
        mov     eax, ebx
117
        ret
118
.fail2:
119
        mov     eax, ebx
120
        call    free
121
.fail:
122
        xor     eax, eax
123
        ret
124
 
5130 serge 125
;not used
2288 clevermous 126
; Destroy V86 machine
127
; in: eax = handle
128
; out: nothing
129
; destroys: eax, ebx, ecx, edx (due to free)
5130 serge 130
;v86_destroy:
131
;        push    eax
132
;        stdcall kernel_free, [eax+V86_machine.pagedir]
133
;        pop     eax
134
;        jmp     free
2288 clevermous 135
 
136
; Translate V86-address to linear address
137
; in: eax=V86 address
138
;     esi=handle
139
; out: eax=linear address
140
; destroys: nothing
141
v86_get_lin_addr:
142
        push    ecx edx
143
        mov     ecx, eax
144
        shr     ecx, 12
5130 serge 145
        mov     edx, [page_tabs+ecx*4]
2288 clevermous 146
        and     eax, 0xFFF
5130 serge 147
        and     edx, 0xFFFFF000
148
        or      eax, edx
2288 clevermous 149
        pop     edx ecx
150
        ret
151
 
5130 serge 152
;not used
2288 clevermous 153
; Sets linear address for V86-page
154
; in: eax=linear address (must be page-aligned)
155
;     ecx=V86 page (NOT address!)
156
;     esi=handle
157
; out: nothing
158
; destroys: nothing
5130 serge 159
;v86_set_page:
160
;        push    eax ebx
161
;        mov     ebx, [esi+V86_machine.pagedir]
162
;        mov     [ebx+ecx*4+0x1800], eax
163
;        call    get_pg_addr
164
;        or      al, 111b
165
;        mov     [ebx+ecx*4+0x1000], eax
166
;        pop     ebx eax
167
;        ret
2288 clevermous 168
 
169
; Allocate memory in V86 machine
170
; in: eax=size (in bytes)
171
;     esi=handle
172
; out: eax=V86 address, para-aligned (0x10 multiple)
173
; destroys: nothing
3539 clevermous 174
; недописана!!!
2288 clevermous 175
;v86_alloc:
176
;        push    ebx ecx edx edi
177
;        lea     ebx, [esi+V86_machine.mutex]
178
;        call    wait_mutex
179
;        add     eax, 0x1F
180
;        shr     eax, 4
181
;        mov     ebx, 0x1000  ; start with address 0x1000 (second page)
182
;        mov     edi, [esi+V86_machine.tables]
183
;.l:
184
;        mov     ecx, ebx
185
;        shr     ecx, 12
186
;        mov     edx, [edi+0x1000+ecx*4] ; get linear address
187
;        test    edx, edx                ; page allocated?
188
;        jz      .unalloc
189
;        mov     ecx, ebx
190
;        and     ecx, 0xFFF
191
;        add     edx, ecx
192
;        cmp     dword [edx], 0          ; free block?
193
;        jnz     .n
194
;        cmp     dword [edx+4],
195
;        and     [esi+V86_machine.mutex], 0
196
;        pop     edi edx ecx ebx
197
;        ret
198
 
199
uglobal
200
sys_v86_machine dd      ?
201
endg
202
 
203
; Called from kernel.asm at first stages of loading
204
; Initialize system V86 machine (used to simulate BIOS int 13h)
205
init_sys_v86:
206
        call    v86_create
207
        mov     [sys_v86_machine], eax
208
        test    eax, eax
209
        jz      .ret
210
        mov     esi, eax
211
if ~DEBUG_SHOW_IO
212
; allow access to all ports
213
        mov     ecx, [esi+V86_machine.iopm]
214
        xor     eax, eax
215
        mov     edi, ecx
216
        mov     ecx, 10000h/8/4
217
        rep stosd
218
end if
219
.ret:
220
        ret
221
 
2384 hidnplayr 222
struct  v86_regs
2288 clevermous 223
; don't change the order, it is important
2384 hidnplayr 224
        edi             dd ?
<