MainframeCICSCICS Complete Reference

CICS BMS Maps: Complete Guide to Basic Mapping Support (2026)

TT
TopicTrick Team
CICS BMS Maps: Complete Guide to Basic Mapping Support (2026)

Introduction: Why BMS Is Still Essential for Mainframe CICS Developers

Long before web browsers, smartphones, and REST APIs, enterprise transactions happened on 3270 terminals — green-screen displays connected to mainframes. CICS still powers billions of transactions daily on these same 3270 sessions, and the technology that paints those screens and reads user input is called Basic Mapping Support (BMS). Even as modern CICS supports web services, RESTful APIs, and JSON, the overwhelming majority of existing CICS COBOL applications use BMS for their terminal interfaces — and those applications will be in production for decades.

This guide teaches BMS from the ground up: how to write mapset definitions, how the symbolic description map becomes a COBOL copybook, and how SEND MAP and RECEIVE MAP drive the screen I/O cycle in a pseudo-conversational program.


The Three BMS Macro Levels

BMS screens are defined using three nested assembler macros:

DFHMSD — Mapset definition (outermost). Defines the load module name, the terminal type (TYPE=MAP for the physical module, TYPE=DSECT for the COBOL copybook), and global attributes like screen size.

DFHMDI — Map definition. Defines one screen within the mapset: its position on the physical screen (LINE, COLUMN), its size, and its name.

DFHMDF — Field definition. Defines one field within a map: its position, length, initial value, and attributes (protected/unprotected, bright/normal/dark, numeric, etc.).

Here is a minimal example that defines a mapset named EMPIMAPS containing one map named EMPIMAP:

assembler
EMPIMAPS DFHMSD TYPE=MAP,                                              X
               LANG=COBOL,                                             X
               MODE=INOUT,                                             X
               TERM=3270-2,                                            X
               TIOAPFX=YES,                                            X
               STORAGE=AUTO

EMPIMAP  DFHMDI SIZE=(24,80),                                          X
               LINE=1,                                                  X
               COLUMN=1

*── Title line ──────────────────────────────────────────────────────
         DFHMDF POS=(1,25),                                            X
               ATTRB=(PROT,NORM),                                      X
               LENGTH=30,                                              X
               INITIAL='EMPLOYEE INQUIRY SCREEN'

*── Employee number prompt ──────────────────────────────────────────
         DFHMDF POS=(5,2),                                             X
               ATTRB=(PROT,NORM),                                      X
               LENGTH=16,                                              X
               INITIAL='EMPLOYEE NUMBER:'

EMPNO    DFHMDF POS=(5,19),                                            X
               ATTRB=(UNPROT,NORM,IC),                                 X
               LENGTH=6

*── Name display (output only) ──────────────────────────────────────
         DFHMDF POS=(7,2),                                             X
               ATTRB=(PROT,NORM),                                      X
               LENGTH=5,                                               X
               INITIAL='NAME:'

EMPNAME  DFHMDF POS=(7,8),                                             X
               ATTRB=(PROT,BRT),                                       X
               LENGTH=30

*── Message line ─────────────────────────────────────────────────────
MSG      DFHMDF POS=(23,2),                                            X
               ATTRB=(PROT,BRT),                                       X
               LENGTH=77

*── Instruction line ─────────────────────────────────────────────────
         DFHMDF POS=(24,2),                                            X
               ATTRB=(PROT,NORM),                                      X
               LENGTH=45,                                              X
               INITIAL='PF3=RETURN  ENTER=SEARCH  CLEAR=RESET'

         DFHMSD TYPE=FINAL
         END

Assembling the Mapset: Physical Map and Symbolic Map

The mapset source is assembled twice — once to produce the physical map (load module installed in CICS) and once to produce the symbolic description map (COBOL DSECT copybook used by your program).

jcl
//ASSEMBLE EXEC PGM=ASMA90,
//         PARM='DECK,NOOBJECT'
//SYSLIB   DD DSN=SYS1.MACLIB,DISP=SHR
//         DD DSN=CICSTS56.CICS.SDFHMAC,DISP=SHR
//SYSIN    DD DSN=your.BMS.SOURCE(EMPIMAPS),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSPUNCH DD DSN=your.OBJ.LIBRARY(EMPIMAPS),DISP=SHR

The physical map load module is then link-edited and installed as a MAPSET resource in the CSD. The symbolic map DSECT is copied into a copybook library (e.g., your.COPYLIB(EMPIMAP)) and referenced in your COBOL program's WORKING-STORAGE.


