*  SYSTEM SEGMENT:  SYS.FCP
*  SYSTEM:  ZCPR3
*  CUSTOMIZED BY:  RICHARD CONN

*
*  PROGRAM:  SYSFCP.ASM
*  AUTHOR:  RICHARD CONN
*  VERSION:  1.0
*  DATE:  22 FEB 84
*  PREVIOUS VERSIONS:  NONE
*
VERSION EQU     10

*
*  Global Library which Defines Addresses for SYSTEM
*
       MACLIB  Z3BASE  ; USE BASE ADDRESSES
       MACLIB  SYSFCP  ; USE EQUATES FROM HEADER FILE

;
LF      EQU     0AH
CR      EQU     0DH
BELL    EQU     07H
;
BASE    EQU     0
WBOOT   EQU     BASE+0000H              ;CP/M WARM BOOT ADDRESS
UDFLAG  EQU     BASE+0004H              ;USER NUM IN HIGH NYBBLE, DISK IN LOW
BDOS    EQU     BASE+0005H              ;BDOS FUNCTION CALL ENTRY PT
TFCB    EQU     BASE+005CH              ;DEFAULT FCB BUFFER
FCB1    EQU     TFCB                    ;1st and 2nd FCBs
FCB2    EQU     TFCB+16
TBUFF   EQU     BASE+0080H              ;DEFAULT DISK I/O BUFFER
TPA     EQU     BASE+0100H              ;BASE OF TPA
;
$-MACRO                 ;FIRST TURN OFF THE EXPANSIONS
;
; MACROS TO PROVIDE Z80 EXTENSIONS
;   MACROS INCLUDE:
;
;       JR      - JUMP RELATIVE
;       JRC     - JUMP RELATIVE IF CARRY
;       JRNC    - JUMP RELATIVE IF NO CARRY
;       JRZ     - JUMP RELATIVE IF ZERO
;       JRNZ    - JUMP RELATIVE IF NO ZERO
;       DJNZ    - DECREMENT B AND JUMP RELATIVE IF NO ZERO
;
;       @GENDD MACRO USED FOR CHECKING AND GENERATING
;       8-BIT JUMP RELATIVE DISPLACEMENTS
;
@GENDD  MACRO   ?DD     ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS
       IF (?DD GT 7FH) AND (?DD LT 0FF80H)
       DB      100H,?DD        ;Displacement Range Error
       ELSE
       DB      ?DD
       ENDIF           ;;RANGE ERROR
       ENDM
;
;
; Z80 MACRO EXTENSIONS
;
JR      MACRO   ?N      ;;JUMP RELATIVE
       IF      I8080   ;;8080/8085
       JMP     ?N
       ELSE            ;;Z80
       DB      18H
       @GENDD  ?N-$-1
       ENDIF           ;;I8080
       ENDM
;
JRC     MACRO   ?N      ;;JUMP RELATIVE ON CARRY
       IF      I8080   ;;8080/8085
       JC      ?N
       ELSE            ;;Z80
       DB      38H
       @GENDD  ?N-$-1
       ENDIF           ;;I8080
       ENDM
;
JRNC    MACRO   ?N      ;;JUMP RELATIVE ON NO CARRY
       IF      I8080   ;;8080/8085
       JNC     ?N
       ELSE            ;;Z80
       DB      30H
       @GENDD  ?N-$-1
       ENDIF           ;;I8080
       ENDM
;
JRZ     MACRO   ?N      ;;JUMP RELATIVE ON ZERO
       IF      I8080   ;;8080/8085
       JZ      ?N
       ELSE            ;;Z80
       DB      28H
       @GENDD  ?N-$-1
       ENDIF           ;;I8080
       ENDM
;
JRNZ    MACRO   ?N      ;;JUMP RELATIVE ON NO ZERO
       IF      I8080   ;;8080/8085
       JNZ     ?N
       ELSE            ;;Z80
       DB      20H
       @GENDD  ?N-$-1
       ENDIF           ;;I8080
       ENDM
;
DJNZ    MACRO   ?N      ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
       IF      I8080   ;;8080/8085
       DCR     B
       JNZ     ?N
       ELSE            ;;Z80
       DB      10H
       @GENDD  ?N-$-1
       ENDIF           ;;I8080
       ENDM
*
*  SYSTEM Entry Point
*
       org     fcp             ; passed for Z3BASE

       db      'Z3FCP'         ; Flag for Package Loader
