1

Edited: Only printf with "\n" would be shown.

int main (int argc, char *argv[])
{
  REGPACK   Regs;
  KEY_DATA  KeyData

  //Set cursor position AH= 02h, BH = Page Number, DH = Row, DL = Column
  Regs.h.ah = 0x02;
  Regs.h.bh = 0;
  Regs.h.dh = 15;
  Regs.h.dl = 40;
  intr(0x10, &Regs);

  printf("Test");

  while (KeyData.Key.ScanCode != SCAN_ESC)  {
   GetKey(&KeyData);
   printf("Key: %c", KeyCode.Key.AsciiChar);
  }
  return 0; 
}

The snippet is as above:

Coding Environment: Windows8.1
Tool chain: Open Watcom (WCL & WASM) v1.9
Executed on: DOSBox, real DOS 6.22

First, I found out that "printf" would not print anything on the screen, no "Test" nor "Key: X" is shown. Then I started to strike the keyboard, about 4~6 keystrokes, the string would come out in bunch, something like:

TestKey: aKey: bKey: cKey: d

The same symptoms occurred every 4~6 continuous keystrokes.

Another scenario, I didn't press anything, printf would not function, and as soon as I terminated this program by pressing "ESC", the two strings would be shown on the upper left of the screen, like there's nothing wrong.

So I began to think there is something wrong about this snippet, and printf only functions when DOS program terminate signal is occurred (INT 21h AH=4Ch).

I've re-wrote the "set cursor position" thing in pure assembly, and did a near call to the proc, the bug still occurred, and I've changed the set cursor position to set video mode 3 from video mode 3 (INT 10h, AH=00, AL=03h) to refresh the screen, no luck, either.

No matter what method I used, after INT10h, the printf just wouldn't work before a DOS terminate signal.

Does anyone know why this happened? And is there a way to avoid this, or for me to use printf mixed with INT10h?

But putc and puts could print on the screen normally under this circumstances, and printf only works when there is a "\n" character (e.g. "helloworld\n"). I'm super confused...

I cannot abandon INT10h, because MSDOS has no native support of these kind of operation, and BIOS call is also effective, nor can I abandon printf, because variadic parameters really save my butt a lot.

Thanks guys!

Gilvin
  • 33
  • 5
  • quick comment, set your `Regs` to zero before you do anything else. The code you have may have unpredictable results dependent upon there. – KevinDTimm Nov 26 '14 at 16:27
  • Thanks KevinDTimm, but it doesn't solved. – Gilvin Nov 26 '14 at 16:52
  • This looks to be a buffering issue. See [here](http://stackoverflow.com/questions/1716296/). – uesp Nov 26 '14 at 16:57
  • @uesp, Wow! Thanks! It is the buffering issue! After I disabled the stdout buffering, printf worked! – Gilvin Nov 26 '14 at 17:07
  • I see you've added the solution to your question *and* posted it as an answer. I suggest deleting the added part of the question; it doesn't belong there. (I haven't checked that it's identical to the answer you posted, or I'd do it myself.) – Keith Thompson Nov 26 '14 at 18:16
  • @KeithThompson Ok, deleted. Still not used to the rules here, learning. – Gilvin Nov 27 '14 at 16:48

2 Answers2

0

Thanks guys! Finds out I'm really lack of this kind of knowledge.
Anyways, if disabling stdout buffering, the whole thing works.

Still don't know why it behaved so strangely after INT10h, and I'm expecting a big overhead on a big scale page print but at least it works for now. As below is the snippet.

int main (int argc, char *argv[])
{
  REGPACK   Regs;
  KEY_DATA  KeyData

  //Disable stdout buffer
  setbuf(stdout, NULL);

  //Set cursor position AH= 02h, BH = Page Number, DH = Row, DL = Column
  Regs.h.ah = 0x02;
  Regs.h.bh = 0;
  Regs.h.dh = 15;
  Regs.h.dl = 40;
  intr(0x10, &Regs);

  printf("Test");

  while (KeyData.Key.ScanCode != SCAN_ESC)  {
   GetKey(&KeyData);
   printf("Key: %c", KeyCode.Key.AsciiChar);
  }
  return 0; 
}
Gilvin
  • 33
  • 5
0
the indicated source would fail to successfully compile 
for several reasons, including:
1) two warnings about unused parameters argc and argv
2) unrecognized function: prtinf()

You can get 'immediate' output from printf calls by ending the 
format string with '\n' 
--or-- 
following the printf with the statement: fflush(stdout);
otherwise, the output is buffered until the OS feels like/has time to 
actually output it. (as for instance, when the program terminates
user3629249
  • 15,593
  • 1
  • 16
  • 17