'程序一
''$INCLUDE: "QB.BI" '此行QBASIC中无效,故行首加'
' 在 QBASIC 中,我们可以用
' DEF SEG = 汇编子程序段地址%
' CALL ABSOLUTE (中断号%,
' inreg AS RegTypeX,
' outreg AS RegTypeX
' 汇编子程序偏移地址%)
'
' 入口:
' 中断号% = 0 到 255
' inreg 和 outreg 为寄存器变量, 必须事先申明作自定义数据类型
' RegTypeX, 方法如下:
'
'自定义变量类型申明
'TYPE RegTypeX
' AX AS INTEGER
' BX AS INTEGER
' CX AS INTEGER
' DX AS INTEGER
' BP AS INTEGER
' SI AS INTEGER
' DI AS INTEGER
' FLAGS AS INTEGER
' DS AS INTEGER
' ES AS INTEGER
'END TYPE
'
' 技巧:
' 如果有必须保留值的寄存器变量, 只要将相应的INreg/OUTreg赋值为 -1,
' 或 NA [= Non-Applicable未使用, 但是要先有 CONST NA = -1 行], 即可.
'
' 出口:
' 若成功:
' 中断号% = 值不变 (0 到 255)
' outreg: 成为调用后寄存器值的保存数组. 其结构同 inreg.
' 若出错:
' 中断号% = -1
' outreg 不变. 不执行中断调用.
' 出错情况:
' 第一个参数值不在 0 到 255 (2^8-1) 范围中
' 第二,三个参数值不在 0 到 1048575 (2^20-1) 范围中
' (VARPTR 的值总是不出这个范围)
'
' 寄存器的变动情况:
' 全部, 除 BP%, DS%, 和 flags (标志寄存器).
' 当然, 也不能避免中断调用本身带来的副作用.
'
' 例外情况:
' 可能出现调用 INT 21H MS-DOS 某些功能时带出的INT 24H 调用.
'自定义变量类型申明
TYPE RegTypeX
ax AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
'汇编子程序申明: 注意REM掉的申明与再下一行在数量和类型上的差异.
'实际使用时,应以一段程序内所有调用中最大的参数数量来进行,类型应申明作ANY,
'这样,% & ! # $各种类型的数据都可以作为实参进行调用了.
'但是,调用时若汇编子程序的参数数量不足最大值,一定要注意形参表中虚实参数的
'对应关系和数量差异,具体操作,请注意本程序的做法.
'DECLARE SUB ABSOLUTE (IntNo%, INreg AS RegTypeX, OUTreg AS RegTypeX, OfsAddr%)
'DECLARE SUB ABSOLUTE (P1%, P2%, numberInWord%, nTHbitFlag%, OfsAddr%)
DECLARE SUB ABSOLUTE (P1 AS ANY, P2 AS ANY, P3 AS ANY, P4 AS ANY, OfsAddr%)
DECLARE FUNCTION SADDr% (SSEGm%, s$)
DECLARE SUB InterruptX (IntNo%, InRegs AS ANY, OutRegs AS ANY)
DECLARE SUB Mouse (aax%, bbx%, ccx%, ddx%)
'常量申明
CONST NA = -1
'变量的自定义类型申明
DIM SHARED INreg AS RegTypeX
DIM SHARED OUTreg AS RegTypeX
'汇编子程序的数组定义
ASMnBytes = 260 '汇编子程序的的字节型长度
DIM SHARED intrpt%(INT(ASMnBytes / 2 + .5)) '使它成为字型长度,偶数化字节数量
RESTORE intrptData ' 数据指针指向intrptData汇编程序代码区
'poke 到内存中
DEF SEG = VARSEG(intrpt%(0)) ' 改段址.
intPtr% = VARPTR(intrpt%(0))
FOR i% = 0 TO ASMnBytes - 1
READ vlu$: POKE intPtr% + i%, VAL("&H" + vlu$)
NEXT
DEF SEG
intrptData: '= 260 字节
DATA 55,8B,EC,83,C4,E2,C7,46,FA,0A,00,89,76,E4,89,7E
DATA E2,8C,5E,FC,9C,8F,46,FE,8B,76,08,8D,7E,E6,8B,4E
DATA FA,FC,16,07,F3,A5,55,8B,76,0A,8B,1C,0A,FF,0F,84
DATA 03,00,E9,B9,00,80,FB,25,0F,84,07,00,80,FB,26,0F
DATA 85,0E,00,B8,08,00,50,B8,02,CA,50,B8,83,C4,50,EB
DATA 07,33,C0,50,B8,CA,06,50,8A,E3,B0,CD,50,0E,B8,A5
DATA 00,50,16,8B,C4,05,06,00,50,8B,46,F4,25,D5,0F,50
DATA 8B,46,E6,8B,5E,E8,8B,4E,EA,8B,56,EC,8B,76,F0,8B
DATA 7E,F2,83,7E,FA,08,0F,84,16,00,83,7E,F6,FF,0F,84
DATA 03,00,8E,5E,F6,83,7E,F8,FF,0F,84,03,00,8E,46,F8
DATA 8B,6E,EE,9D,CB,55,8B,EC,8B,6E,02,9C,8F,46,F4,FF
DATA 76,FE,9D,89,46,E6,89,5E,E8,89,4E,EA,89,56,EC,8B
DATA 46,DE,89,46,EE,89,76,F0,89,7E,F2,8C,5E,F6,8C,46
DATA F8,8E,5E,FC,8D,76,E6,1E,07,8B,7E,06,8B,4E,FA,FC
DATA F3,A5,8B,76,E4,8B,7E,E2,8B,E5,5D,CA,06,00,8B,76
DATA 0A,C7,04,FF,FF,8B,76,E4,8B,7E,E2,8E,5E,FC,8B,E5
DATA 5D,CA,06,00
IF msFlag% = -1 THEN PRINT "跳过功能测试.": GOTO testBit
Mouse 1, -1, -1, -1
PRINT "鼠标已打开..."
SLEEP 2
Mouse 2, -1, -1, -1
PRINT "鼠标已关闭."
testBit:
ASMnBytes = 45
DIM SHARED tBit%(INT(ASMnBytes / 2 + .5))
DEF SEG = VARSEG(tBit%(0))
RESTORE tBitData
tPtr% = VARPTR(tBit%(0))
FOR i% = 0 TO ASMnBytes - 1
READ vlu$: POKE tPtr% + i%, VAL("&H" + vlu$)
NEXT
DEF SEG
tBitData: '=45 字节
DATA 55,8B,EC,8B,7E,08,8B,1D,8B,7E,06,8B,0D,32,ED,FE
DATA C9,E3,02,D3,C3,33,C0,F7,D3,F7,C3,00,80,74,02,EB
DATA 01,40,8B,7E,06,89,05,8B,E5,5D,CA,04,00
hzData:
DATA &H0004,&H7FFE,&H4444,&H4444,&H4444,&H7FFC,&H4204,&H0200
DATA &H07F0,&H0810,&H1420,&H62C0,&H0100,&H0600,&H1800,&HE000
RESTORE hzData
PRINT CHR$(13); "移位测值显示汉字:"; CHR$(13); " 罗 ="
P1% = -1
P2% = -1
OfsAddr% = VARPTR(tBit%(0))
DEF SEG = VARSEG(tBit%(0))
FOR i% = 1 TO 16
READ v%
FOR j% = 1 TO 16
jj% = j%
'原来 CALL testBitFlag (v%, jj%, OfsAddr%)
CALL ABSOLUTE(P1%, P2%, v%, jj%, OfsAddr%)
IF jj% THEN cc$ = "#" ELSE cc$ = "."
LOCATE i%, j% + 22: PRINT cc$;
NEXT
NEXT
DEF SEG