!! Achtung: ab Zeile 253 Assembler-Quellcode (vor Übersetzung trennen)
/**********************************************************************/ 
/*                                                                    */ 
/*  ANSTEUERUNG DES C'T-BUSINTERFACE ALS EIN/AUSGABEPORT              */ 
/*          (SIEHE C'T 7/87 UND 10/87)                                */ 
/*                                                                    */ 
/*                                                                    */ 
/*    VERSION 2.0     FEBRUAR 1988                                    */ 
/*                                                                    */ 
/*  (C) RICHARD WALTER    -ELEKTRONISCHE STEUERUNGEN-                 */ 
/*  BERNBECKWEG 15    8300 LANDSHUT    TEL.0871/21983                 */ 
/*                                                                    */ 
/*  DAS MODUL 'EINAUS' MUSS ZUSAMMEN MIT DEM MODUL 'PORTIO' GELADEN   */ 
/*  WERDEN. 'EINAUS' IST DAS PEARL-MODUL, 'PORTIO' IST DAS ZUGE-      */ 
/*  HOERIGE ASSEMBLERMODUL.                                           */ 
/*                                                                    */ 
/*  BEIM AUFRUF DER PROCEDUREN 'OUTPORT' UND 'INPORT' MUSS U.A. EINE  */ 
/*  PORTNUMMER ALS PARAMETER UEBERGEBEN WERDEN. DIESE PORTNUMMER IST  */ 
/*  WIE FOLGT DEFINIERT ('/' BEDEUTET 'NEGIERT'):                     */ 
/*                                                                    */ 
/*  AUSGAENGE: PORT-NR  1- 8 = ECB-PORT A0-A7                         */ 
/*             PORT-NR  9-16 = ECB-PORT A8-A15                        */ 
/*             PORT-NR 17-20 = ECB-PORT /MRQ,/IORQ,/RD,/WR            */ 
/*             PORT-NR    23 = ECB-PORT /RESET                        */ 
/*                                                                    */ 
/*  EINGAENGE: PORT-NR 30-37 = ECB-PORT D0-D7                         */ 
/*             PORT-NR    38 = ECB-PORT /WAIT                         */ 
/*             PORT-NR 41-42 = ECB-PORT /NMI,/INT                     */ 
/*                                                                    */ 
/*  DIE EINGAENGE PORT-NR 38,41,42 SIND DURCH INTERNE PULLUP-WIDER-   */ 
/*  STAENDE (1 KOHM) AUS HIGH GEZOGEN. DIE UEBRIGEN EIN- AUSGAENGE    */ 
/*  SIND IM RUHEZUSTAND LOW.                                          */ 
/*                                                                    */ 
/*  ES WURDEN NUR EIN/AUSGABELEITUNGEN DES ECBBUS-STECKERS VERWENDET, */ 
/*  DA DIESE AM C'T-BUSINTERFACE AUSSEN ZUR VERFÜEGUNG STEHEN. DAS    */ 
/*  GEHAEUSE MUSS ALSO NICHT GEOEFFNET WERDEN.                        */ 
/*                                                                    */ 
/*  TROTZDEN KÖNNEN OHNE PROGRAMMÄNDERUNG NOCH FOLGENDE LEITUNGEN DES */ 
/*  INTERNEN IBM-BUSSES ANGESTEUERT WERDEN:                           */ 
/*    EINGÄNGE: PORT-NR 39-40 = IBM-BUS IORQ2 UND IORQ3               */ 
/*                                                                    */ 
/*  DURCH KLEINE PROGRAMMÄNDERUNGEN KÖNNEN AUCH NOCH DIE 8 AUSGÄNGE   */ 
/*  VON IC17 DES BUSINTERFACE, DIE EBENFALLS AM IBM-SLOT ANLIEGEN,    */ 
/*  GENUTZT WERDEN.                                                   */ 
/*                                                                    */ 
/*                                                                    */ 
/*  ERKLÄRUNGEN ZUM PROGRAMM:                                         */ 
/*                                                                    */ 
/*  DIE PARAMETERÜBER- UND RÜCKGABE ZUM UND VOM ASSEMBLERPROGRAMM     */ 
/*  ERFOLGT DER EINFACHHEIT HALBER ÜBER GLOBALE DECLARIERTE VARIABLE, */ 
/*  KÖNNTE ABER GENAUSO MITTELS PARAMETERTRANSFER IM PROCEDURAUFRUF   */ 
/*  DES PEARL-PROGRAMMS UND DEM HYPERPROC-BEFEHL 'MPXF ...' IM        */ 
/*  ASSEMBLERPROGRAMM ERFOLGEN.                                       */ 
/*                                                                    */ 
/*  DIE TASKS 'INTEST' UND 'OUTTEST' DIENEN NUR ZUM AUSTESTEN DER     */ 
/*  EIN/AUSGABE-PROCEDUREN.                                           */ 
/*                                                                    */ 
/**********************************************************************/ 

