Table of Contents
- Overview
- The three pieces
- Step 1 — Define the screen (BMS mapset)
- Step 2 — The symbolic map (how the program sees fields)
- Step 3 — Send the screen
- Step 4 — Receive the operator's input
- Step 5 — Connect screens: the pseudo-conversational loop
- Step 6 — Wire it into the application
- Summary
- 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, DFHPF1–DFHPF24, 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.propertiescarries 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 youRETURN TRANSIDto 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(withERASE/DATAONLY) draws the screen;RECEIVE MAP … INTOreads input; handleMAPFAIL. - Use the pseudo-conversational loop:
SEND MAP→RETURN TRANSIDwith aCOMMAREA→ on re-entry checkEIBAID→RECEIVE MAP→ act. - Package BMS source in
bms/, setbms.ctrl/BMSCharset, and register the program/transaction.
Related articles
- How to Configure and Deploy a Migrated CICS Application — packaging, program registry, deploy flow.
- How Transactions Are Managed (ETP + PL/I Runtime) — what happens between pseudo-conversational keystrokes.
- Understanding Your Migrated PL/I Application — the big picture.
0 Comments