/* Register.CPP version 1.0 by Robert Schmidt of Ztiff Zox Softwear 1993 Defines the member functions of the Register class declared in Register.hpp. Defines the stream operators >> and << to read and write register info from istreams/to ostreams in *binary* format. */ #include #include #include "Register.hpp" /* Register::out() Outputs the Register.value to the correct port/index. It takes care of handling recognized special cases, like some VGA ports, correctly. */ void Register::out() { switch (port) { // First handle special cases: case ATTRCON_ADDR: inportb(STATUS_ADDR); // reset read/write flip-flop outportb(ATTRCON_ADDR, index); outportb(ATTRCON_ADDR, value); break; case SEQ_ADDR: if (index == 1) { // Reset the sequencer if the clock polarity settings // are being accessed. outport(SEQ_ADDR, 0x0100); outport(SEQ_ADDR, value<<8 | 1); outport(SEQ_ADDR, 0x0300); break; } case GRACON_ADDR: case CRTC_ADDR: case CHIPSTECH: outport(port, index | value<<8); break; case MISC_ADDR: case VGAENABLE_ADDR: default: // Default is to write the byte outportb(port, value); // directly to the port break; } } /* Register::in() Inputs Register.value to the associated hardware register. It takes care of handling recognized special cases, like some VGA ports, correctly. */ unsigned char Register::in() { switch (port) { // First handle special cases: case MISC_ADDR: value = inportb(0x3cc); // 0x3c2 is write-only, reading // must be mapped to 0x3cc break; case ATTRCON_ADDR: // This 1 is odd. First do a read to inportb(STATUS_ADDR); // reset the index/data flip-flop. // Then give it the index, but: // set bit 5! If cleared, VGA // output is disabled! outportb(ATTRCON_ADDR, index); value = inportb(ATTRCON_ADDR+1); break; case SEQ_ADDR: // These 3 are similar. Give it the case GRACON_ADDR: // register index, then read the case CRTC_ADDR: // byte from port+1. case CHIPSTECH: outportb(port, index); value = inportb(port+1); break; case VGAENABLE_ADDR: default: // Default is to read the byte value = inportb(port); // directly from the port break; } return value; // Return value of first reg. } /* The following stream operators operate on Registers in *binary* format, i.e. they are not suitable for communicating with text streams like the keyboard or the screen (cin/cout). */ istream& operator>> (istream &in, Register &r) { r.port = unsigned(in.get()) | (unsigned(in.get()) << 8); r.index = in.get(); r.value = in.get(); return in; } ostream& operator<< (ostream &out, Register &r) { out.put(char(r.port)); out.put(char(r.port>>8)); out.put(r.index); out.put(r.value); return out; }