Hi all,
I new to this forum and also after 9 years switching back to MASM (had used in college days).
I have Intel EP80579 board with DOS7.1 on it. I need to write applications on it. As the processor is having PCI, I ll need 32 bit addresses. I am using Visual Studio 2008. Will 32 bit instructions work in DOS? Can somebody provide step by step guide.
Also I would like to know how to write device drivers for DOS. Any good reference would be appreciated.
Thanks in advance.
i learned to write DOS device drivers from a book by Ray Duncan
i do not recall the name of the book, nor do i remember how to write the drivers - lol
well - i remember some of the stuff :bg
i think the book title was something like "Advanced Programming for DOS"
wish i still had that book - lost it in a move or something (probably got "borrowed")
you can use 32-bit registers under windows - i am not sure how well that works with DOS
DOS 7 sounds like it might support it without too much difficulty
use a ".586" directive at the beginning of the program and try it out
welcome to the forum :U
Quote from: dedndave on March 09, 2010, 10:57:17 AM
i think the book title was something like "Advanced Programming for DOS"
wish i still had that book - lost it in a move or something (probably got "borrowed")
It's "Advanced MS-DOS Programming". It's available as PDF for free.
http://www.ece.ul.ie/homepage/tom_newe/Modules/CE4204/advdos-Duncan.pdf
thanks all,
Keep posting... I ll also update as I move ahead.
thanks Japheth - nice link
i also found some nice ASM examples here...
http://www.programmersheaven.com/download/1399/Download.aspx
Hi,
32-bit registers and memory variables work in DOS without
problems. 32-bit addressing requires a "DOS extender" or
BIOS system functions. MS-DOS by itself is mostly real mode
not protected mode. EMS, XMS, DPMI, and VCPI are terms
you can use to track down information.
Good luck,
Steve
Quote32-bit addressing requires a "DOS extender" or BIOS system functions.
Not necessarily, for limited
data access it may be possible to set up an otherwise unused segment register with a 32-bit limit and use it to access the 32-bit addresses. I posted an example here:
http://www.masm32.com/board/index.php?topic=13085.msg101551#msg101551
First, don't assume that an embedded CPU *based* on an x86 chip will behave exactly like a regular x86 chip. You defenitly need to read the manual for that specific CPU to see about 32-bit addressing, real-mode, protected-mode, etc. However, since DOS runs on it, it's a good bet it works very similar. If that's the case, then you can't use 32-bit ADDRESSESS under real-mode, as it will generate an excepetion (though, as was said, you can use 32-bit REGISTERS if you assemble it correctly). IMHO, niether XMS nor EMS is worth it, as dos extenders are cheap, plentiful, and easy to use. As for 'unreal' mode, who knows if it will even work on that CPU?
Second, don't try and test software for your embedded system on your development system (presuambly running NT). It will randomly not work, and it will drive you to pull out your hair. Also, using VS2008 to write DOS programs is probably not possible, or at the very least a major headache.
-r
Quote from: redskull on March 09, 2010, 01:37:01 PM
If that's the case, then you can't use 32-bit ADDRESSESS under real-mode, as it will generate an excepetion
Per the specs the EP80379 has an IA-32 core. For IA-32 there is a well-established method of accessing 32-bit addresses from real mode, without generating an exception. Essentially, you avoid having the access exceed the segment limit by modifying the effective limit for whatever segment register you use to do the access. This basic method saw a lot of use in the early 90's, and it was the method that HIMEM.SYS used to access extended memory from real mode.
I never really played with that method, but I was under the impression it involved switching into protected mode to load the descriptor, and then switching back to real mode to "dupe" the CPU into continuting to use the original one; other than being able to utilize DOS system services, which is perhaps less of a concern for an embedded project with lots of custom hardware, what would the advantage be? Basically, if you are already in protected mode, why not just stay there?
-r
Quote from: MichaelW on March 09, 2010, 01:24:19 PM
Not necessarily, for limited data access it may be possible to set up an otherwise unused segment register with a 32-bit limit and use it to access the 32-bit addresses.
Hi,
Yes, my bad. Add to the list at least unreal mode or big
real mode. Was not thinking I guess.
Regards,
Steve N.
QuoteBasically, if you are already in protected mode, why not just stay there?
Only a minimal protected mode setup is necessary to extend the segment limit. The setup necessary to actually run in protected mode would be more complex, and to also access real mode services more complex still. A good
DOS Extender (http://www.japheth.de/HX.html) will handle most of the complexities, but depending on what the OP needs to do and the details of the system, a real-mode application with an extended segment limit might be easier to code.
Thanks all.
I got the idea, how to wrte device driver. Now how application will call the services of the driver? Any example or illustration would help me better? I will be writing driver for CAN protocol for EP80579.
Also I need to write application software in C. Visual Studio 2008 does not seem to support dos function calls in C... also I could not get proper switches to compile program for 16 bit OS. Shall I go for Turbo C for DOS for application programming and MASM in Visual Studio for Device drivers? Will I need to do some changes?
Thanks in advance.
Take a look at djgpp (http://www.delorie.com/djgpp/), and note that the HDPMI DPMI Server (http://www.japheth.de/HX/HDPMI.html) included with the HX DOS Extender (http://www.japheth.de/HX.html) is compatible with djgpp applications.
As an alternative to a real-mode DOS device driver you might want to consider a Resident Service Provider (http://www.delorie.com/djgpp/doc/dpmi/ch4.8.html) that operates in protected mode.
Hi all,
I have started well. I am facing one problem. I need to write DWORD at 300B1000H location of the processor (32 bit address) which is saved in variable (say BaseAddress). How do I do it in DOS? (i.e. 16 bit mode)
Simply put, you can't. To summarize the options already stated:
1) Switch into protected mode, setup a segment register, and switch back
2) Switch into protected mode forever
3) Use a Dos Extender to do automate either of the first two steps for you.
None of the three options are "easy", and probably can't be done in VS2008.
-r
There is at least one other possibility, use the BIOS Move Block functions. This method will not work under Windows, probably will not work in the presence of a 386 memory manager, and possibly will not work with an extended memory manager (e.g. HIMEM.SYS) loaded. The attachment contains an example.
If I wanted a simple method I would use the first one, were the memory access is done through an otherwise unused segment register set up with a 32-bit limit. The amount of code required is much less than for the other methods.
Quote from: MichaelW on March 20, 2010, 09:41:48 AM
...use the BIOS Move Block functions...
Interesting! I hadn't heard of that one before (http://www.ctyme.com/intr/rb-1527.htm), thanks for pointing it out.
-r
Hi,
It seems to work on my DOS box without cleaning the memory
managers out of CONFIG.SYS. That surprised me a bit. Of note,
you seem to be accessing memory that is not visable to MS-DOS
6.2. This could let me do something scary with the unused
memory over 64M I suppose.
Thanks,
Steve
Quote from: MichaelW on March 20, 2010, 09:41:48 AM
There is at least one other possibility, use the BIOS Move Block functions. This method will not work under Windows, probably will not work in the presence of a 386 memory manager, and possibly will not work with an extended memory manager (e.g. HIMEM.SYS) loaded. The attachment contains an example.
The situation is far better - the BIOS "block move" works in Windows and also under EMM / XMS. FreeDOS DEBUG.COM uses this function to implement its "dx" command.
My statement should have been more like: In my tests even a read of linear address 0fffff0h would not work with the Windows 2000 NTVDM:
Exception number: 40000005 (vdm event)
*----> Stack Back Trace <----*
FramePtr ReturnAd Param#1 Param#2 Param#3 Param#4 Function Name
016AFC08 69B01461 40000005 00000000 00000004 69B04160 kernel32!RaiseException
016AFC48 69B0139B 0000000E 69B01387 7FFDF000 016AFC74 ntvdmd!xxxDbgIsDebuggee
016AFC60 77F8806C 69B00000 FFFFFFFF 00000000 69B012F0 ntvdmd!<nosymbols>
016AFC80 77F8AB2F 69B012F0 69B00000 00000002 00000000 ntdll!LdrInitializeThunk
016AFD1C 77F91B93 016AFD30 77F80000 00000000 00010017 ntdll!LdrShutdownThread
00000000 0070018B 039D0016 0070018B 0070018B 021006B9 ntdll!KiUserApcDispatcher
00A71068 00000000 00000000 00000000 00000000 00000000 <nosymbols>
The name Move Block is from a Phoenix BIOS reference. Hans-Peter Messmer also used that name in his Indispensable PC Hardware books. The AMI reference uses Move Extended Memory Block, which is not exactly accurate because the function is not limited to extended memory.
Steve,
Thanks for testing. Re the memory managers, I probably should not have used the term "probably" :lol
I chose an address at the top of the address space for testing purposes, because for the test system I knew what was there.
Hi,
What about "far pointers"??? I think using them we can access the memory... At least for my code it seems to be working.... I dont have debugger so I am not able to confirm and my code is not yet completed for testing the exact result
Following are the lines... the variable Pointer is assigned the address we want to access.
les bx,cs:Pointer ; load base address
mov eax, es:[bx] ;Store away
Please comment.
The maximum segment address that will fit in a segment register is FFFFh. So the highest address that can be reached from real mode without extending the segment limit is FFFF:FFFF in segment:offset format, or 10FFEFh, and this is far short of 300B1000h.
Quote from: redskull on March 19, 2010, 12:13:21 PM
1) Switch into protected mode, setup a segment register, and switch back
Will someone provide me sample of this option? I searched on net, i got few samples but they are confusing? also none of them worked well.
I would like to set GS or FS segment register with base address 0 & segment limit of 4GB.
Thanks in advance.
I confess to being well out of practice with the old stuff but to write a 32 bit value in 16 bit mode you make 2 writes, one to the start of the address and the second to 2 bytes higher up.
Quote from: hutch-- on March 24, 2010, 10:29:44 AM
I confess to being well out of practice with the old stuff but to write a 32 bit value in 16 bit mode you make 2 writes, one to the start of the address and the second to 2 bytes higher up.
I dont want to write 32 bit
VALUE but to a 32bit location...
Hi,
I liked this site back when. Not that I really used it.
http://www.nondot.org/sabre/os/articles/ProtectedMode/
I don't know how it might compare to another, but it
had a bunch of information in one spot. YMMV.
HTH,
Steve N.
as per the source code, whenever LGDT is executed, my processor hangs... :(
OSDev.org has a forum
they have contests for writing boot sectors that switch to protected mode
look through the entries - there are all kinds of examples
http://forum.osdev.org/viewtopic.php?f=2&t=21423&p=171859&hilit=contest#p171859
Many DOS-based memory managers run in protected mode, and then run DOS "inside" as a v86 task. Ensure such drivers are disabled. Also, if you are using a 16-bit debugger to test the code, they can often have spotty support for protected mode, and can easily "get lost" when tracing.
-r
Quote from: suryakant on March 24, 2010, 10:17:02 AM
Quote from: redskull on March 19, 2010, 12:13:21 PM
1) Switch into protected mode, setup a segment register, and switch back
Will someone provide me sample of this option? I searched on net, i got few samples but they are confusing? also none of them worked well.
I would like to set GS or FS segment register with base address 0 & segment limit of 4GB.
I provided a link to a simple example in my first post in this thread.
Thanks all,
when my application runs, its in real mode (but not in virtual 8086 mode).
Following is the dump of EFLAGS: 00007202 h & CR0 : 00000011h
I used following code to display these values. Now how to go ahead?
pushfd
pop eax
mov DisplayValue, eax ; Value to be displayed
call displayLong
mov eax, cr0
mov DisplayValue, eax ; Value to be displayed
call displayLong
Quote from: MichaelW on March 24, 2010, 06:11:17 PM
I provided a link to a simple example in my first post in this thread.
I used the same code, but when LGDT instruction is executed, processor hangs.
Quote from: suryakant on March 25, 2010, 04:48:02 AM
I used the same code, but when LGDT instruction is executed, processor hangs.
Did you try the EXE that I provided?
Quote from: MichaelW on March 25, 2010, 06:26:27 AM
Quote from: suryakant on March 25, 2010, 04:48:02 AM
I used the same code, but when LGDT instruction is executed, processor hangs.
Did you try the EXE that I provided?
Yes, It displays following and hangs. (pressing key has no effect, does not return to dos prompt)
EAD404920231312F32332F303900FC00
1
1
Are you running this on the EP80579, or some other system? It looks like the A20 address line is already enabled, so try eliminating the call to EnableA20_PS2 and see if that helps. HIMEM.SYS had approximately 20 A20 address line handlers to cover the variety of hardware available at the time. I provided only one, that I'm guessing uses the most common method today, but I don't actually know this.
Thanks Micheal, thanks all.
In Config.sys dos was loaded in high memory, also HIGHMEM.SYS and EMM386.SYS were loaded. I removed them
Now application runs in real mode first, switches successfully to protected mode and comes back...
Thanks again Micheal for providing code with exe.
Now i ll concentrate on my main application code... I ll update as I move ahead.. :bg
Quote from: suryakant
Also I need to write application software in C. Visual Studio 2008 does not seem to support dos function calls in C... also I could not get proper switches to compile program for 16 bit OS. Shall I go for Turbo C for DOS for application programming and MASM in Visual Studio for Device drivers? Will I need to do some changes?
Back when I did this kind of stuff and did C and assembler in 32-bit under DOS, I'd use Watcom and a DOS-Extender (DOS4GW, PMW, Causeway, DOS32A). You could pretty much do all the driver and interrupt stuff within a "monolithic" application. The Watcom compiler/linker could generate 32-bit applications for a lot of platforms, pulled 32-bit objects built with MASM. It was also easy enough to write code to load and bind Win32 drivers, EXE and DLLs. I was doing magnetic tape, CD/DVD burning, and 802.11 PCI/PCMCIA wireless, but applications like Ghost and DriveImage used similar methods to deliver platform agnostic DOS 32-bit solutions. Pretty much all my Win32 console apps (using stdio/stdlib) can be built for DOS by simply recompiling.
For 16-bit stuff Microsoft C (5.x, 6.0, 7.0, 8.0 [MSVC 1.52c]), MASM (5.x, 6.xx) worked well, Turbo C 2.x or 3.x or TASM would all be quite workable too. I think Watcom would do 16-bit too, but I always used it for 32-bit.
If you're running on anything 386 or beyond, doing much 16-bit coding seems like an unnecessary exercise.
-Clive
Hi all,
I have successfully written test code to transmit & receive one byte on CAN... :bg
Now its time to go for full fledged driver... Hope you people are there for me :bg
Thanks friends,,, :U