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
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