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
|
PAGE ,132
TITLE DOS KEYB Command - Transient Command Processing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DOS - NLS Support - KEYB Command
;; (C) Copyright 1988 Microsoft
;;
;; File Name: KEYBTBBL.ASM
;; ----------
;;
;; Description:
;; ------------
;; Build SHARED_DATA_AREA with parameters specified
;; in KEYBCMD.ASM
;;
;; Documentation Reference:
;; ------------------------
;; None
;;
;; Procedures Contained in This File:
;; ----------------------------------
;; TABLE_BUILD: Build the header sections of the SHARED_DATA_AREA
;; STATE_BUILD: Build the state sections in the table area
;; FIND_CP_TABLE: Given the language and code page parm, determine the
;; offset of the code page table in KEYBOARD.SYS
;;
;; Include Files Required:
;; -----------------------
;; KEYBSHAR.INC
;; KEYBSYS.INC
;; KEYBDCL.INC
;; KEYBI2F.INC
;;
;; External Procedure References:
;; ------------------------------
;; None
;;
;; Change History:
;; ---------------
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
PUBLIC TABLE_BUILD ;;
PUBLIC FIND_CP_TABLE ;;
PUBLIC CPN_INVALID ;;
PUBLIC SD_LENGTH ;;
;;
CODE SEGMENT PUBLIC 'CODE' ;;
;;
INCLUDE KEYBEQU.INC ;;
INCLUDE KEYBSHAR.INC ;;
INCLUDE KEYBSYS.INC ;;
INCLUDE KEYBCMD.INC ;;
INCLUDE KEYBDCL.INC ;;
INCLUDE COMMSUBS.INC ;;
INCLUDE KEYBCPSD.INC ;;
;;
ASSUME CS:CODE,DS:CODE ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Module: TABLE_BUILD
;;
;; Description:
;; Create the table area within the shared data structure. Each
;; table is made up of a descriptor plus the state sections.
;; Translate tables are found in the Keyboard definition file and are
;; copied into the shared data area by means of the STATE_BUILD
;; routine.
;;
;; Input Registers:
;; DS - points to our data segment
;; ES - points to our data segment
;; BP - points at beginning of CMD_PARM_LIST
;;
;; SHARED_DATA_STR must be allocated in memory
;;
;; The following variables must also be passed from KEYB_COMMAND
;; KEYBSYS_FILE_HANDLE is set to file handle after opening file
;; CP_TAB_OFFSET is the offset of the CP table in the SHARED_DATA_AREA
;; STATE_LOGIC_OFFSET is the offset of the state section in the SHARED_DATA_AREA
;; SYS_CODE_PAGE is the binary representation of the system CP
;; KEYBCMD_LANG_ENTRY_PTR is a pointer to the lang entry in KEY DEF file
;; DESIG_CP_BUFFER is the buffer which holds a list of designated CPs
;; DESIG_CP_OFFSET:WORD is the offset of that list
;; NUM_DESIG_CP is the number of CPs designated
;; FILE_BUFFER is the buffer to read in the KEY DEF file
;**********CNS ***************************************
;; ID_PTR_SIZE is the size of the ID ptr structure
;**********CNS ***************************************
;; LANG_PTR_SIZE is the size of the lang ptr structure
;; CP_PTR_SIZE is the size of the CP ptr structure
;; NUM_CP is the number of CPs in the KEYB DEF file for that lang
;; SHARED_AREA_PTR segment and offset of the SHARED_DATA_AREA
;;
;;
;; Output Registers:
;; CX - RETURN_CODE := 0 - Table build successful
;; 1 - Table build unsuccessful - ERROR 1
;; (Invalid language parm)
;; 2 - Table build unsuccessful - ERROR 2
;; (Invalid Code Page parm)
;; 3 - Table build unsuccessful - ERROR 3
;; (Machine type unavaliable)
;; 4 - Table build unsuccessful - ERROR 4
;; (Bad or missing keyboard def file)
;; 5 - Table build unsuccessful - ERROR 5
;; (Memory overflow occurred)
;; Logic:
;; Calculate Offset difference between TEMP and SHARED_DATA_AREAs
;; Get LANGUAGE_PARM and CODE_PAGE_PARM from parm list
;; Call FIND_CP_TABLE := Determine whether CP is valid for given language
;; IF CP is valid THEN
;; Store them in the SHARED_DATA_AREA
;; Prepare to read Keyboard definition file by LSEEKing to the top
;; READ the header
;; Store maximum table values for calculation of RES_END
;; Set DI to point at TABLE_AREA within SHARED_DATA_AREA
;; FOR the state logic section of the specified language:
;; IF STATE_LOGIC_PTR is not -1 THEN
;; LSEEK to state logic section in keyboard definition file
;; READ the state logic section into the TABLE_AREA
;; Set the hot keyb scan codes
;; Set the LOGIC_PTR in the header
;; FOR the common translate section:
;; IF Length parameter is not 0 THEN
;; Build state
;; Set the COMMON_XLAT_PTR in the header
;; FOR the specific translate sections:
;; Establish addressibility to list of designated code pages
;; FOR each code page
;; IF CP_ENTRY_PTR is not -1 THEN
;; Determine offset of CP table in Keyb Def file
;; IF CP table not avaliable THEN
;; Set CPN_INVALID flag
;; ELSE
;; LSEEK to CPn state section in keyboard definition file
;; IF this is the invoked code page THEN
;; Set ACTIVE_XLAT_PTR in SHARED_DATA_AREA
;; Update RESIDENT_END ptr
;; Build state
;; Update RESIDENT_END ptr
;; End
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
FB EQU FILE_BUFFER ;;
KB_MASK EQU 02H ;;
;;
FIRST_XLAT_TAB DW 0 ;;
NEXT_SECT_PTR DW -1 ;;
;;
MAX_COM_SIZE DW ? ;;
MAX_SPEC_SIZE DW ? ;;
MAX_LOGIC_SIZE DW ? ;;
;;
RESIDENT_END_ACC DW 0 ;;
SA_HEADER_SIZE DW SIZE SHARED_DATA_STR;;
PARM_LIST_OFFSET DW ? ;;
;********************CNS*************************
TB_ID_PARM DW 0
;********************CNS*************************
TB_LANGUAGE_PARM DW 0 ;;
TB_CODE_PAGE_PARM DW 0 ;;
;;
CPN_INVALID DW 0 ;;
;;
KEYB_INSTALLED DW 0 ;;
SD_AREA_DIFFERENCE DW 0 ;;
SD_LENGTH DW 2000 ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Program Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
TABLE_BUILD PROC NEAR ;;
;;
MOV AX,OFFSET SD_SOURCE_PTR ;; Setup the difference
SUB AX,OFFSET SD_DEST_PTR ;; value used to calculate
MOV SD_AREA_DIFFERENCE,AX ;; new ptr values for
;; SHARED_DATA_AREA
MOV AX,[BP].ID_PARM ;; WGR Get id parameter ;AN000
MOV TB_ID_PARM,AX ;; WGR ;AN000
MOV AX,[BP].LANGUAGE_PARM ;; Get language parameter
MOV TB_LANGUAGE_PARM,AX ;;
MOV BX,[BP].CODE_PAGE_PARM ;; Get code page parameter
MOV TB_CODE_PAGE_PARM,BX ;;
;; Make sure code page is
CALL FIND_CP_TABLE ;; valid for the language
CMP CX,0 ;; Test return codes
JE TB_CHECK_CONTINUE1 ;; IF code page is found
JMP TB_ERROR6 ;; for language THEN
;;
TB_CHECK_CONTINUE1: ;;;;;;;;
MOV BP,OFFSET SD_SOURCE_PTR ;; Put language parm and ;AN000
MOV AX,TB_ID_PARM ;; WGR id parm and.. ;AN000
MOV ES:[BP].INVOKED_KBD_ID,AX ;; WGR
MOV BX,TB_CODE_PAGE_PARM ;;
MOV ES:[BP].INVOKED_CP_TABLE,BX ;;;;;; code page parm into the
MOV AX,TB_LANGUAGE_PARM ;; SHARED_DATA_AREA
MOV WORD PTR ES:[BP].ACTIVE_LANGUAGE,AX ;;
;;
MOV BX,KEYBSYS_FILE_HANDLE ;;;;;;;;;;;;;;; Get handle
XOR DX,DX ;; LSEEK file pointer
XOR CX,CX ;; back to top of file
MOV AH,42H ;;
MOV AL,0 ;; If no problem with
INT 21H ;; Keyboard Def file THEN
JNC TB_START ;;
JMP TB_ERROR4 ;;
;;
TB_START: ;; Else
XOR DI,DI ;; Set number
LEA CX,[DI].KH_MAX_LOGIC_SZ+2;; bytes to read header
MOV DX,OFFSET FILE_BUFFER ;; Move contents into file buffer
MOV AH,3FH ;; READ
PUSH CS ;;
POP DS ;;
INT 21H ;; File
JNC TB_CONTINUE1 ;;
JMP TB_ERROR4 ;;
;;
TB_CONTINUE1: ;;
CMP CX,AX ;;
JE TB_ERROR_CHECK1 ;;
MOV CX,4 ;;
JMP TB_CPN_INVALID ;;
;;
TB_ERROR_CHECK1: ;;
MOV CX,FB.KH_MAX_COM_SZ ;; Save values for RESIDENT_END
MOV MAX_COM_SIZE,CX ;; calculation
MOV CX,FB.KH_MAX_SPEC_SZ ;;
MOV MAX_SPEC_SIZE,CX ;;
MOV CX,FB.KH_MAX_LOGIC_SZ ;;
MOV MAX_LOGIC_SIZE,CX ;;
;;
LEA DI,[BP].TABLE_AREA ;; Point at beginning of table area
;; DI ---> TABLE_AREA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ** FOR STATE LOGIC SECTION FOR LANG **
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
TB_STATE_BEGIN: ;;
MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle
MOV CX,WORD PTR STATE_LOGIC_OFFSET+2 ;;
MOV DX,WORD PTR STATE_LOGIC_OFFSET ;; Get LSEEK file pointer
;;
CMP DX,-1 ;;;;;;;;;; If no language table then
JNE TB_STATE_CONTINUE1 ;; jump to code page begin
JMP TB_CP_BEGIN ;;
;;
TB_STATE_CONTINUE1: ;; Else
MOV AH,42H ;; LSEEK to beginning of state logic sect
MOV AL,0 ;; If no problem with
INT 21H ;; Keyboard Def file THEN
JNC TB_STATE_CONTINUE2 ;;
JMP TB_ERROR4 ;;
;;;;;;;;;;
TB_STATE_CONTINUE2: ;;
MOV DX,AX ;;
MOV WORD PTR SB_STATE_OFFSET+2,CX ;; Save the offset of the
MOV WORD PTR SB_STATE_OFFSET,DX ;; states in Keyb Def file
;;
SUB DI,SD_AREA_DIFFERENCE ;; Adjust for relocation
MOV ES:[BP].LOGIC_PTR,DI ;;;;;;;;;; Set because this is state
ADD DI,SD_AREA_DIFFERENCE ;; Adjust for relocation
;;
MOV CX,4 ;; Set number bytes to read length and
;; special features
MOV DX,OFFSET FILE_BUFFER ;; Set the buffer address
MOV AH,3FH ;; Read from the Keyb Def file
INT 21H ;;
JNC TB_STATE_CONTINUE3 ;;
JMP TB_ERROR4 ;;
;;
TB_STATE_CONTINUE3: ;;
CMP CX,AX ;;
JE TB_ERROR_CHECK2 ;;
MOV CX,4 ;;
JMP TB_CPN_INVALID ;;
;;;;;
TB_ERROR_CHECK2: ;;
MOV AX,FB.KT_SPECIAL_FEATURES ;; Save the special features in the
MOV ES:[BP].SPECIAL_FEATURES,AX ;; SHARED_DATA_AREA
;;
CMP HW_TYPE,JR_KB ;;;;;;;;
JNE USE_F1_F2 ;;
TEST AX,JR_HOT_KEY_1_2 ;;
JZ USE_F1_F2 ;;
MOV ES:[BP].HOT_KEY_ON_SCAN,ONE_SCAN ;;
MOV ES:[BP].HOT_KEY_OFF_SCAN,TWO_SCAN ;;
JMP HOT_KEY_SET ;;
;;
USE_F1_F2: ;;
MOV ES:[BP].HOT_KEY_ON_SCAN,F1_SCAN ;;
MOV ES:[BP].HOT_KEY_OFF_SCAN,F2_SCAN ;;
;;
HOT_KEY_SET: ;;;;;;;;
MOV CX,FB.KT_LOGIC_LEN ;; Set length of section to read
CMP CX,0 ;;
JNE TB_STATE_CONTINUE4 ;;
MOV CX,-1 ;;;;;
MOV ES:[BP].LOGIC_PTR,CX ;;
JMP SB_COMM_BEGIN ;;
;;
TB_STATE_CONTINUE4: ;;
MOV ES:[DI],CX ;; Store length parameter in
ADD DI,2 ;; SHARED_DATA_AREA
MOV CX,FB.KT_SPECIAL_FEATURES;; Save the special features
MOV ES:[DI],CX ;;
ADD DI,2 ;;
MOV CX,FB.KT_LOGIC_LEN ;; Set length of section to read
SUB CX,4 ;; Adjust for what we have already read
MOV DX,DI ;; Set the address of SHARED_DATA_AREA
PUSH ES ;;
POP DS ;;
MOV AH,3FH ;; Read logic section from the
INT 21H ;; Keyb Def file
PUSH CS ;;
POP DS ;;
JNC TB_STATE_CONTINUE5 ;;
JMP TB_ERROR4 ;;
;;
TB_STATE_CONTINUE5: ;;
CMP CX,AX ;;
JE TB_ERROR_CHECK3 ;;
MOV CX,4 ;;
JMP TB_CPN_INVALID ;;
;;
TB_ERROR_CHECK3: ;;
ADD DI,CX ;; Set DI at new beginning of area
;; TABLE_AREA
;; STATE_LOGIC
MOV CX,RESIDENT_END_ACC ;; DI --->
ADD CX,SA_HEADER_SIZE ;;
ADD CX,MAX_LOGIC_SIZE ;;
MOV RESIDENT_END_ACC,CX ;; Refresh resident end size
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ** FOR COMMON TRANSLATE SECTION FOR LANG **
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
SB_COMM_BEGIN: ;;
MOV CX,SIZE KEYBSYS_XLAT_SECT-1 ;; Set number bytes to read header
MOV DX,DI ;; Set the SHARED_DATA_AREA address
PUSH ES ;;
POP DS ;;
MOV AH,3FH ;; Read from the Keyb Def file
INT 21H ;;
PUSH CS ;;
POP DS ;;
JNC TB_STATE_CONTINUE6 ;;
JMP TB_ERROR4 ;;
;;
TB_STATE_CONTINUE6: ;;
MOV CX,ES:[DI].KX_SECTION_LEN;; Set length of section to read
CMP CX,0 ;;
JNE TB_STATE_CONTINUE7 ;;
JMP TB_CP_BEGIN ;;
;;;;;;;
TB_STATE_CONTINUE7: ;;
MOV CX,WORD PTR SB_STATE_OFFSET ;; Save the offset of the
ADD CX,FB.KT_LOGIC_LEN ;;
MOV WORD PTR SB_STATE_OFFSET,CX ;; Save the offset of the
SUB DI,SD_AREA_DIFFERENCE ;; Adjust for relocation
MOV ES:[BP].COMMON_XLAT_PTR,DI ;;
ADD DI,SD_AREA_DIFFERENCE ;; Adjust for relocation
;;;;;;;
CALL STATE_BUILD ;;
;; DI set at new beginning of area
;; TABLE_AREA
;; STATE_LOGIC
;; COMMON_XLAT_SECTION
MOV CX,RESIDENT_END_ACC ;;
ADD CX,MAX_COM_SIZE ;;
MOV RESIDENT_END_ACC,CX ;; Refresh resident end size
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; FOR ALL DESIGNATED OR INVOKED CODE PAGES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
TB_CP_BEGIN: ;; Get the offset to
MOV CX,OFFSET DESIG_CP_BUFFER.DESIG_CP_ENTRY ;; the beginning of the
MOV DESIG_CP_OFFSET,CX ;; table of designated
;;;;;; code pages
TB_CPN_BEGIN: ;;
MOV AX,WORD PTR ES:[BP].ACTIVE_LANGUAGE ;; Get the active language
MOV CX,NUM_DESIG_CP ;;;;;;;;;;;;;; Get the number of CPs
CMP CX,0 ;; IF we have done all requested CPs
JNE TB_CPN_VALID1 ;;
JMP TB_DONE ;; Then done
;;
TB_CPN_VALID1: ;;
MOV SI,[DESIG_CP_OFFSET] ;;
MOV BX,[SI] ;; Get the CP
CMP BX,-1 ;;
JNE TB_CPN_CONTINUE1 ;;
JMP TB_CPN_REPEAT ;;
;;
TB_CPN_CONTINUE1: ;; ELSE
PUSH DI ;;
CALL FIND_CP_TABLE ;; Find offset of code page table
POP DI ;;
;;
CMP CX,0 ;; Test return codes
JE TB_CPN_VALID ;; IF code page is not found for language
MOV CPN_INVALID,CX ;; Set flag and go to next CP
JMP TB_CPN_REPEAT ;; Else
;;
TB_CPN_VALID: ;;;;;;
MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle
MOV CX,WORD PTR CP_TAB_OFFSET+2 ;; Get offset of the code page
MOV DX,WORD PTR CP_TAB_OFFSET ;; in the Keyb Def file
;;
CMP DX,-1 ;;;;;; Test if code page is blank
JNE TB_CPN_CONTINUE2 ;;
JMP TB_CPN_REPEAT ;; If it is then go get next CP
;;
TB_CPN_CONTINUE2: ;;
MOV AH,42H ;; LSEEK to table in Keyb Def file
MOV AL,0 ;; If no problem with
INT 21H ;; Keyb Def file Then
JNC TB_CPN_CONTINUE3 ;;
JMP TB_ERROR4 ;;
;;;;;;;;;;
TB_CPN_CONTINUE3: ;;
MOV DX,AX ;;
MOV WORD PTR SB_STATE_OFFSET+2,CX ;; Save the offset of the
MOV WORD PTR SB_STATE_OFFSET,DX ;; states in Keyb Def file
;;
MOV CX,TB_CODE_PAGE_PARM ;;;;; If this code page is the
MOV SI,[DESIG_CP_OFFSET] ;; invoked code page
CMP CX,[SI] ;;
JNE TB_CPN_CONTINUE4 ;; Then
;;
SUB DI,SD_AREA_DIFFERENCE ;; Adjust for relocation
MOV ES:[BP].ACTIVE_XLAT_PTR,DI ;; Set active xlat section
ADD DI,SD_AREA_DIFFERENCE ;; Adjust for relocation
;;;;;;;
TB_CPN_CONTINUE4: ;;
SUB DI,SD_AREA_DIFFERENCE ;; Adjust for relocation
MOV ES:[BP].FIRST_XLAT_PTR,DI;; Set flag
ADD DI,SD_AREA_DIFFERENCE ;; Adjust for relocation
;;
TB_CPN_CONTINUE5: ;;
CALL STATE_BUILD ;; Build state
;; TABLE_AREA
CMP CX,0 ;; COMMON_XLAT_SECTION
JE TB_CPN_REPEAT ;; SPECIFIC_XLAT_SECTION(S)
JMP TB_ERROR4 ;; DI --->
;;
TB_CPN_REPEAT: ;;
MOV CX,RESIDENT_END_ACC ;;
ADD CX,MAX_SPEC_SIZE ;; Refresh resident end size
MOV RESIDENT_END_ACC,CX ;;
;;
MOV CX,DESIG_CP_OFFSET ;;
ADD CX,2 ;; Adjust offset to find next code page
MOV DESIG_CP_OFFSET,CX ;;
;;
MOV CX,NUM_DESIG_CP ;; Adjust the number of code pages left
DEC CX ;;
MOV NUM_DESIG_CP,CX ;;
;;
JMP TB_CPN_BEGIN ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
TB_DONE: ;;
MOV CX,RESIDENT_END_ACC ;; Set final calculated value
ADD CX,BP ;;;;;;;;;;;
SUB CX,SD_AREA_DIFFERENCE ;; Adjust for relocation
MOV ES,WORD PTR SHARED_AREA_PTR ;; Set segment
MOV BP,WORD PTR SHARED_AREA_PTR+2 ;;
CMP CX,ES:[BP].RESIDENT_END ;;
JNA TB_DONE_CONTINUE1 ;;;;;;;;;;;
JMP TB_ERROR5 ;;
;;
TB_DONE_CONTINUE1: ;;
CMP ES:[BP].RESIDENT_END,-1 ;;
JNE DONT_REPLACE ;;
PUSH CS ;;
POP ES ;;
MOV BP,OFFSET SD_SOURCE_PTR ;;
MOV ES:[BP].RESIDENT_END,CX ;; Save resident end
JMP CONTINUE_2_END ;;
;;
DONT_REPLACE: ;;
PUSH CS ;;
POP ES ;;
MOV BP,OFFSET SD_SOURCE_PTR ;;
;;
CONTINUE_2_END: ;;
SUB CX,OFFSET SD_DEST_PTR ;; Calculate # of bytes to copy
MOV SD_LENGTH,CX ;;
;;
XOR CX,CX ;; Set valid completion return code
MOV TB_RETURN_CODE,CX ;;
RET ;;
;;
TB_CPN_INVALID: ;;
CMP CX,1 ;; Set error 1 return code
JNE TB_ERROR2 ;;
MOV TB_RETURN_CODE,CX ;;
RET ;;
;;
TB_ERROR2: ;;
CMP CX,2 ;; Set error 2 return code
JNE TB_ERROR3 ;;
MOV TB_RETURN_CODE,CX ;;
RET ;;
;;
TB_ERROR3: ;;
CMP CX,3 ;; Set error 3 return code
JNE TB_ERROR4 ;;
MOV TB_RETURN_CODE,CX ;;
RET ;;
;;
TB_ERROR4: ;;
CMP CX,4 ;; Set error 4 return code
JNE TB_ERROR5 ;;
MOV TB_RETURN_CODE,CX ;;
RET ;;
;;
TB_ERROR5: ;;
MOV CX,5 ;; Set error 5 return code
MOV TB_RETURN_CODE,CX ;;
RET ;;
;;
TB_ERROR6: ;;
MOV BX,TB_CODE_PAGE_PARM ;;
MOV CX,6 ;;
MOV TB_RETURN_CODE,CX ;; Set error 6 return code
RET ;;
;;
TABLE_BUILD ENDP ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Module: STATE_BUILD
;;
;; Description:
;; Create the state/xlat section within the specific translate section.
;;
;; Input Registers:
;; DS - points to our data segment
;; ES - points to our data segment
;; SB_STATE_OFFSET - offset to the beginning of the info in Keyb Def SYS
;; DI - offset of the beginning of the area used to build states
;;
;; KEYBSYS_FILE_HANDLE - handle of the KEYBOARD.SYS file
;;
;; Output Registers:
;; DI - offset of the end of the area used by STATE_BUILD
;;
;; CX - Return Code := 0 - State build successful
;; 4 - State build unsuccessful
;; (Bad or missing Keyboard Def file)
;;
;; Logic:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
END_OF_AREA_PTR DW 0 ;;
SB_FIRST_STATE DW 0 ;;
SB_STATE_LENGTH DW 0 ;;
SB_STATE_OFFSET DD 0 ;;
STATE_LENGTH DW 0 ;;
RESTORE_BP DW ? ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Program Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
STATE_BUILD PROC NEAR ;;
;;
MOV SI,DI ;; Get the tally pointer
MOV END_OF_AREA_PTR,DI ;; Save pointer
;;
MOV RESTORE_BP,BP ;; Save the base pointer
;;;;;;;;;
MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle
MOV DX,WORD PTR SB_STATE_OFFSET ;; LSEEK file pointer
MOV CX,WORD PTR SB_STATE_OFFSET+2 ;; back to top of XLAT table
MOV AH,42H ;;
MOV AL,0 ;;;;;;;;; If no problem with
INT 21H ;; Keyboard Def file THEN
JNC SB_FIRST_HEADER ;;
JMP SB_ERROR4 ;;
;;
SB_FIRST_HEADER: ;;
XOR BP,BP ;;
LEA CX,[BP].KX_FIRST_STATE ;; Set number of bytes to read header
MOV DX,DI ;;
PUSH ES ;;
POP DS ;;
MOV AH,3FH ;; read in the header
INT 21H ;;
PUSH CS ;;
POP DS ;;
JNC SB_HEAD_CONTINUE1 ;;
JMP SB_ERROR4 ;;
;;
SB_HEAD_CONTINUE1: ;;
MOV DX,NEXT_SECT_PTR ;;
CMP DX,-1 ;;
JE SB_HEAD_CONTINUE2 ;;
SUB DX,SD_AREA_DIFFERENCE ;; Adjust for relocation
;;;;;
SB_HEAD_CONTINUE2: ;;
MOV ES:[DI].XS_NEXT_SECT_PTR,DX ;;
CMP DX,-1 ;;
JE SB_HEAD_CONTINUE3 ;;;;;
ADD DX,SD_AREA_DIFFERENCE ;; Adjust for relocation
;;
SB_HEAD_CONTINUE3: ;;
ADD DI,CX ;; Update the DI pointer
;;
SB_NEXT_STATE: ;;
XOR BP,BP ;; Set number
LEA CX,[BP].KX_STATE_ID ;; bytes to read state length
MOV DX,DI ;; Read the header into the
MOV BX,KEYBSYS_FILE_HANDLE ;; SHARED_DATA_AREA
PUSH ES ;;
POP DS ;;
MOV AH,3FH ;;
INT 21H ;;
;;
SB_CONTINUE1: ;;
PUSH CS ;; Reset the data segment
POP DS ;;
MOV CX,ES:[DI].KX_STATE_LEN ;; If the length of the state section
MOV STATE_LENGTH,CX ;;
ADD DI,2 ;; is zero then done
CMP CX,0 ;;
JE SB_DONE ;;
XOR BP,BP ;; Set number
LEA CX,[BP].KX_FIRST_XLAT-2 ;; bytes to read state length
MOV DX,DI ;; Read the header into the
MOV BX,KEYBSYS_FILE_HANDLE ;; SHARED_DATA_AREA
PUSH ES ;;
POP DS ;;
MOV AH,3FH ;;
INT 21H ;;
;;
SB_CONTINUE1A: ;;
PUSH CS ;; Reset the data segment
POP DS ;;
SUB DI,2 ;;
MOV AX,ES:[DI].XS_KBD_TYPE ;; Get the keyboard type def
TEST AX,HW_TYPE ;; Does it match our hardware?
JNZ SB_CONTINUE2 ;;
MOV DX,ES:[DI].XS_STATE_LEN ;; No, then
LEA CX,[BP].KX_FIRST_XLAT ;;
SUB DX,CX ;;
XOR CX,CX ;;
MOV AH,42H ;; LSEEK past this state
MOV AL,01H ;;
INT 21H ;;
JMP SB_NEXT_STATE ;;
;;
SB_CONTINUE2: ;; Yes, then
MOV AX,SIZE STATE_STR-1 ;;
ADD DI,AX ;; Set PTR and end of header
;;
SB_XLAT_TAB_BEGIN: ;; Begin getting xlat tables
MOV BX,KEYBSYS_FILE_HANDLE ;;
LEA DX,[BP].KX_FIRST_XLAT ;; Adjust for what we have already read
MOV CX,STATE_LENGTH ;;
SUB CX,DX ;;
MOV DX,DI ;;
PUSH ES ;;
POP DS ;;
MOV AH,3FH ;; Read in the xlat tables
INT 21H ;;
PUSH CS ;;
POP DS ;;
JNC SB_CONTINUE4 ;;
JMP SB_ERROR4 ;;
;;
SB_CONTINUE4: ;;
CMP CX,AX ;;
JE SB_ERROR_CHECK1 ;;
JMP SB_ERROR4 ;;
;;
SB_ERROR_CHECK1: ;;
ADD DI,CX ;; Update the end of area ptr
;;
MOV SI,DI ;;
JMP SB_NEXT_STATE ;;
;;
SB_DONE: ;;
MOV AX,-1 ;;
MOV SI,END_OF_AREA_PTR ;;
MOV NEXT_SECT_PTR,SI ;;
;;
MOV BP,RESTORE_BP ;;
RET ;;
;;
SB_ERROR1: ;;
MOV CX,1 ;;
RET ;;
;;
SB_ERROR2: ;;
MOV CX,2 ;;
RET ;;
;;
SB_ERROR3: ;;
MOV CX,3 ;;
RET ;;
;;
SB_ERROR4: ;;
MOV CX,4 ;;
RET ;;
;;
;;
STATE_BUILD ENDP ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Module: FIND_CP_TABLE
;;
;; Description:
;; Determine the offset of the specified code page table in KEYBOARD.SYS
;;
;; Input Registers:
;; DS - points to our data segment
;; ES - points to our data segment
;; AX - ASCII representation of the language parm
;; BX - binary representation of the code page
;;
;; KEYBSYS_FILE_HANDLE - handle of the KEYBOARD.SYS file
;;
;; Output Registers:
;; CP_TAB_OFFSET - offset of the CP table in KEYBOARD.SYS
;;
;; CX - Return Code := 0 - State build successful
;; 2 - Invalid Code page for language
;; 4 - Bad or missing Keyboard Def file
;; Logic:
;;
;; READ language table
;; IF error in reading file THEN
;; Display ERROR message and EXIT
;; ELSE
;; Use table to verify language parm
;; Set pointer values
;; IF code page was specified
;; READ language entry
;; IF error in reading file THEN
;; Display ERROR message and EXIT
;; ELSE
;; READ Code page table
;; IF error in reading file THEN
;; Display ERROR message and EXIT
;; ELSE
;; Use table to get the offset of the code page parm
;; RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
FIND_CP_PARM DW ? ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Program Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
FIND_CP_TABLE PROC NEAR ;;
;;
;;
MOV FIND_CP_PARM,BX ;; Save Code page
;;;;;;;;;;;;;;
MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle
MOV DX,WORD PTR KEYBCMD_LANG_ENTRY_PTR ;; LSEEK file pointer
MOV CX,WORD PTR KEYBCMD_LANG_ENTRY_PTR+2 ;; to top of language entry
MOV AH,42H ;;
MOV AL,0 ;;;;;;;;;;;;;; If no problem with
INT 21H ;; Keyb Def file Then
JNC FIND_BEGIN ;;
JMP FIND_CP_ERROR4 ;;
;;;;;;;;;
FIND_BEGIN: ;;
MOV DI,AX ;;
MOV CX,SIZE KEYBSYS_LANG_ENTRY-1 ;; Set number
;; bytes to read header
MOV DX,OFFSET FILE_BUFFER ;;;;;;;;;
MOV AH,3FH ;; Read language entry in
INT 21H ;; KEYBOARD.SYS file
JNC FIND_VALID4 ;; If no error in opening file then
JMP FIND_CP_ERROR4 ;;
;;
FIND_VALID4: ;;
;****************************** CNS *******************************************
xor ah,ah
mov al,FB.KL_NUM_CP
;****************************** CNS *******************************************
MOV NUM_CP,AX ;; Save the number of code pages
MUL CP_PTR_SIZE ;; Determine # of bytes to read
MOV DX,OFFSET FILE_BUFFER ;; Establish beginning of buffer
MOV CX,AX ;;
CMP CX,FILE_BUFFER_SIZE ;; Make sure buffer is not to small
JBE FIND_VALID5 ;;
JMP FIND_CP_ERROR4 ;;
;;
FIND_VALID5: ;;
MOV AH,3FH ;; Read code page table from
INT 21H ;; KEYBOARD.SYS file
JNC FIND_VALID6 ;; If no error in opening file then
JMP FIND_CP_ERROR4 ;;
;;
FIND_VALID6: ;;
MOV CX,NUM_CP ;; Number of valid codes
MOV DI,OFFSET FILE_BUFFER ;; Point to correct word in table
;;
F_SCAN_CP_TABLE: ;; FOR code page parm
MOV AX,FIND_CP_PARM ;; Get parameter
CMP [DI].KC_CODE_PAGE,AX ;; Valid Code ??
JE F_CODE_PAGE_FOUND ;; If not found AND more entries THEN
ADD DI,LANG_PTR_SIZE ;; Check next entry
DEC CX ;; Decrement count of entries
JNE F_SCAN_CP_TABLE ;; Else
JMP FIND_CP_ERROR2 ;; Display error message
;;;;;;;;;;
F_CODE_PAGE_FOUND: ;;
MOV AX,WORD PTR [DI].KC_ENTRY_PTR ;;
MOV WORD PTR CP_TAB_OFFSET,AX ;;
MOV AX,WORD PTR [DI].KC_ENTRY_PTR+2 ;;
MOV WORD PTR CP_TAB_OFFSET+2,AX ;;
;;
XOR CX,CX ;;;;;;;;;;
RET ;;
;;
FIND_CP_ERROR1: ;;
MOV CX,1 ;;
RET ;;
;;
FIND_CP_ERROR2: ;;
MOV CX,2 ;;
RET ;;
;;
FIND_CP_ERROR3: ;;
MOV CX,3 ;;
RET ;;
;;
FIND_CP_ERROR4: ;;
MOV CX,4 ;;
RET ;;
;;
FIND_CP_TABLE ENDP ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CODE ENDS
END TABLE_BUILD
|