-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdzemmd.asm
1623 lines (1492 loc) · 40.3 KB
/
dzemmd.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; DZEMMD.ASM--
; Copyright (C) 2012 Doszip Developers
;
; Doszip Expanded Memory Manager
;
; Change history:
; 2012-12-12 - created
; 2012-12-29 - fixed Alter Page Map & Call (Japheth)
; 2012-12-30 - added clipboard functions
; 2013-01-16 - fixed bug in Exchange Memory Region (5701h)
;
.386
.model flat
option casemap:none
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
VERSION equ 0106h
USEDOSZIP equ 1
USECLIPBOARD equ 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
includelib kernel32.lib
includelib ntvdm.lib
ifdef USECLIPBOARD
includelib user32.lib
endif
; kernel32.dll
GMEM_FIXED equ 0
GMEM_DDESHARE equ 2000h
GMEM_MOVEABLE equ 2h
GMEM_ZEROINIT equ 40h
GlobalFree proto stdcall :dword
GlobalAlloc proto stdcall :dword, :dword
ifdef USECLIPBOARD
GlobalLock proto stdcall :dword
GlobalUnlock proto stdcall :dword
GlobalSize proto stdcall :dword
GetLastError proto stdcall
; user32.dll
OpenClipboard proto stdcall :dword
CloseClipboard proto stdcall
EmptyClipboard proto stdcall
GetClipboardData proto stdcall :dword
SetClipboardData proto stdcall :dword, :dword
endif
; ntvdm.exe
getBX proto stdcall
getCX proto stdcall
getSI proto stdcall
getBP proto stdcall
getSP proto stdcall
getDI proto stdcall
getIP proto stdcall
getES proto stdcall
getDS proto stdcall
getCS proto stdcall
getSS proto stdcall
getDX proto stdcall
setAL proto stdcall :dword
setAH proto stdcall :dword
setAX proto stdcall :dword
setBX proto stdcall :dword
setCX proto stdcall :dword
setDX proto stdcall :dword
setSP proto stdcall :dword
setCS proto stdcall :dword
setIP proto stdcall :dword
MGetVdmPointer proto stdcall :dword, :dword, :dword
VDDSimulate16 proto stdcall
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EMMPAGES equ 4
EMMPAGE equ 4000h
MAXPAGES equ 4000h
MAXHANDLES equ 255
MAXMAPLEVEL equ 8
EMMH_INUSE equ 01h
HANDLE STRUC
memp dd ?
size dd ?
name db 8 dup(?)
HANDLE ENDS
EMAP STRUC
maph dd EMMPAGES dup(?)
mapp dd EMMPAGES dup(?)
EMAP ENDS
SIZESAVEARRAY equ EMAP
.data
ALIGN 4
reg_AX dd ?
reg_BX dd ?
reg_CX dd ?
reg_DX dd ?
reg_SI dd ?
reg_DI dd ?
emm_page dd ?
emm_label dd ?
emm_seg16 dd ?
emm_seg32 dd ?
emmh HANDLE <0,0,<'SYSTEM'>>
emmh1 HANDLE MAXHANDLES-1 dup(<?>)
emm_flag db MAXHANDLES+1 dup(?)
emm_maplevel dd ?
emm_maph dd EMMPAGES dup(?)
emm_mapp dd EMMPAGES dup(?)
emm_tmph dd EMMPAGES*2*MAXMAPLEVEL dup(?)
emm_tmp0 dd MAXMAPLEVEL dup(?)
ifdef USECLIPBOARD
ClipboardIsOpen dd ?
endif
.code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
assume edx:ptr HANDLE
emm_needhandle proc
.if !edx || edx >= MAXHANDLES
pop eax
jmp emm_error_83
.endif
emm_needhandle endp
emm_getesdi proc uses edx
push eax
shl getES(),16
mov ax,di
pop edx
mov edi,MGetVdmPointer(eax, edx, 0)
ret
emm_getesdi endp
emm_getdssi proc uses edx
push eax
shl getDS(),16
mov ax,si
pop edx
mov esi,MGetVdmPointer(eax, edx, 0)
ret
emm_getdssi endp
emm_gethandle proc
xor eax,eax
mov edx,offset emmh1
mov ecx,1
.repeat
.if emm_flag[ecx] == al
.return edx
.endif
add edx,HANDLE
inc ecx
.until ecx >= MAXHANDLES
ret
emm_gethandle endp
;----------------------------------------------------------
; Allocate Pages
;----------------------------------------------------------
AllocatePages proc uses ebx edx
shl ebx,14
.if GlobalAlloc(GMEM_FIXED, ebx)
mov ecx,ebx
.endif
ret
AllocatePages endp
;----------------------------------------------------------
; Map/Unmap Handle Page
; AL = physical_page_number
; BX = logical_page_number
; DX = emm_handle
;----------------------------------------------------------
; - copy bytes from frame segment to logical page
emm_copymap proc uses edx
mov edx,ebx
mov ecx,EMMPAGE
.repeat
repe cmpsb
.break .ifz
mov eax,ecx
sub eax,EMMPAGE
not eax
add eax,edx ; target offset in lg page
mov ebx,esi
dec ebx ; start source
repne cmpsb ; get size of string
.ifz
inc ecx
dec edi
dec esi
.endif
push ecx
mov ecx,esi
sub ecx,ebx
xchg eax,edi
xchg ebx,esi
rep movsb
pop ecx
mov edi,eax
mov esi,ebx
.until !ecx
ret
emm_copymap endp
emm_pushmap proc uses esi edi ebx edx eax
sub edx,edx
mov edi,emmh.memp
mov esi,emm_seg32
.repeat
.if emm_maph[edx]
mov ebx,emm_mapp[edx]
emm_copymap()
.else
add esi,EMMPAGE
add edi,EMMPAGE
.endif
add edx,4
.until edx == SIZESAVEARRAY/2
ret
emm_pushmap endp
emm_mappage:
movzx eax,al
mov emm_page,eax
.if al >= EMMPAGES
mov ah,8Bh
ret
.endif
.if !edx && bx != -1
mov ah,8Ah
ret
.endif
.if bx == -1
jmp emm_unmappage
.endif
.if edx >= MAXHANDLES
mov ah,8Ah
ret
.endif
shl eax,14 ; EDI to frame segment
mov edi,emm_seg32
add edi,eax
shl edx,4 ; EDX to handle
add edx,offset emmh
mov esi,[edx].memp ; ESI to logical page
.if esi
mov ecx,esi
add ecx,[edx].size
mov eax,ebx
shl eax,14
add esi,eax
mov eax,esi
add eax,EMMPAGE
.if ecx < eax
mov ah,8Ah
.else
sub eax,eax
.endif
.else
mov ah,8Ah
.endif
.if ah
ret
.endif
emm_pushmap()
mov ebx,emm_page
shl ebx,2
mov emm_maph[ebx],edx
mov emm_mapp[ebx],esi
mov ecx,EMMPAGE/4
rep movsd
mov esi,emm_mapp[ebx] ; extra copy needed for compare..
shl ebx,12
mov edi,emmh.memp
add edi,ebx
mov ecx,EMMPAGE/4
rep movsd
sub eax,eax
ret
emm_unmappage:
mov ebx,eax
shl ebx,2
sub eax,eax
mov edx,emm_maph[ebx]
mov emm_maph[ebx],eax ; - unmap page
.if edx && [edx].memp != eax
mov esi,emm_seg32
mov edi,emm_mapp[ebx]
.if esi && edi
mov ecx,ebx
shl ecx,12
add esi,ecx ; copy the frame to buffer
mov edx,edi ; save logical page address
mov ebx,emmh.memp
add ebx,ecx
xchg ebx,edi
emm_copymap()
sub eax,eax
mov ebx,emm_seg32
.repeat ; find dublicate address
.if emm_maph[eax]
.if edx == emm_mapp[eax]
mov edi,ebx
mov esi,edx
mov ecx,EMMPAGE/4
rep movsd
.endif
.endif
add eax,4
add ebx,EMMPAGE
.until eax == SIZESAVEARRAY/2
.endif
.endif
sub eax,eax
ret
emm_updatemap proc uses edi ecx eax
sub eax,eax
mov ecx,EMMPAGES
mov edi,offset emm_maph
.repeat
mov edx,[edi]
.if edx && [edx].memp == eax
mov [edi],eax
.endif
add edi,4
.untilcxz
ret
emm_updatemap endp
emm_popmap proc uses esi edi ebx ecx eax
xor eax,eax
mov ebx,emm_seg32
.if ebx
.repeat
.if emm_maph[eax]
mov esi,emm_mapp[eax]
mov edi,ebx
mov ecx,EMMPAGE/4
rep movsd
.endif
add eax,4
add ebx,EMMPAGE
.until eax == SIZESAVEARRAY/2
.endif
ret
emm_popmap endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;----------------------------------------------------------
emm_01: ; Get Status 40h
;----------------------------------------------------------
setAX(1) ; Signature: 0001
ret
;----------------------------------------------------------
emm_02: ; Get Page Frame Segment Address 41h
;----------------------------------------------------------
.if emm_seg16
setBX(emm_seg16)
jmp emm_success
.endif
jmp emm_error_84
;----------------------------------------------------------
emm_03: ; Get Unallocated Page Count 42h
;----------------------------------------------------------
xor ebx,ebx
mov ecx,MAXHANDLES-1
mov edx,offset emmh1
.repeat
.if [edx].memp
mov eax,[edx].size
shr eax,14
add ebx,eax
.endif
add edx,HANDLE
.untilcxz
mov eax,MAXPAGES
.if ebx > eax
sub eax,eax
.else
sub eax,ebx
.endif
setBX(eax) ; unallocated pages
setDX(MAXPAGES) ; total pages
jmp emm_success
;----------------------------------------------------------
emm_04: ; Allocate Pages 43h
;----------------------------------------------------------
.if !ebx
jmp emm_error_89
.endif
;----------------------------------------------------------
emm_27: ; Allocate Standard Pages 5A00h
; Allocate Raw Pages 5A01h
;
; BX = num_of_pages_to_alloc
;
;----------------------------------------------------------
.if emm_gethandle()
mov emm_flag[ecx],EMMH_INUSE
.if !ebx
setDX(ecx)
jmp emm_success
.endif
mov edi,eax
mov esi,ecx
emm_pushmap()
.if AllocatePages()
mov [edx].memp,eax
mov [edx].size,ecx
setDX(esi)
jmp emm_success
.endif
jmp emm_error_87
.endif
jmp emm_error_85
;----------------------------------------------------------
emm_05: ; Map/Unmap Handle Page 44h
;
; AL = physical_page_number
; BX = logical_page_number
; DX = emm_handle
;----------------------------------------------------------
.if emm_mappage()
jmp emm_setAX
.endif
jmp emm_success
;----------------------------------------------------------
emm_06: ; Deallocate Pages 45h
;----------------------------------------------------------
.if !edx
jmp emm_success
.endif
.if edx < MAXHANDLES
mov emm_flag[edx],0
shl edx,4
add edx,offset emmh
mov edi,edx
.if [edx].memp
GlobalFree([edx].memp)
.endif
mov edx,edi
sub eax,eax
mov [edx].memp,eax
mov [edx].size,eax
mov edi,eax
mov ecx,EMMPAGES
.repeat
.if emm_maph[edi] == edx
mov emm_maph[edi],eax
.endif
add edi,4
.untilcxz
mov [edx+8],eax
mov [edx+12],eax
jmp emm_success
.endif
jmp emm_error_83
;----------------------------------------------------------
emm_07: ; Get Version 46h
;----------------------------------------------------------
setAX(0040h)
ret
;----------------------------------------------------------
emm_08: ; Save Page Map 47h
;----------------------------------------------------------
cmp emm_maplevel,MAXMAPLEVEL-1
jae emm_error_8C
inc emm_maplevel
emm_pushmap()
mov esi,offset emm_maph
mov edi,offset emm_tmph
mov ecx,EMAP * MAXMAPLEVEL - 1
add esi,ecx
add edi,ecx
inc ecx
std
rep movsb
cld
.if GlobalAlloc(GMEM_FIXED, EMMPAGES*EMMPAGE*2)
mov edi,eax
mov eax,emm_maplevel
dec eax
shl eax,2
mov emm_tmp0[eax],edi
mov esi,emmh.memp
mov ecx,(EMMPAGES*EMMPAGE)/4
rep movsd
mov esi,emm_seg32
mov ecx,(EMMPAGES*EMMPAGE)/4
rep movsd
.endif
jmp emm_success
;----------------------------------------------------------
emm_09: ; Restore Page Map 48h
;----------------------------------------------------------
cmp emm_maplevel,0
je emm_error_8C
emm_pushmap()
dec emm_maplevel
mov edi,offset emm_maph
mov esi,offset emm_tmph
mov ecx,EMAP * MAXMAPLEVEL
rep movsb
mov eax,emm_maplevel
shl eax,2
mov esi,emm_tmp0[eax]
mov emm_tmp0[eax],0
.if esi
mov ebx,esi
mov edi,emmh.memp
mov ecx,(EMMPAGES*EMMPAGE)/4
rep movsd
mov edi,emm_seg32
mov ecx,(EMMPAGES*EMMPAGE)/4
rep movsd
GlobalFree(ebx)
.endif
emm_updatemap()
emm_popmap()
jmp emm_success
;----------------------------------------------------------
emm_10: ; Reserved 49h
emm_11: ; Reserved 4Ah
jmp emm_error_84
;----------------------------------------------------------
emm_12: ; Get Handle Count 4Bh
;----------------------------------------------------------
mov eax,1
mov ecx,MAXHANDLES-1
mov edx,offset emmh1
.repeat
.if [edx].memp
inc eax
.endif
add edx,HANDLE
.untilcxz
setBX(eax)
jmp emm_success
;----------------------------------------------------------
emm_13: ; Get Handle Pages 4Ch
;----------------------------------------------------------
.if edx >= MAXHANDLES
jmp emm_error_83
.endif
shl edx,4
add edx,offset emmh
mov eax,[edx].size
shr eax,14
setBX(eax)
jmp emm_success
;----------------------------------------------------------
emm_14: ; Get All Handle Pages 4Dh
;
; handle_page_struct STRUC
; emm_handle DW ?
; pages_alloc_to_handle DW ?
; handle_page_struct ENDS
;
; ES:DI = pointer to handle_page
;----------------------------------------------------------
mov eax,4*MAXHANDLES
emm_getesdi()
sub ebx,ebx
sub esi,esi
mov ecx,MAXHANDLES
mov edx,offset emmh
.repeat
.if [edx].memp
mov eax,[edx].size
shl eax,2
mov ax,si
stosd
inc ebx
.endif
inc esi
add edx,HANDLE
.untilcxz
setBX(ebx)
jmp emm_success
;----------------------------------------------------------
emm_15: ; Get Page Map 4E00h
; ES:DI = dest_page_map
;----------------------------------------------------------
test al,al
jnz emm_1501
mov eax,SIZESAVEARRAY
emm_getesdi()
mov esi,offset emm_maph
mov ecx,SIZESAVEARRAY
rep movsb
jmp emm_success
;----------------------------------------------------------
emm_1501: ; Set Page Map 4E01h
; DS:SI = source_page_map
;----------------------------------------------------------
cmp al,1
jne emm_1502
emm_150102:
mov eax,SIZESAVEARRAY
emm_getdssi()
emm_pushmap()
mov edi,offset emm_maph
mov ecx,SIZESAVEARRAY
rep movsb
emm_updatemap()
emm_popmap()
jmp emm_success
;----------------------------------------------------------
emm_1502: ; Get & Set Page Map 4E02h
;----------------------------------------------------------
cmp al,2
jne emm_1503
mov eax,SIZESAVEARRAY
emm_getesdi()
push esi
mov esi,offset emm_maph
mov ecx,SIZESAVEARRAY
rep movsb
pop esi
jmp emm_150102
;----------------------------------------------------------
emm_1503: ; Get Size of Page Map Save Array 4E03h
;----------------------------------------------------------
setAX(SIZESAVEARRAY)
ret
;----------------------------------------------------------
emm_16: ; Get Partial Page Map 4F00h
;
; partial_page_map_struct STRUC
; mappable_segment_count DW ?
; mappable_segment DW (?) DUP (?)
; partial_page_map_struct ENDS
;
; DS:SI = partial_page_map
; ES:DI = dest_array
; pointer to the destination array address in
; Segment:Offset format.
;----------------------------------------------------------
test al,al
jnz emm_1601
mov eax,EMMPAGES*4
emm_getesdi()
mov eax,emm_seg16
movzx ecx,word ptr [edi]
add edi,2
.repeat
stosw
add eax,EMMPAGE/16
.untilcxz
jmp emm_success
;----------------------------------------------------------
emm_1601: ; Set Partial Page Map 4F01h
; DS:SI = source_array
;----------------------------------------------------------
cmp al,1
je emm_150102
;----------------------------------------------------------
emm_1602:; Get Size of Partial Page Map Save Array 4F02h
;----------------------------------------------------------
jmp emm_1503
;----------------------------------------------------------
emm_17: ; Map/Unmap Multiple Handle Pages (Physical) 5000h
;
; log_to_phys_map_struct STRUC
; log_page_number DW ?
; phys_page_number DW ?
; log_to_phys_map_struct ENDS
;
; DS:SI = pointer to log_to_phys_map array
; DX = handle
; CX = log_to_phys_map_len
;----------------------------------------------------------
.if !ecx || edx >= MAXHANDLES
jmp emm_error_8F
.endif
push eax
push ecx
mov eax,ecx
shl eax,2
emm_getdssi()
pop ecx
pop eax
test al,al
jnz emm_1701
.repeat
push esi
push ecx
push edx
movzx ebx,word ptr [esi]
mov al,[esi+2]
emm_mappage()
pop edx
pop ecx
pop esi
.if eax
jmp emm_setAX
.endif
add esi,4
.untilcxz
jmp emm_success
;----------------------------------------------------------
emm_1701:; Map/Unmap Multiple Handle Pages (Segment) 5001h
;
; log_to_seg_map_struct STRUC
; log_page_number DW ?
; mappable_segment_address DW ?
; log_to_seg_map_struct ENDS
;
; DX = handle
; CX = log_to_segment_map_len
; DS:SI = pointer to log_to_segment_map array
;----------------------------------------------------------
.repeat
push esi
push ecx
push edx
movzx ebx,word ptr [esi]
movzx eax,word ptr [esi+2]
sub eax,emm_seg16
shr eax,10
emm_mappage()
pop edx
pop ecx
pop esi
.if eax
jmp emm_setAX
.endif
add esi,4
.untilcxz
jmp emm_success
;----------------------------------------------------------
emm_18: ; Reallocate Pages 51h
; DX = handle
; BX = number of pages to be allocated to handle
; return:
; BX = actual number of pages allocated to handle
;----------------------------------------------------------
;
; No realloc of handle 0 !!
;
emm_needhandle()
emm_pushmap()
shl edx,4
add edx,offset emmh
.if AllocatePages()
mov edi,eax ; pointer
mov ebx,ecx ; new size
mov esi,[edx].memp
.if esi
;
; Copy content from old buffer
;
mov ecx,[edx].size
.if ecx > ebx
mov ecx,ebx
.endif
rep movsb
mov edi,eax
mov esi,edx
GlobalFree([edx].memp)
mov edx,esi
.endif
;
; Reset mapping table
;
sub esi,esi
mov ecx,EMMPAGES
.repeat
.if emm_maph[esi] == edx
mov eax,emm_mapp[esi]
sub eax,[edx].memp
add eax,EMMPAGE
.if eax <= ebx
sub eax,EMMPAGE
add eax,edi
mov emm_mapp[esi],eax
.else
sub eax,eax
mov emm_maph[esi],eax
;
; @@ TODO !!
;
.endif
.endif
add esi,4
.untilcxz
mov [edx].memp,edi
mov [edx].size,ebx
shr ebx,14
setBX(ebx)
jmp emm_success
.endif
mov [esi+8],eax
mov [esi+12],eax
jmp emm_error_87 ; There aren't enough expanded memory pages
;----------------------------------------------------------
emm_19: ; Get Handle Attribute 5200h
;----------------------------------------------------------
.if edx >= MAXHANDLES
jmp emm_error_83
.endif
.if al == 2 || al == 0
setAX(0) ; only volatile handles supported
ret
.endif
jmp emm_error_91
;----------------------------------------------------------
emm_20: ; Get Handle Name 5300h
; DX = handle number
; ES:DI = pointer to handle_name array
;----------------------------------------------------------
.if edx >= MAXHANDLES
jmp emm_error_83
.endif
cmp al,0
jne emm_2001
mov eax,8
emm_getesdi()
shl edx,4
add edx,offset emmh
mov eax,[edx+8]
mov [edi],eax
mov eax,[edx+12]
mov [edi+4],eax
jmp emm_success
;----------------------------------------------------------
emm_2001: ; Set Handle Name 5301h
;----------------------------------------------------------
mov eax,8
emm_getdssi()
shl edx,4
add edx,offset emmh
mov eax,[esi]
mov [edx+8],eax
mov eax,[esi+4]
mov [edx+12],eax
jmp emm_success
;----------------------------------------------------------
emm_21: ; Get Handle Directory 54h
; handle_dir_struct STRUC
; handle_value DW ?
; handle_name DB 8 DUP (?)
; handle_dir_struct ENDS
;
; ES:DI = pointer to handle_dir
;----------------------------------------------------------
cmp al,0
jne emm_2101
mov eax,10*MAXHANDLES
emm_getesdi()
sub ebx,ebx
mov ecx,MAXHANDLES
mov edx,offset emmh
.repeat
.if [edx].memp
mov eax,ebx
stosw
mov eax,[edx+8]
stosd
mov eax,[edx+12]
stosd
inc ebx
.endif
add edx,HANDLE
.untilcxz
setAX(ebx)
ret
;----------------------------------------------------------
emm_2101: ; Search for Named Handle 5401h
;----------------------------------------------------------
cmp al,1
jne emm_2102
mov eax,8
emm_getdssi()
mov eax,[esi]
mov edx,[esi+4]
sub ebx,ebx
mov edi,ebx
mov esi,offset emmh + 8
.repeat
.if [esi] == eax && [esi+4] == edx
sub esi,8
mov ebx,esi
.break
.endif
inc edi
add esi,HANDLE
.until edi == MAXHANDLES
.if ebx
.if !eax && !edx
jmp emm_error_A1
.else
setDX(edi)
jmp emm_success
.endif
.else
jmp emm_error_A0
.endif
ret
;----------------------------------------------------------
emm_2102: ; Get Total Handles 5402h
;----------------------------------------------------------
setBX(MAXHANDLES)
jmp emm_success
;----------------------------------------------------------
emm_22: ; Alter Page Map & Jump (Physical page mode) 5500h
;----------------------------------------------------------
emm_2201:; Alter Page Map & Jump (Segment mode) 5501h
;----------------------------------------------------------
;
; log_phys_map_struct STRUC
; log_page_number DW ?
; phys_page_number_seg DW ?
; log_phys_map_struct ENDS
;
; map_and_jump_struct STRUC
; target_address DD ?
; log_phys_map_len DB ?
; log_phys_map_ptr DD ?
; map_and_jump_struct ENDS
;
; AL = physical page number/segment selector
; 0 = physical page numbers
; 1 = segment address
;
; DX = handle number
;
; DS:SI = pointer to map_and_jump structure
;
;----------------------------------------------------------
.if al > 1
jmp emm_error_8F
.endif
push eax
mov eax,9
emm_getdssi()
movzx ecx,byte ptr [esi+4]
pop eax
mov ah,50h
push esi
mov esi,[esi+5]
emm_17()
pop esi
test ah,ah
jnz emm_setAX
mov eax,[esi]
shr eax,16