|
Home Site Structure Programming Home Basic Home GUI & OS Home QB Knowledge Base Professor Answers Codename Surena QB Downloads Write Us
Special LinksQB DirectoryNEW Codename Surena Forums |
|
||
How to imitate CALL INTERRUPT in QBASIC 1.1? 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 TYPE RegType AX AS INTEGER BX AS INTEGER CX AS INTEGER DX AS INTEGER BP AS INTEGER SI AS INTEGER DI AS INTEGER Flags AS INTEGER END TYPE ' 'This procedure works the same as INTERRUPT routine in later 'versions of QuickBASIC. ' 'Parameters: ' INTNUM: The interrupt number ' InRegs: The values of registers for the interrupt routine ' OutRegs: The values of the registers after calling the interrupt service ' SUB Interrupt (INTNUM AS INTEGER, InRegs AS RegType, OutRegs AS RegType) DIM asm AS STRING DIM code(0) AS INTEGER asm = asm + CHR$(&H50) 'push ax asm = asm + CHR$(&H53) 'push bx asm = asm + CHR$(&H51) 'push cx asm = asm + CHR$(&H52) 'push dx asm = asm + CHR$(&H56) 'push si asm = asm + CHR$(&H57) 'push di asm = asm + CHR$(&H55) 'push bp asm = asm + CHR$(&H1E) 'push ds asm = asm + CHR$(&HB8) + MKI$(InRegs.Flags) 'mov ax, inregs.flags asm = asm + CHR$(&H50) 'push ax asm = asm + CHR$(&HB8) + MKI$(InRegs.AX) 'mov ax, inregs.ax asm = asm + CHR$(&HBB) + MKI$(InRegs.BX) 'mov bx, inregs.bx asm = asm + CHR$(&HB9) + MKI$(InRegs.CX) 'mov cx, inregs.cx asm = asm + CHR$(&HBA) + MKI$(InRegs.DX) 'mov dx, inregs.dx asm = asm + CHR$(&HBE) + MKI$(InRegs.SI) 'mov si, inregs.si asm = asm + CHR$(&HBF) + MKI$(InRegs.DI) 'mov di, inregs.di asm = asm + CHR$(&HBD) + MKI$(InRegs.BP) 'mov bp, inregs.bp asm = asm + CHR$(&H9D) 'popf asm = asm + CHR$(&HCD) + CHR$(INTNUM) 'int intnum asm = asm + CHR$(&H50) 'push ax asm = asm + CHR$(&H53) 'push bx asm = asm + CHR$(&H9C) 'pushf asm = asm + CHR$(&H5B) 'pop bx asm = asm + CHR$(&HB8) + MKI$(VARSEG(OutRegs.Flags)) 'mov ax, varseg(outregs.flags) asm = asm + CHR$(&H8E) + CHR$(&HD8) 'mov ds, ax asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H1E) + MKI$(VARPTR(OutRegs.Flags)) 'mov ds:[varptr(outregs.flags)], bx asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H36) + MKI$(VARPTR(OutRegs.SI)) 'mov ds:[varptr(outregs.si)], si asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H3E) + MKI$(VARPTR(OutRegs.DI)) 'mov ds:[varptr(outregs.di)], di asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H2E) + MKI$(VARPTR(OutRegs.BP)) 'mov ds:[varptr(outregs.bp)], bp asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H16) + MKI$(VARPTR(OutRegs.DX)) 'mov ds:[varptr(outregs.dx)], dx asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&HE) + MKI$(VARPTR(OutRegs.CX)) 'mov ds:[varptr(outregs.cx)], cx asm = asm + CHR$(&H5B) 'pop bx asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H1E) + MKI$(VARPTR(OutRegs.BX)) 'mov ds:[varptr(outregs.bx)], bx asm = asm + CHR$(&H58) 'pop bx asm = asm + CHR$(&H3E) + CHR$(&HA3) + MKI$(VARPTR(OutRegs.AX)) 'mov ds:[varptr(outregs.ax)], ax asm = asm + CHR$(&H1F) 'pop ds asm = asm + CHR$(&H5D) 'pop bp asm = asm + CHR$(&H5F) 'pop di asm = asm + CHR$(&H5E) 'pop si asm = asm + CHR$(&H5A) 'pop dx asm = asm + CHR$(&H59) 'pop cx asm = asm + CHR$(&H5B) 'pop bx asm = asm + CHR$(&H58) 'pop ax asm = asm + CHR$(&HCB) 'retf REDIM code(LEN(asm) \ 2 + 1) AS INTEGER DEF SEG = VARSEG(code(0)) FOR i = 1 TO LEN(asm) POKE VARPTR(code(0)) + i - 1, ASC(MID$(asm, i, 1)) NEXT CALL Absolute(VARPTR(code(0))) END SUB ' 'This procedure works the same as INTERRUPTX routine in later 'versions of QuickBASIC. ' 'This routine, supports segment registers (DS and ES) in addition 'to the registers supported by INTERRUPT routine. ' 'Parameters: ' INTNUM: The interrupt number ' InRegs: The values of registers for the interrupt routine ' OutRegs: The values of the registers after calling the interrupt service ' SUB InterruptX (INTNUM AS INTEGER, InRegs AS RegTypeX, OutRegs AS RegTypeX) DIM asm AS STRING DIM code(0) AS INTEGER asm = asm + CHR$(&H50) 'push ax asm = asm + CHR$(&H53) 'push bx asm = asm + CHR$(&H51) 'push cx asm = asm + CHR$(&H52) 'push dx asm = asm + CHR$(&H56) 'push si asm = asm + CHR$(&H57) 'push di asm = asm + CHR$(&H55) 'push bp asm = asm + CHR$(&H6) 'push es asm = asm + CHR$(&H1E) 'push ds asm = asm + CHR$(&HB8) + MKI$(InRegs.Flags) 'mov ax, inregs.flags asm = asm + CHR$(&H50) 'push ax asm = asm + CHR$(&HB8) + MKI$(InRegs.DS) 'mov ax, inregs.ds asm = asm + CHR$(&H8E) + CHR$(&HD8) 'mov ds, ax asm = asm + CHR$(&HB8) + MKI$(InRegs.ES) 'mov ax, inregs.es asm = asm + CHR$(&H8E) + CHR$(&HC0) 'mov es, ax asm = asm + CHR$(&HB8) + MKI$(InRegs.AX) 'mov ax, inregs.ax asm = asm + CHR$(&HBB) + MKI$(InRegs.BX) 'mov bx, inregs.bx asm = asm + CHR$(&HB9) + MKI$(InRegs.CX) 'mov cx, inregs.cx asm = asm + CHR$(&HBA) + MKI$(InRegs.DX) 'mov dx, inregs.dx asm = asm + CHR$(&HBE) + MKI$(InRegs.SI) 'mov si, inregs.si asm = asm + CHR$(&HBF) + MKI$(InRegs.DI) 'mov di, inregs.di asm = asm + CHR$(&HBD) + MKI$(InRegs.BP) 'mov bp, inregs.bp asm = asm + CHR$(&H9D) 'popf asm = asm + CHR$(&HCD) + CHR$(INTNUM) 'int intnum asm = asm + CHR$(&H50) 'push ax asm = asm + CHR$(&H53) 'push bx asm = asm + CHR$(&H9C) 'pushf asm = asm + CHR$(&H5B) 'pop bx asm = asm + CHR$(&HB8) + MKI$(VARSEG(OutRegs.Flags)) 'mov ax, varseg(outregs.flags) asm = asm + CHR$(&H8E) + CHR$(&HD8) 'mov ds, ax asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H1E) + MKI$(VARPTR(OutRegs.Flags)) 'mov ds:[varptr(outregs.flags)], bx asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H36) + MKI$(VARPTR(OutRegs.SI)) 'mov ds:[varptr(outregs.si)], si asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H3E) + MKI$(VARPTR(OutRegs.DI)) 'mov ds:[varptr(outregs.di)], di asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H2E) + MKI$(VARPTR(OutRegs.BP)) 'mov ds:[varptr(outregs.bp)], bp asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H16) + MKI$(VARPTR(OutRegs.DX)) 'mov ds:[varptr(outregs.dx)], dx asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&HE) + MKI$(VARPTR(OutRegs.CX)) 'mov ds:[varptr(outregs.cx)], cx asm = asm + CHR$(&H5B) 'pop bx asm = asm + CHR$(&H3E) + CHR$(&H89) + CHR$(&H1E) + MKI$(VARPTR(OutRegs.BX)) 'mov ds:[varptr(outregs.bx)], bx asm = asm + CHR$(&H58) 'pop bx asm = asm + CHR$(&H3E) + CHR$(&HA3) + MKI$(VARPTR(OutRegs.AX)) 'mov ds:[varptr(outregs.ax)], ax asm = asm + CHR$(&H8C) + CHR$(&HC0) 'mov ax, es asm = asm + CHR$(&H3E) + CHR$(&HA3) + MKI$(VARPTR(OutRegs.ES)) 'mov ds:[varptr(outregs.es)], ax asm = asm + CHR$(&H8C) + CHR$(&HD8) 'mov ax, ds asm = asm + CHR$(&H3E) + CHR$(&HA3) + MKI$(VARPTR(OutRegs.DS)) 'mov ds:[varptr(outregs.ds)], ax asm = asm + CHR$(&H1F) 'pop ds asm = asm + CHR$(&H7) 'pop es asm = asm + CHR$(&H5D) 'pop bp asm = asm + CHR$(&H5F) 'pop di asm = asm + CHR$(&H5E) 'pop si asm = asm + CHR$(&H5A) 'pop dx asm = asm + CHR$(&H59) 'pop cx asm = asm + CHR$(&H5B) 'pop bx asm = asm + CHR$(&H58) 'pop ax asm = asm + CHR$(&HCB) 'retf REDIM code(LEN(asm) \ 2 + 1) AS INTEGER DEF SEG = VARSEG(code(0)) FOR i = 1 TO LEN(asm) POKE VARPTR(code(0)) + i - 1, ASC(MID$(asm, i, 1)) NEXT CALL Absolute(VARPTR(code(0))) END SUB For using these routines, you should declare a variable of type RegType (or RegTypeX) to set the values of the registers. You may also declare another variable of this type (or you may use the same variable) to receive the value of the registers after calling the interrupt service. To get the above code in a BAS file, as well as an example of using the routines, you can download intrpt.zip. |