Simple in/out port question

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ComputerPsi
Member
Member
Posts: 83
Joined: Fri Oct 22, 2004 11:00 pm

Simple in/out port question

Post by ComputerPsi »

Hello. I have known this before however I forgot over time:
How would you express one 16-bit out/in opcode as two 8-bit out/in opcodes?
Is it the same with 32-bits?

Thanks,
ComputerPsi
xsix
Member
Member
Posts: 59
Joined: Tue Oct 24, 2006 10:52 am

Post by xsix »

i don't know but i think it is impossible. you can use 16bit IN/OUT and you can use 2 8bit IN/OUT but it's only with some of the ports. Like VGA. Some devices needs 16bits or 32bits transferred at one time, not 2 times with 8 bits. But about encoding, hm
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

when you do a word out to for instance the VGA, one byte of the value will go to the index port and the other to the value port, which is located at +1. The value written to these ports are the same as when you write the same value to memory and the result get split over two bytes.

hence the least significant byte will go to the first port and the most significant byte to the second port. That is the native byteorder of the processor.
When you look at it, the numbers are reversed:
mov ax, 0x0201
out dx, ax
0x01 gets written to dx, and 0x02 gets written to dx+1.

But as said before, the size does matter. Because, on the bus you will only see the address and the bits involved and its up to the hardware to decode that to something that makes sense. Of the devices I know only the VGA properly supports encoding OUTs in this fashion, so don't try doing that with other devices as well unless you know it works.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
xsix
Member
Member
Posts: 59
Joined: Tue Oct 24, 2006 10:52 am

Post by xsix »

as I said. for example ATA/ATAPI device's data _MUST_ be taken/written via 16bit OUT/IN
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

i agree with xsix. do NOT combine the 8 bit read to one 16 bit read. In some cases especially with PCI this will give you hell as it will never work. Instead define io read/ writes for each type.

these are mine (for gcc):

Code: Select all

typedef unsigned                int8u       __attribute__((mode(QI)));
typedef unsigned                int16u      __attribute__((mode(HI)));
typedef unsigned                int32u      __attribute__((mode(SI)));
typedef const unsigned          int16uc     __attribute__((mode(HI)));

inline int8u    rd08(int16uc port) {
    int8u               val8u;
    asm volatile("inb %1, %0" : "=a"(val8u) : "Nd"(port));
    return(val8u);
}

inline int16u   rd16(int16uc port) {
    int16u              val16u;
    asm volatile("inw %1, %0" : "=a"(val16u) : "Nd"(port));
    return(val16u);
}

inline int32u   rd32(int16uc port) {
    int32u              val32u;
    asm volatile("inl %1, %0" : "=a"(val32u) : "Nd"(port));
    return(val32u);
}

inline void     wr08(int16uc port, int8u val8u) {
    asm volatile("outb %0, %1" : : "a"(val8u), "Nd"(port));
}

inline void     wr16(int16uc port, int16u val16u) {
    asm volatile("outw %0, %1" : : "a"(val16u), "Nd"(port));
}

inline void     wr32(int16uc port, int32u val32u) {
    asm volatile("outl %0, %1" : : "a"(val32u), "Nd"(port));
}
i also have one for 64 bit but that's because i use 64bit mode.
Author of COBOS
Post Reply