CTRL-STOP is not caught (batch file)

Door Eugeny_Brychkov

Paragon (1217)

afbeelding van Eugeny_Brychkov

13-07-2022, 23:00

I am struggling with very stupid issue. Hope you can help me.

I disable interrupts, and sense CTRL-STOP myself. As soon as I detect it, I set INTFLG to 03h, restore slots and exit.
And I run application in batch file. Therefore I would expect when DOS gets control through BDOS 00h, it immediately checks for CTRL-STOP press flag, and ask "terminate batch file?".

But it does not happen - in time. Application happily exits, then next application is being run, and the earliest time flag is checked when next application tries to print something onto the screen with BDOS 09h.

I have made a test - when exiting after setting INTFLG to do BDOS 09h, but with empty string "$". No difference. Ensured that interrupts are enabled before I perform "final" BDOS 09h with empty string, and even wait for next VDP interrupt - no difference. The ONLY difference is when I try to output some character, at least one, then DOS immediately says "terminate batch file"?

But I do not want to display anything 'real' on app exit. Is there any right way to give DOS a chance to check for CTRL-STOP flag and ask for batch file (execution) termination?

Edit: I also found out that file I/O operations do not trigger this sense, because application which is being started after exit manages to load file (open/read/close) before outputting to the screen. Therefore it is not just as simple as call any BDOS function.

Aangemeld of registreer om reacties te plaatsen

Van ducasp

Hero (579)

afbeelding van ducasp

13-07-2022, 23:13

Perhaps a (not so) ugly hack would be to output left arrow direction, or right arrow direction, nothing will be printed and a new line will come afterwards anyway, if that works, you might not have the display and get what you want.

Van Eugeny_Brychkov

Paragon (1217)

afbeelding van Eugeny_Brychkov

14-07-2022, 01:45

Calling BDOS 62h with exit code 9fh seems to do the job. What's about DOS1?
In DOS1 mode INTFLG seems not to work at all, therefore it is not a way to tell DOS1 that there was CTRL-STOP condition.

Edit: some more strange information. I decided to look how BREAKX system call works. Was very astonished to see that it does NOT disable interrupts between reading and writing the registers, in particular:

in a,(0aah)
out (0aah),a
in a,(0aah)
dec a
out (0aah),a

To my understanding DEC A is not a proper way to go because during *** interrupt may be invoked scanning the keyboard corrupting the lower nibble in the keyboard row number PPI register.

Edit: I see kernel call this BREAKX routine with interrupts disabled, and documentation says "Remark: In this routine, interrupts are inhibited" which is kind of misleading, and must say that interrupts MUST be disabled before calling this routine. In the form it is said now means that interrupts are being disabled within this routine.

Update: for DOS1 writing 0ffh into 0f336h (input available) and 03h (break character) into the 0f337h does the job - and no console I/O is needed, DOS1 proactively checks for chars available and displays "terminate batch file?". DOS2 seems not using these locations at all.

Van Eugeny_Brychkov

Paragon (1217)

afbeelding van Eugeny_Brychkov

14-07-2022, 14:55

Way to go:

DOS1: 0f336 <- 0ffh, 0f337h <- 03h, and normal exit using BDOS 0h.

DOS2: INTFLG <- 03h, BDOS 09h some string (I used space 020h + BS 08h), and exit using BDOS 62h with code 09fh (.STOP). There's one thing though - DOS2 thinks that current line some string above was printed on is not empty any more, and adds another CR/LF before saying "CTRL-STOP pressed".

And regarding BREAKX... The problem appears even in the official documentation, you can see here where sample code calls BREAKX after calling CHPUT, and CHPUT enables the interrupts, therefore BREAKX is misused even in official doc.