-
Notifications
You must be signed in to change notification settings - Fork 3
/
IMD.ASM
executable file
·1730 lines (1669 loc) · 57.8 KB
/
IMD.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
; File: IMD.ASM (From NZY.ASM)
; 92,9-96,4. By: Jian Jing
; Allright reserved.
; ==================================================================
; 装载扩展词汇文件 ACZY.DAT 到XMS或者放于硬盘,然后登记 INT 66h
; 整个输入法仅占用3K内存空间, 且编码库突破 64K 限制.
; 94.12.3 完成一个模块安装管理10种自由输入法的集成功能
.model tiny
.code
.286p
org 100h
start:
jmp begin
; 每个编码库需要的结构, 每个结构占 59-12 bytes, 共有10个结构
; -------------------------------------------------------
filename db 'DRV\'
fichg db 'SP .IMD',0
max_seg dw 0
max_off dw 0
EMB_count dd 0
EMB_Sr_hand dw 0
EMB_Sr_offset dd 0
EMB_Dr_hand dw 0
EMB_Dr_offset dd 0
in_if_09 db 0 ; 是否允许数字编码
in_zymi db 0 ; 最大码长
in_name db 8 dup(0) ; 输入法名称
; -------------------------------------------------------
i1_beg db 'DRV\IMDY1 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY2 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY3 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY4 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY5 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY6 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY7 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY8 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY9 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
db 'DRV\IMDY0 .IMD',0
dw 0
dw 0
dd 0
dw 0
dd 0
dw 0
dd 0
db 0
db 0
db 8 dup(0)
; -----------------------------
XMS_Entry dd 0
xmsumb dw 0
file_hand dw 0
dgdy db 0
dis_begin_82 dw 0
di_begin_82 dw 0
dis_begin_81 dw 0
di_begin_81 dw 0
dis_begin dw 0
di_begin dw 0
dis_continue dw 0
di_continue dw 0
di_this dw 0
es_this dw 0
fun_aczy db 0
; -----------------------------
di_offset dw offset cz_buf ;0
cl_begin_82 db 0
si_begin_82 dw 0
si_buf dw 0
di_buf dw 0
mblg db 0 ; 输入码长度
tuzm_add dw 0
just_tuzm db "~"
int65h dd 0
int66h dd 0 ; 前翻页时递归调用
all_leng db 24 ; 一次可转换词汇总长度(联想时为50)
pre_al db 0
; 下面三个变量位置不应改动
; -------------------------------
if_09 db 0 ; 是否允许数字编码
zymi db 0 ; 最大码长
input_name db ' ' ; 自定义输入法名
; -------------------------------
; 进入:
; AH=0自动记忆,7fh释放,80h从头找,81h后翻页,82h前翻页,83h从当前页找
; AL = 输入法号(0-9)
; DS:SI = 双拼编码所在地址
; DS:DI = 词汇转移地址
; CL = 词汇编码长度
; = 80h , 代表查找联想字词(在 SI 中)
; DS:BP = "?" 所在位置替代的字符(顺序排放)
; 返回:
; CL = 词汇长度 (包括重码), 若 CL = 0 则代表无此编码词汇
; DL = 重码个数 (全部放在DS:SI)
; -------------------------------
int66:
cld
mov cs:fun_aczy,ah
or ah,ah ; AH=0, 自动记忆调用
jnz short n_self_word
mov byte ptr cs:i66c65,1
pushf
call cs:int65h
mov byte ptr cs:i66c65,0
iret
n_self_word:
cmp ah,7Fh ; 7Fh 功能, 释放自己
jnz short not_free
cmp al,1
ja short nfrall ; 非全体释放, 转
fr_nxal:
call fr_al
inc al
cmp al,10d
jbe short fr_nxal
mov dx,cs:xmsumb
or dx,dx
jz short dos_umb
mov ah,11h
call cs:XMS_Entry
jmp short okfreeumb
dos_umb:
push cs
pop es
mov ah,49h
int 21h ; 释放自身内存空间
okfreeumb:
xor dx,dx
mov ds,dx
mov ax,8365h ; 65 取消登记屏幕取词功能
int 16h
iret
nfrall:
call fr_al
iret
; 释放AL号输入法(AL=1-10)
; -----------------------
fr_al:
push ax
push bx
push dx
xor ah,ah
mov bx,59d-12d
mul bx
add ax,offset filename
mov bx,ax
mov word ptr cs:[bx],0
mov dx,cs:[bx+37d-12d] ;30d] ;EMB_Sr_hand
or dx,dx
jz short nf_xms
mov word ptr cs:[bx+37d-12d],0 ;30d],0
mov ah,5
call cs:XMS_Entry
mov ah,0ah
call cs:XMS_Entry
nf_xms:
pop dx
pop bx
pop ax
retn
not_free:
cmp byte ptr cs:dgdy,0
jnz short nopen ;not_move
cmp al,cs:pre_al
jz short not_move ;AL=当前输入法,不再搬移参数
call mov_pre_al
mov cs:pre_al,al
not_move:
cmp word ptr cs:EMB_Sr_hand,0
jnz short nopen
push ds
push ax
push dx
push cs
pop ds
mov dx,offset filename
mov ax,95fch
int 10h
mov ax,3D00h
int 21h
mov cs:file_hand,ax
pop dx
pop ax
pop ds
nopen:
push es
push di ; 保存转移地址
mov cs:source_di,di
mov cs:mblg,cl ; 编码长度
mov byte ptr cs:all_leng,24 ; 查编码字词时长度30
cmp byte ptr cs:mblg,80h
jnz short upok
mov byte ptr cs:all_leng,50 ; 查联想字词时长度50
upok:
xor cx,cx
xor dl,dl
xor di,di
mov es,di
mov cs:si_buf,si
mov cs:tuzm_add,bp
mov word ptr cs:cx_max,0
cmp ah,82h ; AH=82H 前翻页
jz short is82_fun
jmp if_foll
is82_fun:
push di
mov di,es
cmp di,cs:dis_begin
pop di
jnz short nequ_es
cmp di,cs:di_begin
jnz short nequ_es
jmp cp_nxt_1 ; 比较上一回起始指针,已在库首,转一切从头
nequ_es:
mov di,cs:dis_begin
mov cs:dis_begin_82,di ; 保存上次起始地址
mov di,cs:di_begin
mov cs:di_begin_82,di
mov cl,cs:mblg
mov cs:cl_begin_82,cl
mov cs:si_begin_82,si
pop di
push di
mov ah,80h ; 首先从头查找
mov byte ptr cs:dgdy,1
pushf
call cs:int66h ; 递归调用
mov byte ptr cs:dgdy,0
if_vdok:
mov cl,cs:cl_begin_82
mov si,cs:si_begin_82
mov ax,cs:dis_continue
cmp ax,cs:dis_begin_82
jnz short nequ_es1
mov ax,cs:di_continue
cmp ax,cs:di_begin_82 ; 上次结束处是否本次开始处?
jz short vdok ; 是,上页开始在 di_begin
nequ_es1:
pop di
push di
mov ah,81h ; 否则,后翻页继续查找
mov byte ptr cs:dgdy,1
pushf
call cs:int66h ; 递归调用
mov byte ptr cs:dgdy,0
jmp short if_vdok
vdok:
mov es,cs:dis_begin
mov di,cs:di_begin
xor cx,cx ; 初始化记数变量
xor dl,dl
jmp short cp_nxt_1
if_foll:
cmp ah,81h ; AH=81H 后翻页,继续查找
jnz short ifcure_p ; 从上次结束处开始
mov es,cs:dis_continue
mov di,cs:di_continue
jmp short cp_nxt_1
ifcure_p:
cmp ah,83h ; AH=83H 从当前页开始查找
jnz short cp_nxt_1
mov es,cs:es_this
mov di,cs:di_this
cp_nxt_1:
mov si,cs:dis_begin
mov cs:dis_begin_81,si
mov si,cs:di_begin
mov cs:di_begin_81,si ; 先保存起始指针,以便在未找到编码字词时恢复
mov cs:dis_begin,es
mov cs:di_begin,di ; 记录当前起始指针
call move_to_esdi
cp_nxt:
mov word ptr cs:mov_todi,0
mov si,cs:si_buf
mov bx,cs:di_offset
mov al,cs:[bx] ; +offset cz_buf]
cmp al,'$'
jnz short cpbegin
cmp byte ptr cs:mblg,81h
jnz short nrpdies
mov cx,cs:cx_max
mov di,cs:dis_begin_81
mov cs:dis_begin,di
mov di,cs:di_begin_81
mov cs:di_begin,di ; 恢复原来起始指针
jmp pdies
nrpdies:
jmp cppw_ok ; 整个词库搜索结束,转
cpbegin:
xor bx,bx ; 初始比较偏移长度
cmp byte ptr cs:mblg,80h ; 查联想字词
jae ishz_to
jmp chokok
ishz_to:
mov bx,cs:di_offset
mov al,cs:[bx]
cmp al,0A0h
ja short islxhz ; 搜索到第一个汉字开始
cmp byte ptr cs:mblg,81h
jnz short dincnx ; 非查找输入码
mov bx,offset my_bm ; cs:source_di
add bx,cs:mov_todi
mov cs:[bx],al
inc word ptr cs:mov_todi
dincnx:
call di_inc
jmp short ishz_to
islxhz:
mov ax,word ptr cs:[bx] ; +offset cz_buf]
add bx,2
cmp si,ax
jz short xdvc
nbmok:
jmp cnok ; 非联想字, 转
xdvc:
mov ah,cs:[bx] ; +offset cz_buf]
cmp byte ptr cs:mblg,81h
jnz short jbea0
cmp ah,0a0h
ja short nbmok ; 非单字,不是编码
ishvbm:
mov cx,cs:mov_todi ; CX=编码长度
cmp cx,cs:cx_max
jb short nbmok
mov cs:cx_max,cx
push si
mov si,offset my_bm
mov bx,cs:source_di
nxmytoy:
mov al,cs:[si]
mov ds:[bx],al
inc si
inc bx
loop nxmytoy
pop si
jmp short nbmok
jbea0:
cmp ah,0a0h
jbe short cnok ; 单汉字编码,无联想字词
sub bx,2
sub bx,cs:di_offset
jmp cppw_eq ; 否则联想字词找到,转
; -------------
chokok:
cmp al,'\'
jnz short cp10n
mov ah,al
call get_tuzm ; 转提示编码
mov bx,1
jmp cppw_eq
cp10n:
mov al,ds:[si+bx]
add bx,cs:di_offset
mov ah,cs:[bx] ; +offset cz_buf]
cmp ah,0a0h
ja short cnok ; 若非编码(为汉字),转不匹配处理
cmp al,'?' ; '/'
jz short mhdz ; 模糊单字母,直接相等
cmp al,'*' ; '?'
jz short x_d_x ; 以后字母模糊 "*.*"
and ax,5f5fh ; 转为小写字母比较
cmp al,ah
jnz short cnok
mhdz:
sub bx,cs:di_offset
inc bx
cmp bl,cs:mblg
jae short si_over
cmp byte ptr ds:[si+bx],'*' ;'?'
jnz short cp10n ; 下个字符是'?',模糊确定
add bx,cs:di_offset
mov ah,cs:[bx] ; +offset cz_buf]
dec bx ; jmp short xdx1
x_d_x:
call get_tuzm ; 转提示编码
x_d_xx:
inc bx ; BX 长度加到下个词汇开始
cmp byte ptr cs:[bx],0A1h ;+offset cz_buf],0A1h
jb short x_d_xx
sub bx,cs:di_offset
jmp short cppw_eq
cnok:
cnok_ct:
call di_inc ; 编码不匹配,继续找下一个
mov bx,cs:di_offset
cmp byte ptr cs:[bx],0A1h ; +offset cz_buf],0A1h
jb short cnok_ct
cnok_nx:
call di_inc
mov bx,cs:di_offset
mov al,cs:[bx] ; +offset cz_buf]
cmp al,0a0h
ja short cnok_nx
cmp byte ptr cs:mblg,80h ; 查联想字词,重码不跳过
jz short jcp_nxt
cmp al,'\' ; 查编码字词,跳过重码
jnz short jcp_nxt
cmp byte ptr cs:mblg,81h ; 查联想字词,重码不跳过
jnz short cnok_nx
cmp byte ptr cs:[bx+3],0A0h
ja short cnok_nx
mov ax,cs:[bx+1]
cmp si,ax
jnz short cnok_nx
jmp ishvbm
jcp_nxt:
jmp cp_nxt
; ------------------------------------------------------------
si_over:
add bx,cs:di_offset
cmp byte ptr cs:[bx],0A1h ; +offset cz_buf],0A1h
jb short cnok ; 词汇库中的词汇编码长度是否比较完毕
sub bx,cs:di_offset ; 没有,编码不匹配
cppw_eq:
or dl,dl
jnz short no_first
cmp byte ptr cs:mblg,80h
jz short no_first ; 联想方式, 不记录
cmp byte ptr cs:fun_aczy,80h
jz short y_first
cmp byte ptr cs:fun_aczy,83h
jnz short no_first
y_first:
mov cs:di_this,di
mov cs:es_this,es ;当前页第一词位置
mov word ptr cs:dis_begin,0
mov word ptr cs:di_begin,0
mov word ptr cs:dis_begin_81,0
mov word ptr cs:di_begin_81,0
no_first:
inc dl ; 匹配词汇加一
call di_addbx
mov si,di ; 编码匹配, SI 指向词汇
pop di
and word ptr ds:[di-2],7f7fh ; 前个重码尾部汉字
cp_eq1:
mov bx,cs:di_offset
mov al,cs:[bx] ; +offset cz_buf]
cmp byte ptr cs:mblg,80h ; 查联想字词
jz short ce_1
cmp al,'\'
jnz short ce_1
mov ah,al
call get_tuzm
cmp byte ptr cs:[bx+1],0A1h ; +(offset cz_buf+1)],0A1h
jb short noidl
cmp cl,cs:all_leng
jae short cppw_ok2
cmp dl,9
ja short cppw_ok2
inc dl ; 重码个数加 1
noidl:
and word ptr ds:[di-2],7f7fh ; 前个重码尾部汉字屏蔽掉高位
jmp short ce_2
ce_1:
cmp al,0a0h
jbe short cppw_ok2
mov ds:[di],al ; 词汇转移进 DS:DI
inc cl ; 长度加 1
inc di
ce_2:
call si_inc
jmp short cp_eq1
; ----------------------------------------------------------------
rep_di dw 0
rep_leng db 0
source_di dw 0
mov_todi dw 0
cx_max dw 0
my_bm db 12d dup(0)
cppw_ok2:
and word ptr ds:[di-2],7f7fh
cmp byte ptr cs:mblg,80h ; 查联想字词
jnz short cppw_ok_1
; ----------------------
; 取消重复联想字词子程序
pusha
push ds
push es
push ds
pop es
mov si,di
sub si,2
nssi2:
sub si,2
cmp si,cs:source_di
jbe short okcim
mov ax,ds:[si]
test ax,8080h
jnz short nssi2
add si,2
mov cs:rep_di,si ; 本联想字词开始地址
mov cx,di
sub cx,si
mov cs:rep_leng,cl ; 本联想字词长度
mov di,cs:source_di
cpniml:
push cx
push di
push si
rep cmpsb
pop si
pop di
pop cx
jz short ok_subim ; 前面已有,转取消本字词
addi2ok:
add di,2
mov ax,ds:[di]
test ax,8080h
jnz short addi2ok
add di,2
cmp di,si
jae short okcim
jmp short cpniml
ok_subim:
pop es
pop ds
popa
mov di,cs:rep_di
sub cl,cs:rep_leng
dec dl
jmp short cppw_ok_1
okcim:
pop es
pop ds
popa
; ----------------------
cppw_ok_1:
push di
mov cs:di_buf,di ; 保存当前的 DS:DI 指针
mov di,si ; DI = SI (词汇库当前指针)
cmp cl,cs:all_leng
jae short cppw_ok ; 词汇总长度超过30,返回
cmp dl,9
ja short cppw_ok
jmp cp_nxt ; 找下一个相同的编码
; ----------------------------------------------------------------------
cppw_ok:
mov cs:dis_continue,es
mov cs:di_continue,di ; 保存当前词汇库指针
cmp dl,1
jae short cppw_ok_2 ; 无重码, 直接返回
mov di,cs:dis_begin_81
mov cs:dis_begin,di
mov di,cs:di_begin_81
mov cs:di_begin,di ; 无码返回, 恢复原来起始指针
cppw_ok_2:
xor al,al
mov bx,cs:dis_begin
or bx,bx
jnz short pdies
mov bx,cs:di_begin
or bx,bx
jnz short pdies
mov al,1 ; 当前在第一页,AL=1,否则AL=0
pdies:
pop di
pop es
cmp word ptr cs:EMB_Sr_hand,0
jnz short nclose
cmp byte ptr cs:dgdy,0
jnz short nclose
push ax
mov bx,cs:file_hand
mov ah,3eh
int 21h
pop ax
nclose:
iret
; --------------------------
get_tuzm:
push si
push dx
mov si,cs:tuzm_add
xor dh,dh
add si,dx
cmp ah,0a0h
jbe short vjt
mov ah,"~"
jmp short vjt2
vjt:
cmp ah,'\'
jnz short vjt1
mov ah,byte ptr cs:just_tuzm
jmp short vjt2
vjt1:
and ah,5fh
add ah,20h ; 转为小写字母
vjt2:
mov byte ptr ds:[si],ah ; 填写替代码
mov byte ptr cs:just_tuzm,ah
pop dx
pop si
retn
; 移动词库指针到指定的搜索32位指针处(ES:DI)
; -----------------------------------------
move_to_esdi:
push ds
pusha
push cs
pop ds
mov dx,di
mov cx,es
add dx,12d ; 词库文件头长度 12 Bytes
adc cx,0
mov cure_cx,cx
mov cure_dx,dx
cmp word ptr EMB_Sr_hand,0
jz short isfile
; 从 XMS 中读出词库当前指针处的内容
mov word ptr EMB_Sr_offset,dx
mov word ptr EMB_Sr_offset+2,cx
mov word ptr EMB_count,1024d*1d
cmp cx,max_seg
jb short ms_cont
mov cx,max_off
sub cx,dx
test cx,1
jz short cxeuu
inc cx
cxeuu:
cmp cx,1024d*1d
jae short ms_cont
mov word ptr EMB_count,cx
ms_cont:
mov si,offset EMB_count
mov ah,0Bh
call cs:XMS_Entry
or ax,ax
jnz short okax
sub word ptr EMB_count,2
jmp short ms_cont
okax:
mov ax,word ptr EMB_count
jmp short move_end
isfile:
mov bx,file_hand
mov ax,4200h
int 21h ; 移动指针 -> ES:DI
mov ah,3fh
mov bx,file_hand
mov cx,1024d*1d
mov dx,offset cz_buf
int 21h
move_end:
mov word ptr di_offset,offset cz_buf ;0; 初始缓冲区记数为0
popa
pop ds
retn
si_inc:
inc si
jnz short nises
push si
mov si,es
inc si
mov es,si
pop si
nises:
inc word ptr cs:di_offset
cmp word ptr cs:di_offset,offset cz_buf+1024d*1d-20d
jb short diinc_ret
push di
mov di,si
call move_to_esdi
pop di
retn
di_inc:
inc di
jnz short nies
push di
mov di,es
inc di
mov es,di
pop di
nies:
inc word ptr cs:di_offset
cmpczof:
cmp word ptr cs:di_offset,offset cz_buf+1024d*1d-20d
jb short diinc_ret
call move_to_esdi
diinc_ret:
retn
di_addbx:
add di,bx
jnc short naes
push di
mov di,es
inc di
mov es,di
pop di
naes:
add word ptr cs:di_offset,bx
jmp short cmpczof
lodsw_hz:
lodsw
cmp byte ptr cs:i66c65,0
jz short lbsw
sub cl,2
retn
lbsw:
xor ah,ah
dec cl
jz short cl0ret
cmp al,0A0h
jbe short lodsw_hz
mov ah,ds:[si]
inc si
inc si
dec cl
jz short cl0ret
cmp ah,0A0h
jbe short lodsw_hz
cl0ret:
retn
; 取汉字编码子程序(AX=汉字内码,DS:DI=编码转移地址)
get_cbm:
push cx
push ds
push si
push cs
pop ds
mov si,ax ; SI=汉字码
mov cl,81h ; CL=81h
mov ah,80h ; AH=80h
mov al,cs:pre_al ; AL=当前输入法号
push di
push bx
pushf
call cs:int66h
pop bx
pop di
pop si
pop ds
add di,cx
mov byte ptr cs:[di],0 ; 无编码,置为0
sub di,cx
nz00:
pop cx
retn
nxf1c:
or cl,cl
jz short endf1c
mov al,cs:[si]
or al,al
jz short endf1c
mov ds:[bx],al
inc bx
inc si
dec cl
jmp short nxf1c
endf1c:
retn
cbm1 db 13d dup(0)
cbm2 db 13d dup(0)
cbm3 db 13d dup(0)
cbm4 db 13d dup(0)
di_tmp dw 0
i66c65 db 0
;---------------------
; AH=0取词,=1返回当前输入法号->AL,输入法名称->DS:SI
; DS:SI = 词汇屏幕地址
; DS:BX = 词汇编码地址
; CL = 词汇长度
; CH = 词汇编码长度(CH=0时,返回自动编码)
;---------------------
int65:
cld
or ah,ah
jz short isqcok
mov al,cs:pre_al
push cs
pop ds
mov si,offset in_name
iret
isqcok:
pusha
push es
push ds
or ch,ch
jz short isself_bm
jmp nselfbm ; CH>0, 表示有自定义编码
; 自动编码+(')
isself_bm:
push cx
push si
push bx
mov byte ptr cs:cbm1[0],0
mov byte ptr cs:cbm2[0],0
mov byte ptr cs:cbm3[0],0
mov byte ptr cs:cbm4[0],0
mov ch,cl ; CH=CL
call lodsw_hz
mov di,offset cbm1 ; 首汉字
call get_cbm
or cl,cl
jz short end_offhzbm
call lodsw_hz
mov di,offset cbm2 ; 第二个汉字
call get_cbm
or cl,cl
jz short end_offhzbm
call lodsw_hz
mov di,offset cbm3 ; 第三个汉字
call get_cbm
or cl,cl
jz short end_offhzbm
clnhz:
call lodsw_hz
or cl,cl
jnz short clnhz
mov di,offset cbm4 ; 末汉字
call get_cbm
end_offhzbm:
cmp ch,8
jae short is_mode1 ; 多字词,转
cmp ch,4
jz short is2zc ; 2字词
cmp ch,2
ja short n1zc
mov si,offset cbm1
mov cl,10d
call nxf1c ; 单汉字
jmp endsch
is_mode1:
mov si,offset cbm1 ; 多字词
mov cl,1
call nxf1c
mov si,offset cbm2
mov cl,1
call nxf1c
mov si,offset cbm3
mov cl,1
call nxf1c
mov si,offset cbm4
mov cl,1
call nxf1c
jmp endsch
is2zc:
cmp byte ptr cs:in_zymi,4
jbe short mizd4
mov cl,10d ; 码长超出4码的,2字词取全码
mov si,offset cbm1
call nxf1c
mov si,offset cbm2
call nxf1c
jmp endsch
mizd4:
mov si,offset cbm1
mov cl,2 ; 2字词
call nxf1c
mov si,offset cbm2
mov cl,2
call nxf1c
jmp short endsch
n1zc:
cmp byte ptr cs:in_zymi,4
jbe short mizd4_3z
mov si,offset cbm1 ; 最大码长超出4码的,3字词各取首码
mov cl,1
call nxf1c
mov si,offset cbm2
mov cl,1
call nxf1c
mov si,offset cbm3
mov cl,1
call nxf1c
jmp short endsch
mizd4_3z:
test byte ptr cs:in_if_09,20h
jnz short is3zc ; 3字词,首字头两码,转
mov si,offset cbm1 ; 否则,末字头两码
mov cl,1