OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 7:27 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: QEMU Port 0xE9 Output?
PostPosted: Fri May 25, 2018 4:57 pm 
Offline
Member
Member

Joined: Thu Apr 26, 2018 11:21 pm
Posts: 49
How do you get port 0xE9 output in QEMU as in Bochs? I've written a function to enable redirecting all kernel output to 0xE9 (or elsewhere) which works fine in Bochs.

Would be extremely helpful if I could have the same in QEMU for graphics debugging.

The command-line option "-debugcon stdio" produces no output in the command line when QEMU is launched in it.


Top
 Profile  
 
 Post subject: Re: QEMU Port 0xE9 Output?
PostPosted: Fri May 25, 2018 5:27 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
Write to the parallel port.

Doing this is almost as easy as writing to port 0xE9 and as long as the emulator supports a parallel port, you can direct any text to a specific file.

0) Read port 0x379, polling bit 7.
1) Write the char to port 0x378
2) "toggle" bit 0 in port 0x37A
3) Read port 0x379, polling bit 6.

You might want to "catch" CRLF's if your guest uses CRLF instead of LF. The text file may not look quite right with CRLF's or LF alone depending on the platform you are using.

Ben
- http://www.fysnet.net/osdesign_book_series.htm

Update: Since the OP has had a chance to write up his/her own code (as it should be), here is an example: http://www.fysnet.net/blog/2018/06/


Last edited by BenLunt on Sat Jun 02, 2018 12:26 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: QEMU Port 0xE9 Output?
PostPosted: Fri May 25, 2018 8:12 pm 
Offline
Member
Member

Joined: Thu Apr 26, 2018 11:21 pm
Posts: 49
Hey, thanks for the suggestion.

I tried it but polling for BUSY results in an infinite loop and ignoring it causes only one character to be written on the parallel output.

Code:
PollParallelBusy:
   push ax
   push dx
   
   mov dx, 0x379
.loop:
   in al, dx
   and al, 10000000b
   cmp al, 0
   jnz .loop
   
   pop dx
   pop ax
   ret

StringOut:
...
.debugOutLoop:
   lodsb
   inc edx
   
   ; For Bochs
   out 0xE9, al
   
   ; For QEMU:
   push dx
   
   ;call PollParallelBusy

   ; Write character
   mov dx, 0x378
   out dx, al
   
   ; Toggle bit 0 (STROBE) of 0x37A to say data is ready
   mov dx, 0x37A
   in al, dx
   or al, 00000001b
   out dx, al
   
   ; ... Left out polling 0x379 acknowledge for now
   
.next:
   pop dx
   
   cmp edx, ecx
   jl .debugOutLoop


Top
 Profile  
 
 Post subject: Re: QEMU Port 0xE9 Output?
PostPosted: Fri May 25, 2018 9:01 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
rwosdev wrote:
Hey, thanks for the suggestion.

I tried it but polling for BUSY results in an infinite loop and ignoring it causes only one character to be written on the parallel output.

Code:
PollParallelBusy:
   push ax
   push dx
   
   mov dx, 0x379
.loop:
   in al, dx
   and al, 10000000b
   cmp al, 0
   jnz .loop

No need for the "cmp al,0" instruction. The "and" sets the flags identical to the "cmp". In fact, the "cmp" is an "and" instruction, disregarding the results.

In my first reply, I tried to point you in the right direction, which it seems I did, though I tried not to do it for you.

Please search a little more and find out what value to watch for in bit 7. A lot of places say that it is the busy bit, which is correct, but is it set or clear to indicate busy?

rwosdev wrote:
Code:
   pop dx
   pop ax
   ret

StringOut:
...
.debugOutLoop:
   lodsb
   inc edx
   
   ; For Bochs
   out 0xE9, al
   
   ; For QEMU:
   push dx
   
   ;call PollParallelBusy

   ; Write character
   mov dx, 0x378
   out dx, al
   
   ; Toggle bit 0 (STROBE) of 0x37A to say data is ready
   mov dx, 0x37A
   in al, dx
   or al, 00000001b
   out dx, al
   
   ; ... Left out polling 0x379 acknowledge for now

The reason it only outputs one char, is that you never turn off the strobe to be able to turn it back on, indicating another character. An on bit only indicates to the other side to read the parallel lines for the char. Only when the bit goes low (drops the power on that line), does the hardware indicate that it needs to be ready for the next char. This is where timing comes into play. How fast can I toggle (strobe) the strobe line and the "other side" will receive all my characters intact? For a simple thing as outputting to a file using an emulator, the fact that the line goes high, then low is enough. No need for timing. However, my code pauses for a slight bit, while the line is high, before dropping the strobe, just to be sure.

rwosdev wrote:
Code:
.next:
   pop dx
   
   cmp edx, ecx
   jl .debugOutLoop