*
*  **** Command Table for FCP ****
*       This table is FCP-dependent!
*
*       The command name table is structured as follows:
*
*       ctable:
*               DB      'CMNDNAME'      ; Table Record Structure is
*               DW      cmndaddress     ; 8 Chars for Name and 2 Bytes for Adr
*               ...
*               DB      0       ; End of Table
*
cnsize  equ     4               ; NUMBER OF CHARS IN COMMAND NAME
       db      cnsize  ; size of text entries
ctab:
       db      'IF  '
       dw      ifstart
       db      'ELSE'
       dw      ifelse
       db      'FI  '
       dw      ifend
       db      'XIF '
       dw      ifexit
       db      0
;
; Condition Table
;
condtab:
;
       IF      IFOTRUE
       db      'T '            ;TRUE
       dw      ifctrue
       db      'F '            ;FALSE
       dw      ifcfalse
       ENDIF
;
       IF      IFOEMPTY
       db      'EM'            ;file empty
       dw      ifcempty
       ENDIF
;
       IF      IFOERROR
       db      'ER'            ;error message
       dw      ifcerror
       ENDIF
;
       IF      IFOEXIST
       db      'EX'            ;file exists
       dw      ifcex
       ENDIF
;
       IF      IFOINPUT
       db      'IN'            ;user input
       dw      ifcinput
       ENDIF
;
       IF      IFONULL
       db      'NU'
       dw      ifcnull
       ENDIF
;
       IF      IFOTCAP         ;Z3 TCAP available
       db      'TC'
       dw      ifctcap
       ENDIF
;
       IF      IFOWHEEL        ;Wheel Byte
       db      'WH'
       dw      ifcwheel
       ENDIF
;
       db      0

*
*  Print " IF"
*
prif:
       call    print
       db      'IF',' '+80H
       ret
*
*  Print String (terminated in 0 or MSB Set) at Return Address
*
print:
       IF      NOISE
       mvi     a,' '           ;print leading space
       call    conout
       ENDIF           ;NOISE
       xthl                    ; get address
       call    print1
       xthl                    ; put address
       ret
*
*  Print String (terminated by MSB Set) pted to by HL
*
print1:
       mov     a,m             ; done?
       inx     h               ; pt to next
       call    conout          ; print char
       ora     a               ; set MSB flag (M)
       rm                      ; MSB terminator
       jr      print1

*
*  **** FCP Routines ****
*  All code from here on is FCP-dependent!
*

;
; FCP Command: XIF
;   XIF terminates all IFs, restoring a basic TRUE state
;
ifexit:
       IF      NOISE
       call    nl              ;print new line
       ENDIF           ;NOISE
       call    iftest          ;see if current IF is running and FALSE
       jrz     ifstat          ;abort with status message if so
       lxi     h,z3msg+1       ;pt to IF flag
       xra     a               ;A=0
       mov     m,a             ;zero IF flag
       jr      ifendmsg        ;print message

;
; FCP Command: FI
;   FI decrements to the previous IF
;
;   Algorithm:
;       Rotate Current IF Bit (1st IF Message) Right 1 Bit Position
;
ifend:
       IF      NOISE
       call    nl              ;print new line
       ENDIF           ;NOISE
       lxi     h,z3msg+1       ;pt to IF flag
       mov     a,m             ;get it
       ora     a               ;no IF active?
       jrz     ifnderr
ifendmsg:
       IF      NOISE
       push    psw             ;save A
       call    print
       db      'T','o'+80H     ;prefix to status display
       pop     psw             ;get A
       ENDIF           ;NOISE
       rrc                     ;move right 1 bit
       ani     7fh             ;mask msb 0
       mov     m,a             ;store active bit
       jrnz    ifstat          ;print status if IF still active
ifnderr:
       IF      NOISE
       call    print           ;print message
       db      'N','o'+80H
       jmp     prif
       ELSE            ;NOT NOISE
       ret
       ENDIF           ;NOISE

