Beispiele

Die folgenden Beispiele stammen aus dem CPC464-Projekt. Ich habe sie gewählt, weil hier drei Sprachen zum Einsatz kommen: C, Python und (das gnadenlos veraltete) Locomotive Basic.

C: Die Python-Extension

#include 
#include 
#include 
#include 

static PyObject* PortError;

static PyObject* readport(PyObject* self, PyObject *args)
{

    /* Open registers */
    ioperm(0x378,1,1);
    ioperm(0x379,1,1);
    ioperm(0x37A,1,1);

    char *reg;
    int addr;

    if (!PyArg_ParseTuple(args, "si", ®, &addr))
    {
        return NULL;
    }

    PyArg_ParseTuple(args, "si", ®, &addr);

    if (!strcmp(reg, "d"))
    {
        /* Set dataport to read mode */
        outb(255, addr+2);
        /* Read the port */
        return Py_BuildValue("i", inb(addr));
    }
    else if (!strcmp(reg, "s") | !strcmp(reg, "c"))
    {
        /* Read the port */
        return Py_BuildValue("i", inb(addr));
    }
    else
    {
        PyErr_SetString(PortError, "Please choose a valid register: d(ata), c(ontroll) or s(tatus)");
        return NULL;
    }
}

static PyObject* writeport(PyObject* self, PyObject *args)
{
    /* Open registers */
    ioperm(0x378,1,1);
    ioperm(0x379,1,1);
    ioperm(0x37A,1,1);

    int val;
    char *reg;
    int addr;

    if (!PyArg_ParseTuple(args, "isi", &val, ®, &addr))
    {
        return NULL;
    }
    PyArg_ParseTuple(args, "isi", &val, ®, &addr);

    if (!strcmp(reg, "d"))
    {
        /* Set dataport to write mode */
        outb(0, addr+2);
        /* Set the port */
        outb(val, addr);
    }
    else if (!strcmp(reg, "s") | !strcmp(reg, "c"))
    {
        /* Set the port */
        outb(val, addr);
    }
    else
    {
        PyErr_SetString(PortError, "Please choose a valid register: d(ata), c(ontroll) or s(tatus)");
        return NULL;
    }
    Py_RETURN_NONE;
}


static PyMethodDef pyparport_funcs[] = {
    {"read",    (PyCFunction)readport,  METH_VARARGS},
    {"write",   (PyCFunction)writeport, METH_VARARGS},
    {NULL}
};

#if PY_MAJOR_VERSION >= 3 // Python3 compatibilty
static struct PyModuleDef _interface =
{
    PyModuleDef_HEAD_INIT,
        "_interface",
        "Python parallel port object",
        -1,
        pyparport_funcs
};

PyMODINIT_FUNC PyInit__interface(void) {
    PyObject *module;
    module = PyModule_Create(&_interface);

    PortError = PyErr_NewException("pyparport.PortError", NULL, NULL);
    Py_INCREF(PortError);
    PyModule_AddObject(module, "PortError", PortError);

    return module;
}

#else // Python2 compatibilty
void init_interface(void)
{
    PyObject *module;
    module = Py_InitModule3("_interface", pyparport_funcs, "Python parallel port object");

    PortError = PyErr_NewException("pyparport.PortError", NULL, NULL);
    Py_INCREF(PortError);
    PyModule_AddObject(module, "PortError", PortError);
}
#endif
    

Python: Das Python-Modul

#!/usr/bin/env python
# coding: utf-8

import _interface

PortError = _interface.PortError


class Port(object):
    """ Abstraction layer for a more comfortable use """

    def __init__(self, port, addr):
        self.port = port
        self.addr = addr

    def read(self):
        return _interface.read(self.port, self.addr)

    def write(self, value):
        return _interface.write(value, self.port, self.addr)


class PyParport(object):
    """ The main class which implements the interface to the port """

    def __init__(self, base_addres=0x378):
        self.data_address = base_addres
        self.status_address = base_addres + 1
        self.control_address = base_addres + 2

        self.data = Port("d", self.data_address)
        self.status = Port("s", self.status_address)
        self.control = Port("c", self.control_address)
    

Locomotive Basic: Ein "Browser"

10 MODE 2
20 OUT &EF, 127
30 INPUT "$: ", content$
40 sig=1
50 IF MID$(BIN$(INP(&F500),7)​,1,1)=cur$ THEN GOTO 50 ELSE GOTO 60
60 FOR c=1 TO LEN(content$) STEP 1
70 IF sig=1 THEN GOTO 80 ELSE GOTO 110
80 sig=0
90 OUT &EF, ASC(MID$(content$,c,1))​+128
100 GOTO 130
110 sig=1
120 OUT &EF, ASC(MID$(content$,c,1))
130 NEXT c
140 OUT &EF, 0
150 OUT &EF, 129
160 t=TIME:WHILE TIME<t+300:WEND
170 linecount=0
180 resp$=""
190 a$=""
200 sig=0
210 FOR i=1 TO 7 STEP 1
220 t=TIME:WHILE TIME<t+1:WEND
230 IF sig=0 THEN 240 ELSE GOTO 270
240 sig=1
250 OUT &EF, 129
260 GOTO 290
270 sig=0
280 OUT &EF, 0
290 IF INP(&F500)=122 THEN GOTO 300 ELSE GOTO 320
300 a$=a$+"0"
310 GOTO 330
320 a$=a$+"1"
330 NEXT i
340 res$=CHR$(VAL("&x"+a$))
350 OUT &EF, 0
360 IF res$=CHR$(4) THEN GOTO 460
370 resp$=resp$+res$
380 IF LEN(resp$)>74 THEN GOTO 390 ELSE GOTO 450
390 PRINT resp$
400 LINECOUNT=LINECOUNT+1
410 IF LINECOUNT=22 THEN GOTO 420 ELSE 440
420 INPUT "-- continue --", CON$
430 LINECOUNT=0
440 resp$=""
450 GOTO 190
460 PRINT resp$
470 GOTO 20