Side note: The Parallel Port hardware, in the standard form, has little or no circuitry. It simply is a bit representation of the status of each of the pins. If a pin is high (has power), the bit will be set (or clear), period. Writing a value to the data port, simply sets high all lines (pins) that have a bit set, dropping the power (setting to low) all the pins that have a zero bit. It is the closest you can come to actually physically manipulating the hardware without any firmware getting in the way. Long live the Parall....oh, ya, its dead...

Hope this helps,
Ben


Top
 Profile  
 
 Post subject: Re: QEMU Port 0xE9 Output?
PostPosted: Fri May 25, 2018 9:46 pm 
Offline
Member
Member

Joined: Thu Apr 26, 2018 11:21 pm
Posts: 49
Took everything you said into consideration, here's the new code which seems to work nicely.

I've never used the parallel port before so if there's something not quite right here please let me know.

In my OS, I only send newlines in strings ('\n') so this code catches them as you said and sends an additional carriage return byte to the parallel port so each string starts on a new line when requested.

Screenshot of result attached, showing correct text sent from two different drivers being routed through the parallel port.

Many thanks

Code:
ParallelPollStatus:
; bl = mask
   push ax
   push dx
   
   mov dx, 0x379
.loop:
   in al, dx
   and al, bl
   jz .loop ; Function is only used for BUSY and ACK, and them being 0 means they're set.
   ; https://wiki.osdev.org/Parallel_port says: The ERROR, ACK and BUSY signals are active low when reading from the IO port.
   
   pop dx
   pop ax
   ret
   
ParallelWriteByte:
; al = character
   push ax
   push bx
   push dx
   
   mov bl, 10000000b ; Wait until not busy
   call ParallelPollStatus

   mov dx, 0x378
   out dx, al   ; Write character
   
   mov dx, 0x37A
   in al, dx
   or al, 00000001b
   out dx, al ; Set STROBE to say 'data is ready'
   
   mov bl, 01000000b ; Wait until acknowledgement
   call ParallelPollStatus
   
   and al, 11111110b  ; Clear STROBE so device is ready for next character
   out dx, al
   
   mov bl, 01000000b ; Wait until acknowledgement
   call ParallelPollStatus
      
   pop dx
   pop bx
   pop ax
   
   ret

StringOut:
...
.debugOutLoop:
   lodsb
   mov ah, al
   inc edx
   
   ; For Bochs
   out 0xE9, al
   
   ; For QEMU:
   call ParallelWriteByte
   
   cmp al, 10 ; Catch newline
   jne .next
   
.addCR:      ; If newline, add carriage return
   mov al, 13
   call ParallelWriteByte
   
.next:
   cmp edx, ecx
   jl .debugOutLoop

.done:
   ...
   ret


Attachments:
parallel.jpg
parallel.jpg [ 34.68 KiB | Viewed 2484 times ]
Top
 Profile  
 
 Post subject: Re: QEMU Port 0xE9 Output?
PostPosted: Sat May 26, 2018 2:15 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
"-debugcon stdio" certainly works. If it does not, maybe it was deactivated during configure-time (?). Of course, this also only works if you run qemu from a terminal.

If you want to write to a real device, I would suggest serial over parallel ports as modern PCs actually have serial ports but no parallel ports.

Use "-serial stdio" or the equivalent option for the parallel port to redirect output to the terminal qemu is running in.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: QEMU Port 0xE9 Output?
PostPosted: Sat May 26, 2018 9:30 am 
Offline
Member
Member

Joined: Thu Apr 26, 2018 11:21 pm
Posts: 49
I just discovered I was using qemu-system-i386w.exe - I switched to qemu-system-i386.exe and port 0xE9 output in the command line (with -debugcon stdio) worked, as did parallel output using -parallel stdio

Still keeping the parallel code and learned some new things as well so nothing's in vain.

Cheers guys


Top
 Profile  
 
 Post subject: Re: QEMU Port 0xE9 Output?
PostPosted: Mon May 28, 2018 10:15 am 
Offline
User avatar

Joined: Tue Jul 05, 2011 5:17 am
Posts: 8
Location: Delft, Netherlands

Slightly off topic:

BenLunt wrote:
In fact, the "cmp" is an "and" instruction, disregarding the results.


You're confusing cmp with test :wink:

cmp compares by subtracting (so, sub), while test does the bitwise and


Top
 Profile  
 
 Post subject: Re: QEMU Port 0xE9 Output?
PostPosted: Mon May 28, 2018 4:20 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
Wukl wrote:
BenLunt wrote:
In fact, the "cmp" is an "and" instruction, disregarding the results.

You're confusing cmp with test :wink:

cmp compares by subtracting (so, sub), while test does the bitwise and

Oh ya, you're right. Sorry. I don't know why I thought that. Long day probably.

Thanks,
Ben


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 142 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group