S=$2F00; 
/*+M */ 

MODULE EINAUS; 

/**********************************************************************/ 
SYSTEM; 
  NUL: NIL; 
  TASTE:A1(TFU=1); 
  TERM:A1; 
  PP:PP; 

/**********************************************************************/ 
PROBLEM; 


/* DATIONEN */ 
  SPC NUL DATION OUT ALPHIC CONTROL(ALL); 
  SPC TERM DATION INOUT ALPHIC CONTROL(ALL); 
  SPC TASTE DATION IN ALPHIC CONTROL(ALL); 
  SPC PP DATION OUT ALPHIC CONTROL(ALL); 

/* GLOBALE PROCEDUREN UND VARIABLE */ 

  SPC INOUT ENTRY GLOBAL; 
  DCL (DAT,ERG) BIT(16) GLOBAL; 
  DCL ADR BIT(32) GLOBAL; 


/* KONSTANTE */ 

  DCL ADR1 INV BIT(32) INIT('00FB0500'B4); 
  DCL ADR2 INV BIT(32) INIT('00FB0400'B4); 
  DCL ADR3 INV BIT(32) INIT('00FB0200'B4); 
  DCL ADR4 INV BIT(32) INIT('00FB0101'B4); 
  DCL ADR5 INV BIT(32) INIT('00FB0601'B4); 

  DCL (TRUE,HIGH) BIT(1) INIT('1'B); 
  DCL (FALSE,LOW) BIT(1) INIT('0'B); 

/* ARRAYS */ 

  DCL PORTDAT(3) BIT(16); /* PORTDATEN MERKEN */ 

/**********************************************************************/ 
OUTPORT:PROC (SET FIXED,PORT FIXED ) GLOBAL; 
/**********************************************************************/ 
/* SET=1    => DER PORT WIRD GESETZT */ 
/* SET=0    => DER PORT WIRD GELOESCHT */ 

DCL (HILF,HILF1,MERK) FIXED; 
DCL DATEN BIT(16) INIT('0000'B4); 

FALSE='0'B; 
TRUE='1'B; 

/* ADRESSE BESTIMMEN */ 
IF PORT<9 THEN               /* PORT 1...8 */ 
  ADR=ADR1; 
  HILF=0; 
  MERK=1; 
  DAT=PORTDAT(1); 
ELSE 
  IF PORT>16 THEN            /* PORT 17...23 */ 
    ADR=ADR3; 
    HILF=16; 
    MERK=3; 
    DAT=PORTDAT(3); 
  ELSE                       /* PORT 9...16 */ 
    ADR=ADR2; 
    HILF=8; 
    MERK=2; 
    DAT=PORTDAT(2); 
  FIN; 
FIN; 

/* ENTSPRECHENDES BIT SETZEN ODER LOESCHEN */ 

HILF1=PORT-HILF; 
IF SET==1 THEN 
  DAT.BIT(17-HILF1)=TRUE; 
ELSE 
  DAT.BIT(17-HILF1)=FALSE; 
FIN; 

/* NEUEN PORTZUSTAND MERKEN */ 
PORTDAT(MERK)=DAT; 

/* NEUEN PORTZUSTAND AN PORT AUSGEBEN */ 
CALL INOUT; /* GLOBALE FUNKTION (MASCHINENPROG.) */ 

END; /* OF PROC 'OUTPORT' */ 
/**********************************************************************/ 



/**********************************************************************/ 
INPORT:PROC (PORT FIXED) RETURNS(BIT(1)) GLOBAL; 
/**********************************************************************/ 

DCL HILF FIXED INIT(0); 
DCL ERGEBNIS BIT(1) INIT('0'B); 

ERG='00000000'B; /* VOREINSTELLUNG */ 
DAT='00000000'B; 

/* ADRESSE BESTIMMEN */ 

IF PORT>29 AND PORT<43 THEN 

    IF PORT<38 THEN            /* PORT 30...37 */ 
      HILF=29; 
      ADR=ADR4; 
    ELSE                       /* PORT 38...42 */ 
      HILF=37; 
      ADR=ADR5; 
    FIN; 

    /* HILFSPROCEDUR AUFRUFEN */ 
    CALL INOUT; 
    ERGEBNIS=ERG.BIT(17-(PORT-HILF)); 
FIN; 
RETURN (ERGEBNIS); 
END; /* OF PROC 'INPORT' */ 
/**********************************************************************/ 


/**********************************************************************/ 
OUTTEST:TASK; 
/**********************************************************************/ 

/* DIESE TASK TESTET DIE PROC 'OUTPORT' */ 

DCL HILF1 CHAR(1) INIT('A'); 
DCL HILF2 CHAR(1); 
DCL BORT FIXED; 

PORTDAT(1)='0000'B4; 
PORTDAT(2)='0000'B4; 
PORTDAT(3)='0000'B4; 
ADR='00000000'B4; 
DAT='0000'B4; 
ERG='0000'B4; 

WHILE HILF1 /= 'E' REPEAT 

  PUT 'PORT SETZEN:' TO TERM BY (2)SKIP,A; 
  PUT 'BITTE PORT-NR EINGEBEN >' TO TERM BY SKIP,A; 
  GET BORT FROM TERM BY SKIP,F(2); 
  CALL OUTPORT(1,BORT); 

  PUT 'PORT WIEDER LOESCHEN  => <RETURN>' TO TERM BY (2)SKIP,A; 
  GET HILF1 FROM TERM BY SKIP,A; 
  CALL OUTPORT(0,BORT); 

  PUT '<E>=ENDE   <RETURN>=NOCHMAL' TO TERM BY (2)SKIP,A; 
  GET HILF1 FROM TASTE BY SKIP,A; 

END; /* OF WHILE */ 

END; /* OF TASK 'OUTTEST' */ 
/**********************************************************************/ 


/**********************************************************************/ 
INTEST:TASK; 
/**********************************************************************/ 

DCL HILF1 CHAR(1) INIT ('A'); 
DCL HILF2 CHAR(1); 
DCL PORTNR FIXED; 
DCL ZUSTAND BIT(1) INIT('0'B); 

WHILE HILF1 /= 'E' REPEAT 

  PUT 'BITTE PORT-NUMMER EINGEBEN !  ' TO TERM BY (5)SKIP,A; 
  GET PORTNR FROM TERM; 

  ZUSTAND=INPORT(PORTNR);  /* PORTZUSTAND EINLESEN */ 
  PUT 'DER PORT NR ' TO TERM BY A; 
  PUT PORTNR TO TERM BY F(2); 
  PUT ' IST JETZT ' TO TERM BY A; 
  PUT ZUSTAND TO TERM BY B,(2)SKIP; 
  PUT '<E>=ENDE   <RETURN>=NOCHMAL' TO TERM BY A,SKIP;
  GET HILF1 FROM TASTE BY SKIP,A;

END;  /* OF WHILE */

END; /* OF TASK 'INTEST' */
/**********************************************************************/

MODEND;

Assembler-Teil (getrennt übersetzen):
************************************************************************
*   MODULKOPF FUER RTOS
*
       DC.L   0
       DC.L   0
       DC     $0010
       DC.B   'PORTIO'
*
*
************************************************************************ 
*     VERWENDETE TRAPS UND HYPERPROC-BEFEHLE 
* 
RETN   OPD    $4E4C 
ENTR   OPD.V  29 
EPAR   OPD.V  19 
OFF    OPD    $4E4F          DISPATCHER OFF, SUPERVISOR EIN 
QDPC   OPD    $4E43          ANSCHLIESSEND DISPATCHER STARTEN 
* 
* 
WSPSZ  EQU    $0             WORKSPACE-GROESSE 0 BYTES 
* 
* 
************************************************************************ 
*   PROGRAMMANFANG 
* 
>INOUT ENTR   WSPSZ.L        PROCEDUR-EINTRITT 
       EPAR                  KEINE PARAMETER 
* 
************************************************************************ 
* 
       MOVE.L =$00000000,D0       D0 LOESCHEN 
* 
       MOVE.L =$00000000,D1       D1 LOESCHEN 
* 
* 
* 
       MOVEA.L >ADR,A0       A0 MIT DER BASISADRESSE LADEN 
       MOVE.W >DAT,D0        DATEN IN D0 
       OFF                   DISPATCHER OFF, SUPERVISOR ON 
* 
*      LESEN VON ADR(A0+D0) = SCHREIBEN DER DATEN, D1=ERGEBNIS 
       MOVE.B 0(A0,D0.L),D1 
* 
       ANDI =$D8FF,SR        SUPERVISOR WIEDER AUSSCHALTEN 
       QDPC 
