Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programming documentation #1

Closed
vincentbernat opened this issue Dec 16, 2017 · 6 comments
Closed

Programming documentation #1

vincentbernat opened this issue Dec 16, 2017 · 6 comments

Comments

@vincentbernat
Copy link
Contributor

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.

@pdewacht
Copy link
Owner

pdewacht commented Dec 17, 2017

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.

@vincentbernat
Copy link
Contributor Author

Thanks!

@vincentbernat
Copy link
Contributor Author

Hey!

With the OPL3LPT, how should we write to the second register?

@pdewacht
Copy link
Owner

pdewacht commented Jul 7, 2018


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);
        }
}```

@pdewacht
Copy link
Owner

pdewacht commented Jul 7, 2018

Sorry, not tested, but that should do it.

@vincentbernat
Copy link
Contributor Author

Thanks, it works for me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants