         TITLE DOS Keyboard Setup Command FLIP
         COMMENT *
                 This assembly language routine allows the use to change the
                 state of the Num Lock and Caps Lock Keys via a DOS command.
                 Syntax:
                        FLIP |NUM| |ON |
                             |CAP| |OFF|
                        or
                        FLIP |MONO |
                             |COLOR| |80|
                                     |40|
                Where NUM indicates to change the Num Lock state and CAP
                indicates to change the Caps Lock state.  ON indicates
                to use numbers or capitals respecitively, OFF has the
                obvious effect.
                The MONO and COLOR parameters flip between the MONO and
                COLOR display adapter cards on systems so equipped:  40 or
                80 defines the number of characters per line if the COLOR
                parameter is used: 40 or 80 is not necessary for MONO.
                This command must be converted to a COM file via the DEBUG
                Write command or the PC-DOS 1.10 EXE to BIN convertor.  This
                code WILL NOT RUN as an EXE file.  A BASIC program is available
                to generate this COM file.
                Copyright (c) 1982 Thomas J. Foth
                Rights granted to distribute this routine with the inclusion of
                this notice but not for profit.
                Author makes no warranty, expressed or implied, as to the
                correct nature and operation of this software.
                *
BIOSDATA SEGMENT AT 40H                        ;Map the BIOS Data segment
         ORG     10H
EQUIP_FLAG DB    ?                             ;Map the equipment flags
MONOMODE EQU     30H                           ;Mono card bits
CL40MODE EQU     10H                           ;Color 40x25 bits
CL80MODE EQU     20H                           ;Color 80x25 bits
MONOINIT EQU     07H                           ;AX value for video call
CL80INIT EQU     02H                           ;
CL40INIT EQU     00H                           ;
         ORG     17H
KB_FLAG  DB      ?                             ;Map the KB key
CAPS_STATE EQU   40H
NUM_STATE EQU    20H
BIOSDATA ENDS
;STACKSEG SEGMENT STACK                         ;Fake out linker
;STACKSEG ENDS
FLIPKB   SEGMENT PARA PUBLIC 'CODE'
         ASSUME  CS:FLIPKB
         ORG     5DH
CAPNUM   DB      3 DUP(?)                      ;First formatted file
         ORG     6DH
ON_OFF   DB      3 DUP(?)                      ;Second formatted file
         ORG     100H
START:   MOV     AX,40H                        ;Segment of BIOS work space
         MOV     DS,AX                         ;Set up DS for addressability
         ASSUME  DS:BIOSDATA
         MOV     BL,CAPS_STATE                 ;Assume caps
         MOV     SI,OFFSET CAPNUM              ;Point to parm
         MOV     DI,OFFSET CAPPARM             ;Point to literal
         MOV     CX,3                          ;Three chars to test
         CLD                                   ;forward compare
         REPE    CMPS CS:BYTE PTR [SI],ES:[DI] ;Do the compare
         CMP     CX,0                          ;all chars equal
         JZ      SET                           ;Yep
         MOV     BL,NUM_STATE                  ;May be num state
         MOV     SI,OFFSET CAPNUM              ;point to parm
         MOV     DI,OFFSET NUMPARM             ;point to literal
         MOV     CX,3                          ;three chars
         REPE    CMPS CS:BYTE PTR [SI],ES:[DI] ;do compare
         CMP     CX,0                          ;all three chars same
         JNZ     TST4DISP                      ;Nope, go check for display
SET:     MOV     SI,OFFSET ON_OFF              ;Point to parm
         MOV     AX,CS:ONPARM                  ;get literal
         CMP     AX,ES:[SI]                    ;the same
         JE      SETON                         ;Yep, go OR
         MOV     SI,OFFSET ON_OFF              ;Point to parm
         MOV     DI,OFFSET OFFPARM             ;Point to literal
         MOV     CX,3                          ;three chars to compare
         REPE    CMPS CS:BYTE PTR [SI],ES:[DI] ;Compare
         CMP     CX,0                          ;All three same
         JNZ     PRTERR                        ;Nope, go display error
         XOR     BL,0FFH                       ;Flip the bit
         AND     KB_FLAG,BL                    ;Pass all but CAPS or NUM
         INT     20H                           ;Exit
SETON:   OR      KB_FLAG,BL                    ;Turn CAPS or NUM on
         INT     20H                           ;Exit
TST4DISP:MOV     SI,OFFSET CAPNUM              ;point to parm
         MOV     DI,OFFSET MONOPARM            ;point to literal
         MOV     CX,4                          ;four chars
         REPE    CMPS CS:BYTE PTR [SI],ES:[DI] ;do compare
         CMP     CX,0                          ;all four chars same
         JNZ     TST4COLR                      ;Nope
         OR      EQUIP_FLAG,MONOMODE           ;Flip to mono mode
         MOV     AX,MONOINIT                   ;Do mono initialization
         INT     10H                           ;Call video
         INT     20H                           ;Return
PRTERR:  MOV     DX,OFFSET ERROR1              ;Point to string
         MOV     AX,CS                         ;Restore DS
         MOV     DS,AX                         ;Via AX
         MOV     AH,9                          ;Print function
         INT     21H                           ;Display error message
         INT     20H                           ;Exit
TST4COLR:MOV     SI,OFFSET CAPNUM              ;point to parm
         MOV     DI,OFFSET COLRPARM            ;point to literal
         MOV     CX,5                          ;five chars
         REPE    CMPS CS:BYTE PTR [SI],ES:[DI] ;do compare
         CMP     CX,0                          ;all five chars same
         JNZ     PRTERR                        ;Nope
         MOV     SI,OFFSET ON_OFF              ;Point to parm
         MOV     AX,CS:N80PARM                 ;get literal
         CMP     AX,ES:[SI]                    ;the same
         JNE     TST_4_40                      ;Nope, go check for 40x25
         MOV     CL,CL80MODE                   ;80x25 mode
         MOV     BX,CL80INIT                   ;Do 80x25 BW init
         JMP     SETCOLOR                      ;Go set color
TST_4_40:MOV     AX,CS:N40PARM                 ;get literal
         CMP     AX,ES:[SI]                    ;the same
         JNE     PRTERR                        ;Nope, display error
         MOV     CL,CL40MODE                   ;40x25 mode
         MOV     BX,CL40INIT                   ;Init for 40x25 mode
SETCOLOR:MOV     AL,0CFH                       ;Move in mask
         AND     AL,EQUIP_FLAG                 ;Get the equipment flag
         OR      AL,CL                         ;Set appropriate color mode
         MOV     EQUIP_FLAG,AL                 ;Set the flag back
         MOV     AX,BX                         ;Set up to
         INT     10H                           ;call video
         INT     20H                           ;Return
ONPARM   DW      'NO'
OFFPARM  DB      'OFF'
CAPPARM  DB      'CAP'
NUMPARM  DB      'NUM'
MONOPARM DB      'MONO'
COLRPARM DB      'COLOR'
N80PARM  DW      '08'
N40PARM  DW      '04'
ERROR1   DB      0AH,0DH
         DB      'FLIP ignored: Invalid parameter'
         DB      0AH,0DH,24H
FLIPKB   ENDS
         END     START
