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
Simple in/out port question
- Combuster
- 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:
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.
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.
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):
i also have one for 64 bit but that's because i use 64bit mode.
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));
}
Author of COBOS