alf@edstip.EDS.COM (John Hamill) (07/15/89)
I am writing a MASM program for the IBM PC CGA monitor. I am setting the
stack pointer to the screen memory and using PUSHes to move data to this
area of the screen. This works fine for the whole screen, but when I
do a small rectangle area there is a problem. The problem is: I think
the computer is doing an interupt and pushing and poping from the stack,
which is the screen, so now there is garbage on the screen. This doesn't
happen when I do the whole screen becouse I write over the whole screen and
this writes over the garbage. Is there a way to make the computer not do
any interupts while I'm doing this screen push? Any other comments would
be helpful. I am doing this form of screen update becouse it is very very
fast, and I don't want to see the screen being painted, I want the screen
to snap to a new image.
--
/~~| |\ |\ John W. Hamill, EDS `""""""" UUCP: ...!uunet!edsews!edstip!alf
| | |/ |/ 1400 N. Woodward Ave (. (. > alf@edstip.EDS.COM
\__\_/^\_/|\_/ Bloomfield Hills, Voice:(313)645-4524 Fax:645-4824
\/ MI 48013 * The above are my views only!!
wiml@blake.acs.washington.edu (William Lewis) (07/15/89)
In article <313@edstip.EDS.COM> alf@edstip.EDS.COM (John Hamill) writes: >I am writing a MASM program for the IBM PC CGA monitor. I am setting the >stack pointer to the screen memory and using PUSHes to move data to this >area of the screen. This works fine for the whole screen, but when I >do a small rectangle area there is a problem. The problem is: I think >the computer is doing an interupt and pushing and poping from the stack, >which is the screen, so now there is garbage on the screen. This doesn't >happen when I do the whole screen becouse I write over the whole screen and >this writes over the garbage. Is there a way to make the computer not do >any interupts while I'm doing this screen push? Any other comments would >be helpful. I am doing this form of screen update becouse it is very very >fast, and I don't want to see the screen being painted, I want the screen >to snap to a new image. I've seen this question several times just recently. It makes me wonder how well people read manuals. There are two ways around this problem that just spring to mind. The first way is just enlarging on the kludge of PUSHing to screen memory. (Ugh!). "Is there a way to make the computer not do any interrupts while I'm doing this screen push?". Yes: turn off the interrupts! This is done with the "CLI" instruction. But remember to turn 'em back on with "STI". (Those are CLear Interrupt flag, and STart Interrupts.) The second way is what you should have done in the first place. Use a REP MOVSB (or REP MOVSW or...) instruction. Not only is this instruction uninterruptible (on mostm processors), but it is also faster. Not only that, but you are using "the right opcode for the job", which tends to get better results. setflame(0); /* end of message clean-up */ --- phelliax "<incoherent>"
chasm@attctc.DALLAS.TX.US (Charles Marslett) (07/17/89)
In article <2820@blake.acs.washington.edu>, wiml@blake.acs.washington.edu (William Lewis) writes: > The first way is just enlarging on the kludge of PUSHing to screen memory. > (Ugh!). "Is there a way to make the computer not do any interrupts while > I'm doing this screen push?". Yes: turn off the interrupts! This is done with > the "CLI" instruction. But remember to turn 'em back on with "STI". (Those > are CLear Interrupt flag, and STart Interrupts.) > The second way is what you should have done in the first place. Use > a REP MOVSB (or REP MOVSW or...) instruction. Not only is this instruction > uninterruptible (on mostm processors), but it is also faster. Not only > that, but you are using "the right opcode for the job", which tends > to get better results. "Read the manual" applies to this comment as well. See page 17-140 in the 386 Programmer's Ref. Manual from intel. (I don't have the 8088 or 286 books handy, but I believe they have identical, or at least equivalent, language describing interrupts and the REP instructions. To do a REP STOSB or REP MOVSB with interrupts off you had better bracket it with a CLI and an STI just like the code above. On the other hand, interrupts don't modify the memory pointed to by ES:DI (usually ;^). One final point, the CLI disables normal interrupts, not NMIs. If you have an odd computer that uses NMI for any normal operation, you may need to go through some gyrations to disable and reenable them too. (IBM's micro- channel computers and Tandy's old 1000 are two cases that come to mind.) > --- phelliax Charles Marslett chasm@attctc.dallas.tx.us
cliff@ficc.uu.net (cliff click) (07/17/89)
In article <2820@blake.acs.washington.edu>, wiml@blake.acs.washington.edu (William Lewis) writes: > [...] a REP MOVSB (or REP MOVSW or...) instruction. Not only is this > instruction uninterruptible (on most processors), [...] Actually it *IS* interruptable on all processors that have it (i.e. i80x86), however the return from interrupt will pick the block move back up where it left off - it works just fine in the presence of interrupts. -- Cliff Click, Software Contractor at Large Business: uunet.uu.net!ficc!cliff, cliff@ficc.uu.net, +1 713 274 5368 (w). Disclaimer: lost in the vortices of nilspace... +1 713 568 3460 (h).
buck@siswat.UUCP (A. Lester Buck) (07/18/89)
In article <2820@blake.acs.washington.edu>, wiml@blake.acs.washington.edu (William Lewis) writes: > > I've seen this question several times just recently. It makes me > wonder how well people read manuals. There are two ways around this problem > that just spring to mind. > > The second way is what you should have done in the first place. Use > a REP MOVSB (or REP MOVSW or...) instruction. Not only is this instruction > uninterruptible (on mostm processors), but it is also faster. You obviously don't read the manual yourself. From iAPX86/88, 186/188 User's Manual, Hardware Reference, p 3-31: "Repeated string sequences are interruptable; the processor recognizes the interrupt before processing the next string element. System interrupt processing is not affected in any way. Upon return from the interrupt, the repeated operation is resumed from the point of interruption." An interrupt is not recognized between the REP prefix and the MOVSB, of course. -- A. Lester Buck ...!texbell!moray!siswat!buck
d88-eli@nada.kth.se (Erik Liljencrantz) (07/18/89)
About the REP MOVSW: It is interuptable, and it does resume after an interrupt accured, but don't use a segment override prefix! It works fine to move from DS:[SI] to ES:[DI], and it's possible to override a single MOVSW to use CS, ES or SS as it's sourcesegment, but never use both REP and segment override! The segment prefix are forgotten if an interrupt occurs! BTW: The destination segment is always ES. Can't be overridden. Perhaps this discussion has gone a little beside the point in comp.graphics. Erik Liljencrantz | "No silly quotes!" d88-eli@nada.kth.se | Emraquel Tuta
mcripps@mtuxo.att.com (XMP12-M.CRIPPS) (07/21/89)
In article <313@edstip.EDS.COM>, alf@edstip.EDS.COM (John Hamill) writes: > I am writing a MASM program for the IBM PC CGA monitor. I am setting the > stack pointer to the screen memory and using PUSHes to move data to this > area of the screen. This works fine for the whole screen, but when I > do a small rectangle area there is a problem. The problem is: I think > the computer is doing an interupt and pushing and poping from the stack, > which is the screen, so now there is garbage on the screen. This doesn't > happen when I do the whole screen becouse I write over the whole screen and > this writes over the garbage. Is there a way to make the computer not do > any interupts while I'm doing this screen push? Any other comments would > be helpful. I am doing this form of screen update becouse it is very very > fast, and I don't want to see the screen being painted, I want the screen > to snap to a new image. Well, you could disable interrupts in your routine (CLI instruction) and reenable them when you are done (STI). Unfortunately, this won't stop a non-maskable interrupt. Why don't you use the STOSB or STOSW instructions instead of PUSH. These instructions will store a value and increment the destination pointer all in one. With the REP prefix, they will do a whole loop, such as: MOV CX,WIDTH ; number of words horizontally MOV DI,ADDRESS ; location on screen MOV AX,VALUE ; value to store REP MOVSW This will write WIDTH words of VALUE starting at ADDRESS. I know PUSH is fast, but I question whether: MOV CX,WIDTH MOV AX,VALUE MOV SP,ADDRESS here: PUSH AX LOOP here is any faster than using MOVSW. Mike Cripps mtuxo!mcripps AT&T Bell Labs Lincroft, NJ (when used with REP) all in one
jxh@cup.portal.com (Jim - Hickstein) (07/27/89)
> Perhaps this discussion has gone a little beside the point in comp.graphics. Notwithstanding that, I can't resist: > About the REP MOVSW: It is interuptable, and it does resume after an > interrupt accured, but don't use a segment override prefix! > It works fine to move from DS:[SI] to ES:[DI], and it's possible to > override a single MOVSW to use CS, ES or SS as it's sourcesegment, but > never use both REP and segment override! The segment prefix are forgotten > if an interrupt occurs! Actually, you *can* write it so it will work on all 80x86 CPUs, to wit: On 8086/8088 (and maybe '18x) the instruction will be restarted after an interrupt at the last prefix byte, normally the REP. On '286 and '386, the entire sequence of prefix bytes is restarted. This simply means that if you use both a segment override and REP, you must put the segment override last, so you can check for CX=0 and loop back, thus: AGAIN: REP DS: ; I know this isn't MASM, but it's clearer for this example. STOSW LOOP AGAIN ; finish interrupted REP On the early machines, this will catch a premature exit of the REP owing to an interrupt that restarted at the DS: prefix; on later machines, it will never take the jump. This is all explained in the 1979 "PRELIMINARY" 8086 Family User's Manual. Don't they teach this stuff in school any more? :-) Actually, the Family Manual says only that this should be avoided or run with interrupts disabled, but that applies only when other fun prefixes like LOCK are needed. The extra check with LOOP is the conventional wisdom among those who ought to know, but I have never actually tried it. THEORETICALLY, the restarted string instruction fails to decrement CX (since REP does that), and the LOOP compensates for this. Perhaps someone may know something about a later machine that makes this stop working. That would be just like Intel. DO NOT disable interrupts during this operation unless it is ABSOLUTELY necessary, as this can take quite a while to complete, in relative terms. P.S. Beware the CX=0 nasty! On early machines this means REPeat 10000h times, on the newer ones 0 means 0. How about that? :-) -Jim Hickstein Hanger-on Emeritus, 8086 Old-Timers' Home jxh@cup.portal.com ...!sun!portal!cup.portal.com!jxh "Egad! This stuff is TEN YEARS OLD!"