The Symbolic Description Map: What Your COBOL Program Sees

When you assemble with TYPE=DSECT, BMS generates a COBOL level-01 structure for each map. For the EMPIMAP map above, the generated copybook looks approximately like this (names follow the BMS naming conventions):

cobol
01  EMPIMAPO.                         *> Output map (sending data to screen)
    02  FILLER         PIC X(12).
    02  EMPNOL         PIC S9(4) COMP.
    02  EMPNOA         PIC X.         *> Attribute byte for EMPNO
    02  EMPNOO         PIC X(6).      *> Output: EMPNO field data
    02  EMPNAMEL       PIC S9(4) COMP.
    02  EMPNAMEA       PIC X.
    02  EMPNAMEO       PIC X(30).
    02  MSGL           PIC S9(4) COMP.
    02  MSGA           PIC X.
    02  MSGO           PIC X(77).

01  EMPIMAPO REDEFINES EMPIMAPO.     *> Input map (receiving data from screen)
    02  FILLER         PIC X(12).
    02  EMPNOL         PIC S9(4) COMP. *> Length of data typed
    02  EMPNOF         PIC X.          *> Flag byte
    02  EMPNOI         PIC X(6).       *> Input: data typed by user
    02  EMPNAMEL       PIC S9(4) COMP.
    02  EMPNAMEF       PIC X.
    02  EMPNAMEI       PIC X(30).
    02  MSGL           PIC S9(4) COMP.
    02  MSGF           PIC X.
    02  MSGI           PIC X(77).

The naming convention uses suffixes:

  • L — length of data received/sent for this field
  • A — attribute byte (modify at runtime to change field characteristics)
  • O — output field (you move data here before SEND MAP)
  • I — input field (CICS populates this after RECEIVE MAP)
  • F — flag byte on input map (contains the Modified Data Tag and cursor information)

In WORKING-STORAGE, you declare the map using the copybook name, and both EMPIMAPO (output) and EMPIMAPI (input, via REDEFINES) are available:

cobol
WORKING-STORAGE SECTION.
    COPY DFHBMSCA.       *> BMS attribute constants (DFHBMUNP, DFHBMPROT, etc.)
    COPY DFHAID.         *> AID key constants
    COPY EMPIMAP.        *> Your generated symbolic map

EXEC CICS SEND MAP — Writing to the Screen

SEND MAP transfers the contents of your symbolic output map to the 3270 terminal. You populate the output fields (the O-suffix fields) and then issue the command.

cobol
*── Populate output fields ──────────────────────────────────────
MOVE WS-EMPLOYEE-NUMBER TO EMPNOO
MOVE WS-EMPLOYEE-NAME   TO EMPNAMEO
MOVE SPACES              TO MSGO

*── Send the map to the terminal ────────────────────────────────
EXEC CICS SEND MAP('EMPIMAP')
          MAPSET('EMPIMAPS')
          FROM(EMPIMAPO)
          DATAONLY
          RESP(WS-RESP)
          RESP2(WS-RESP2)
END-EXEC.

Key SEND MAP options:

OptionMeaning
MAPName of the map (4-8 chars)
MAPSETName of the mapset load module
FROMThe output area (symbolic output map)
ERASEErase entire screen before writing
DATAONLYSend data only (do not re-send field attributes/labels)
MAPONLYSend field attributes and labels only (no data)
CURSORPosition cursor at a specific location
ALARMSound the terminal alarm

For the first send (initial display), use ERASE to clear the screen and paint all labels and attributes. For subsequent re-sends (after user input), use DATAONLY to avoid re-transmitting the static labels — this reduces line traffic and improves performance.

cobol
*── First time: erase and paint everything ──────────────────────
EXEC CICS SEND MAP('EMPIMAP')
          MAPSET('EMPIMAPS')
          FROM(EMPIMAPO)
          ERASE
          CURSOR
          RESP(WS-RESP)
END-EXEC.

EXEC CICS RECEIVE MAP — Reading User Input

After the terminal user types data and presses an AID key (Enter, PF1-PF24, etc.), CICS holds the task. When the user returns to the program on the next pseudo-conversational invocation, RECEIVE MAP reads the modified fields from the terminal into the symbolic input map:

cobol
EXEC CICS RECEIVE MAP('EMPIMAP')
          MAPSET('EMPIMAPS')
          INTO(EMPIMAPI)
          RESP(WS-RESP)
          RESP2(WS-RESP2)
END-EXEC.

