Closed vincentbernat closed 6 years ago
If it's for a DOS program, you can use this routine:
int lpt_base;
void opl2lpt_write(char reg, char data) {
if (!lpt_base) {
return;
}
int lpt_data = lpt_base;
int lpt_ctrl = lpt_base + 2;
/* Select OPL2 register */
outp(lpt_data, reg);
outp(lpt_ctrl, 13);
outp(lpt_ctrl, 9);
outp(lpt_ctrl, 13);
/* Wait at least 3.3 microseconds */
for (int i = 0; i < 6; i++) {
(volatile) inp(lpt_ctrl);
}
/* Set value */
outp(lpt_data, data);
outp(lpt_ctrl, 12);
outp(lpt_ctrl, 8);
outp(lpt_ctrl, 12);
/* Wait at least 23 microseconds */
for (int i = 0; i < 35; i++) {
(volatile) inp(lpt_ctrl);
}
}
The variable lpt_base
should be initialized to the base address of the parallel port, you can find that address in the BIOS Data Area (it might vary from computer to computer):
port | address |
---|---|
LPT1 | 0040:0008 |
LPT2 | 0040:000A |
LPT3 | 0040:000C |
There's no method to detect the presence of an OPL2LPT.
Thanks!
Hey!
With the OPL3LPT, how should we write to the second register?
void opl3lpt_write(int reg, char data) {
if (!lpt_base) {
return;
}
int lpt_data = lpt_base;
int lpt_ctrl = lpt_base + 2;
/* Select OPL3 register */
outp(lpt_data, reg & 0xFF);
if (reg < 0x100) {
outp(lpt_ctrl, 13);
outp(lpt_ctrl, 9);
outp(lpt_ctrl, 13);
} else {
outp(lpt_ctrl, 5);
outp(lpt_ctrl, 1);
outp(lpt_ctrl, 5);
}
/* Wait at least 3.3 microseconds */
for (int i = 0; i < 6; i++) {
(volatile) inp(lpt_ctrl);
}
/* Set value */
outp(lpt_data, data);
outp(lpt_ctrl, 12);
outp(lpt_ctrl, 8);
outp(lpt_ctrl, 12);
/* 3.3 microseconds is sufficient here as well for OPL3 */
for (int i = 0; i < 6; i++) {
(volatile) inp(lpt_ctrl);
}
}```
Sorry, not tested, but that should do it.
Thanks, it works for me!
Hey!
Do you have some notes on how to adapt code working with AdLib to code working with the OPL2LPT? This could be extracted from the driver, but since it is using some assembly foo, I am unsure to grasp the differences.