;
; FCP Command: ELSE
;   ELSE complements the Active Bit for the Current IF
;
;   Algorithm:
;       If Current IF is 0 (no IF) or 1 (one IF), then toggle
;               Active IF Bit associated with Current IF
;       Else
;               If Previous IF was Active then toggle
;                       Active IF Bit associated with Current IF
;               Else do nothing
;
ifelse:
       IF      NOISE
       call    nl              ;print new line
       ENDIF           ;NOISE
       lxi     h,z3msg+1       ;pt to IF msgs
       mov     a,m             ;get current IF
       mov     b,a             ;save current IF in B
       inx     h               ;pt to active IF message
       rrc                     ;back up to previous IF level
       ani     7fh             ;mask out possible carry
       jrz     iftog           ;toggle if IF level is 0 or 1
       ana     m               ;determine previous IF status
       jrz     ifstat          ;don't toggle, and just print status
iftog:
       mov     a,m             ;get active IF message
       cma                     ;flip bits
       ana     b               ;look at only interested bit
       mov     c,a             ;result in C
       mov     a,b             ;complement IF byte
       cma
       mov     b,a
       mov     a,m             ;get active byte
       ana     b               ;mask in only uninterested bits
       ora     c               ;mask in complement of interested bit
       mov     m,a             ;save result and fall thru to print status
;
; Indicate if current IF is True or False
;
ifstat:
       IF      NOISE
       call    prif
       mvi     b,'F'           ;assume False
       call    iftest          ;see if IF is FALSE (Z if so)
       jrz     ifst1           ;Zero means IF F or No IF
       mvi     b,'T'           ;set True
ifst1:
       mov     a,b             ;get T/F flag and fall thru to print it
       ELSE            ;NOT NOISE
       ret
       ENDIF           ;NOISE

;
;  Console Output Routine
;
conout:
       push    h               ; save regs
       push    d
       push    b
       push    psw
       ani     7fh             ; mask MSB
       mov     e,a             ; char in E
       mvi     c,2             ; output
       call    bdos
       pop     psw             ; get regs
       pop     b
       pop     d
       pop     h
       ret

;
;  Output LF (to go with CR from ZCPR3)
;
nl:
       mvi     a,lf            ;output LF
       jr      conout

;
; FCP Command: IF
;
ifstart:
       IF      NOISE
       call    nl              ;print new line
       ENDIF           ;NOISE
       call    iftest          ;see if current IF is running and FALSE
;
       IF      NOT COMIF
       jrz     ifcfalse        ;raise next IF level to FALSE if so
       ELSE
       jz      ifcf
       ENDIF           ;NOT COMIF
;

;****************************************************************
;*                                                              *
;* IF.COM Processing                                            *
;*                                                              *
;****************************************************************

;
; If IF.COM to be processed, goto ROOT (base of path) and load it
;
       IF      COMIF
;
; Get Current Disk and User in BC
;
       lda     udflag          ;get UD
       push    psw             ;save UD flag
       ani     0fh             ;get disk
       sta     cdisk           ;set current disk
       mov     b,a             ;B=disk (A=0)
       pop     psw             ;get UD flag
       rlc                     ;get user in low 4 bits
       rlc
       rlc
       rlc
       ani     0fh             ;get user
       sta     cuser           ;set current user
       mov     c,a             ;... in C
;
; Pt to Start of Path
;
       lxi     h,expath        ;pt to path
;
; Check for End of Path
;
fndroot:
       mov     a,m             ;check for done
       ora     a               ;end of path?
       jrz     froot2
;
; Process Next Path Element
;
       cpi     '$'             ;current disk?
       jrnz    froot0
       lda     cdisk           ;get current disk
       inr     a               ;+1 for following -1
froot0:
       dcr     a               ;set A=0
       mov     b,a             ;set disk
       inx     h               ;pt to user
       mov     a,m             ;get user
       cpi     '$'             ;current user?
       jrnz    froot1
       lda     cuser           ;get current user
froot1:
       mov     c,a             ;set user
       inx     h               ;pt to next
       jr      fndroot
;
; Done with Search - BC Contains ROOT DU
;
froot2:
;
; Log Into ROOT
;
       call    logbc           ;log into root DU
;
; Set Address of Next Load and Set DMA for OPEN
;
       lxi     h,100h          ;pt to TPA
       shld    nxtload         ;set address for next load
       xchg                    ;DE=100H so don't wipe out buffers
       mvi     c,26            ;set DMA
       call    bdos
;
; Try to Open File IF.COM
;
       lxi     d,extfcb        ;pt to FCB
       mvi     c,15            ;open file
       call    bdos
       inr     a               ;check for found
       jz      ifnotfnd
