Skip to content

Commit 5c8b5e7

Browse files
Merge pull request #3347 from leecher1337/dosdev
Dosdev
2 parents 6ef9829 + 378b7dd commit 5c8b5e7

File tree

4 files changed

+95
-43
lines changed

4 files changed

+95
-43
lines changed

include/dos_system.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,46 @@ class DOS_Device : public DOS_File {
134134
Bitu devnum;
135135
};
136136

137+
struct ExtDeviceData {
138+
uint16_t attribute;
139+
uint16_t segment;
140+
uint16_t strategy;
141+
uint16_t interrupt;
142+
};
143+
144+
class DOS_ExtDevice : public DOS_Device {
145+
public:
146+
DOS_ExtDevice(const DOS_ExtDevice& orig) :DOS_Device(orig) {
147+
ext = orig.ext;
148+
}
149+
DOS_ExtDevice(const char* name, uint16_t seg, uint16_t off) {
150+
SetName(name);
151+
ext.attribute = real_readw(seg, off + 4);
152+
ext.segment = seg;
153+
ext.strategy = real_readw(seg, off + 6);
154+
ext.interrupt = real_readw(seg, off + 8);
155+
}
156+
DOS_ExtDevice& operator= (const DOS_ExtDevice& orig) {
157+
DOS_Device::operator=(orig);
158+
ext = orig.ext;
159+
return *this;
160+
}
161+
162+
virtual bool Read(uint8_t* data, uint16_t* size);
163+
virtual bool Write(const uint8_t* data, uint16_t* size);
164+
virtual bool Seek(uint32_t* pos, uint32_t type);
165+
virtual bool Close();
166+
virtual uint16_t GetInformation(void);
167+
virtual bool ReadFromControlChannel(PhysPt bufptr, uint16_t size, uint16_t* retcode);
168+
virtual bool WriteToControlChannel(PhysPt bufptr, uint16_t size, uint16_t* retcode);
169+
virtual uint8_t GetStatus(bool input_flag);
170+
bool CheckSameDevice(uint16_t seg, uint16_t s_off, uint16_t i_off);
171+
uint16_t CallDeviceFunction(uint8_t command, uint8_t length, uint16_t seg, uint16_t offset, uint16_t size);
172+
private:
173+
struct ExtDeviceData ext;
174+
175+
};
176+
137177
class localFile : public DOS_File {
138178
public:
139179
localFile();

src/dos/dos.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,8 @@ static Bitu DOS_21Handler(void) {
18591859
/* TODO: If handle is STDIN and not binary do CTRL+C checking */
18601860
{
18611861
uint16_t toread=reg_cx;
1862+
uint32_t handle = RealHandle(reg_bx);
1863+
bool fRead = false;
18621864

18631865
/* if the offset and size exceed the end of the 64KB segment,
18641866
* truncate the read according to observed MS-DOS 5.0 behavior
@@ -1879,8 +1881,27 @@ static Bitu DOS_21Handler(void) {
18791881
}
18801882

18811883
dos.echo=true;
1882-
if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) {
1883-
MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread);
1884+
1885+
if(handle >= DOS_FILES) {
1886+
DOS_SetError(DOSERR_INVALID_HANDLE);
1887+
} else
1888+
if(!Files[handle] || !Files[handle]->IsOpen())
1889+
DOS_SetError(DOSERR_INVALID_HANDLE);
1890+
else if(Files[handle]->GetInformation() & EXT_DEVICE_BIT)
1891+
{
1892+
fRead = !(((DOS_ExtDevice*)Files[handle])->CallDeviceFunction(4, 26, SegValue(ds), reg_dx, toread) & 0x8000);
1893+
#if defined(USE_TTF)
1894+
if(fRead && ttf.inUse && reg_bx == WPvga512CHMhandle)
1895+
MEM_BlockRead(SegPhys(ds) + reg_dx, dos_copybuf, toread);
1896+
#endif
1897+
}
1898+
else
1899+
{
1900+
if(fRead = DOS_ReadFile(reg_bx, dos_copybuf, &toread))
1901+
MEM_BlockWrite(SegPhys(ds) + reg_dx, dos_copybuf, toread);
1902+
}
1903+
1904+
if (fRead) {
18841905
reg_ax=toread;
18851906
#if defined(USE_TTF)
18861907
if (ttf.inUse && reg_bx == WPvga512CHMhandle){
@@ -1928,6 +1949,7 @@ static Bitu DOS_21Handler(void) {
19281949
unmask_irq0 |= disk_io_unmask_irq0;
19291950
{
19301951
uint16_t towrite=reg_cx;
1952+
bool fWritten;
19311953

19321954
/* if the offset and size exceed the end of the 64KB segment,
19331955
* truncate the write according to observed MS-DOS 5.0 READ behavior
@@ -1946,7 +1968,24 @@ static Bitu DOS_21Handler(void) {
19461968

19471969
MEM_BlockRead(SegPhys(ds)+reg_dx,dos_copybuf,towrite);
19481970
packerr=reg_bx==2&&towrite==22&&!strncmp((char *)dos_copybuf,"Packed file is corrupt",towrite);
1949-
if ((packerr && !(i4dos && !shellrun) && (!autofixwarn || (autofixwarn==2 && infix==0) || (autofixwarn==1 && infix==1))) || DOS_WriteFile(reg_bx,dos_copybuf,&towrite)) {
1971+
fWritten = (packerr && !(i4dos && !shellrun) && (!autofixwarn || (autofixwarn == 2 && infix == 0) || (autofixwarn == 1 && infix == 1)));
1972+
if(!fWritten)
1973+
{
1974+
uint32_t handle = RealHandle(reg_bx);
1975+
1976+
if(handle >= DOS_FILES) {
1977+
DOS_SetError(DOSERR_INVALID_HANDLE);
1978+
}
1979+
else
1980+
if(!Files[handle] || !Files[handle]->IsOpen())
1981+
DOS_SetError(DOSERR_INVALID_HANDLE);
1982+
else if(Files[handle]->GetInformation() & EXT_DEVICE_BIT)
1983+
{
1984+
fWritten = !(((DOS_ExtDevice*)Files[handle])->CallDeviceFunction(8, 26, SegValue(ds), reg_dx, towrite) & 0x8000);
1985+
}
1986+
else fWritten = DOS_WriteFile(reg_bx, dos_copybuf, &towrite);
1987+
}
1988+
if (fWritten) {
19501989
reg_ax=towrite;
19511990
CALLBACK_SCF(false);
19521991
} else {

src/dos/dos_devices.cpp

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -49,36 +49,6 @@ bool isDBCSCP(), shiftjis_lead_byte(int c);
4949
bool Network_IsNetworkResource(const char * filename), TTF_using(void);
5050
bool CodePageGuestToHostUTF16(uint16_t *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/);
5151

52-
struct ExtDeviceData {
53-
uint16_t attribute;
54-
uint16_t segment;
55-
uint16_t strategy;
56-
uint16_t interrupt;
57-
};
58-
59-
class DOS_ExtDevice : public DOS_Device {
60-
public:
61-
DOS_ExtDevice(const char *name, uint16_t seg, uint16_t off) {
62-
SetName(name);
63-
ext.attribute = real_readw(seg, off + 4);
64-
ext.segment = seg;
65-
ext.strategy = real_readw(seg, off + 6);
66-
ext.interrupt = real_readw(seg, off + 8);
67-
}
68-
virtual bool Read(uint8_t * data,uint16_t * size);
69-
virtual bool Write(const uint8_t * data,uint16_t * size);
70-
virtual bool Seek(uint32_t * pos,uint32_t type);
71-
virtual bool Close();
72-
virtual uint16_t GetInformation(void);
73-
virtual bool ReadFromControlChannel(PhysPt bufptr,uint16_t size,uint16_t * retcode);
74-
virtual bool WriteToControlChannel(PhysPt bufptr,uint16_t size,uint16_t * retcode);
75-
virtual uint8_t GetStatus(bool input_flag);
76-
bool CheckSameDevice(uint16_t seg, uint16_t s_off, uint16_t i_off);
77-
private:
78-
struct ExtDeviceData ext;
79-
80-
uint16_t CallDeviceFunction(uint8_t command, uint8_t length, PhysPt bufptr, uint16_t size);
81-
};
8252

8353
bool DOS_ExtDevice::CheckSameDevice(uint16_t seg, uint16_t s_off, uint16_t i_off) {
8454
if(seg == ext.segment && s_off == ext.strategy && i_off == ext.interrupt) {
@@ -87,7 +57,7 @@ bool DOS_ExtDevice::CheckSameDevice(uint16_t seg, uint16_t s_off, uint16_t i_off
8757
return false;
8858
}
8959

90-
uint16_t DOS_ExtDevice::CallDeviceFunction(uint8_t command, uint8_t length, PhysPt bufptr, uint16_t size) {
60+
uint16_t DOS_ExtDevice::CallDeviceFunction(uint8_t command, uint8_t length, uint16_t seg, uint16_t offset, uint16_t size) {
9161
uint16_t oldbx = reg_bx;
9262
uint16_t oldes = SegValue(es);
9363

@@ -98,8 +68,8 @@ uint16_t DOS_ExtDevice::CallDeviceFunction(uint8_t command, uint8_t length, Phys
9868
real_writed(dos.dcp, 5, 0);
9969
real_writed(dos.dcp, 9, 0);
10070
real_writeb(dos.dcp, 13, 0);
101-
real_writew(dos.dcp, 14, (uint16_t)(bufptr & 0x000f));
102-
real_writew(dos.dcp, 16, (uint16_t)(bufptr >> 4));
71+
real_writew(dos.dcp, 14, offset);
72+
real_writew(dos.dcp, 16, seg);
10373
real_writew(dos.dcp, 18, size);
10474

10575
reg_bx = 0;
@@ -115,7 +85,7 @@ uint16_t DOS_ExtDevice::CallDeviceFunction(uint8_t command, uint8_t length, Phys
11585
bool DOS_ExtDevice::ReadFromControlChannel(PhysPt bufptr,uint16_t size,uint16_t * retcode) {
11686
if(ext.attribute & 0x4000) {
11787
// IOCTL INPUT
118-
if((CallDeviceFunction(3, 26, bufptr, size) & 0x8000) == 0) {
88+
if((CallDeviceFunction(3, 26, (uint16_t)(bufptr >> 4), (uint16_t)(bufptr & 0x000f), size) & 0x8000) == 0) {
11989
*retcode = real_readw(dos.dcp, 18);
12090
return true;
12191
}
@@ -126,7 +96,7 @@ bool DOS_ExtDevice::ReadFromControlChannel(PhysPt bufptr,uint16_t size,uint16_t
12696
bool DOS_ExtDevice::WriteToControlChannel(PhysPt bufptr,uint16_t size,uint16_t * retcode) {
12797
if(ext.attribute & 0x4000) {
12898
// IOCTL OUTPUT
129-
if((CallDeviceFunction(12, 26, bufptr, size) & 0x8000) == 0) {
99+
if((CallDeviceFunction(12, 26, (uint16_t)(bufptr >> 4), (uint16_t)(bufptr & 0x000f), size) & 0x8000) == 0) {
130100
*retcode = real_readw(dos.dcp, 18);
131101
return true;
132102
}
@@ -138,7 +108,7 @@ bool DOS_ExtDevice::Read(uint8_t * data,uint16_t * size) {
138108
PhysPt bufptr = (dos.dcp << 4) | 32;
139109
for(uint16_t no = 0 ; no < *size ; no++) {
140110
// INPUT
141-
if((CallDeviceFunction(4, 26, bufptr, 1) & 0x8000)) {
111+
if((CallDeviceFunction(4, 26, dos.dcp + 2, 0, 1) & 0x8000)) {
142112
return false;
143113
} else {
144114
if(real_readw(dos.dcp, 18) != 1) {
@@ -155,7 +125,7 @@ bool DOS_ExtDevice::Write(const uint8_t * data,uint16_t * size) {
155125
for(uint16_t no = 0 ; no < *size ; no++) {
156126
mem_writeb(bufptr, *data);
157127
// OUTPUT
158-
if((CallDeviceFunction(8, 26, bufptr, 1) & 0x8000)) {
128+
if((CallDeviceFunction(8, 26, dos.dcp + 2, 0, 1) & 0x8000)) {
159129
return false;
160130
} else {
161131
if(real_readw(dos.dcp, 18) != 1) {
@@ -186,10 +156,10 @@ uint8_t DOS_ExtDevice::GetStatus(bool input_flag) {
186156
uint16_t status;
187157
if(input_flag) {
188158
// NON-DESTRUCTIVE INPUT NO WAIT
189-
status = CallDeviceFunction(5, 14, 0, 0);
159+
status = CallDeviceFunction(5, 14, 0, 0, 0);
190160
} else {
191161
// OUTPUT STATUS
192-
status = CallDeviceFunction(10, 13, 0, 0);
162+
status = CallDeviceFunction(10, 13, 0, 0, 0);
193163
}
194164
// check NO ERROR & BUSY
195165
if((status & 0x8200) == 0) {

src/dos/dos_files.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,10 @@ bool DOS_OpenFile(char const * name,uint8_t flags,uint16_t * entry,bool fcb) {
877877
}
878878
bool exists=false;
879879
if (device) {
880-
Files[handle]=new DOS_Device(*Devices[devnum]);
880+
if (Devices[devnum]->GetInformation() & EXT_DEVICE_BIT)
881+
Files[handle] = new DOS_ExtDevice(*(DOS_ExtDevice*)Devices[devnum]);
882+
else
883+
Files[handle]=new DOS_Device(*Devices[devnum]);
881884
} else {
882885
exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags) || Drives[drive]->FileOpen(&Files[handle],upcase(fullname),flags);
883886
if (exists) Files[handle]->SetDrive(drive);

0 commit comments

Comments
 (0)