Follow

How to Build a CICS Application with BMS Screens

Table of Contents

  1. Overview
  2. The three pieces
  3. Step 1 — Define the screen (BMS mapset)
  4. Step 2 — The symbolic map (how the program sees fields)
  5. Step 3 — Send the screen
  6. Step 4 — Receive the operator's input
  7. Step 5 — Connect screens: the pseudo-conversational loop
  8. Step 6 — Wire it into the application
  9. Summary
  10. Related articles

Audience: developers building or maintaining the screen (3270/BMS) part of a CICS PL/I application migrated to Java with Heirloom.


Overview

A BMS application shows the user a screen (a map), reads what they type, acts on it, and shows the next screen. Heirloom preserves this model end-to-end: your BMS map definitions and your EXEC CICS SEND MAP / RECEIVE MAP logic work the same after migration — the screen simply renders to a terminal emulator or web 3270 front end instead of a mainframe terminal.

This guide keeps things simple: define a screen, let the program read/write its fields, and connect screens together in the classic pseudo-conversational loop.

Note: All map, field, transaction, and program names below are examples. Use your own. The structure and commands are the part to learn.


The three pieces

Piece What it is
BMS map (mapset) The screen layout — where each field sits, its length, and its attributes. Defined in BMS source.
Symbolic map A data structure the program uses to read/write the screen's fields. Generated from the map.
Program logic Your PL/I that fills output fields, sends the map, receives input, and decides the next screen.

Step 1 — Define the screen (BMS mapset)

A mapset groups one or more maps. Each map lists its fields with a position (POS=(row,col)), a LENGTH, attributes (ATTRB), and optional constant text (INITIAL). Named fields are the ones the program reads or writes; unnamed fields are fixed labels.

MYSET    DFHMSD TYPE=MAP,MODE=INOUT,LANG=PLI,CTRL=FREEKB,STORAGE=AUTO
MENUMAP  DFHMDI SIZE=(24,80),TIOAPFX=YES
*        ---- fixed label (no name) ----
         DFHMDF POS=(01,01),LENGTH=10,ATTRB=(ASKIP,BRT),INITIAL='FUNCTION:'
*        ---- input field the operator types into ----
FUNCT    DFHMDF POS=(01,12),LENGTH=4,ATTRB=(UNPROT)
*        ---- output-only message line ----
MSG      DFHMDF POS=(24,01),LENGTH=79,ATTRB=(ASKIP)
         DFHMSD TYPE=FINAL
         END

Common attributes (ATTRB)

Attribute Meaning
UNPROT Operator can type into the field (input)
PROT Protected — display only
ASKIP Auto-skip — cursor jumps past it (labels, output)
BRT / NORM / DRK Bright / normal / non-display (e.g. passwords)
NUM Numeric input only

Place the BMS source files in the application's bms/ folder so they are packaged with the app.


Step 2 — The symbolic map (how the program sees fields)

For each named field, BMS generates a small set of fields the program uses. For a field named FUNCT:

Generated field Use
FUNCTI Input — what the operator typed
FUNCTO Output — what you want displayed
FUNCTL Length / cursor info
FUNCTA Attribute byte — change it to alter color/protection at runtime

The symbolic map is brought into the program with an include (your migration keeps the copybook), and your program reads …I fields and writes …O fields.


Step 3 — Send the screen

Fill the output fields, then SEND MAP. ERASE clears the screen first (use it for the first send of a screen):

MSGO = 'Enter a function code';        /* set an output field */
EXEC CICS SEND MAP('MENUMAP') MAPSET('MYSET')
          ERASE
          RESP(WS_RESP) RESP2(WS_RESP2);

Useful options:

  • ERASE — clear the screen before drawing.
  • DATAONLY — send only the data (keep the existing layout) — for re-displays.
  • MAPONLY — send the layout with no program data.
  • CURSOR — position the cursor.

Step 4 — Receive the operator's input

EXEC CICS RECEIVE MAP('MENUMAP') MAPSET('MYSET')
          INTO(MENU_SYMBOLIC)
          RESP(WS_RESP) RESP2(WS_RESP2);

IF WS_RESP = DFHRESP(MAPFAIL) THEN
   /* operator pressed a key without entering data — handle it */ ;
ELSE
   /* read the typed value from FUNCTI */ ;

MAPFAIL means there was no input data to map (for example the operator just pressed Enter on an empty screen) — handle it rather than treating it as an error.


Step 5 — Connect screens: the pseudo-conversational loop

CICS screen apps are usually pseudo-conversational: the program sends a screen and ends, returning control with the transaction to run next. When the operator presses a key, that transaction starts again, receives the input, and continues. This frees resources while the user is thinking.

/* ... SEND MAP to show the screen ... */
EXEC CICS RETURN TRANSID('TRN1')          /* run TRN1 again on next key */
          COMMAREA(STATE)                 /* carry state across the pause */
          RESP(WS_RESP);

On re-entry, check which key the operator pressed via EIBAID, then act:

IF EIBAID = DFHPF3 THEN
   /* PF3 = exit */ ;
ELSE IF EIBAID = DFHENTER THEN
   DO;
      EXEC CICS RECEIVE MAP('MENUMAP') MAPSET('MYSET') INTO(MENU_SYMBOLIC);
      /* validate FUNCTI, do the work, decide the next screen */
   END;

DFHENTER, DFHPF1DFHPF24, DFHCLEAR, etc. come from the standard attention-id definitions (carried in via the usual include). The state you need between keystrokes travels in the COMMAREA.

        ┌─────────────────────────────────────────────┐
        ▼                                               │
   SEND MAP  ──▶  RETURN TRANSID('TRN1') (program ends) │
                                                        │
   operator presses a key ──▶ TRN1 starts again ────────┘
        │
        ▼
   check EIBAID ──▶ RECEIVE MAP ──▶ validate ──▶ next screen / exit

Step 6 — Wire it into the application

  • Package the maps: put the BMS source in the app's bms/ folder so it ships with the WAR.
  • Configure BMS: the application's deploy.properties carries BMS settings such as the control options (bms.ctrl) and the map character set (BMSCharset).
  • Register the program & transaction: add the program to the program registry (program.<name>) and make sure the transaction id you RETURN TRANSID to maps to it. (See How to Configure and Deploy a Migrated CICS Application.)
  • Front end: the screen renders to a 3270 terminal emulator or web 3270 client; field attributes and positions from your BMS source are honored.

Summary

  • A BMS app is map (layout) + symbolic map (fields) + program logic.
  • Define fields with POS / LENGTH / ATTRB; named fields become …I (input) / …O (output) in the symbolic map.
  • SEND MAP (with ERASE / DATAONLY) draws the screen; RECEIVE MAP … INTO reads input; handle MAPFAIL.
  • Use the pseudo-conversational loop: SEND MAPRETURN TRANSID with a COMMAREA → on re-entry check EIBAIDRECEIVE MAP → act.
  • Package BMS source in bms/, set bms.ctrl / BMSCharset, and register the program/transaction.

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

0 Comments

Article is closed for comments.
Powered by Zendesk