;
; Load File IF.COM
;
ifload:
;
; Set Load Address
;
       lhld    nxtload         ;get address of next load
       push    h               ;save it
       lxi     d,80h           ;pt to following
       dad     d
       shld    nxtload
       pop     d               ;get load address
       mvi     c,26            ;set DMA
       call    bdos
;
; Read in Block (Sector) and Loop Back if Not Done
;
       lxi     d,extfcb        ;read file
       mvi     c,20
       push    d               ;save ptr in case of failure (done)
       call    bdos
       pop     d
       ora     a               ;OK?
       jz      ifload
;
; Done - Close File
;
       mvi     c,16            ;close file
       call    bdos
;
; Reset Environment (DMA and DU) and Run IF.COM
;
       call    reset           ;reset DMA and directory
       jmp     tpa             ;run IF.COM
;
; Reset DMA Address and Current Disk (in CDISK) and User (in CUSER)
;
reset:
       lxi     d,80h           ;reset DMA address
       mvi     c,26
       call    bdos
       lda     cdisk           ;return home
       mov     b,a
       lda     cuser
       mov     c,a
;
; Log Into DU in BC
;
logbc:
       mov     e,b             ;set disk
       push    b
       mvi     c,14            ;select disk
       call    bdos
       pop     b
       mov     e,c             ;set user
       mvi     c,32            ;select user
       jmp     bdos
;
; IF.COM not found - Process as IF F
;
ifnotfnd:
       call    reset           ;return home
       jr      ifcf
;
; Buffers for COMIF
;
nxtload:
       ds      2               ;address of next block (sector) to load
cuser:
       ds      1               ;current user
cdisk:
       ds      1               ;current disk (A=0)
;
       ENDIF           ;COMIF
;

       IF      NOT COMIF
;****************************************************************
;*                                                              *
;* Non-IF.COM Processing                                        *
;*                                                              *
;****************************************************************

;
; Test for Equality if Enabled
;
       IF      IFOEQ
       lxi     h,tbuff+1       ;look for '=' in line
tsteq:
       mov     a,m             ;get char
       inx     h               ;pt to next
       ora     a               ;EOL?
       jrz     ifck0           ;continue if so
       cpi     '='             ;'=' found?
       jrnz    tsteq
       lxi     h,fcb1+1        ;compare FCBs
       lxi     d,fcb2+1
       mvi     b,11            ;11 bytes
eqtest:
       ldax    d               ;compare
       cmp     m
       jrnz    ifcf
       inx     h               ;pt to next
       inx     d
       djnz    eqtest
       jr      ifct
       ENDIF           ;IFOEQ
;
; Test Condition in FCB1 and file name in FCB2
;   Execute condition processing routine
;
ifck0:
       lxi     d,fcb1+1        ;pt to first char in FCB1
;
       IF      IFONEG
       ldax    d               ;get it
       sta     negflag         ;set negate flag
       cpi     negchar         ;is it a negate?
       jrnz    ifck1
       inx     d               ;pt to char after negchar
ifck1:
       ENDIF           ;IFONEG
;
       IF      IFOREG          ;REGISTERS
       call    regtest         ;test for register value
       jrnz    runreg
       ENDIF           ;IFOREG
;
       call    condtest        ;test of condition match
       jrnz    runcond         ;process condition
       call    print           ;beep to indicate error
       db      bell+80H
       jmp     ifstat          ;no condition, display current condition
;
; Process register - register value is in A
;
       IF      IFOREG
runreg:
       push    psw             ;save value
       call    getnum          ;extract value in FCB2 as a number
       pop     psw             ;get value
       cmp     b               ;compare against extracted value
       jrz     ifctrue         ;TRUE if match
       jr      ifcfalse        ;FALSE if non-match
       ENDIF           ;IFOREG
;
; Process conditional test - address of conditional routine is in HL
;
runcond:
       pchl                    ;"call" routine pted to by HL
;
       ENDIF           ;NOT COMIF
;

;
; Condition:  NULL (2nd file name)
;
       IF      IFONULL
ifcnull:
       lda     fcb2+1          ;get first char of 2nd file name
       cpi     ' '             ;space = null
       jrz     ifctrue
       jr      ifcfalse
       ENDIF           ;IFONULL

;
; Condition:  TCAP
;
       IF      IFOTCAP
ifctcap:
       lda     z3env+80H       ;get first char of Z3 TCAP Entry
       cpi     ' '+1           ;space or less = none
       jrc     ifcfalse
       jr      ifctrue
       ENDIF           ;IFOTCAP

