751fd6166da4eebeb294cd1de99cfc3f8a37cc64
[fifth.git] / emulator / emulator.asm
1 ; virtual processor, emulator for FIFTH\r
2 \r
3 ; registers usage:\r
4 \r
5 ; edi - data stack pointer\r
6 ; esi - instruction pointer\r
7 ; es = 0\r
8 ; cs - emulator program code segment\r
9 ; ds = cs\r
10 \r
11 \r
12 org     100h\r
13 \r
14         call    system_init             ; init system, allocate XMS\r
15         call    KB_init                 ; init keyoard\r
16 \r
17         push    0                       ; initialize segments\r
18         pop     es\r
19         push    cs\r
20         pop     ds\r
21         sub     ebx, ebx                ; initialize pointers\r
22         mov     bx, cs\r
23         shl     ebx, 4\r
24         add     ebx, buf\r
25         add     ebx, 20000\r
26         mov     edi, ebx                ; data stack\r
27         add     ebx, 10000\r
28         mov     [resp], ebx             ; return stack\r
29         mov     esi, [xms_addr]         ; instruction pointer\r
30 \r
31         mov     ah, 3dh                 ; open diskfile\r
32         mov     al, 2\r
33         mov     dx, infile\r
34         int     21h\r
35         mov     word [fileh], ax\r
36 \r
37         mov     ax, 4F02h               ; set VESA 640*480 8 bit\r
38         mov     bx, 101h\r
39         int     10h\r
40 \r
41         mov     ecx, 0                  ; load boot block (first 1024 bytes)\r
42         mov     ebx, [xms_addr]\r
43         call    diskload\r
44         jmp     emu\r
45 \r
46 xmemtot dw 0    ; amount of accessible XMS\r
47 \r
48 infile  db 'disk.raw', 0 ; virtual disk file name\r
49 fileh   dw 0    ; it's handle\r
50 \r
51 coresiz dw 4096 ; core size\r
52 gran    dw 0    ; VESA granule size\r
53 \r
54 quit:   mov      ax, 3                   ; restore text mode\r
55         int      10h\r
56 \r
57         mov     ah, 3eh                 ; close diskfile\r
58         mov     bx, word [fileh]\r
59         int     21h\r
60 \r
61         call    KB_restore\r
62         jmp     system_exit             ; terminate program\r
63 \r
64 resp    dd 0    ; return stack pointer\r
65 \r
66 emu:                    ; pick instruction\r
67 movzx   bx, byte [es:esi]\r
68 inc     esi\r
69 shl     bx, 1\r
70 add     bx, table\r
71 jmp     word [cs:bx]\r
72 \r
73 table   dw emu          ; 0\r
74         dw quit\r
75         dw xkbd@\r
76         dw xnum\r
77         dw xjmp\r
78         dw xcall        ; 5\r
79         dw xinc\r
80         dw xdec\r
81         dw xdup\r
82         dw xdrop\r
83         dw xif          ; 10\r
84         dw xret\r
85         dw xc@\r
86         dw xc!\r
87         dw xpush\r
88         dw xpop         ; 15\r
89         dw 0\r
90         dw xrot\r
91         dw xdisk@\r
92         dw xdisk!\r
93         dw x@           ; 20\r
94         dw x!\r
95         dw xover\r
96         dw xswap\r
97         dw xplus\r
98         dw xminus       ; 25\r
99         dw xmul\r
100         dw xdiv\r
101         dw xgreat\r
102         dw xless\r
103         dw xnot         ; 30\r
104         dw xi\r
105         dw xcprt@\r
106         dw xcprt!\r
107         dw xi2\r
108         dw xi3          ; 35\r
109         dw xshl\r
110         dw xshr\r
111         dw lor\r
112         dw lxor\r
113         dw xvidmap      ; 40\r
114         dw xmouse@\r
115         dw xvidput\r
116         dw xcmove\r
117         dw xcfill\r
118         dw xtvidput     ; 45\r
119         dw xdep\r
120         dw xcharput\r
121 \r
122 xkbd@:  call    KB_read\r
123         sub     edi, 4\r
124         mov     [es:edi], dl\r
125 \r
126         mov     ah, 0bh         ; check for key in keyboard buffer\r
127         int     21h\r
128         cmp     al, 0h\r
129         je      emu\r
130         mov     ah, 0           ; read key\r
131         int     16h\r
132         jmp     emu\r
133 \r
134 xnum:   mov     edx, dword [es:esi]\r
135         sub     edi, 4\r
136         mov     [es:edi], edx\r
137         add     esi, 4\r
138         jmp     emu\r
139 \r
140 xjmp:   mov     esi, dword [es:esi]\r
141         add     esi, [xms_addr]\r
142         jmp     emu\r
143 \r
144 xcall:  mov     edx, dword [es:esi]\r
145         mov     eax, [resp]\r
146         sub     eax, 4\r
147         mov     ebx, esi\r
148         add     ebx, 4\r
149         sub     ebx, [xms_addr]\r
150         mov     [es:eax], ebx\r
151         mov     [resp], eax\r
152         mov     esi, edx\r
153         add     esi, [xms_addr]\r
154         jmp     emu\r
155 \r
156 xinc:   inc     dword [es:edi]\r
157         jmp     emu\r
158 \r
159 xdec:   dec     dword [es:edi]\r
160         jmp     emu\r
161 \r
162 xdup:   mov     eax, [es:edi]\r
163         sub     edi, 4\r
164         mov     [es:edi], eax\r
165         jmp     emu\r
166 \r
167 xdrop:  add     edi, 4\r
168         jmp     emu\r
169 \r
170 xif:    mov     eax, [es:edi]\r
171         add     edi, 4\r
172         cmp     eax, 0\r
173         jne     l2\r
174         mov     esi, [es:esi]\r
175         add     esi, [xms_addr]\r
176         jmp     emu\r
177 l2:\r
178         add     esi, 4\r
179         jmp     emu\r
180 \r
181 xret:   mov     eax, [resp]\r
182         mov     esi, [es:eax]\r
183         add     esi, [xms_addr]\r
184         add     eax, 4\r
185         mov     [resp], eax\r
186         jmp     emu\r
187 \r
188 xc@:    mov     eax, [es:edi]\r
189         add     eax, [xms_addr]\r
190         sub     ecx, ecx\r
191         mov     cl, [es:eax]\r
192         mov     [es:edi], ecx\r
193         jmp     emu\r
194 \r
195 xc!:    ;( n addr -- )\r
196         mov     ebx, [es:edi]\r
197         add     edi, 4\r
198         mov     ecx, [es:edi]\r
199         add     edi, 4\r
200         add     ebx, [xms_addr]\r
201         mov     [es:ebx], cl\r
202         jmp     emu\r
203 \r
204 xpush:  mov     ebx, [es:edi]\r
205         add     edi, 4\r
206         mov     eax, [resp]\r
207         sub     eax, 4\r
208         mov     [es:eax], ebx\r
209         mov     [resp], eax\r
210         jmp     emu\r
211 \r
212 xpop:   mov     eax, [resp]\r
213         mov     ebx, [es:eax]\r
214         add     eax, 4\r
215         mov     [resp], eax\r
216         sub     edi, 4\r
217         mov     [es:edi], ebx\r
218         jmp     emu\r
219 \r
220 xrot:   mov     ebx, [es:edi]\r
221         mov     ecx, [es:edi+4]\r
222         mov     edx, [es:edi+8]\r
223         mov     [es:edi+8], ecx\r
224         mov     [es:edi+4], ebx\r
225         mov     [es:edi], edx\r
226         jmp     emu\r
227 \r
228 xdisk@: mov     ebx, [es:edi]\r
229         add     ebx, [xms_addr]\r
230         mov     ecx, [es:edi+4]\r
231         add     edi, 8\r
232         call    diskload        ; ecx-fromdisk ebx-tomem\r
233         jmp     emu\r
234 \r
235 xdisk!: mov     ecx, [es:edi]\r
236         call    file_seek\r
237         mov     ecx, 1024\r
238         mov     ebx, [es:edi+4]\r
239         add     edi, 8\r
240         add     ebx, [xms_addr]\r
241         sub     edx, edx\r
242         mov     dx, cs\r
243         shl     edx, 4\r
244         add     edx, buf\r
245         call    memmove  ; ebx - from, edx - to, ecx - amount\r
246         mov     ah, 40h\r
247         mov     bx, [fileh]\r
248         mov     cx, 1024\r
249         mov     dx, buf\r
250         int     21h\r
251         jmp     emu\r
252 \r
253 x@:     mov     eax, [es:edi]\r
254         add     eax, [xms_addr]\r
255         mov     eax, [es:eax]\r
256         mov     [es:edi], eax\r
257         jmp     emu\r
258 \r
259 x!:     ;( n addr -- )\r
260         mov     eax, [es:edi]\r
261         add     eax, [xms_addr]\r
262         mov     ecx, [es:edi+4]\r
263         add     edi, 8\r
264         mov     [es:eax], ecx\r
265         jmp     emu\r
266 \r
267 xover:  mov     ebx, [es:edi+4]\r
268         sub     edi, 4\r
269         mov     [es:edi], ebx\r
270         jmp     emu\r
271 \r
272 xswap:  mov     ebx, [es:edi]\r
273         xchg    ebx, [es:edi+4]\r
274         mov     [es:edi], ebx\r
275         jmp     emu\r
276 \r
277 xplus:  mov     ebx, [es:edi]\r
278         add     edi, 4\r
279         add     [es:edi], ebx\r
280         jmp     emu\r
281 \r
282 xminus: mov     ebx, [es:edi]\r
283         add     edi, 4\r
284         sub     [es:edi], ebx\r
285         jmp     emu\r
286 \r
287 xmul:   mov     eax, [es:edi]\r
288         add     edi, 4\r
289         sub     edx, edx\r
290         imul     dword [es:edi]\r
291         mov     [es:edi], eax\r
292         jmp     emu\r
293 \r
294 xdiv:   add     edi, 4\r
295         mov     eax, [es:edi]\r
296         cdq\r
297         idiv    dword [es:edi-4]\r
298         mov     [es:edi], eax\r
299         jmp     emu\r
300 \r
301 xgreat: mov     eax, [es:edi]\r
302         add     edi, 4\r
303         mov     edx, 0\r
304         cmp     [es:edi], eax\r
305         jng     l3\r
306         dec     edx\r
307 l3:     mov     [es:edi], edx\r
308         jmp     emu\r
309 \r
310 xless:  mov     eax, [es:edi]\r
311         add     edi, 4\r
312         mov     edx, 0\r
313         cmp     [es:edi], eax\r
314         jnl     l4\r
315         dec     edx\r
316 l4:     mov     [es:edi], edx\r
317         jmp     emu\r
318 \r
319 file_seek:      ; ( ecx - pointer to seek )\r
320         mov     eax, 1024\r
321         mul     ecx\r
322         mov     ecx, eax\r
323         mov     dx, cx\r
324         shr     ecx, 16\r
325         mov     ah, 42h\r
326         mov     al, 0\r
327         mov     bx, [ds:fileh]\r
328         int     21h\r
329         ret\r
330 \r
331 xnot:   not     dword [es:edi]\r
332         jmp     emu\r
333 \r
334 xi:     mov  ebx, [resp]\r
335         mov     eax, [es:ebx]\r
336         sub     edi, 4\r
337         mov     [es:edi], eax\r
338         jmp     emu\r
339 \r
340 xcprt@: mov     dx, [es:edi]\r
341         in      al, dx\r
342         sub     ecx, ecx\r
343         mov     cl, al\r
344         mov     [es:edi], ecx\r
345         jmp     emu\r
346 \r
347 xcprt!: mov     dx, [es:edi]\r
348         mov     al, [es:edi+4]\r
349         add     edi, 8\r
350         out     dx, al\r
351         jmp     emu\r
352 \r
353 xi2:    mov ebx, [resp]\r
354         mov     eax, [es:ebx+4]\r
355         sub     edi, 4\r
356         mov     [es:edi], eax\r
357         jmp     emu\r
358 \r
359 xi3:    mov ebx, [resp]\r
360         mov     eax, [es:ebx+8]\r
361         sub     edi, 4\r
362         mov     [es:edi], eax\r
363         jmp     emu\r
364 \r
365 xshl:   mov     cl, [es:edi]\r
366         add     edi, 4\r
367         shl     dword [es:edi], cl\r
368         jmp     emu\r
369 \r
370 xshr:   mov     cl, [es:edi]\r
371         add     edi, 4\r
372         shr     dword [es:edi], cl\r
373         jmp     emu\r
374 \r
375 lor:    mov     eax, [es:edi]\r
376         add     edi, 4\r
377         or      [es:edi], eax\r
378         jmp     emu\r
379 \r
380 lxor:   mov     eax, [es:edi]\r
381         add     edi, 4\r
382         xor      [es:edi], eax\r
383         jmp     emu\r
384 \r
385 xvidmap:\r
386         mov     edx, [es:edi]\r
387         add     edx, [xms_addr]\r
388         add     edi, 4\r
389         push    edi\r
390         push    esi\r
391         push    0a000h\r
392         pop     es\r
393         mov     word [ds:gra], 0\r
394         push    0\r
395         pop     ds\r
396         mov     esi, edx\r
397 mapl1:  mov     dx, [cs:gra]\r
398         xor     bx, bx\r
399         mov     ax, 4f05h\r
400         int     10h\r
401         mov     edi, 0\r
402         mov     cx, 4096\r
403 ;       mov     cx, 16384\r
404 mapl2:  mov     eax, [ds:esi]\r
405         add     esi, 4\r
406         stosd\r
407         loop    mapl2\r
408         inc     word [cs:gra]\r
409 ;       cmp     word [cs:gra], 5\r
410         cmp     word [cs:gra], 19\r
411         jne     mapl1\r
412         push    0\r
413         pop     es\r
414         push    cs\r
415         pop     ds\r
416         pop     esi\r
417         pop     edi\r
418         jmp     emu\r
419 gra     dw 0\r
420 \r
421 \r
422 xmouse@:\r
423         mov     ax, 0bh         ; read motion counter\r
424         int     33h\r
425         push    dx\r
426         sub     eax, eax\r
427         mov     ax, cx\r
428         cwd\r
429         shl     edx, 16\r
430         add     edx, eax\r
431         mov     [es:edi-4], edx\r
432         pop     ax\r
433         cwd\r
434         shl     edx, 16\r
435         add     edx, eax\r
436         mov     [es:edi-8], edx\r
437         mov     ax, 3           ; read buttons\r
438         int     33h\r
439         sub     eax, eax\r
440         mov     ax, bx\r
441         sub     edi, 12\r
442         mov     [es:edi], eax\r
443         jmp     emu\r
444 \r
445 memmove:                ; ebx - from, edx - to, ecx - amount\r
446         cmp     ecx, 0\r
447         je      l11\r
448         mov     al, [es:ebx]\r
449         mov     [es:edx], al\r
450         inc     ebx\r
451         inc     edx\r
452         dec     ecx\r
453         jmp     memmove\r
454 l11:    ret\r
455 \r
456 memmove2:               ; ebx - from, edx - to, ecx - amount\r
457         add     ebx, ecx\r
458         add     edx, ecx\r
459 l7:     cmp     ecx, 0\r
460         je      l12\r
461         dec     ebx\r
462         dec     edx\r
463         mov     al, [es:ebx]\r
464         mov     [es:edx], al\r
465         dec     ecx\r
466         jmp     l7\r
467 l12:    ret\r
468 \r
469 xcmove: mov     ecx, [es:edi]\r
470         add     edi, 12\r
471         mov     edx, [es:edi-8]\r
472         add     edx, [xms_addr]\r
473         mov     ebx, [es:edi-4]\r
474         add     ebx, [xms_addr]\r
475         cmp     ecx, 0\r
476         je      emu\r
477         cmp     ebx, edx\r
478         ja      l8\r
479         call    memmove2\r
480         jmp     emu\r
481 l8:     call    memmove\r
482         jmp     emu\r
483 \r
484 xcfill: mov     ecx, [es:edi]\r
485         mov     edx, [es:edi+4]\r
486         add     edx, [xms_addr]\r
487         mov     eax, [es:edi+8]\r
488         add     edi, 12\r
489 l9:     cmp     ecx, 0\r
490         je      emu\r
491         mov     [es:edx], al\r
492         inc     edx\r
493         dec     ecx\r
494         jmp     l9\r
495 \r
496 diskload:       ; ecx-fromdisk ebx-tomem\r
497         push    ebx\r
498         call    file_seek\r
499         mov     cx, 1024\r
500         mov     ah, 3fh\r
501         mov     bx, [fileh]\r
502         mov     dx, buf\r
503         int     21h\r
504 \r
505         sub     ebx, ebx                        ; move it to XMS\r
506         mov     bx, cs\r
507         shl     ebx, 4\r
508         add     ebx, buf\r
509         pop     edx\r
510         mov     ecx, 1024\r
511         call    memmove  ; ebx - from, edx - to, ecx - amount\r
512         ret\r
513 \r
514 xdep:   sub     eax, eax\r
515         mov     ax, cs\r
516         shl     eax, 4\r
517         add     eax, buf\r
518         add     eax, 20000\r
519         sub     eax, edi\r
520         shr     eax, 2\r
521         sub     edi, 4\r
522         mov     [es:edi], eax\r
523         jmp     emu\r
524 \r
525 include 'vidput.inc'\r
526 include 'tvidput.inc'\r
527 include 'charput.inc'\r
528 include 'system.inc'\r
529 include 'kbdrive.inc'\r
530 \r
531 buf:                    ; pointer to end of the code\r