The WIDTH operator (which is used only with records) returns the width in bits of a record or record field. The MASK operator returns a bit mask for the bit positions occupied by the given record field. A bit in the mask contains a 1 if that bit corresponds to a bit field. The example below shows how to use MASK and WIDTH.
.DATA
COLOR RECORD blink:1, back:3, intense:1, fore:3
message COLOR <1, 5, 1, 1>
wblink EQU WIDTH blink ; "wblink" = 1
wback EQU WIDTH back ; "wback" = 3
wintense EQU WIDTH intense ; "wintense" = 1
wfore EQU WIDTH fore ; "wfore" = 3
wcolor EQU WIDTH color ; "wcolor" = 8
.CODE
.
.
.
mov ah, message ; Load initial 0101 1001
and ah, NOT MASK back ; Turn off AND 1000 1111
; "back" ---------
; 0000 1001
or ah, MASK blink ; Turn on OR 1000 0000
; "blink" ---------
; 1000 1001
xor ah, MASK intense ; Toggle XOR 0000 1000
; "intense" ---------
; 1000 0001
.
IF (WIDTH color) GE 8 ; If color is 16 bit, load
mov ax, message ; into 16-bit register
ELSE ; else
mov al, message ; load into low 8-bit register
xor ah, ah ; and clear high 8-bits
ENDIF
This example illustrates several ways in which record fields can be used as operands and in expressions.
; Rotate "back" of "cursor" without changing other values
mov al, cursor ; Load value from memory
mov ah, al ; Save a copy for work 1101 1001=ah/al
and al, NOT MASK back; Mask out old bits AND 1000 1111=mask
; to save old cursor ---------
; 1000 1001=al
mov cl, back ; Load bit position
shr ah, cl ; Shift to right 0000 1101=ah
inc ah ; Increment 0000 1110=ah
shl ah, cl ; Shift left again 1110 0000=ah
and ah, MASK back ; Mask off extra bits AND 0111 0000=mask
; to get new cursor ---------
; 0110 0000 ah
or ah, al ; Combine old and new OR 1000 1001 al
; ---------
mov cursor, ah ; Write back to memory 1110 1001 ah
Record variables are often used with the logical operators to perform logical operations on the bit fields of the record, as in the previous example using the MASK operator.