;COLORINIT EQU 03H ;Value to initialize color screen (80x25) COLORINIT EQU 01H ;Value to initialize color screen (40X25) ; ; Now, describe our own segment ; SETSCRN SEGMENT ;Set operating segment for CODE and DATA ; ASSUME CS:SETSCRN,DS:SETSCRN,ES:SETSCRN,SS:SETSCRN ;All segments ; ORG 100H ;Begin assembly at standard .COM offset ; MAIN PROC NEAR ;COM files use NEAR linkage JMP BEGIN ;And, it is helpful to put the data first, but ; ;then you must branch around it. ; ; Data used in SETSCRN ; CHANGELOC DD EQUIP ;Location of the EQUIP, recorded as far pointer MONOPROMPT DB 'Please press the plus ( + ) key.$' ;User sees on mono COLORPROMPT DB 'Please press the minus ( - ) key.$' ;User sees on color Several things are illustrated on this page. First, in addition to titles, the assembler supports subtitles: hence the SUBTTL pseudo-op. Second, the PAGE pseudo-op can be used to go to a new page in the listing. You see an example here of the DSECT-style segment in the "SEGMENT AT 40H". Here, our our interest is in correctly describing the location of some data in the BIOS work area which really is located at segment 40H. You will also see illustrated the EQU instruction, which just gives a sym- bolic name to a number. I don't make a fetish of giving a name to every single number in a program. I do feel strongly, though, that interrupts and function codes, where the number is arbitrary and the function being performed is the thing of interest, should always be given symbolic names. One last new element in this section is the define doubleword (DD) instruc- tion. A doubleword constant can refer, as in this case, to a location in another segment. The assembler will be happy to use information at its disposal to properly assemble it. In this case, the assembler knows that EQUIP is offset 10 in the segment BIOSDATA which is at 40H. SUBTTL -- Perform function PAGE BEGIN: CALL MONOON ;Turn on mono display MOV DX,OFFSET MONOPROMPT ;GET MONO PROMPT MOV AH,PRTMSG ;ISSUE INT DOS ;IT CALL COLORON ;Turn on color display MOV DX,OFFSET COLORPROMPT ;GET COLOR PROMPT MOV AH,PRTMSG ;ISSUE INT DOS ;IT MOV AH,GETKEY ;Obtain user response INT KBD CMP AL,'+' ;Does he want MONO? JNZ NOMONO IBM PC Assembly Language Tutorial 26 CALL MONOON ;yes. give it to him NOMONO: RET MAIN ENDP The main code section makes use of subroutines to keep the basic flow sim- ple. About all that's new to you in this section is the use of the BIOS interrupt KBD to read a character from the keyboard. Now for the subroutines, MONOON and COLORON: SUBTTL -- Routines to turn monitors on PAGE MONOON PROC NEAR ;Turn mono on LES DI,CHANGELOC ;Get location to change ASSUME ES:BIOSDATA ;TELL ASSEMBLER ABOUT CHANGE TO ES OR EQUIP,MONO MOV AX,MONOINIT ;Get screen initialization value INT SCREEN ;Initialize screen RET MONOON ENDP COLORON PROC NEAR ;Turn color on LES DI,CHANGELOC ;Get location to change ASSUME ES:BIOSDATA ;TELL ASSEMBLER ABOUT CHANGE TO ES AND EQUIP,COLOR MOV AX,COLORINIT ;Get screen initialization value INT SCREEN ;Initialize screen RET COLORON ENDP SETSCRN ENDS ;End of segment END MAIN ;End of assembly; execution at MAIN The instructions LES and LDS are useful ones for dealing with doubleword addresses. The offset is loaded into the operand register and the segment into ES (for LES) or DS (for LDS). By telling the assembler, with an ASSUME, that ES now addresses the BIOSDATA segment, it is able to correctly assemble the OR and AND instructions which refer to the EQUIP byte. An ES segment prefix is added. To understand the action here, you simply need to know that flags in that particular byte control how the BIOS screen service initializes the adapt- ers. BIOS will only work with one adapter at a time; by setting the equip- ment flags to show one or the other as installed and calling BIOS screen initialization, we achieve the desired effect. The rest is up to you. IBM PC Assembly Language Tutorial 27 . The rest is up to you.