clippy
Junior Member
Posts: 32
|
Post by clippy on Oct 25, 2007 21:34:24 GMT
I tried using QB.BI for interrupt routines and then tried an experiment. I Edited QB.BI to have only the RegTypeX definition in it. I also took the X off of the Type name and called it RegType.BI.
I later used '$INCLUDE: 'RegType.BI' and never even used InterruptX again! Just plain Interrupt just does all of the things that InterruptX used to do! My RegType includes DS and ES.
I also found that the SUB declarations for both are already defined in the library and are not needed in QB.BI at all! In fact, if you DECLARE the Interrupts, it says the SUB is already defined.
Any comments?
|
|
|
Post by Mikrondel on Oct 27, 2007 4:05:47 GMT
There's a simple answer, Ted, and that's that RegTypeX is simply RegType with two extra entries at the end. The INTERRUPT subroutine is given the memory address of the beginning of a RegTypeX; it couldn't care less whether this memory address contained a RegType or a quote from Shakespeare; it's been designed with RegType in mind and it'll place the first two bytes in AX, the second two in BX, etc.; the 13th and 14th bytes go in DI, and the next two get sifted into the processor flags. (And after the interrupt is called the whole procedure is reversed.)
Now, RegTypeX just happens to be laid out the same way, except with four extra bytes afterwards. INTERRUPT doesn't expect them to be there and certainly doesn't touch them; for all it knows there could be something vital stored there. It just goes about its business and ignores the DS and ES members of the RegTypeX.
The lesson to be learned here is that data types are just an abstraction; they simply inform the compiler what set of instructions to use when you want to manipulate the data. When you do x+y and both are INTEGERs, the processor will use the processor's ADD instruction. If they are both LONGs, it will use something more complex probably involving an ADD and an ADC (add with carry) instruction. If they are both SINGLEs, still more complex stuff occurs. And if they are both strings! That results in a more complicated procedure call to QB's string library.
It's a lot like file formats; you can read any file byte by byte; but to get true meaning you need to know how to interpret the data.
|
|
clippy
Junior Member
Posts: 32
|
Post by clippy on Oct 27, 2007 19:55:43 GMT
Well, your explanation was very good except for one thing.
I can use INTERRUPT instead of INTERRUPTX to access those last four bites. I don't use INTERRUPTX any more in routines written specifically for INTERRUPTX. So, why does it work?
It appears to not matter. Also remember that my RegType.BI file has no declarations in it at all. The original QB.BI however does!
Ted
|
|
|
Post by Mikrondel on Oct 27, 2007 20:51:49 GMT
I really doubt it. If you're successfully using routines that require DS or ES to be set to something, I would be quite surprised. But just because something uses INTERRUPTX doesn't mean it uses DS or ES.
Please show me if you have anything that does make use of them and still works...
|
|
clippy
Junior Member
Posts: 32
|
Post by clippy on Oct 28, 2007 7:51:12 GMT
FUNCTION GetDir$ (Drive$) DIM Registers AS RegType STATIC Temp$, Drive, Zero 'local variables IF Drive$ > CHR$(64) AND Drive$ < CHR$(91) THEN Drive = ASC(UCASE$(Drive$)) - 64 'convert to DOS drive number END IF Temp$ = SPACE$(65) 'DOS stores the name here Registers.AX = &H4700 'get directory service Registers.DX = Drive 'set the drive Registers.SI = SADD(Temp$) 'show DOS where Temp$ is 'Registers.DS = SSEG(Temp$) 'use this with BASIC PDS Registers.DS = -1 'use this with QuickBASIC CALL Interrupt(&H21, Registers, Registers) 'call DOS IF Registers.Flags AND 1 THEN 'find an invalid drive GetDir$ = "" 'returns a null string if invalid ELSE : Zero = INSTR(Temp$, CHR$(0)) 'find the zero byte GetDir$ = Drive$ + ":\" + LEFT$(Temp$, Zero - 1) 'Valid drive END IF END FUNCTION
Keep in mind that my RegType includes DS and ES like the X Type. Below is part of another routine. The PrintDTA SUB just displays the file information from the DTA Type defined values for time, date stamp and size.
Regs.AX = &H1A00 Regs.DX = VARPTR(DTA) 'Set DTA (Place where the info about each file goes) Regs.DS = VARSEG(DTA) CALL Interrupt(&H21, Regs, Regs) 'int 33 Regs.AX = &H4E00 Regs.CX = 1 + 2 + 4 + 16 + 32 Regs.DX = VARPTR(FSpec$) 'f CALL Interrupt(&H21, Regs, Regs) VIEW PRINT 25 TO 27 Count = 0 DO WHILE (Regs.AX AND 255) = 0 'end program at last file or directory Count = Count + 1 GOSUB PrintDTA 'SUB call FOR Row = 25 TO 27 COLOR 11: LOCATE Row, 1: PRINT CHR$(179); LOCATE Row, 80: PRINT CHR$(179); NEXT Row DO: K$ = INKEY$: LOOP UNTIL LEN(K$) 'pause to next file IF K$ = CHR$(27) THEN BEEP: EXIT DO 'end routine CLS 2 Regs.AX = &H4F00 Regs.CX = 1 + 2 + 4 + 16 + 32 CALL Interrupt(&H21, Regs, Regs) LOOP IF (Regs.AX AND 255) <> 0 THEN LOCATE 25, 32: COLOR 12: IF Count THEN PRINT " END of Files! ": SOUND 700, 4 ELSE : PRINT "NO FILES FOUND!": SOUND 800, 4 END IF END IF
I was surprised about all of this, but it sure seems to work for me. Try it and let me know what you think and if you figure a way it won't work. I did not have to use ES yet.
Ted
|
|
clippy
Junior Member
Posts: 32
|
Post by clippy on Oct 30, 2007 14:59:26 GMT
I did find one thing that may give a clue.
First let me tell you the process I use: 1) Made a new RegType.BI file with a RegType including DS an ES, but no Interrupt declarations 2) 'INCLUDE: 'RegType.BI' 3) DIM SHARED Regs AS RegType (could use InRegs and OutRegs also) 4) CALL Interrupt ONLY. Just Interrupt will NOT work!
I found that I MUST use CALL! I think that it is the only way that the Library will know to DECLARE it. Without CALL, the IDE says "Procedure undefined". I cannot DECLARE an Interrupt in the procedure either. IDE says "Procedure already Declared in Quick Library". The only place that it could be declared is in the QB4.5 Library itself.
Now I am debating, placing an Interrupt SUB declaration in RegType.BI although I prefer CALL anyhow.
Ted
|
|
|
Post by Mikrondel on Oct 30, 2007 22:55:08 GMT
Sorry, just dumb luck.
This line: Registers.DS = -1 'use this with QuickBASIC in the context of CALL INTERRUPTX, means "leave DS as the default". In the context of CALL INTERRUPT, it is ignored... so guess what, DS is already set to the default.
And in the second routine:
Regs.DS = VARSEG(DTA)
Again, I have a strong feeling that VARSEG(DTA) just ends up being the same as the default DS. So when you CALL INTERRUPT, Regs.DS is ignored but the real DS value is already correct anyway. VARSEG(DTA) depends a little bit on where and how you DIM DTA, but most of the time it will be DGROUP.
DGROUP is where most of QB's variables (and in the case of QB4.5, strings) go, and DS is set to this by default.
Gotta dash but I'll say more when I get back.
|
|
clippy
Junior Member
Posts: 32
|
Post by clippy on Oct 31, 2007 4:29:37 GMT
OK find a real Interrupt procedure using DS and ES. Try my way and let me know. You may be right, but I doubt it. I have searched for all of them I can get LOL and even have one from M$. I also wonder why I cannot DECLARE Interrupt in a procedure I get from the web. I have to take it out of the code for a lot of routines. The Interrupt "procedure is already defined in the Quick Library" so it says. So I cannot declare it and my RegType.BI does not either! Here is another procedure that used InterruptX and DS two times differently: FUNCTION FileExist% (Spec$) FnFileExist% = -1 'assume the file exists R.DX = VARPTR(DTAData) 'set a new DOS DTA R.DS = VARSEG(DTAData) R.AX = &H1A00 CALL Interrupt(&H21, R, R) 'DOS interrupt Spec$ = Spec$ + CHR$(0) 'DOS needs an ASCIIZ string R.AX = &H4E00 'find file name service R.CX = 39 'attribute for any file R.DX = SADD(Spec$) 'show where the spec is ' R.DS = SSEG(Spec$) 'use this with BASIC PDS R.DS = VARSEG(Spec$) 'use this with QuickBASIC CALL Interrupt(&H21, R, R) 'DOS iterrupt IF (R.Flags AND 1) THEN FnFileExist% = 0 END FUNCTION My plan is to use Interrupt to avoid QuickBasic and DOS file errors. I also see potential to send data to a parallel port printer in XP without the limitations sometimes created in LPRINT using another routine for LPT ports. Ted
|
|
|
Post by Mikrondel on Nov 4, 2007 22:41:58 GMT
Yet again, under QB4.5, both VARSEGs will end up as the default segment. Under PDS, the second one (the string one) won't, because strings are stored outside the DGROUP segment, and hence I predict this routine does not work in PDS.
Try finding a routine that uses ES. I have a strong feeling it will not work unless you use INTERRUPTX.
EDIT: Try a routine that returns something into DS or ES. Those will definitely not work.
|
|
clippy
Junior Member
Posts: 32
|
Post by clippy on Nov 5, 2007 18:14:32 GMT
I just redid many of my Interrupt routines so that User or program entries are fixed length strings. Thus I was able to eliminate SADD and SSEG differences for QB1 and PDS. It also eliminated DS in some routines alltogether.
I guess you were correct about the need for DS at all in those routines. Thanks to Ildurest for his help on PDS code! Most of my code was taken from Ethan Winer's book, which is somewhat dated.
I would appreciate any Interrupt routines that require DS or ES to experiment with.
Thanks, Ted
|
|
|
Post by Ronaldsed on May 16, 2019 14:47:48 GMT
Hi, so here is a website that will give you free coupons for some hot deals Click here>>>
|
|
|
Post by Ronaldsed on May 17, 2019 22:29:28 GMT
Hi, so here is a website that will give you free coupons for some hot deals Click here!..
|
|
|
Post by uquwuli on Jun 20, 2019 17:48:22 GMT
|
|
|
Post by ewamivihatjad on Jun 20, 2019 20:08:35 GMT
|
|
|
Post by aerorpsot on Aug 4, 2020 10:06:44 GMT
Buy Generic Viagra Overnight Shipping moogsFuh Cialis Flenomum Propecia Dosage Directions esonarAssose <a href=https://ascialis.com/#>is there a generic cialis available</a> Fruile Cialis Costo Farmacia
|
|