Re: FreeCOM bug in CTTY: Should not open O_BINARY (CR/LF issue)
Bart Oldeman <[email protected]> Tue, 12 Nov 2002 00:34:18 -0500 (EST)
| Newsgroups | gmane.os.freedos.devel |
|---|---|
| Message-ID | <[email protected]> |
On Tue, 12 Nov 2002, Eric Auer wrote:
> Whatever. Strange enough, the MS kernel seems to have an internal CR-LF
> conversion, so in MS-DOS, opening CON in O_BINARY mode does not harm.
> Not sure if I should like this feature.
be aware that DOSEMU's BIOS int10/ah=0xe when presented with a bare line
feed will also perform a CR. DOSEMU's source code (src/base/bios/int10.c)
says
case '\n': /* Newline */
/* Color newline */
newline_att = gfx_mode ? 0 : ATTR(SCREEN_ADR(s) + ypos*co + xpos);
ypos++;
xpos = 0; /* EDLIN needs this behavior */
break;
not sure why EDLIN needs this ....
However if you use NANSI.SYS in DOSEMU, then the BIOS isn't used for this
screen output, and it processes an LF as a pure line feed.
> To whoever wants to know: The kernel uses the CON device -> ConTable ->
> CONSOLE.ASM -> int 0x29 ("fast console output") -> int 0x10.ah=0x0e.bx=7,
> plus some more steps of abstraction between you doing "printf" and the
> file I/O functions reaching CON. Surprising how layered even the DOS
> architecture is. I bet that int 0x10 call is a "single point of failure"
> where you could catch most DOS output (well, apart from the other two
> popular int 0x10.ah=2 and int 0x10.ah=9). Let us read CHARIO.C and CONSOLE.ASM
> -> BinaryCharIO or int 0x29 used... but hey, it seems to boil down
> to the same int 0x29 -> int 0x10.0x0e !
yes. This is how NANSI.SYS can gain such an enormous speed difference,
replacing the
mov al,[es:di]
inc di
int 29h ; Do fast output call
loop ConWr1 ; Loop if more to output
loop in console.asm (used for raw(binary) output by one that writes
directly to video memory. On the other hand NANSI doesn't play nicely with
dosemu -dumb.
when you use cooked output it will also use int29 but now in the chario.c
loop.
for (xfer = 0; err >= SUCCESS && xfer < n && *bp != CTL_Z; bp++, xfer++)
err = cooked_put_char(sft_idx, *bp);
where cooked_put_char expands TABs and calls raw_put_char, which calls
int29.
LF -> CRLF expansion is something that is not done by the FreeDOS kernel
at all.
> Conclusion: Bart/Tom, correct me if I am wrong, but am I right that
> FreeDOS -never- uses INT 0x10.2/9 for console output?
that is correct.
> Then I have
> to tell all of you that my TURBO3.COM driver will NOT speed up the
> output of FreeDOS. Probably it WILL speed up the output when NANSI.SYS
> is used.
Nope.
> Would be nice if some NANSI expert could tell me. When my
> assumptions are all correct, then I should probably write a TURBOFD.COM
> driver that speeds up INT 0x10.0x0e instead of INT 0x10.2/9 !?!?
Yep.
Bart
P.S. this is the nansi loop:
; The Inner Loop: 4+12 +4+4 +4+4 +4+4 +4+18 = 60? cycles/loop
; on 8088; at 4.77 MHz, that gives 13 microseconds/loop.
; At that speed, it takes 25 milliseconds to fill a screen.
; Get a character, put it on the screen, repeat 'til end of line
; or no more characters.
jcxz f_loopdone ; if count = 0, we're already
done.
cmp cs:escvector, 0 ; If in middle of an escape
sequence,
jnz f_in_escapex ; jump to escape sequence handler.
f_tloop:; | If in graphics mode, jump to alternate loop
; | What a massive kludge! A better approach would have been
; | to collect characters for a "write n chars" routine
; | which would handle both text and graphics modes.
call in_g_mode
jc f_t_cloop
jmp f_g_cloop
f_t_cloop:
LODSB ; get char! (al = ds:[si++])
cmp al, 28 ; is it a control char?
jb f_control ; maybe...
f_t_nctl:
STOSW ; Put Char! (es:[di++] = ax)
dec dx ; count down to end of line
loopnz f_t_cloop ; and go back for more.
jz f_t_at_eol ; at end of line; maybe do a crlf.
jmp short f_loopdone
f_looploop:
f_ansi_exit: ; in case we switched into
loopnz f_tloop ; a graphics mode
f_t_at_eol:
jz f_at_eol
f_loopdone: