unit capi;

  interface (* capi *)

    const (* konstanten *)

      (* --- INTERRUPT UND SPEICHERGRSSEN --- *)

      capi_int          = $F1;  (* interrupt-nummer                   *)
      capi_messages     =  70;  (* anzahl speicherbare messages       *)
      capi_level_3      =   4;  (* anzahl ebene-3-verbindungen        *)
      capi_b3_data      =   8;  (* anzahl empfangene b3-datenblcke   *)
      capi_b3_size      = 130;  (* maximale lnge empfangene b3-daten *)
      capi_message_size = 180;  (* maximale message-lnge             *)

      (* --- COMMANDS --- *)

      capi_connect            = $02;
      capi_connect_info       = $09;
      capi_connect_active     = $03;
      capi_disconnect         = $04;
      capi_listen             = $05;
      capi_get_params         = $06;
      capi_info               = $07;
      capi_data               = $08;
      capi_select_b2_protocol = $40;
      capi_select_b3_protocol = $80;
      capi_listen_b3          = $81;
      capi_connect_b3         = $82;
      capi_connect_b3_active  = $83;
      capi_disconnect_b3      = $84;
      capi_get_b3_params      = $85;
      capi_data_b3            = $86;
      capi_reset_b3           = $01;
      capi_handset            = $87;
      capi_manufacturer       = $FF;

      (* --- SUBCOMMANDS --- *)

      capi_req  = 0;
      capi_conf = 1;
      capi_ind  = 2;
      capi_resp = 3;

      (* --- COMMANDS & SUBCOMMANDS (NUR DIE ERLAUBTEN) --- *)
      (* --- COMMAND STEHT IM MSB, SUBCOMMAND IM LSB --- *)

      capi_connect_req             = (capi_connect            shl 8) or capi_req;
      capi_connect_conf            = (capi_connect            shl 8) or capi_conf;
      capi_connect_ind             = (capi_connect            shl 8) or capi_ind;
      capi_connect_resp            = (capi_connect            shl 8) or capi_resp;

      capi_connect_info_req        = (capi_connect_info       shl 8) or capi_req;
      capi_connect_info_conf       = (capi_connect_info       shl 8) or capi_conf;

      capi_connect_active_ind      = (capi_connect_active     shl 8) or capi_ind;
      capi_connect_active_resp     = (capi_connect_active     shl 8) or capi_resp;

      capi_disconnect_req          = (capi_disconnect         shl 8) or capi_req;
      capi_disconnect_conf         = (capi_disconnect         shl 8) or capi_conf;
      capi_disconnect_ind          = (capi_disconnect         shl 8) or capi_ind;
      capi_disconnect_resp         = (capi_disconnect         shl 8) or capi_resp;

      capi_listen_req              = (capi_listen             shl 8) or capi_req;
      capi_listen_conf             = (capi_listen             shl 8) or capi_conf;

      capi_get_params_req          = (capi_get_params         shl 8) or capi_req;
      capi_get_params_conf         = (capi_get_params         shl 8) or capi_conf;

      capi_info_req                = (capi_info               shl 8) or capi_req;
      capi_info_conf               = (capi_info               shl 8) or capi_conf;
      capi_info_ind                = (capi_info               shl 8) or capi_ind;
      capi_info_resp               = (capi_info               shl 8) or capi_resp;

      capi_data_req                = (capi_data               shl 8) or capi_req;
      capi_data_conf               = (capi_data               shl 8) or capi_conf;
      capi_data_ind                = (capi_data               shl 8) or capi_ind;
      capi_data_resp               = (capi_data               shl 8) or capi_resp;

      capi_select_b2_protocol_req  = (capi_select_b2_protocol shl 8) or capi_req;
      capi_select_b2_protocol_conf = (capi_select_b2_protocol shl 8) or capi_conf;

      capi_select_b3_protocol_req  = (capi_select_b3_protocol shl 8) or capi_req;
      capi_select_b3_protocol_conf = (capi_select_b3_protocol shl 8) or capi_conf;

      capi_listen_b3_req           = (capi_listen_b3          shl 8) or capi_req;
      capi_listen_b3_conf          = (capi_listen_b3          shl 8) or capi_req;

      capi_connect_b3_req          = (capi_connect_b3         shl 8) or capi_req;
      capi_connect_b3_conf         = (capi_connect_b3         shl 8) or capi_conf;
      capi_connect_b3_ind          = (capi_connect_b3         shl 8) or capi_ind;
      capi_connect_b3_resp         = (capi_connect_b3         shl 8) or capi_resp;

      capi_connect_b3_active_ind   = (capi_connect_b3_active  shl 8) or capi_ind;
      capi_connect_b3_active_resp  = (capi_connect_b3_active  shl 8) or capi_resp;

      capi_disconnect_b3_req       = (capi_disconnect_b3      shl 8) or capi_req;
      capi_disconnect_b3_conf      = (capi_disconnect_b3      shl 8) or capi_conf;
      capi_disconnect_b3_ind       = (capi_disconnect_b3      shl 8) or capi_ind;
      capi_disconnect_b3_resp      = (capi_disconnect_b3      shl 8) or capi_resp;

      capi_get_b3_params_req       = (capi_get_b3_params      shl 8) or capi_req;
      capi_get_b3_params_conf      = (capi_get_b3_params      shl 8) or capi_conf;

      capi_data_b3_req             = (capi_data_b3            shl 8) or capi_req;
      capi_data_b3_conf            = (capi_data_b3            shl 8) or capi_conf;
      capi_data_b3_ind             = (capi_data_b3            shl 8) or capi_ind;
      capi_data_b3_resp            = (capi_data_b3            shl 8) or capi_resp;

      capi_reset_b3_req            = (capi_reset_b3           shl 8) or capi_req;
      capi_reset_b3_conf           = (capi_reset_b3           shl 8) or capi_conf;
      capi_reset_b3_ind            = (capi_reset_b3           shl 8) or capi_ind;
      capi_reset_b3_resp           = (capi_reset_b3           shl 8) or capi_resp;

      capi_handset_ind             = (capi_handset            shl 8) or capi_ind;
      capi_handset_resp            = (capi_handset            shl 8) or capi_resp;

      capi_manufacturer_req        = (capi_manufacturer       shl 8) or capi_req;
      capi_manufacturer_conf       = (capi_manufacturer       shl 8) or capi_conf;
      capi_manufacturer_ind        = (capi_manufacturer       shl 8) or capi_ind;
      capi_manufacturer_resp       = (capi_manufacturer       shl 8) or capi_resp;

    type (* typen *)

      capi_header=record
                    length    :word;
                    appl_id   :word;
                    command   :byte;
                    subcommand:byte;
                    number    :word
                  end; (* capi_header *)

      capi_body=record
                  case word of
                    capi_connect_req             : (capi_connect_req_controller               : byte;
                                                    capi_connect_req_b_channel                : byte;
                                                    capi_connect_req_info_mask                : longint;
                                                    capi_connect_req_outgoing_service         : byte;
                                                    capi_connect_req_outgoing_service_add     : byte;
                                                    capi_connect_req_source_eaz               : char;
                                                    capi_connect_req_destination_address      : string);
                    capi_connect_conf            : (capi_connect_conf_plci                    : word;
                                                    capi_connect_conf_info                    : word);
                    capi_connect_ind             : (capi_connect_ind_plci                     : word;
                                                    capi_connect_ind_controller               : byte;
                                                    capi_connect_ind_requested_service        : byte;
                                                    capi_connect_ind_requested_service_add    : byte;
                                                    capi_connect_ind_requested_eaz            : char;
                                                    capi_connect_ind_caller_address           : string);
                    capi_connect_resp            : (capi_connect_resp_plci                    : word;
                                                    capi_connect_resp_reject                  : byte);
                    capi_connect_info_req        : (capi_connect_info_req_plci                : word;
                                                    capi_connect_info_req_destination_address : string);
                    capi_connect_info_conf       : (capi_connect_info_conf_plci               : word;
                                                    capi_connect_info_conf_info               : word);
                    capi_connect_active_ind      : (capi_connect_active_ind_plci              : word;
                                                    capi_connect_active_ind_connected_address : string);
                    capi_connect_active_resp     : (capi_connect_active_resp_plci             : word);
                    capi_disconnect_req          : (capi_disconnect_req_plci                  : word;
                                                    capi_disconnect_req_cause                 : byte);
                    capi_disconnect_conf         : (capi_disconnect_conf_plci                 : word;
                                                    capi_disconnect_conf_info                 : word);
                    capi_disconnect_ind          : (capi_disconnect_ind_plci                  : word;
                                                    capi_disconnect_ind_info                  : word);
                    capi_disconnect_resp         : (capi_disconnect_resp_plci                 : word);
                    capi_listen_req              : (capi_listen_req_controller                : byte;
                                                    capi_listen_req_info_mask                 : longint;
                                                    capi_listen_req_serviced_eaz_mask         : word;
                                                    capi_listen_req_serviced_si_mask          : word);
                    capi_listen_conf             : (capi_listen_conf_controller               : byte;
                                                    capi_listen_conf_info                     : word);
                    capi_get_params_req          : (capi_get_params_req_plci                  : word);
                    capi_get_params_conf         : (capi_get_params_conf_plci                 : word;
                                                    capi_get_params_conf_controller           : byte;
                                                    capi_get_params_conf_b_channel            : byte;
                                                    capi_get_params_conf_info                 : word;
                                                    capi_get_params_conf_b3_link_count        : byte;
                                                    capi_get_params_conf_service              : byte;
                                                    capi_get_params_conf_service_add          : byte;
                                                    capi_get_params_conf_serviced_eaz         : char;
                                                    capi_get_params_conf_connected_address    : string);
                    capi_info_req                : (capi_info_req_plci                        : word;
                                                    capi_info_req_info_mask                   : longint);
                    capi_info_conf               : (capi_info_conf_plci                       : word;
                                                    capi_info_conf_info                       : word);
                    capi_info_ind                : (capi_info_ind_plci                        : word;
                                                    capi_info_ind_info_number                 : word;
                                                    capi_info_ind_info_element                : string);
                    capi_info_resp               : (capi_info_resp_plci                       : word);
                    capi_data_req                : (capi_data_req_plci                        : word;
                                                    capi_data_req_user_data                   : string);
                    capi_data_conf               : (capi_data_conf_plci                       : word;
                                                    capi_data_conf_info                      : word);
                    capi_data_ind                : (capi_data_ind_plci                        : word;
                                                    capi_data_ind_user_data                   : string);
                    capi_data_resp               : (capi_data_resp_plci                       : word);
                    capi_select_b2_protocol_req  : (capi_select_b2_protocol_req_plci          : word;
                                                    capi_select_b2_protocol_req_b2_protocol   : byte;
                                                    capi_select_b2_protocol_req_dlpd          : record
                                                                                                  length         : byte;
                                                                                                  data_length    : word;
                                                                                                  link_address_a : byte;
                                                                                                  link_address_b : byte;
                                                                                                  modulo_mode    : byte;
                                                                                                  window_size    : byte;
                                                                                                  v110_user_rate : byte;
                                                                                                  xid            : string
                                                                                                end);
                    capi_select_b2_protocol_conf : (capi_select_b2_protocol_conf_plci         : word;
                                                    capi_select_b2_protocol_conf_info         : word);
                    capi_select_b3_protocol_req  : (capi_select_b3_protocol_req_plci          : word;
                                                    capi_select_b3_protocol_req_b3_protocol   : byte;
                                                    capi_select_b3_protocol_req_ncpd          : record
                                                                                                  length      : byte;
                                                                                                  lic         : word;
                                                                                                  hic         : word;
                                                                                                  ltc         : word;
                                                                                                  htc         : word;
                                                                                                  loc         : word;
                                                                                                  hoc         : word;
                                                                                                  modulo_mode : byte
                                                                                                end);
                    capi_select_b3_protocol_conf : (capi_select_b3_protocol_conf_plci         : word;
                                                    capi_select_b3_protocol_conf_info         : word);
                    capi_listen_b3_req           : (capi_listen_b3_req_plci                   : word);
                    capi_listen_b3_conf          : (capi_listen_b3_conf_plci                  : word;
                                                    capi_listen_b3_conf_info                  : word);
                    capi_connect_b3_req          : (capi_connect_b3_req_plci                  : word;
                                                    capi_connect_b3_req_ncpi                  : string);
                    capi_connect_b3_conf         : (capi_connect_b3_conf_plci                 : word;
                                                    capi_connect_b3_conf_ncci                 : word;
                                                    capi_connect_b3_conf_info                 : word);
                    capi_connect_b3_ind          : (capi_connect_b3_ind_ncci                  : word;
                                                    capi_connect_b3_ind_plci                  : word;
                                                    capi_connect_b3_ind_ncpi                  : string);
                    capi_connect_b3_resp         : (capi_connect_b3_resp_ncci                 : word;
                                                    capi_connect_b3_resp_reject               : byte;
                                                    capi_connect_b3_resp_ncpi                 : string);
                    capi_connect_b3_active_ind   : (capi_connect_b3_active_ind_ncci           : word;
                                                    capi_connect_b3_active_ind_ncpi           : string);
                    capi_connect_b3_active_resp  : (capi_connect_b3_active_resp_ncci          : word);
                    capi_disconnect_b3_req       : (capi_disconnect_b3_req_ncci               : word;
                                                    capi_disconnect_b3_req_ncpi               : string);
                    capi_disconnect_b3_conf      : (capi_disconnect_b3_conf_ncci              : word;
                                                    capi_disconnect_b3_conf_info              : word);
                    capi_disconnect_b3_ind       : (capi_disconnect_b3_ind_ncci               : word;
                                                    capi_disconnect_b3_ind_info               : word;
                                                    capi_disconnect_b3_ind_ncpi               : string);
                    capi_disconnect_b3_resp      : (capi_disconnect_b3_resp_ncci              : word);
                    capi_get_b3_params_req       : (capi_get_b3_params_req_ncci               : word);
                    capi_get_b3_params_conf      : (capi_get_b3_params_conf_ncci              : word;
                                                    capi_get_b3_params_conf_plci              : word;
                                                    capi_get_b3_params_conf_info              : word);
                    capi_data_b3_req             : (capi_data_b3_req_ncci                     : word;
                                                    capi_data_b3_req_data_length              : word;
                                                    capi_data_b3_req_data                     : pointer;
                                                    capi_data_b3_req_number                   : byte;
                                                    capi_data_b3_req_flags                    : word);
                    capi_data_b3_conf            : (capi_data_b3_conf_ncci                    : word;
                                                    capi_data_b3_conf_number                  : byte;
                                                    capi_data_b3_conf_info                    : word);
                    capi_data_b3_ind             : (capi_data_b3_ind_ncci                     : word;
                                                    capi_data_b3_ind_data_length              : word;
                                                    capi_data_b3_ind_data                     : pointer;
                                                    capi_data_b3_ind_number                   : byte;
                                                    capi_data_b3_ind_flags                    : word);
                    capi_data_b3_resp            : (capi_data_b3_resp_ncci                    : word;
                                                    capi_data_b3_resp_number                  : byte);
                    capi_reset_b3_req            : (capi_reset_b3_req_ncci                    : word);
                    capi_reset_b3_conf           : (capi_reset_b3_conf_ncci                   : word;
                                                    capi_reset_b3_conf_info                   : word);
                    capi_reset_b3_ind            : (capi_reset_b3_ind_ncci                    : word);
                    capi_reset_b3_resp           : (capi_reset_b3_resp_ncci                   : word);
                    capi_handset_ind             : (capi_handset_ind_plci                     : word;
                                                    capi_handset_ind_controller               : byte;
                                                    capi_handset_ind_status                   : char);
                    capi_handset_resp            : (capi_handset_resp_plci                    : word);
                    capi_manufacturer_req        : (capi_manufacturer_req_specific            : string);
                    capi_manufacturer_conf       : (capi_manufacturer_conf_specific           : string);
                    capi_manufacturer_ind        : (capi_manufacturer_ind_specific            : string);
                    capi_manufacturer_resp       : (capi_manufacturer_resp_specific           : string)
                end; (* capi_body *)

      capi_message=record
                     h:capi_header;
                     b:capi_body
                   end; (* capi_message *)

      capi_pointer=^capi_message;

    (* --- PROZEDUREN UND FUNKTIONEN --- *)

    function capi_command(b:byte;sub:boolean):string;
    function capi_error(error:word):string;
    function capi_get_manufacturer:string;
    function capi_get_message(var p:capi_pointer):word;
    function capi_get_serial_number:string;
    function capi_get_version:string;
    function capi_is_installed:boolean;
    function capi_put_message(var message):word;
    function capi_register:word;
    function capi_release:word;
    function capi_send_req(comm:byte;block:capi_body;paramlen:word):word;
    function capi_send_resp(comm:byte;block:capi_body;paramlen,nr:word):word;

  implementation (* capi *)

    uses dos,util;

    var capi_buffer:array[ 1
                           ..
                           capi_message_size*capi_messages
                           +
                           capi_level_3*capi_b3_data*capi_b3_size
                         ] of byte;
        capi_appl_id,capi_msg_out:word;

    function capi_command(b:byte;sub:boolean):string;
      var temp:string;
      begin (* capi_command *)
        if sub then begin (* subcommand *)
          case b of
            $00:temp:='REQ';
            $01:temp:='CONF';
            $02:temp:='IND';
            $03:temp:='RESP'
          else (* case b *)
            temp:='SUBCOMMAND_'+hex_byte(b,false)
          end (* case b *)
        end else begin (* also: not sub: command *)
          case b of
            $02:temp:='CONNECT';
            $09:temp:='CONNECT_INFO';
            $03:temp:='CONNECT_ACTIVE';
            $04:temp:='DISCONNECT';
            $05:temp:='LISTEN';
            $06:temp:='GET_PARAMS';
            $07:temp:='INFO';
            $08:temp:='DATA';
            $40:temp:='SELECT_B2_PROTOCOL';
            $80:temp:='SELECT_B3_PROTOCOL';
            $81:temp:='LISTEN_B3';
            $82:temp:='CONNECT_B3';
            $83:temp:='CONNECT_B3_ACTIVE';
            $84:temp:='DISCONNECT_B3';
            $85:temp:='GET_B3_PARAMS';
            $86:temp:='DATA_B3';
            $01:temp:='RESET_B3';
            $87:temp:='HANDSET';
            $FF:temp:='MANUFACTURER'
          else (* case b *)
            temp:='COMMAND_'+hex_byte(b,false)
          end (* case b *)
        end; (* not sub: command *)
        capi_command:=temp
      end; (* capi_command *)

    function capi_error(error:word):string;
      var temp:string;
      begin (* capi_error *)
        case error of
          $0000:temp:='Kein Fehler';
          $1001:temp:='Fehler beim Registrieren';
          $1002:temp:='Applikationsnummer falsch';
          $1003:temp:='Message zu klein oder Messagenummer falsch kodiert';
          $1004:temp:='Falsches Command oder Subcommand';
          $1005:temp:='Message-Queue voll';
          $1006:temp:='Message-Queue war leer';
          $1007:temp:='Mindestens eine Message an die Applikation ist'^M^J+
                      'verlorengegangen, da die Message-Queue voll war';
          $1008:temp:='Fehler bei Deinstallation';
          $2001:temp:='Falscher Controller';
          $2002:temp:='Falscher PLCI';
          $2003:temp:='Falscher NCCI';
          $3101:temp:='B-Channel falsch kodiert';
          $3102:temp:='Info-Mask falsch kodiert';
          $3103:temp:='Serviced-EAZ-Mask falsch kodiert';
          $3104:temp:='Serviced-SI-Mask falsch kodiert';
          $3105:temp:='B2-Protocol falsch';
          $3106:temp:='DLPD falsch';
          $3107:temp:='B3-Protocol falsch';
          $3108:temp:='NCPD falsch';
          $3109:temp:='NCPI falsch';
          $310A:temp:='Flags falsch kodiert';
          $3202:temp:='Konflikt zwischen Anmeldungen';
          $3203:temp:='Funktion wird nicht untersttzt';
          $3204:temp:='PLCI nicht aktiv';
          $3205:temp:='NCCI nicht aktiv';
          $3206:temp:='B2-Protokoll wird nicht untersttzt';
          $3207:temp:='Umschalten des B2-Protokolls in diesem Zustand nicht mglich';
          $3208:temp:='B3-Protokoll wird nicht untersttzt';
          $3209:temp:='Umschalten des B3-Protokolls in diesem Zustand nicht mglich';
          $320A:temp:='Verwendete Parameter im DLPD werden nicht untersttzt';
          $320B:temp:='Verwendete Parameter im NCPD werden nicht untersttzt';
          $320C:temp:='Verwendete Parameter im MCPI werden nicht untersttzt';
          $320D:temp:='Nicht untersttzte Data-Length';
          $3301:temp:='Fehler beim Aufbau D-Kanal Ebene 1';
          $3302:temp:='Fehler beim Aufbau D-Kanal Ebene 2';
          $3303:temp:='Fehler beim Aufbau B-Kanal Ebene 1';
          $3304:temp:='Fehler beim Aufbau B-Kanal Ebene 2';
          $3305:temp:='Abbruch D-Kanal Ebene 1';
          $3306:temp:='Abbruch D-Kanal Ebene 2';
          $3307:temp:='Abbruch D-Kanal Ebene 3';
          $3308:temp:='Abbruch B-Kanal Ebene 1';
          $3309:temp:='Abbruch B-Kanal Ebene 2';
          $330A:temp:='Abbruch B-Kanal Ebene 3';
          $330C:temp:='Reestablish B-Kanal Ebene 3';
          $3400
            ..
          $34FF:temp:='Abbruch durch das Netzwerk, Cause 0'+hex_byte(lo(error),false)+'H'
        else (* case error *)
          temp:='Fehler 0'+hex_word(error,false)+'H'
        end; (* case error *)
        capi_error:=temp
      end; (* capi_error *)

    function capi_get_manufacturer:string;
      var regs:registers;
          temp:string;
      begin (* capi_get_manufacturer *)
        with regs do begin
          ah:=$F0; (* API_GET_MANUFACTURER *)
          es:=seg(temp);
          bx:=ofs(temp)
        end; (* with regs *)
        intr(capi_int,regs);
        capi_get_manufacturer:=asciiz_to_string(temp)
      end; (* capi_get_manufacturer *)

    function capi_get_message(var p:capi_pointer):word;
      var regs:registers;
      begin (* capi_get_message *)
        with regs do begin
          ah:=4; (* API_GET_MESSAGE *)
          dx:=capi_appl_id
        end; (* with regs *)
        intr(capi_int,regs);
        with regs do begin
          capi_get_message:=ax;
          if ax=0 then (* aufruf ok, pointer zuweisen *)
            p:=ptr(es,bx)
        end (* with regs *)
      end; (* capi_get_message *)

    function capi_get_serial_number:string;
      var regs:registers;
          temp:string;
      begin (* capi_get_serial_number *)
        with regs do begin
          ah:=$F2; (* API_GET_SERIAL_NUMBER *)
          es:=seg(temp);
          bx:=ofs(temp)
        end; (* with regs *)
        intr(capi_int,regs);
        capi_get_serial_number:=asciiz_to_string(temp)
      end; (* capi_get_serial_number *)

    function capi_get_version:string;
      var regs:registers;
          temp:string;
      begin (* capi_get_version *)
        with regs do begin
          ah:=$F1; (* API_GET_VERSION *)
          es:=seg(temp);
          bx:=ofs(temp)
        end; (* with regs *)
        intr(capi_int,regs);
        capi_get_version:=asciiz_to_string(temp)
      end; (* capi_get_version *)

    function capi_is_installed:boolean;
      var regs:registers;
          pb:^byte;
          pw:^word;
      const ia:word=byte('I') or (byte('A') shl 8);
      begin (* capi_is_installed *)
        with regs do begin
          ah:=$35;
          al:=capi_int
        end; (* with regs *)
        msdos(regs);
        with regs do
          pb:=ptr(es,bx);
        if pb=nil then (* steht 0 im interrupt vector *)
          capi_is_installed:=false
        else begin (* also: pb<>nil: irgendeinen pointer gibt's da *)
          if pb^=$C3 then (* da steht nur IRET *)
            capi_is_installed:=false
          else begin (* also: pb^<>$C3: da steht irgendeine routine *)
            with regs do
              pw:=ptr(es,bx+9);
            capi_is_installed:=(pw^=ia)
          end (* pb^<>$C3: da steht irgendeine routine *)
        end (* pb<>nil: irgendeinen pointer gibt's da *)
      end; (* capi_is_installed *)

    function capi_put_message(var message):word;
      var regs:registers;
      begin (* capi_put_message *)
        with regs do begin
          ah:=3; (* API_PUT_MESSAGE *)
          dx:=capi_appl_id;
          es:=seg(message);
          bx:=ofs(message)
        end; (* with regs *)
        intr(capi_int,regs);
        capi_put_message:=regs.ax
      end; (* capi_put_message *)

    function capi_register:word;
      var regs:registers;
      begin (* capi_register *)
        if capi_appl_id=0 then begin (* noch nicht registered *)
          with regs do begin
            ah:=1; (* API_REGISTER *)
            es:=seg(capi_buffer);
            bx:=ofs(capi_buffer);
            cx:=capi_messages;
            dx:=capi_level_3;
            si:=capi_b3_data;
            di:=capi_b3_size
          end; (* with regs *)
          intr(capi_int,regs);
          with regs do begin
            if ax=0 then (* fehler: error in bx *)
              capi_register:=bx
            else begin (* also: ax(<)>0: kein fehler, appl_id in ax *)
              capi_appl_id:=ax;
              capi_msg_out:=0;
              capi_register:=0
            end (* ax(<)>0: kein fehler, appl_id in ax *)
          end (* with regs *)
        end else (* also: capi_appl_id(<)>0: schon registered *)
          capi_register:=$FFFF
      end; (* capi_register *)

    function capi_release:word;
      var regs:registers;
      begin (* capi_release *)
        if capi_appl_id=0 then (* war gar nicht registered *)
          capi_release:=$FFFF
        else begin (* also: capi_appl_id(<)>0: war registered *)
          with regs do begin
            ah:=2; (* API_RELEASE *)
            dx:=capi_appl_id
          end; (* with regs *)
          intr(capi_int,regs);
          capi_release:=regs.ax
        end (* capi_appl_id(<)>0: war registered *)
      end; (* capi_release *)

    function capi_send_req(comm:byte;block:capi_body;paramlen:word):word;
      var message:capi_message;
      begin (* capi_send_req *)
        with message do begin
          with h do begin (* header aufbauen *)
            length:=sizeof(h)+paramlen;
            appl_id:=capi_appl_id;
            command:=comm;
            subcommand:=capi_req;
            number:=capi_msg_out
          end; (* with h: header aufbauen *)
          b:=block
        end; (* with message *)
        inc(capi_msg_out);
        if capi_msg_out=$8000 then
          capi_msg_out:=0;
        capi_send_req:=capi_put_message(message)
      end; (* capi_send_req *)

    function capi_send_resp(comm:byte;block:capi_body;paramlen,nr:word):word;
      var message:capi_message;
      begin (* capi_send_resp *)
        with message do begin
          with h do begin (* header aufbauen *)
            length:=sizeof(h)+paramlen;
            appl_id:=capi_appl_id;
            command:=comm;
            subcommand:=capi_resp;
            number:=nr
          end; (* with h: header aufbauen *)
          b:=block
        end; (* with message *)
        capi_send_resp:=capi_put_message(message)
      end; (* capi_send_resp *)

  begin (* capi *)
    capi_appl_id:=0 (* not registered *)
  end. (* capi *)