;
; Condition:  WHEEL
;
       IF      IFOWHEEL
ifcwheel:
       lhld    z3env+29h       ;get address of wheel byte
       mov     a,m             ;get byte
       ora     a               ;test for true
       jrz     ifcfalse        ;FALSE if 0
       jr      ifctrue
       ENDIF           ;IFOWHEEL
;
; Condition:  TRUE
;       IFCTRUE  enables an active IF
; Condition:  FALSE
;       IFCFALSE enables an inactive IF
;
ifctrue:
;
       IF      IFONEG
       call    negtest ;test for negate
       jrz     ifcf
       ENDIF           ;IFONEG
;
ifct:
       mvi     b,0ffh  ;active
       jmp     ifset
ifcfalse:
;
       IF      IFONEG
       call    negtest ;test for negate
       jrz     ifct
       ENDIF           ;IFONEG
;
ifcf:
       mvi     b,0     ;inactive
       jmp     ifset

;
; Condition: INPUT (from user)
;
       IF      IFOINPUT
ifcinput:
       lxi     h,z3msg+7       ;pt to ZEX message byte
       mvi     m,10b           ;suspend ZEX input
       push    h               ;save ptr to ZEX message byte
       IF      NOT NOISE
       call    nl
       ENDIF           ;NOT NOISE
       call    prif
       call    print
       db      'True?',' '+80H
       mvi     c,1             ;input from console
       call    bdos
       pop     h               ;get ptr to ZEX message byte
       mvi     m,0             ;return ZEX to normal processing
       cpi     ' '             ;yes?
       jrz     ifctrue
       ani     5fh             ;mask and capitalize user input
       cpi     'T'             ;true?
       jrz     ifctrue
       cpi     'Y'             ;yes?
       jrz     ifctrue
       cpi     CR              ;yes?
       jrz     ifctrue
       jr      ifcfalse
       ENDIF           ;IFOINPUT

;
; Condition: EXIST filename.typ
;
       IF      IFOEXIST
ifcex:
       call    tlog    ;log into DU
       lxi     d,fcb2  ;pt to fcb
       mvi     c,17    ;search for first
       call    bdos
       inr     a       ;set zero if error
       jrz     ifcfalse        ;return FALSE
       jr      ifctrue         ;return TRUE
       ENDIF           ;IFOEXIST

;
; Condition: EMPTY filename.typ
;
       IF      IFOEMPTY
ifcempty:
       call    tlog            ;log into FCB2's DU
       lxi     d,fcb2          ;pt to fcb2
       mvi     c,15            ;open file
       push    d               ;save fcb ptr
       call    bdos
       pop     d
       inr     a               ;not found?
       jrz     ifctrue
       mvi     c,20            ;try to read a record
       call    bdos
       ora     a               ;0=OK
       jrnz    ifctrue         ;NZ if no read
       jr      ifcfalse
       ENDIF           ;IFOEMPTY

;
; Condition: ERROR
;
       IF      IFOERROR
ifcerror:
       lda     z3msg+6         ;get error byte
       ora     a               ;0=TRUE
       jrz     ifctrue
       jr      ifcfalse
       ENDIF           ;IFOERROR

;
; **** Support Routines ****
;

;
; Convert chars in FCB2 into a number in B
;
       IF      IFOREG
getnum:
       mvi     b,0     ;set number
       lxi     h,fcb2+1        ;pt to first char
getn1:
       mov     a,m     ;get char
       inx     h       ;pt to next
       sui     '0'     ;convert to binary
       rc              ;done if error
       cpi     10      ;range?
       rnc             ;done if out of range
       mov     c,a     ;value in C
       mov     a,b     ;A=old value
       add     a       ;*2
       add     a       ;*4
       add     b       ;*5
       add     a       ;*10
       add     c       ;add in new digit value
       mov     b,a     ;result in B
       jr      getn1   ;continue processing
       ENDIF           ;IFOREG

;
; Log into DU in FCB2
;
       IF      NOT COMIF
tlog:
       lda     fcb2    ;get disk
       ora     a       ;current?
       jrnz    tlog1
       mvi     c,25    ;get disk
       call    bdos
       inr     a       ;increment for following decrement
tlog1:
       dcr     a       ;A=0
       mov     e,a     ;disk in E
       mvi     c,14
       call    bdos
       lda     fcb2+13 ;pt to user
       mov     e,a
       mvi     c,32    ;set user
       jmp     bdos