*── Now read what the user typed ────────────────────────────────
MOVE EMPNOI TO WS-SEARCH-KEY.
IF EMPNOL = ZERO
    MOVE 'PLEASE ENTER AN EMPLOYEE NUMBER.' TO MSGO
    PERFORM REDISPLAY-MAP
END-IF.

Important: RECEIVE MAP only returns fields that were modified by the user (those with the MDT — Modified Data Tag — set). Fields the user did not type in will contain low-values. Always check the length field (e.g., EMPNOL) to determine whether the user entered data in a given field.


Modifying Field Attributes at Runtime

One of the most powerful BMS techniques is changing field attributes dynamically. You write to the attribute byte field (the A-suffix field) before SEND MAP. The DFHBMSCA copybook defines the attribute byte values:

cobol
COPY DFHBMSCA.
*> Key constants:
*>   DFHBMUNP  = Unprotected normal (user can type, normal intensity)
*>   DFHBMPROT = Protected (user cannot type)
*>   DFHBMBRY  = Bright (highlighted)
*>   DFHBMDAR  = Dark (invisible — for passwords)
*>   DFHBMFSE  = Field Set (marks MDT so field is always sent)
*>   DFHNEUTR  = Neutral (unprotected, no MDT set)

*── Make EMPNO field bright to indicate an error ────────────────
MOVE DFHBMBRY TO EMPNOA.

*── Protect a field (make it output-only) ───────────────────────
MOVE DFHBMPROT TO EMPNAMEA.

*── Make a password field invisible ────────────────────────────
MOVE DFHBMDAR TO PASSWORDA.

This technique lets a single map serve multiple display states — for example, highlighting fields that failed validation without requiring a separate map definition.


Cursor Positioning

The INSERT CURSOR (IC) attribute in the DFHMDF macro sets the default cursor position when the map is first sent. To move the cursor to a specific field at runtime, use the CURSOR option on SEND MAP with a numeric offset value, or use the symbolic approach: set the DFHBMFSE attribute and use CURSOR without a value (CICS will position the cursor at the field with IC set):

cobol
*── Move cursor to EMPNO field on re-send ───────────────────────
MOVE DFHBMUNP TO EMPNOA     *> Unprotected, cursor will go here
EXEC CICS SEND MAP('EMPIMAP')
          MAPSET('EMPIMAPS')
          FROM(EMPIMAPO)
          DATAONLY
          CURSOR
END-EXEC.

Alternatively, provide an absolute screen position to the CURSOR option:

cobol
EXEC CICS SEND MAP('EMPIMAP')
          MAPSET('EMPIMAPS')
          FROM(EMPIMAPO)
          DATAONLY
          CURSOR(338)        *> Row 5, col 19 on an 80-column screen: (5-1)*80 + 19 = 338
END-EXEC.

Common BMS Mistakes

Mistake 1: Sending DATAONLY on the first invocation. The first SEND MAP must use ERASE to paint the full screen. Using DATAONLY on the first send leaves garbage on the screen because the 3270 buffer is not initialised.

Mistake 2: Reading EMPNOI before checking EMPNOL. If the user did not modify a field, EMPNOI contains low-values (X'00'), not spaces. Always test EMPNOL > 0 before using input field data, or use INSPECT/MOVE to sanitise.

Mistake 3: Forgetting TIOAPFX=YES in DFHMSD. Without TIOAPFX=YES, the 12-byte TIOA prefix (the FILLER at the start of the symbolic map) is not generated, causing a 12-byte misalignment between physical and symbolic map data. Always include TIOAPFX=YES.

Mistake 4: Installing the wrong TYPE. The load module in CICS must be assembled with TYPE=MAP. The copybook must be assembled with TYPE=DSECT. Mixing these causes display corruption or ABEND.

Mistake 5: Not clearing output fields before SEND MAP. If a previous SEND MAP populated EMPNAMEO with a 30-character name and the next search returns a 15-character name, the rightmost 15 characters of the previous value remain on screen. Always MOVE SPACES to output fields before populating them.


Key Takeaways

BMS maps are the bridge between CICS COBOL programs and 3270 terminal users. DFHMSD defines the mapset container, DFHMDI defines each screen, and DFHMDF defines every field with its position, length, and initial attributes. At runtime, SEND MAP paints the screen and RECEIVE MAP captures user input. Dynamic attribute modification lets a single map serve multiple display states — error highlighting, protected fields, hidden passwords — without multiple map definitions.

To understand what happens after RECEIVE MAP (how to save state between pseudo-conversational invocations), see CICS COMMAREA. For the full CICS programming context, visit the CICS Mastery Course.