; ; UPPER CASE CONVERSION PROGRAM ; VERSION 2 ; STATUS EQU 1 ;RDT STATUS PORT DATA EQU 2 ;RDT DATA PORT INMASK EQU 0x80 ;STATUS PORT BIT D0 = 7 WHEN KEYBOARD CHARACTER DATA AVAILABLE OUTMASK EQU 0x40 ;STATUS PORT BIT D7 = 6 WHEN TERMINAL BUSY PROCESSING CHARACTER DATA BUFSIZE EQU 60 ;INPUT BUFFER SIZE ; ORG 0X0000 ;PROGRAM START ADDRESS ; ; INITIALIZATION SEGMENT BEGINS ; LXI SP,STACK ;STACK -> SP CALL CLRSCR ;CLEAR SCREEN ; ; INITIALIZATION SEGMENT ENDS ; ; MAIN SEGMENT BEGINS ; LXI H,WLCMSG ;OUTPUT WELCOME MESSAGE CALL MSGOUT ; ; GET MESSAGE FROM KEYBOARD (CR TO TERMINATE) ; AGAIN: CALL BUFIN JNZ UCVRT ;IF NO ERROR THEN CONTINUE CALL CRLF ;NEW LINE LXI H,ERRMSG ;OUTPUT ERROR MESSAGE CALL MSGOUT JMP AGAIN ;DO AGAIN ; ; MAKE UPPERCASE CONVERSION ; UCVRT: LXI H, BUFSTRT ;START OF INOUTTED MESSAGE -> HL LXI D, REV_MSG ;START OF MEMORY SPACE FOR REVISED COPY -> DE ; LOOP0: MOV A,M ;CHARACTER->A ORA A ;IF A=0 THEN JUMP CONT1 JZ CONT1 CPI 0x61 ;IF CHARACTER < 'a' THEN JUMP CONT JC CONT0 CPI 0x7B ;IF CHARACTER >= 'z'+1 THEN JUMP CONT JNC CONT0 ANI 0b11011111 ;ZERO BIT 5 CONT0: STAX D ;CHARACTER->[DE] NOTE: [rp] MEANS MEMORY ADDRESS POINTED TO BY REGISTER PAIR rp INX H ;NEXT HL ADDRESS INX D ;NEXT DE ADDRESS JMP LOOP0 ;GET NEXT CHARACTER ; CONT1: STAX D ;STORE SIGNAL (END) BYTE LXI H,REV_MSG ;OUTPUT REVISED MESSAGE CALL MSGOUT CALL CRLF ;NEW LINE JMP AGAIN ;DO AGAIN ; ; MAIN SEGMENT ENDS ; ; SUBROUTINE SEGMENT BEGINS ; ; CLEAR SCREEN SUBROUTINE ; ; DATA TRANSFER FROM CALL: NONE ; DATA TRANSFER ON RETURN: NONE ; ; REGISTERS USED: A AND C ; CLRSCR: MVI C,25 ;CLEAR SCREEN CHARACTER -> C JMP CHROUT ;BRANCH TO CHARACTER OUTPUT SUBROUTINE ; ; CR AND LF OUTPUT SUBROUTINE ; ; DATA TRANSFER FROM CALL: NONE ; DATA TRANSFER ON RETURN: NONE ; ; REGISTERS USED: A AND C ; CRLF: MVI C,13 ;CR -> C CALL CHROUT ;SEND CHARACTER TO TEMINAL SCREEN MVI C,10 ;LF -> C JMP CHROUT ;BRANCH TO CHARACTER OUTPUT SUBROUTINE ; ; CR AND LF OUTPUT SUBROUTINE ; ; DATA TRANSFER FROM CALL: HL POINTS TO START OF MESSAGE ; DATA TRANSFER ON RETURN: NONE ; ; REGISTERS USED: A, C, H, AND L ; MSGOUT: MOV A,M ;CHARACTER -> A ORA A ;IF A=0 THEN JUMP CONT2 RZ ;RETURN WHEN DONE MOV C,A ;CHARACTER -> C CALL CHROUT ;SEND CHARACTER TO TERMINAL SCREEN INX H ;NEXT HL ADDRESS JMP MSGOUT ;GET NEXT CHARACTER ; ; BUFFER INPUT SUBROUTINE ; ; DATA TRANSFER FROM CALL: NONE ; DATA TRANSFER ON RETURN: BUFSTRT POINTS TO INPUTTED MESSAGE ; ; REGISTERS USED: A,C ; BUFIN: LXI H, BUFSTRT ;INPUT BUFFER MVI B, BUFSIZE+1 ;MAX BUFFER CHARACTERS OVER: CALL CHRIN ;GET CHARACTER AND ECHO CPI 13 ;CR? JZ BUFEND ;DONE MOV M,A INX H DCR B ;EXCEED BUFFER LENGTH? RZ ;RETURN WITH Z (BUFFER SIZE EXCEEDED ERROR) JMP OVER ;GET NEXT CHARACTER BUFEND: MVI M,0 ;SENTINEL VALUE -> M ORA A ;RETURN WITH NZ (NO ERROR) RET ; ; CHARACTER INPUT SUBROUTINE WITH ECHO ; ; DATA TRANSFER FROM CALL: NONE ; DATA TRANSFER ON RETURN: A CONTAINS CHARACTER INPUTTED ; ; REGISTERS USED: A AND C ; CHRIN: IN STATUS ;STATUS BYTE -> A ANI INMASK ;MASK CHARACTER DATA AVAILABLE BIT D0 JNZ CHRIN ;WAIT IF D0 = 1 - NO CHARACTER AVAILABLE IN DATA ;KEYBOARD CHARACTER -> A MOV C,A ;INPUTTED CHARACTER -> C ; ; CHARACTER OUTPUT SUBROUTINE ; ; DATA TRANSFER FROM CALL: CHARACTER TO BE OUTPUT IN C REGISTER ; DATA TRANSFER ON RETURN: A CONTAINS CHARACTER OUTPUTTED AND INPUTTED IF CALLED AT CHRIN ; ; REGISTERS USED: A AND C ; CHROUT: IN STATUS ;STATUS BYTE -> A ANI OUTMASK ;MASK TERMINAL BUSY BIT D7 JNZ CHROUT ;WAIT IF D7 = 1 - TERMINAL BUSY MOV A,C ;CHARACTER -> A OUT DATA ;SEND CHARACTER TO TEMINAL SCREEN RET ; ; SUBROUTINE SEGMENT ENDS ; ; DATA SEGMENT BEGINS ; WLCMSG: DM 'INPUT BUFFERED ECHO PROGRAM WITH UPPER CASE CONVERSION' DB 13,10,0 ;CR + LF + SENTINEL BYTE (0) ; ERRMSG: DM 'MESSAGE EXCEEDS BUFFER SIZE. TRY AGAIN.' DB 13,10,0 ;CR + LF + SENTINEL BYTE (0) ; BUFSTRT:DS BUFSIZE ;MEMORY SPACE FOR INPUT BUFFER ; REV_MSG:DS 100 ;MEMORY SPACE FOR REVISED MESSAGE ; DS 100 ;MEMORY SWPACE FOR STACK STACK: DS 1 ; ; DATA SEGMENT ENDS ;