;
       ENDIF           ;NOT COMIF

;
; Test of Negate Flag = negchar
;
       IF      IFONEG
negtest:
negflag equ     $+1             ;pointer for in-the-code modification
       mvi     a,0             ;2nd byte is filled in
       cpi     negchar         ;test for No
       ret
       ENDIF           ;IFONEG

;
; Test FCB1 against a single digit (0-9)
;  Return with register value in A and NZ if so
;
       IF      IFOREG
regtest:
       ldax    d               ;get digit
       sui     '0'
       jrc     zret            ;Z flag for no digit
       cpi     10              ;range?
       jrnc    zret            ;Z flag for no digit
       lxi     h,z3msg+30H     ;pt to registers
       add     l               ;pt to register
       mov     l,a
       mov     a,h             ;add in H
       aci     0
       mov     h,a
       xra     a               ;set NZ
       dcr     a
       mov     a,m             ;get register value
       ret
zret:
       xra     a               ;set Z
       ret
       ENDIF           ;IFOREG

;
; Test to see if a current IF is running and if it is FALSE
;   If so, return with Zero Flag Set (Z)
;   If not, return with Zero Flag Clear (NZ)
; Affect only HL and PSW
;
iftest:
       lxi     h,z3msg+1       ;get IF flag
       mov     a,m             ;test for active IF
       ora     a
       jrz     ifok            ;no active IF
       inx     h               ;pt to active flag
       ana     m               ;check active flag
       rz                      ;return Z since IF running and FALSE
ifok:
       xra     a               ;return NZ for OK
       dcr     a
       ret

;
; Test FCB1 against condition table (must have 2-char entries)
;  Return with routine address in HL if match and NZ flag
;
       IF      NOT COMIF
condtest:
       lxi     h,condtab       ;pt to table
condt1:
       mov     a,m             ;end of table?
       ora     a
       rz
       ldax    d               ;get char
       mov     b,m             ;get other char in B
       inx     h               ;pt to next
       inx     d
       cmp     b               ;compare entries
       jrnz    condt2
       ldax    d               ;get 2nd char
       cmp     m               ;compare
       jrnz    condt2
       inx     h               ;pt to address
       mov     a,m             ;get address in HL
       inx     h
       mov     h,m
       mov     l,a             ;HL = address
       xra     a               ;set NZ for OK
       dcr     a
       ret
condt2:
       lxi     b,3             ;pt to next entry
       dad     b               ; ... 1 byte for text + 2 bytes for address
       dcx     d               ;pt to 1st char of condition
       jr      condt1
;
       ENDIF           ;NOT COMIF
;
; Turn on next IF level
;   B register is 0 if level is inactive, 0FFH is level is active
;   Return with
Z flag set if OK
;
ifset:
       lxi     h,z3msg+1       ;get IF flag
       mov     a,m
       ora     a               ;if no if at all, start 1st one
       jrz     ifset1
       cpi     80h             ;check for overflow (8 IFs max)
       jrz     iferr
       inx     h               ;pt to active IF byte
       ana     m               ;check to see if current IF is TRUE
       jrnz    ifset0          ;if TRUE, proceed
       mvi     b,0             ;set False IF
ifset0:
       dcx     h               ;pt to IF level
       mov     a,m             ;get it
       rlc                     ;advance to next level
       ani     0feh            ;only 1 bit on
       mov     m,a             ;set IF byte
       jr      ifset2
ifset1:
       inr     a               ;A=1
       mov     m,a             ;set 1st IF
       inx     h               ;clear active IF byte
       mvi     m,0
       dcx     h
ifset2:
       mov     d,a             ;get IF byte
       ana     b               ;set interested bit
       mov     b,a
       inx     h               ;pt to active flag
       mov     a,d             ;complement IF byte
       cma
       mov     d,a
       mov     a,m             ;get active byte
       ana     d               ;mask in only uninterested bits
       ora     b               ;mask in complement of interested bit
       mov     m,a             ;save result
       call    ifstat          ;print status
       xra     a               ;return with Z
       ret
iferr:
       call    print           ;beep to indicate overflow
       db      bell+80H
       xra     a               ;set NZ
       dcr     a
       ret

;
; Test for Size Error
;
       if      ($ GT (FCP + FCPS*128))
sizerr  equ     novalue ;FCP is too large for buffer
       endif

       end