summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/XMA2EMS/LIM40.INC
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DEV/XMA2EMS/LIM40.INC')
-rw-r--r--v4.0/src/DEV/XMA2EMS/LIM40.INC1792
1 files changed, 1792 insertions, 0 deletions
diff --git a/v4.0/src/DEV/XMA2EMS/LIM40.INC b/v4.0/src/DEV/XMA2EMS/LIM40.INC
new file mode 100644
index 0000000..8cd006c
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/LIM40.INC
@@ -0,0 +1,1792 @@
1 page
2;-------------------------------------------------------------------
3;
4; Equates that are specific to LIM 4.0 functions go here
5;
6;-------------------------------------------------------------------
7
8null equ 0 ; null value, used everywhere
9max_phys_pages equ 255 ; largest allowable phys page
10
11sf_pm_get equ 0 ; 4f00 - get partial map
12sf_pm_set equ 1 ; 4f01 - set partial map
13sf_pm_size equ 2 ; 4f02 - get partial map size
14
15mu_ppn equ 0 ; 5000 - map/unmap multiple
16mu_seg equ 1 ; 5001 - map/unmap multiple
17mu_max_fcn equ 1 ; 50 - map/unmap multiple
18
19Hn_Attr_Max_Fcn equ 2 ; 52xx - max subfunction ;an000; dms;
20
21sf_hn_get equ 0 ; 5300 - get handle name
22sf_hn_set equ 1 ; 5301 - set handle name
23hn_max_fcn equ 1 ; 53 - handle name sub-functions 00, 01
24
25sf_hd_get equ 0 ; 5400 - get handle dir
26sf_hd_search equ 1 ; 5401 - search for named handle
27sf_hd_total equ 2 ; 5402 - get total number of handles
28hd_max_fcn equ 2 ; 54 - get handle directory s-f's 00, 01, 02
29
30Add_Get_Array equ 0 ; 5800 - Get Mappable Physical Address Array
31Add_Get_Size equ 1 ; 5801 - Get Mappable Physical Address Array Entries
32
33hi_info equ 0 ; 5900 - hardware info
34hi_raw equ 1 ; 5901 - # raw pages
35
36am_get equ 0 ; 5b00 - get alternate map register set
37am_set equ 1 ; 5b01 - set alternate map register set
38am_size equ 2 ; 5b02 - get alternate map save array size
39am_alloc equ 3 ; 5b03 - allocate alternate map register set
40am_dealloc equ 4 ; 5b04 - deallocate alternate map register set
41am_dma_alloc equ 5 ; 5b05 - allocate DMA register set
42am_dma_enable equ 6 ; 5b06 - enable DMA register set
43am_dma_disable equ 7 ; 5b07 - disable DMA register set
44am_dma_dealloc equ 8 ; 5b08 - deallocate DMA register set
45
46os_enable equ 0 ; 5d00 - enable OS/E function
47os_disable equ 1 ; 5d01 - disable OS/E function
48os_access equ 2 ; 5d02 - "return" access key function
49
50map_pages_fcn equ 44h ; function code used to map pages
51get_free_pages equ 42h ; function code used to get free page count
52
53read_clock equ 2ch ; function code to read clock
54dos_int equ 21h ; interrupt 21
55xor_mask equ 0ffffh ; mask used to confuse the random numbers a little
56
57ppm_struct STRUC ; define the structure
58phys_page_offset dw ? ; offsets into PPM entry
59ppm_handle_offset dw ?
60ppm_log_page_offset dw ?
61ppm_struct ENDS
62
63 page
64;-------------------------------------------------------------------
65;
66; 4F - get/set partial page map
67;
68; INPUT:
69; AL = 00, get partial page map pm_get
70; 01, set partial page map pm_set
71; 02, get partial page map size pm_size
72;
73; OUTPUT:
74; See individual function headers
75;
76;-------------------------------------------------------------------
77partial_map proc
78
79; use AL value to select sub-function
80
81 cmp al,sf_pm_get ; al = 00, get partial page map
82 je pm_get
83
84 cmp al,sf_pm_set ; al = 01, set partial page map
85 je pm_set
86
87 cmp al,sf_pm_size ; al = 02, get partial page map size
88 jne pm_invalid_sfcn
89 jmp pm_size
90
91
92; invalid sub-function, report the error
93
94pm_invalid_sfcn:
95 mov ah,ems_code8F ; invalid sub-function code
96 ret
97
98 page
99;-------------------------------------------------------------------
100;
101; 4F00 - get partial page map
102;
103; INPUT:
104; DS:SI -> partial page map
105;
106; dw ? ; segment count (number
107; ; of following entries)
108; dw ? ; segment address to save
109; : ; (repeats count times)
110; :
111;
112; ES:DI -> user array for mapping info
113; size determined by function 4F02
114;
115;
116; OUTPUT:
117; AH = 00, No error
118; 80H, Software error
119; 81H, Hardware error
120; 84H, Invalid function
121; 8FH, Invalid sub-function
122; A3H, Contents of control structure are invalid
123;
124; ES:DI -> saved partial state array
125; format for this is un-disclosed to the user
126; but will be:
127;
128; ppm_count dw ? ; number of saved entries
129; ppm_phys_page dw ? ; physical page
130; ppm_handle dw ? ; handle
131; ppm_log_page dw ? ; logical page
132; : ; repeats for each requested page
133; :
134;
135;
136;-------------------------------------------------------------------
137pm_get:
138
139 push bx ; save some regs
140 push cx
141 push dx
142 push di
143 push si
144 push ds
145
146 mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to mapping control structure
147
148
149;-------------------------------------------------------------------
150
151; get count from caller's control structure
152
153 mov cx,ds:[si] ; the first word of the control
154 ; structure holds the # of entries
155
156 cmp cx,0 ; 0 pages requested? ;an000; dms;
157 je PM_Get_Error_A3 ; yes - flag an error ;an000; dms;
158
159 cmp cx,cs:Map_Count ; do some sanity checking
160 jbe pm_phys_ok ; requested number is ok, do the copies
161
162; They asked for more than we can possibly have. Sounds like trouble.
163
164PM_Get_Error_A3:
165
166 mov ah,ems_codea3 ; bad stuff in the control structure
167 jmp pm_exit00 ; return the error code
168
169pm_phys_ok:
170 mov cx,DS:word ptr [si] ; get count from control structure
171 mov ES:word ptr [di],cx ; save count in save area
172 add di,2 ; increment save area pointer
173
174;-------------------------------------------------------------------
175;
176; everything is OK so far, copy the entries requested
177;
178;-------------------------------------------------------------------
179
180ppm_copies:
181
182 add si,2 ; point to next segment number
183 mov ax,DS:word ptr [si] ; get segment value from control structure
184
185 push si ; save user's si
186 push ds ; save user's ds
187 push cx ; save counter for outer loop
188
189; ready to do the lookup and copy operation
190
191 push cs ; make DS:SI point to internal data area
192 pop ds
193 lea si,map_table
194
195 mov cx,map_count ; number of mappable segments
196
197ppm_inner_copy_loop:
198 cmp ax,ds:word ptr [si+phys_page_segment] ; is this entry the requested?
199 jne ppm_not_yet ; no, try again
200
201 mov cx,ppm_size ; number of bytes to copy
202 cld ; make sure direction flag is right
203 add si,2 ; point to phys_page_number
204
205 rep movsb ; copy the entry
206
207 sub si,2 ; reset si
208
209 jmp ppm_entry_done ; done with this copy, go on
210
211ppm_not_yet:
212 add si,type mappable_phys_page_struct ; point to next entry
213 loop ppm_inner_copy_loop ; try some more
214
215 pop cx ; restore counter for outer loop
216 pop ds ; restore user's ds
217 pop si ; restore user's si
218 mov ah,EMS_Code8B ; we have an invalid segment specified ;an000; dms;
219 jmp PM_Exit00 ; exit the program
220
221ppm_entry_done:
222
223; restore pointer to control structure
224
225 pop cx ; restore counter for outer loop
226 pop ds ; restore user's ds
227 pop si ; restore user's si
228
229
230 loop ppm_copies ; keep going until proper number of
231 ; entries have been copied
232
233 xor ah,ah ; good return code
234;-------------------------------------------------------------------
235pm_exit00:
236 pop ds ; restore these registers
237 pop si
238 pop di
239 pop dx
240 pop cx
241 pop bx
242
243 ret ; return to caller
244
245
246
247 page
248;-------------------------------------------------------------------
249;
250; 4F01 - set partial page map
251;
252; INPUT:
253; DS:SI -> source array
254; Format:
255;
256; ppm_count dw ? ; number of saved entries
257; ppm_phys_page dw ? ; physical page
258; ppm_handle dw ? ; handle
259; ppm_log_page dw ? ; logical page
260; : ; repeats ppm_count times
261; :
262;
263;
264; OUTPUT:
265; AH = 00, No error
266; 80H, Software error
267; 81H, Hardware error
268; 84H, Invalid function
269; 8FH, Invalid sub-function
270; A3H, Contents of source array invalid
271;
272;-------------------------------------------------------------------
273pm_set:
274
275 push bx ; save some regs
276 push cx
277 push dx
278 push di
279 push si
280 push ds
281
282 mov cx,DS:word ptr [si] ; get number of entries in save area
283
284 cmp cx,0 ; is the count zero?
285 je pm_set_error_A3 ; yes - error ;an000; dms;
286
287 cmp cx,cs:Map_Count ; greater than phys pages avail? ;an000; dms;
288 jbe count_ok ; no - data not corrupted ;an000; dms;
289
290pm_set_error_A3:
291
292 mov ah,EMS_CODEA3 ; control structure error
293 jmp pm_exit01 ; exit
294
295count_ok:
296 add si,2 ; point to first entry in save area
297
298pm01_loop:
299
300 mov ax,DS:word ptr [si+phys_page_offset] ; set up regs for map_l_to_p
301 mov ah,map_pages_fcn
302 mov dx,DS:word ptr [si+ppm_handle_offset]
303 mov bx,DS:word ptr [si+ppm_log_page_offset]
304
305 cmp dx,0ffffh ; is there a real entry?
306 je no_map ; no, skip the call to map_l_to_p
307
308 call map_l_to_p ; make the mapping call
309
310no_map:
311 add si,type ppm_struct ; point to next entry
312
313 loop pm01_loop ;
314
315 xor ah,ah ; good return code
316pm_exit01:
317
318 pop ds ; restore these registers
319 pop si
320 pop di
321 pop dx
322 pop cx
323 pop bx
324
325 ret ; return to caller
326
327
328 page
329;-------------------------------------------------------------------
330;
331; 4F02 - get partial page map size
332;
333; INPUT:
334; AX = 4f02h
335;
336; BX = number of pages in partial page map
337;
338; OUTPUT:
339; AH = 00, No error
340; 80H, Software error
341; 81H, Hardware error
342; 84H, Invalid function
343; 8FH, Invalid sub-function
344;
345; AL = size of partial page map save array
346; number of bytes that will be needed
347; to save the requested number of pages
348;
349;-------------------------------------------------------------------
350pm_size:
351
352 push dx ; save dx
353
354 cmp bx,0 ; 0 pages requested? ;an000; dms;
355 je PM_Size_Error_8B ; yes flag an error ;an000; dms;
356
357 cmp bx,cs:Map_Count ; page count > phys pages? ;an000; dms;
358 jbe PM_Size_Return ; no - continue ;an000; dms;
359
360PM_Size_Error_8B:
361
362 mov ah,EMS_Code8B ; signal page count exceeded ;an000; dms;
363 jmp PM_Exit02 ; exit routine ;an000; dms;
364
365PM_Size_Return:
366
367 mov dx,bx ; number of pages times ...
368 mov ax,ppm_size ; * size of an entry ...
369 mul dx ; = number of bytes in save array
370 add ax,2 ; increase by 2 to include count word
371
372 xor ah,ah ; good return code
373
374pm_exit02:
375 pop dx ; restore dx
376
377 ret ; return to caller
378
379partial_map endp
380
381
382 page
383;-------------------------------------------------------------------
384;
385; 50 - map/unmap multiple handle pages
386;
387; INPUT:
388; AH = 00 physical page numbers
389; 01 segment numbers
390;
391;-------------------------------------------------------------------
392map_mult proc
393
394 cmp al,mu_ppn ; is this a map request?
395 je mu_ppn_fcn ; yes, go do it
396
397 cmp al,mu_seg ; no, is this an unmap request?
398 je mu_seg_fcn ; yes, go do it
399
400 xor al,al ; clear al, why not?
401 mov ah,ems_code8f ; no, return invalid sub-function code
402 ret ; return to caller
403
404;-------------------------------------------------------------------
405;
406; 5000 - map/unmap multiple handle pages using physical page numbers
407;
408; INPUT:
409; AX = 5000h
410;
411; DX = handle
412;
413; CX = num entries in control structure
414;
415; DS:SI -> points to control structure
416; Format:
417;
418; log_pg_num dw ? ; logical page number
419; phys_pg_num dw ? ; physical page number
420; : ; repeats CX times
421; :
422;
423; OUTPUT:
424;
425; AH = 00, No error
426; 80H, Software error
427; 81H, Hardware error
428; 83H, Invalid handle
429; 84H, Invalid function
430; 8AH, Invalid logical page
431; 8BH, Invalid physical page
432; 8FH, Invalid sub-function
433;
434;-------------------------------------------------------------------
435
436mu_ppn_fcn:
437
438 push bx ; save regs ;an000; dms;
439 push cx ; save count
440 push dx ; ;an000; dms;
441 push si ; save pointer
442
443 xor ah,ah ; good return code
444 cmp cx,0 ; is count 0?
445 je mu_ppn_exit
446
447mu_ppn_loop:
448 mov bx,ds:word ptr[si+0] ; get logical page number
449 mov ax,ds:word ptr[si+2] ; get physical page number
450 mov ah,map_pages_fcn ; fcn code for mapping
451
452 push cx
453 call map_l_to_p ; call the mapping routine
454 pop cx
455
456 cmp ah,0 ; was return code OK
457 jne mu_ppn_error
458
459 add si,4 ; point to next entry
460
461 loop mu_ppn_loop ; do it again
462
463 xor ah,ah ; good return code
464 jmp mu_ppn_exit
465
466mu_ppn_error:
467mu_ppn_exit:
468 pop si ; restore pointer
469 pop dx ; ;an000; dms;
470 pop cx ; restore count
471 pop bx ; restore regs ;an000; dms;
472
473 ret ; return to caller
474
475
476;-------------------------------------------------------------------
477;
478; 5001 - map/unmap multiple handle pages using segment addresses
479;
480; INPUT:
481; AX = 5001h
482;
483; DX = handle
484;
485; CX = num entries in control structure
486;
487; DS:SI -> points to control structure
488; Format:
489;
490; log_pg_num dw ? ; logical page number
491; seg_address dw ? ; physical segment address
492; : ; repeats CX times
493; :
494;
495; OUTPUT:
496;
497; AH = 00, No error
498; 80H, Software error
499; 81H, Hardware error
500; 83H, Invalid handle
501; 84H, Invalid function
502; 8AH, Invalid logical page
503; 8BH, Invalid physical page
504; 8FH, Invalid sub-function
505;
506;-------------------------------------------------------------------
507
508mu_seg_fcn:
509
510 push bx ; save regs ;an000; dms;
511 push cx ; save count
512 push dx ; ;an000; dms;
513 push si ; save pointer
514
515 xor ah,ah ; good return code
516 cmp cx,0 ; is count 0?
517 je mu_seg_exit
518
519mu_seg_loop:
520 mov bx,ds:word ptr[si+0] ; get logical page number
521
522 push dx ; save handle
523 mov dx,ds:word ptr[si+2] ; get physical page number
524 call Get_Phys_Seg_Page ; convert to logical page circle
525 mov ax,dx ; must be in AX
526 pop dx ; restore handle
527
528 mov ah,map_pages_fcn ; fcn code for mapping
529
530 push cx
531 call map_l_to_p ; call the mapping routine
532 pop cx
533
534 cmp ah,0 ; was return code OK
535 jne mu_seg_error
536
537 add si,4 ; point to next entry
538
539 loop mu_seg_loop ; do it again
540
541 xor ah,ah ; good return code
542 jmp mu_seg_exit
543
544mu_seg_error:
545mu_seg_exit:
546 pop si ; restore pointer
547 pop dx ; ;an000; dms;
548 pop cx ; restore count
549 pop bx ; restore regs ;an000; dms;
550
551 ret ; return to caller
552
553map_mult endp
554
555;-------------------------------------------------------------------
556include lim40b.inc
557;-------------------------------------------------------------------
558
559 page
560;-------------------------------------------------------------------
561;
562; 52 - get/set handle attributes
563;
564; The LIM 4.0 spec strongly advises EMS implementers to avoid this
565; call. Our current implementation of this function is not to provide
566; support. Possibly in future releases it will be supported, if
567; the proper hardware becomes available.
568;
569; DMS 4/29/88
570;
571;-------------------------------------------------------------------
572handle_attrib proc
573
574
575 cmp al,Hn_Attr_Max_Fcn ;maximum subfunction number ;an000; dms;
576 jbe Handle_Attrib_Cont ;continue routine ;an000; dms;
577 mov ah,EMS_Code8F ;we have an invalid subfunction ;an000; dms;
578 jmp Handle_Attrib_Exit ; exit the routine ;an000; dms;
579
580Handle_Attrib_Cont:
581
582 mov ah,EMS_Code91 ;this function is not supported ;an000; dms;
583
584Handle_Attrib_Exit:
585
586 RET ; return to caller
587
588handle_attrib endp
589
590 page
591;-------------------------------------------------------------------
592;
593; 53 - get/set handle name
594;
595; Virtual Mode Note: The Handle Name functions (53 and 54) will @RH6
596; be handled differently when running on a system in virtual mode. @RH6
597; This is to accommadate the Workstation Program's bank switching. @RH6
598; In this case, handle names and ID's will only be returned for @RH6
599; handles allocated in the same PC bank, or for handles in bank 0. @RH6
600; Bank 0 is for device drivers, system extensions, or applications @RH6
601; that install resident before WSP loads. @RH6
602; When interfacing with handles in bank 0, one must be aware of @RH6
603; the problem of two PC applications running simultaneously that @RH6
604; get the handle ID of the resident program and map its pages. @RH6
605; Data corruption will occur if both map and write to the same page @RH6
606; at the same time. @RH6
607; While these new LIM 4.0 functions will return info only for @RH6
608; bank 0 and the current bank, the existing LIM 3.2 functions will @RH6
609; continue to return total system values. For example, function 4B @RH6
610; will return the number of active handles in all banks. @RH6
611;
612; INPUT:
613; AL = sub-function code
614; 00 = get handle name hn_get
615; 01 = set handle name hn_set
616;
617; DX = handle
618;
619; ES:DI -> Get caller's name buffer (8 char's)
620; DS:SI -> Set caller's name buffer (8 char's)
621;
622;
623; OUTPUT:
624; AH = 00, No error
625; 80H, Software error
626; 81H, Hardware error
627; 83H, Handle not found
628; 84H, Invalid function
629; 8FH, Invalid sub-function
630;
631; AL = 0
632;
633;
634; gga 8/21/87
635;
636;-------------------------------------------------------------------
637
638 Null_Handle_Name db 8 dup(0) ;null handle value ;an000; dms;
639
640handle_name proc
641
642 push bx ; save some regs
643 push cx
644 push dx
645 push di
646 push si
647 push ds
648
649 PUSH CS ;Set addressability to our tables @RH8
650 POP DS ;Must restore DS for Set name @RH8
651
652 cmp al,hn_max_fcn ; al = 00 or 01, anything else = error
653 jbe hn_val_sf
654
655; invalid sub-function, report the error
656
657 mov ah,ems_code8F ; invalid sub-function code
658 jmp hn_exit ; exit
659
660; check the handle for valid range
661
662hn_val_sf:
663
664 cmp dx,num_handles-1 ; handle within range ?
665 jnae hn_range_ok ; yes, get down to business
666
667 mov ah,ems_code83 ; handle not found
668 jmp hn_exit ; exit
669
670;------------------------
671; handle is within valid range, now see if it is valid handle (i.e. in use)
672
673hn_range_ok:
674
675 push ax ; save fcn code
676 push dx ; save handle
677
678 MOV AX,DX ;DX = handle id
679 MOV DX,TYPE H_LOOKUP_STRUC ;DI = entry's offset into
680 MUL DX ; the handle lookup table
681 MOV DI,AX ;
682 POP DX ; restore handle
683 POP AX ; restore fcn code
684
685 CMP HANDLE_LOOKUP_TABLE.H_PAGES[DI],REUSABLE_HANDLE
686 JNE HN_IN_USE ;Is this handle valid (in use)?
687 ; No...error
688 mov ah,ems_code83 ; handle not found
689 jmp hn_exit ; return the error code
690
691HN_IN_USE: ;Check bank ID if in virutal mode
692
693 mov bx,ax ;save ax ;an000; dms;
694 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
695 JZ HN_VALID ; (i.e. bank swapping), then read @RH6
696 MOV DX,IDREG ; the current bank ID. @RH6
697 IN AL,DX ; @RH6
698 CMP HANDLE_LOOKUP_TABLE.H_BANK[DI],AL ;If handle's bank ID @RH6
699 JE HN_VALID ; is 0 (resident) or @RH6
700 CMP HANDLE_LOOKUP_TABLE.H_BANK[DI],0 ; = requesters bank @RH6
701 JE HN_VALID ; then OK @RH6
702 ;Else invalid requester bank @RH6
703 MOV AH,EMS_CODE83 ;Indicate handle not found @RH6
704 JMP HN_EXIT
705
706;------------------------
707; find out if get or set operation
708
709hn_valid:
710 mov ax,bx ;restore ax ;an000; dms;
711 cmp al,sf_hn_get ; al = 00 means GET
712 je hn_get
713
714 cmp al,sf_hn_set ; = 01 means SET
715 je hn_set
716
717; invalid sub-function, report the error
718
719 mov ah,ems_code8F ; invalid sub-function code
720 jmp hn_exit ; exit
721
722
723
724 page
725;-------------------------------------------------------------------
726;
727; 5300 - GET sub-function
728; ES:DI -> User's area where name is stored
729;-------------------------------------------------------------------
730hn_get:
731 ;Here DI = offset into h lookup
732 LEA SI,HANDLE_LOOKUP_TABLE ;Set the source SI to the handle's
733 ADD SI,DI ; name field in the handle lookup
734 ADD SI,H_NAME ; lookup table
735
736 MOV DI,cs:[bp].IE_Saved_DI_Reg ;Restore the user's dest where
737 ; the handle name will be stored
738
739 MOV CX,8 ; want to copy 8 characters
740 CLD ; make sure direction flag is right
741 REP MOVSB ; copy the string
742
743 XOR AH,AH ; set good return code
744 JMP HN_EXIT ; exit
745
746
747 page
748;-------------------------------------------------------------------
749;
750; 5301 - SET sub-function
751; DS:SI -> User's area where name comes from
752;
753;-------------------------------------------------------------------
754
755hn_set:
756
757 POP DS ;Restore the user's source where @RH6
758 PUSH DS ; the handle name will come from
759
760
761;------------------------
762 push si ;save regs ;an000; dms;
763 push di ; ;an000; dms;
764 push cx ; ;an000; dms;
765 push es ; ;an000; dms;
766
767 push cs ;swap segs for compare ;an000; dms;
768 pop es ; ;an000; dms;
769
770 mov di,offset cs:Null_Handle_Name ;point to null handle name ;an000; dms;
771 mov cx,8 ;8 bytes to compare ;an000; dms;
772 cld
773 cli ;ints off ;an000; dms;
774 rep cmpsb ;null string entered? ;an000; dms;
775 sti ;ints on ;an000; dms;
776
777 pop es ;restore regs ;an000; dms;
778 pop cx ; ;an000; dms;
779 pop di ; ;an000; dms;
780 pop si ; ;an000; dms;
781 je HN_Set_Null_Entered ;continue - don't look for match ;an000; dms;
782
783 push dx
784 call hd_named_handle ; find out if name is in use
785 pop dx
786
787 cmp ah,0 ; is return code good
788 je name_in_use
789
790HN_Set_Null_Entered:
791
792;------------------------
793 ;Here DI = offset into h lookup
794 ADD DI,OFFSET HANDLE_LOOKUP_TABLE ;Set the dest. DI to the @RH6
795 ADD DI,OFFSET H_NAME ; handle's name field in @RH6
796 ; the handle lookup table @RH6
797
798 PUSH ES ;Make ES:DI -> destination in
799 PUSH CS ; the handle lookup table where
800 POP ES ; the name will be stored
801
802 mov cx,8 ; want to copy 8 characters
803 cld ; clear DF to auto-increment
804 rep movsb ; copy the string
805
806; all done with the SET function, set good return code and exit
807
808 pop es ; restore user's ES
809 xor ax,ax ; set good return code
810 jmp hn_exit
811
812
813;------------------------
814name_in_use:
815 mov ah,ems_codea1 ; name is use error
816
817
818hn_exit:
819 pop ds ; restore these registers
820 pop si
821 pop di
822 pop dx
823 pop cx
824 pop bx
825
826 ret
827
828handle_name endp
829
830
831
832 page
833;-------------------------------------------------------------------
834;
835; 54 - get handle directory
836;
837; SUB-FCNS:
838; AL = 00, get handle directory hd_directory
839; 01, search for named handle hd_named_handle
840; 02, get total handles hd_total_handles
841;
842;-------------------------------------------------------------------
843handle_dir proc
844
845 cmp al,sf_hd_get ; 00 get handle dir
846 je hd_directory
847
848 cmp al,sf_hd_search ; 01 search for named handle
849 je hd_named_handle
850
851 cmp al,sf_hd_total ; 02 get total number of handles
852 jne hd_invalid_sfcn ; must be an invalid function code
853
854 jmp hd_total_handles ; go display total handles
855
856
857; invalid sub-function, report the error
858
859hd_invalid_sfcn:
860 mov ah,ems_code8F ; invalid sub-function code
861
862; invalid sub-function, fall through to exit
863
864hd_exit:
865
866 ret
867
868
869;-------------------------------------------------------------------
870; 5400 - get handle directory
871;
872;
873; INPUT:
874; AL = 00, get handle directory
875;
876; ES:DI -> caller's buffer for handle directory
877;
878; OUTPUT:
879; AH = 00H, no error
880; 80H, software error
881; 81H, hardware error
882; 84H, invalid function
883; 8FH, invalid subfunction
884;
885; AL = number of entries in handle directory
886;
887; ES:DI -> handle directory
888;
889; dw ? ; handle number
890; db 8 dup(?) ; handle name
891; :
892; : ; repeats AL times
893;
894;-------------------------------------------------------------------
895hd_directory:
896
897 push bx ; save some regs
898 push cx
899 push dx
900 push di
901 push si
902 push ds
903
904 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
905 JZ HD_LOOP_INIT ; (i.e. bank swapping), then read @RH6
906 MOV DX,IDREG ; the current bank ID and save it. @RH6
907 IN AL,DX ; @RH6
908 MOV cs:BANKID,AL
909
910
911; initialize some things for the loop
912HD_LOOP_INIT:
913 mov di,cs:[bp].IE_Saved_DI_Reg ;restore users DI ;an000; dms;
914 xor al,al ; al = num entries
915 xor dx,dx ; dx = handle index
916 mov cx,NUM_HANDLES ; loop enough for all handles
917 cld ; make sure direction flag cleared
918
919 push cs ; get cs
920 pop ds ; into ds
921 XOR SI,SI ; SI = offset into handle lookup @RH6
922 ; table
923hd_loop:
924 CMP HANDLE_LOOKUP_TABLE.h_pages[SI],REUSABLE_HANDLE
925 ; If handle not active, then @RH6
926 je hd_next_hndl ; loop and look again
927;-------------------------
928; Active handle...if in virtual mode check bank ID @RH6
929;-------------------------
930
931 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
932 JZ HD_ACTIVE ; (i.e. bank swapping), then check @RH6
933 MOV BL,cs:BANKID ; handle's bank id @RH6
934 CMP HANDLE_LOOKUP_TABLE.H_BANK[SI],BL ;If handle's bank ID @RH6
935 JE HD_Active ; is 0 (resident) or @RH6
936 CMP HANDLE_LOOKUP_TABLE.H_BANK[SI],0 ; = requesters bank @RH6
937 JE HD_Active ; then OK @RH6
938 jmp HD_Next_Hndl ;Else skip to next one @RH6
939
940;------------------------
941; found an active handle, copy info to directory
942;------------------------
943hd_active:
944 mov es:word ptr[di],dx ; put handle number in directory
945 add di,2 ; move directory table pointer along,
946 ; must point to area for handle name now
947
948 push cx ; save counter for outer loop
949 push si ; save si for outer loop
950
951 mov cx,8 ; need to copy 8 chars
952 add si,offset Handle_LookUp_Table ;point to entry ;an000; dms;
953 add si,h_name ; make DS:SI -> handle name in lookup table
954
955rep movsb ; copy the string
956
957 pop si ; restore si for outer loop
958 pop cx ; restore counter for outer loop
959 inc al ; increment entry count
960
961;------------------------
962; done with the copy
963;------------------------
964
965hd_next_hndl:
966 inc dx ; update handle index
967 add si,type h_lookup_struc ; point to next entry in lookup table
968 loop hd_loop ; look for more
969
970 xor ah,ah ; good return code
971
972; all done, fall through to exit
973
974hd_exit00:
975
976 pop ds ;restore these registers
977 pop si
978 pop di
979 pop dx
980 pop cx
981 pop bx
982
983 ret
984
985
986
987 page
988;-------------------------------------------------------------------
989;
990; 5401 - Search for named handle sub-function
991;
992;
993; INPUT:
994; AL = 01, search for named handle
995;
996; DS:SI = Pointer to handle name to search for
997;
998;
999; OUTPUT sub-fcn 01: Search for named handle
1000;
1001; AH = 00H, no error
1002; 80H, software error
1003; 81H, hardware error
1004; 84H, invalid function
1005; 8FH, invalid subfunction
1006; A0H, no matching handle found
1007; A1H, duplicate handle found
1008;
1009; DX = value of named handle
1010;
1011;-------------------------------------------------------------------
1012
1013hd_named_handle:
1014
1015 push bx ; save some regs
1016 push cx
1017 push di
1018 push si
1019 push ds
1020 push es ;an000; dms;
1021
1022 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
1023 JZ HD1_LOOP_INIT ; (i.e. bank swapping), then read @RH6
1024 MOV DX,IDREG ; the current bank ID and save it. @RH6
1025 IN AL,DX ; @RH6
1026 MOV cs:BANKID,AL
1027
1028
1029; initialize some things for the loop
1030HD1_LOOP_INIT:
1031 xor ah,ah ; good return code
1032 xor dx,dx ; dx = handle index
1033 mov cx,NUM_HANDLES ; loop enough for all handles
1034 cld ; make sure direction flag cleared
1035
1036 push cs ; get cs
1037 pop es ; into es
1038 XOR DI,DI ; DI = offset into handle lookup @RH6
1039 ; table @RH6
1040hd1_loop:
1041 CMP ES:HANDLE_LOOKUP_TABLE.h_pages[DI],REUSABLE_HANDLE
1042 ; If handle not active, then @RH6
1043 je hd1_next_hndl ; loop and look again
1044;-------------------------
1045; Active handle...if in virtual mode check bank ID @RH6
1046;-------------------------
1047
1048 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
1049 JZ HD1_ACTIVE ; (i.e. bank swapping), then check @RH6
1050 MOV BL,cs:BANKID ; handle's bank id @RH6
1051 CMP ES:HANDLE_LOOKUP_TABLE.H_BANK[DI],BL ;If handle's bank ID @RH6
1052 JE HD1_Active ; is 0 (resident) or @RH6
1053 CMP ES:HANDLE_LOOKUP_TABLE.H_BANK[DI],0 ; = requesters bank @RH6
1054 JE HD1_Active ; then OK @RH6
1055 jmp HD1_Next_Hndl ;Else skip to next one @RH6
1056;------------------------
1057; found an active handle, check the name
1058;------------------------
1059
1060HD1_ACTIVE:
1061 push cx ; save counter for outer loop
1062 push si ; save si for outer loop
1063 push di ; save di for outer loop
1064
1065 mov cx,8 ; need to compare 8 chars
1066 add di,offset Handle_LookUp_Table ;point to entry ;an000; dms;
1067 add di,offset H_Name ; must point to area for handle name now;an000; dms;
1068
1069rep cmpsb ; compare the strings
1070
1071 pop di ; restore di for outer loop
1072 pop si ; restore si for outer loop
1073 pop cx ; restore counter for outer loop
1074 je hd_exit01 ; found a match, exit
1075
1076;------------------------
1077; done with the check
1078;------------------------
1079
1080hd1_next_hndl:
1081 inc dx ; update handle index
1082 add di,type h_lookup_struc ; point to next entry in lookup table
1083 loop hd1_loop ; look for more
1084
1085
1086
1087; all done, if we fall through loop without finding a match,
1088; must report the error
1089
1090 mov ah,ems_codea0 ; no matching handle
1091 xor dx,dx ; invalid handle
1092
1093hd_exit01:
1094
1095
1096 pop es ;restore these registers ;an000; dms;
1097 pop ds
1098 pop si
1099 pop di
1100 pop cx
1101 pop bx
1102
1103 ret
1104
1105
1106
1107 page
1108;-------------------------------------------------------------------
1109;
1110; 5402 - Get total handles sub-function
1111;
1112; INPUT:
1113; AL = 02, get total handles
1114;
1115;
1116; OUTPUT:
1117; AH = 00H, no error
1118; 80H, software error
1119; 81H, hardware error
1120; 84H, invalid function
1121; 8FH, invalid subfunction
1122;
1123; BX = total number of handles (includes OS handle, 0)
1124;
1125;-------------------------------------------------------------------
1126
1127hd_total_handles:
1128
1129 mov bx,NUM_HANDLES ; return number of handles
1130 xor ah,ah ; good return code
1131
1132; all done, fall through to exit
1133
1134hd_exit02:
1135
1136 ret ; return to caller
1137
1138handle_dir endp
1139
1140 page
1141;-------------------------------------------------------------------
1142;
1143; 58 - Get mappable physical address array
1144;
1145;
1146; INPUT:
1147; AX = 5800h
1148;
1149; ES:DI -> mappable physical array address
1150;
1151; OUTPUT:
1152; AH = 00, no error
1153; 80H, software error
1154; 81H, hardware error
1155; 84H, invalid function
1156; 8FH, invalid subfunction
1157;
1158; CX = number of entries returned in the table below
1159;
1160; ES:DI -> DW ? ; phys_page_segment
1161; DW ? ; phys_page_number
1162; :
1163; : ; repeats CX times
1164;
1165;-------------------------------------------------------------------
1166address_array proc
1167
1168 cmp al,Add_Get_Array ; subfunction 00 Get Mappable Physical ;an000; dms;
1169 ; Address Array
1170 je Address_Get_Physical_Address
1171
1172 cmp al,Add_Get_Size ; subfunction 01 Get Mappable Physical ;an000; dms;
1173 ; Address Array Entries
1174 je Address_Get_Size_Entries
1175
1176 mov ah,EMS_Code8F ; none of the above - invalid sub parm ;an000; dms;
1177
1178 ret
1179
1180
1181Address_Get_Physical_Address:
1182
1183 push si ; save some regs
1184 push di ; save di ;an000; dms;
1185 push ds ; save DS
1186
1187
1188; set up some things for the loop
1189
1190 mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to handle area
1191
1192 mov cx,map_count ; number of entries in table
1193
1194 push cs ; make DS:SI -> array
1195 pop ds
1196
1197 lea si,map_table
1198
1199 cld ; make sure direction flag is right
1200
1201copy_address_array:
1202
1203 mov ax,DS:[si+phys_page_segment]
1204 mov ES:[di],ax
1205 add di,2 ; increment destination pointer
1206 mov ax,DS:[si+phys_page_number]
1207 mov ES:[di],ax
1208
1209 add si,type mappable_phys_page_struct ; increment pointer
1210 add di,2 ; increment destination pointer
1211
1212 loop copy_address_array
1213
1214 mov cx,map_count ; number of entries
1215 xor ah,ah ; good return code
1216
1217 pop ds ; restore DS
1218 pop di ; restore di
1219 pop si ; restore SI
1220
1221 RET ; return to caller
1222
1223Address_Get_Size_Entries:
1224
1225 mov cx,cs:Map_Count ; return the number of pages allocated ;an000; dms;
1226 xor ax,ax ; clear error flag ;an000; dms;
1227 ret ; return to caller ;an000; dms;
1228
1229
1230address_array endp
1231
1232
1233
1234 page
1235;-------------------------------------------------------------------
1236;
1237; 59 - Get extended momory hardware information
1238;
1239;-------------------------------------------------------------------
1240hardware_info proc
1241
1242 cmp ose_functions,ose_enabled ; first, check for fcns enabled
1243 je hi_enabled ;
1244
1245
1246 mov ah,EMS_CODEA4 ; access denied
1247 jmp hi_exit ; exit
1248
1249hi_enabled:
1250 cmp al,hi_info ; 5900 - hardware info fcn
1251 je hi_info_fcn
1252
1253 cmp al,hi_raw ; 5901 - unallocated raw page count
1254 je hi_raw_fcn
1255
1256 mov ah,EMS_CODE8F ; invalid sub-function
1257
1258hi_exit:
1259 RET ; return to caller
1260
1261
1262 page
1263;-------------------------------------------------------------------
1264;
1265; hi_info_fcn
1266;
1267;-------------------------------------------------------------------
1268
1269hi_info_fcn:
1270
1271 mov di,cs:[bp].IE_Saved_DI_Reg ; get di register
1272
1273 mov es:word ptr[di+0],1024 ; raw page size = 16KB
1274 mov es:word ptr[di+2],0 ; number of alternate register sets
1275 mov es:word ptr[di+4],type H_SAVE_STRUC ; size of save array
1276 mov es:word ptr[di+6],0 ; number of DMA register sets
1277 mov es:word ptr[di+8],1 ; 1 = no special DMA register sets
1278
1279 xor ah,ah ; good return code
1280 ret ; return to caller
1281
1282 page
1283;-------------------------------------------------------------------
1284;
1285; hi_raw_fcn
1286;
1287;-------------------------------------------------------------------
1288
1289hi_raw_fcn:
1290
1291 mov ah,get_free_pages ; function code to get free pages
1292
1293 call q_pages ; pass this one through, since our
1294 ; raw pages = 16 KB
1295 ; this fcn returns exacly the same
1296 ; regs as are needed here
1297
1298 ret ; return to caller
1299
1300hardware_info endp
1301
1302 page
1303;-------------------------------------------------------------------
1304;
1305; 5B - alternate map register set
1306;
1307;-------------------------------------------------------------------
1308
1309 AM_ES_Save dw 0 ;ES save variable ;an000; dms;
1310 AM_DI_Save dw 0 ;DI save variable ;an000; dms;
1311 AM_Set_Flag db 0 ;set called flag ;an000; dms;
1312
1313alternate_map proc
1314
1315 cmp ose_functions,ose_enabled ; first, check for fcns enabled
1316 je am_enabled ;
1317
1318
1319 mov ah,EMS_CODEA4 ; access denied
1320 jmp am_exit ; exit
1321
1322am_enabled:
1323 cmp al,am_get ; 5b00 - get alternate map register set
1324 je _am_get
1325
1326 cmp al,am_set ; 5b01 - set alternate map register set
1327 je _am_set
1328
1329 cmp al,am_size ; 5b02 - get alternate map save array size
1330 je _am_size
1331
1332 cmp al,am_alloc ; 5b03 - allocate alternate map register set
1333 je _am_alloc
1334
1335 cmp al,am_dealloc ; 5b04 - deallocate alternate map register set
1336 je _am_dealloc
1337
1338 cmp al,am_dma_alloc ; 5b05 - allocate DMA register set
1339 je _am_dma_alloc
1340
1341 cmp al,am_dma_enable ; 5b06 - enable DMA register set
1342 je _am_dma_enable
1343
1344 cmp al,am_dma_disable ; 5b07 - disable DMA register set
1345 je _am_dma_disable
1346
1347 cmp al,am_dma_dealloc ; 5b08 - deallocate DMA register set
1348 je _am_dma_dealloc
1349
1350 mov ah,EMS_CODE8F ; invalid sub-function
1351
1352am_exit:
1353 ret ; return to caller
1354
1355
1356 page
1357;-------------------------------------------------------------------
1358;
1359; _am_get
1360;
1361;-------------------------------------------------------------------
1362_am_get:
1363
1364 cmp cs:AM_Set_Flag,0 ;flag set? ;an000; dms;
1365 jne AM_Get_Continue ;yes ;an000; dms;
1366 xor di,di ;signal set has not ;an000; dms;
1367 mov es,di ; been performed ;an000; dms;
1368 xor ah,ah ;signal good exit ;an000; dms;
1369 jmp AM_Get_Exit ;exit routine ;an000; dms;
1370
1371AM_Get_Continue:
1372
1373 mov di,cs:AM_DI_Save
1374 mov es,cs:AM_ES_Save
1375 mov cs:[bp].IE_Saved_DI_Reg,di;set instance table entry ;an000; dms;
1376
1377 call GET_SUBFCN ; copy the save area info to user's buffer
1378
1379 xor bl,bl ; bl = 0 for our implementation
1380 ; this indicates to user that ES:DI
1381 ; buffer has been filled in with save
1382 ; area info
1383AM_Get_Exit:
1384
1385 ret
1386
1387 page
1388;-------------------------------------------------------------------
1389;
1390; _am_set
1391;
1392;-------------------------------------------------------------------
1393_am_set:
1394
1395 push si
1396 push ds
1397
1398 cmp bl,null ; bl must be 0 for us
1399 jne _am_set_error ; set error code and exit
1400
1401 mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to mapping control structure
1402
1403 mov cs:AM_ES_Save,es ; save es value ;an000; dms;
1404 mov cs:AM_DI_Save,di ; save di value ;an000; dms;
1405 mov cs:AM_Set_Flag,01 ; flag indicates set performed ;an000; dms;
1406 mov si,di ; restore_pgfrm_map expects DS:SI to point to save area
1407 push es
1408 pop ds
1409
1410 call RESTORE_PGFRM_MAP
1411
1412 xor ah,ah ; good return code
1413
1414 jmp _am_set_exit
1415
1416_am_set_error:
1417 mov ah,EMS_CODE9C ; fast regs not supported and BL != 0
1418
1419_am_set_exit:
1420
1421 pop ds
1422 pop si
1423
1424 ret
1425
1426 page
1427;-------------------------------------------------------------------
1428;
1429; _am_size
1430;
1431;-------------------------------------------------------------------
1432_am_size:
1433
1434 mov dx,type h_save_struc ; get size requirements for save area
1435
1436 xor ah,ah ; good return code
1437
1438 ret
1439
1440 page
1441;-------------------------------------------------------------------
1442;
1443; _am_alloc
1444;
1445;-------------------------------------------------------------------
1446_am_alloc:
1447
1448
1449 xor bl,bl ; We don't support this function
1450 ; in hardware, so return 0.
1451 ; This indicates we will do software
1452 ; emulation of these register sets.
1453
1454 xor ah,ah ; good return code
1455
1456 ret
1457
1458 page
1459;-------------------------------------------------------------------
1460;
1461; _am_dealloc - 5b04
1462;
1463;-------------------------------------------------------------------
1464_am_dealloc:
1465
1466 xor ah,ah ; assume good return code
1467
1468 cmp bl,0 ; is this a deallocate for 0?
1469 je _am_dealloc_exit ; yes, goo return code
1470
1471 mov ah,EMS_CODE9C ; error code for dealloc of unsupported
1472 ; register set
1473
1474_am_dealloc_exit:
1475
1476 ret
1477
1478 page
1479;-------------------------------------------------------------------
1480;
1481; _am_dma_alloc
1482;
1483;-------------------------------------------------------------------
1484_am_dma_alloc:
1485
1486 xor ah,ah ; good return code
1487 xor bl,bl ; no DMA sets available
1488
1489 ret
1490
1491 page
1492;-------------------------------------------------------------------
1493;
1494; _am_dma_enable
1495;
1496;-------------------------------------------------------------------
1497_am_dma_enable:
1498
1499 mov ah,EMS_CODE9E ; dedicated DMA not supported
1500
1501 ret
1502
1503 page
1504;-------------------------------------------------------------------
1505;
1506; _am_dma_disable
1507;
1508;-------------------------------------------------------------------
1509_am_dma_disable:
1510
1511 mov ah,EMS_CODE9E ; dedicated DMA not supported
1512
1513 ret
1514
1515 page
1516;-------------------------------------------------------------------
1517;
1518; _am_dma_dealloc
1519;
1520;-------------------------------------------------------------------
1521_am_dma_dealloc:
1522
1523 xor ah,ah ; assume good return code
1524
1525 cmp bl,null ; is the DMA channel 0?
1526 je _am_dma_de_exit
1527
1528 mov ah,EMS_CODE9C ; DMA register sets are not
1529 ; supported and bl != 0
1530
1531_am_dma_de_exit:
1532 ret
1533
1534
1535alternate_map endp
1536
1537 page
1538;-------------------------------------------------------------------
1539;
1540; 5D - enable/disable OS/E functions set functions
1541;
1542;-------------------------------------------------------------------
1543enable_os proc
1544
1545 cmp al,os_enable ; fcn code for enable
1546 je os_enable_fcn
1547
1548 cmp al,os_disable ; fcn code for disable
1549 je os_disable_fcn
1550
1551 cmp al,os_access ; fcn code for access key return
1552 je os_access_fcn
1553
1554 mov ah,EMS_CODE8F ;invalid sub-function code error
1555
1556 ret ; return to caller
1557
1558 page
1559;-------------------------------------------------------------------
1560;
1561; 5d00 - enable OS/E function set
1562;
1563; INPUT:
1564;
1565; BX,CX = Access key
1566;
1567; OUTPUT:
1568;
1569; AH = 00h, no error
1570; 80H, software error
1571; 81H, hardware error
1572; 84H, invalid function
1573; 8FH, invalid subfunction
1574; A4H, access denied, incorrect access key supplied
1575;
1576;-------------------------------------------------------------------
1577os_enable_fcn:
1578
1579; find out if this is the first time
1580
1581 cmp word ptr access_code[0],0 ; access_code = 0, means enabled
1582 jne ose_check_code ; not 0, must check access code
1583
1584 cmp word ptr access_code[2],0 ; access_code = 0, means enabled
1585 jne ose_check_code ; not 0, must check access code
1586
1587 call get_code ; get access code to return
1588
1589 xor ah,ah ; good return code
1590 jmp ose_exit
1591
1592; not the first time, must check access code
1593
1594ose_check_code:
1595
1596 cmp word ptr access_code[0],bx ; does it match?
1597 jne ose_bad ; no, return access denied error
1598
1599 cmp word ptr access_code[2],cx ; get second word of access code
1600 jne ose_bad ; no, return access denied error
1601
1602; access code was OK, enable functions and return no error condition
1603
1604 mov word ptr ose_functions,ose_enabled ; reset enabled flag
1605
1606 xor ah,ah ; good return code
1607 jmp ose_exit ; all done, exit
1608
1609ose_bad:
1610 mov ah,EMS_CODEA4 ; return access denied error code
1611
1612ose_exit:
1613 ret ; return to caller
1614
1615
1616 page
1617;-------------------------------------------------------------------
1618;
1619; 5d01 - disable OS/E function set
1620;
1621; INPUT:
1622;
1623; BX,CX = Access key
1624;
1625; OUTPUT:
1626;
1627; AH = 00h, no error
1628; 80H, software error
1629; 81H, hardware error
1630; 84H, invalid function
1631; 8FH, invalid subfunction
1632; A4H, access denied, incorrect access key supplied
1633;
1634;-------------------------------------------------------------------
1635os_disable_fcn:
1636
1637; find out if this is the first time
1638
1639 cmp word ptr access_code[0],0 ; access_code = 0, means enabled
1640 jne osd_check_code ; not 0, must check access code
1641
1642 cmp word ptr access_code[2],0 ; access_code = 0, means enabled
1643 jne osd_check_code ; not 0, must check access code
1644
1645; yes, first time, must set access code and disable fcns
1646
1647 call get_code ; get access code to return
1648
1649 mov word ptr ose_functions,ose_disabled ; disable fcns
1650
1651 xor ah,ah ; good return code
1652 jmp osd_exit
1653
1654; not the first time, must check access code
1655
1656osd_check_code:
1657
1658 cmp word ptr access_code[0],bx ; does it match?
1659 jne osd_bad ; no, return access denied error
1660
1661 cmp word ptr access_code[2],cx ; get second word of access code
1662 jne osd_bad ; no, return access denied error
1663
1664; access code was OK, enable functions and return no error condition
1665
1666 mov word ptr ose_functions,ose_disabled ; disable functions
1667
1668 xor ah,ah ; good return code
1669 jmp osd_exit ; all done, exit
1670
1671osd_bad:
1672 mov ah,EMS_CODEA4 ; return access denied error code
1673
1674osd_exit:
1675 ret ; return to caller
1676
1677 page
1678;-------------------------------------------------------------------
1679;
1680; 5d02 - return OS/E function set access code
1681;
1682; INPUT:
1683;
1684; BX,CX = Access key
1685;
1686; OUTPUT:
1687;
1688; AH = 00h, no error
1689; 80H, software error
1690; 81H, hardware error
1691; 84H, invalid function
1692; 8FH, invalid subfunction
1693; A4H, access denied, incorrect access key supplied
1694;
1695;-------------------------------------------------------------------
1696os_access_fcn:
1697
1698; check access code
1699
1700
1701 cmp word ptr access_code[0],bx ; does it match?
1702 jne osa_bad ; no, return access denied error
1703
1704 cmp word ptr access_code[2],cx ; get second word of access code
1705 jne osa_bad ; no, return access denied error
1706
1707; clear access code and return "no error" return code (AH = 00)
1708
1709 xor ax,ax ; clear ax
1710 mov word ptr access_code[0],ax ; clear access code
1711 mov word ptr access_code[2],ax ; clear access code
1712
1713 jmp osa_exit
1714
1715osa_bad:
1716 mov ah,ems_codeA4 ; access denied error code
1717
1718osa_exit:
1719 ret ; return to caller
1720
1721
1722
1723
1724 page
1725;-------------------------------------------------------------------
1726;
1727; get_code - returns random access code in cx,dx and stores it in
1728; system variable access_code. Access_code is a double-word
1729; which is used to save the bx,cx combination making up the
1730; "password" for OS/E functions.
1731;
1732;-------------------------------------------------------------------
1733
1734get_code:
1735
1736 push dx ; save dx
1737
1738; get a "random" number for first word of access code
1739
1740redo1:
1741 call get_rand ; returns "random" num in dx
1742 xor dx,xor_mask ; confuse it a little
1743
1744 cmp dx,0 ; make sure we didn't end up w/0
1745 je redo1
1746
1747 mov word ptr access_code[0],dx ; save it away
1748 mov bx,dx
1749
1750; get another one for second word of access code
1751
1752redo2:
1753 call get_rand
1754 add dx,dx ; confuse it a little
1755 xor dx,xor_mask
1756
1757 cmp dx,0 ; make sure we didn't end up w/0
1758 je redo2
1759
1760 mov word ptr access_code[2],dx ; save it away
1761 mov cx,dx ; put second word in cx
1762
1763 pop dx ; restore
1764
1765 ret ; return to caller
1766
1767
1768;-------------------------------------------------------------------
1769;
1770; get_rand - returns a "random" number in dx
1771;
1772;-------------------------------------------------------------------
1773get_rand:
1774
1775 push ax ; save some regs
1776 push cx
1777
1778redo:
1779 mov ah,read_clock ; function code to read clock
1780 int dos_int ; read the time
1781 ; keep DX since it changes the most
1782
1783 cmp dx,0 ; did we end up with 0?
1784 je redo ; yes, redo it ... never want 0
1785
1786 pop cx ; restore some regs
1787 pop ax
1788
1789 ret ; return to caller
1790
1791enable_os endp
1792