Inject newlines before displaying DOS prompt
In an earlier change, I removed appending newline outside of batch mode in DOS shell code - that made DOSBox behave less like MS-DOS and more like modern shells, that do not try to compensate for buggy applications. However, we should recognize that DOSBox (unlike e.g. FreeDOS) is designed to run legacy applications, which might make assumptions about DOS implementation. Some examples: - PC Player Benchmark assumes, that help commands are displayed exactly at 80x25 terminal and formats the output to fill the whole screen (scrolling past DOS4GW messages). - Quake and other ID games print shareware information on exit, but do it via a direct memory dump (not interrupts to print DOS text), and follow up with setting cursor exactly at line 22 (which is partly written already), expecting shell to inject newline. - PCC Compiler prints status message on exit without newline, depending on MS-DOS shell behaviour. - TEXTUTIL set of external commands do not print nothing to standard output, and are designed to clear the screen, therefore writing a newline after .COM commands would be a mistake. Therefore we want to inject this newline, but not in every case. New implementation reuses a static variable used by Program base class (for purpose of translating UNIX newlines to DOS newlines) for detection if it's appropriate to inject an additional newline or not. Injecting the newline happens in function displaying the DOS prompt (so we don't need to write additonal logic for separately handling batch mode). When starting a non-COM, non-internal command the static variable is set to the state indicating that next DOS prompt should inject the newline. Fixes: #208
This commit is contained in:
parent
d125b61f66
commit
a956f14de1
4 changed files with 27 additions and 3 deletions
|
@ -82,10 +82,12 @@ public:
|
|||
bool GetEnvNum(Bitu num,std::string & result);
|
||||
Bitu GetEnvCount(void);
|
||||
bool SetEnv(const char * entry,const char * new_string);
|
||||
void WriteOut(const char * format,...); /* Write to standard output */
|
||||
void WriteOut_NoParsing(const char * format); /* Write to standard output, no parsing */
|
||||
void WriteOut(const char *format, ...); // printf to DOS stdout
|
||||
void WriteOut_NoParsing(const char *str); // write string to DOS stdout
|
||||
void InjectMissingNewline();
|
||||
void ChangeToLongCmd();
|
||||
|
||||
static void ResetLastWrittenChar(char c);
|
||||
};
|
||||
|
||||
typedef void (PROGRAMS_Main)(Program * * make);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "callback.h"
|
||||
#include "debug.h"
|
||||
#include "cpu.h"
|
||||
#include "programs.h"
|
||||
|
||||
const char * RunningProgram="DOSBOX";
|
||||
|
||||
|
@ -422,6 +423,8 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
|||
csip=RealMake(loadseg+head.initCS,head.initIP);
|
||||
sssp=RealMake(loadseg+head.initSS,head.initSP);
|
||||
if (head.initSP<4) LOG(LOG_EXEC,LOG_ERROR)("stack underflow/wrap at EXEC");
|
||||
|
||||
Program::ResetLastWrittenChar('\0'); // triggers newline injection after DOS programs
|
||||
}
|
||||
|
||||
if ((flags==LOAD) || (flags==LOADNGO)) {
|
||||
|
|
|
@ -174,6 +174,23 @@ void Program::WriteOut_NoParsing(const char * format) {
|
|||
// DOS_WriteFile(STDOUT,(Bit8u *)format,&size);
|
||||
}
|
||||
|
||||
void Program::ResetLastWrittenChar(char c)
|
||||
{
|
||||
last_written_character = c;
|
||||
}
|
||||
|
||||
void Program::InjectMissingNewline()
|
||||
{
|
||||
if (last_written_character == '\n')
|
||||
return;
|
||||
|
||||
uint16_t n = 2;
|
||||
uint8_t dos_nl[] = "\r\n";
|
||||
dos.internal_output = true;
|
||||
DOS_WriteFile(STDOUT, dos_nl, &n);
|
||||
dos.internal_output = false;
|
||||
last_written_character = '\n';
|
||||
}
|
||||
|
||||
bool Program::GetEnvStr(const char * entry,std::string & result) {
|
||||
/* Walk through the internal environment and see for a match */
|
||||
|
|
|
@ -33,7 +33,9 @@ void DOS_Shell::ShowPrompt(void) {
|
|||
char dir[DOS_PATHLENGTH];
|
||||
dir[0] = 0; //DOS_GetCurrentDir doesn't always return something. (if drive is messed up)
|
||||
DOS_GetCurrentDir(0,dir);
|
||||
WriteOut("%c:\\%s>",drive,dir);
|
||||
InjectMissingNewline();
|
||||
WriteOut("%c:\\%s>", drive, dir);
|
||||
ResetLastWrittenChar('\n'); // prevents excessive newline if cmd prints nothing
|
||||
}
|
||||
|
||||
static void outc(Bit8u c) {
|
||||
|
|
Loading…
Add table
Reference in a new issue