UNIT CmpSci 201 Lab Exercise #7
; Robert S. Laramee
; cs201
; start date 23 Nov 1996
PROCEDURE
Get PSHH R0 ; <--\ procedure
PSHH R1 ; | must be
PSHH R2 ; | completely
PSHH R3 ; | transparent
PSHH R4 ; |
PSHH R5 ; <--/
MOVB A,R0 ; get InBuf index
CMPB #'#',InBuf[R0] ; IF the last character of InBuf
BREQ ignore ; is already a '#' THEN --> ignore
MOVB B,R1 ; IF InBuf has a complete string
CMPB #0,WorkBuf[R1] ; not yet copied to WorkBuf
BRNE ignore ; THEN --> ignore
INPB 22h,R2 ;
CMPB #'#',R2 ; IF IN register contains a '#'
BRNE skip ;
ADDB #1,R0 ; increment [i]
MOVB #'#',InBuf[R0] ; THEN put the '#' in InBuf
MOVB R0,A ; store [i]
BRUN exit_G ;
skip CMPB #10,R0 ; IF the number of characters in
BUGE ignore ; Inbuf is >= 10 THEN --> ignore
; otherwise
ADDB #1,R0 ; increment InBuf index
INPB 22h,InBuf[R0] ; (Inbuf) = ASCII code of input char
; [22h = input data reg add]
MOVB R0,A ; store InBuf Index
BRUN exit_G
ignore INPB 22h,trash ; trash = ASCII code of input char
; [22h = input data reg add]
exit_G POPH R5 ; <--\
POPH R4 ; |
POPH R3 ; |
POPH R2 ; |
POPH R1 ; |
POPH R0 ; <--/
IRET
ENDP
PROCEDURE
Put PSHH R0 ; <--\ procedure
PSHH R1 ; | must be
PSHH R2 ; | completely
PSHH R3 ; | transparent
PSHH R4 ; |
PSHH R5 ; <--/
MOVB C,R0 ; get OutBuf index
CMPB #0,OutBuf[R0] ; IF Outbuf[i] = 0 (meaning done)
BREQ disable ; THEN --> disable
OUTB OutBuf[R0],24h ; (Outbuf) = ASCII code of input char
; [24h = output data reg add]
ADDB #1,R0 ; increment OutBuf index
MOVB R0,C ; store OutBuf Index
BRUN exit_P ; skip disable instruction
disable INTF 1011b ; enable input interrupts only
exit_P POPH R5 ; <--\
POPH R4 ; |
POPH R3 ; |
POPH R2 ; |
POPH R1 ; |
POPH R0 ; <--/
IRET
ENDP
PROGRAM Lab7
Stack DH 32
A DB (0) ; variable declarations
B DB (0)
C DB (1)
InBuf DB 12
WorkBuf DB 12
OutBuf DB 12
trash DB (0)
INTF 0 ; 1. Disable all interrupts
OUTB #00110011b,26h ; 2. initialize IO interface
; [26h = control register]
; bits 0 & 1 = 11b --> output & input mode = 8-bit
; bit 4 = 1b --> output interrupt level 2 enabled
; bit 5 = 1b --> input interrupt level 3 enabled
MOVH #0,8 ; 3. initialize interrupt vectors:
MOVH #Put,10 ; --> character out
MOVH #0,12 ;
MOVH #Get,14 ; --> character in
; /--------------------------------------------\
; | initialize InBuf, WorkBuf, OutBuf, A, B, C |
; \--------------------------------------------/
begin MOVB #0,A
MOVB #0,B
MOVB #1,C
SUBH R5,R5
array1 CMPH #13,R5
BUGE array2
MOVB #0,InBuf[R5]
ADDH #1,R5
BRUN array1
array2 SUBH R5,R5
reset2 CMPH #13,R5
BUGE array3
MOVB #0,WorkBuf[R5]
ADDH #1,R5
BRUN reset2
array3 SUBH R5,R5
reset3 CMPH #13,R5
BUGE ok
MOVB #0,OutBuf[R5]
ADDH #1,R5
BRUN reset3
ok INTF 1011b ; 4. enable only input interrupts
; /---------------------------------------------\
; | Loop: |
; | Delay until a complete string has been read |
; | into the input buffer (InBuf) |
; \---------------------------------------------/
loop SUBH R0,R0 ; clear R0
MOVB A,R0 ; get InBuf index
CMPB #'#',InBuf[R0] ; look for a '#' character
BREQ if ; IF InBuf[i] = '#' character
; THEN --> if
BRUN loop ; otherwise --> loop
; /-------------------------------------------\
; | IF the input string consists of only a |
; | single '#' THEN halt program execution |
; \-------------------------------------------/
if INTF 0 ; disable input interrupts
MOVB A,R0 ; get InBuf index
SUBB #1,R0 ; [i] = [i] - 1
CMPB #0,InBuf[R0] ; look at previous character
BREQ done ; IF previous character = 0
; THEN halt program execution
; /------------------------------------------\
; | copy the string in InBuf into the work |
; | buffer (WorkBuf) |
; \------------------------------------------/
SUBH R0,R0 ; use R0 as index [i]
I_to_W CMPB #13,R0 ;
BUGE replace ; IF [i] >= 13 THEN --> replace
MOVB InBuf[R0],WorkBuf[R0]
; copy string in InBuf to WorkBuf
MOVB R0,B ; B = current index of WorkBuf
ADDB #1,R0 ; increment index [i]
BRUN I_to_W ;
replace INTF 1011b ; enable input interrupts
; /---------------------------------------------\
; | replace each digit in WorkBuf with a 'd'. |
; | replace each lowecase letter with an 'l'. |
; | replace each uppercase letter with a 'u'. |
; | replace all other characters with an 'o'. |
; \---------------------------------------------/
MOVH #1,R0 ; use R0 as index [i]
next0 MOVB WorkBuf[R0],R1 ; get character at [i]
CMPB #0,R1 ;
BREQ outwait ; IF [i] = 0 THEN --> outwait
CMPB #2Fh,R1 ;
BUGT next1 ; IF ASCII value > '/' THEN --> next1
MOVB #'o',WorkBuf[R0] ; otherwise replace with 'o'
BRUN next_char ;
next1 CMPB #39h,R1 ;
BUGT next2 ; IF ASCII value > '9' THEN --> next2
MOVB #'d',WorkBuf[R0] ; otherwise replace with 'd'
BRUN next_char ;
next2 CMPB #40h,R1 ;
BUGT next3 ; IF ASCII value > '@' THEN --> next3
MOVB #'o',WorkBuf[R0] ; otherwise replace with 'o'
BRUN next_char ;
next3 CMPB #5Ah,R1 ;
BUGT next4 ; IF ASCII value > 'Z' THEN --> next4
MOVB #'u',WorkBuf[R0] ; otherwise replace with 'u'
BRUN next_char ;
next4 CMPB #60h,R1 ;
BUGT next5 ; IF ASCII value > '`' THEN --> next5
MOVB #'o',WorkBuf[R0] ; otherwise replace with 'o'
BRUN next_char ;
next5 CMPB #7Ah,R1 ;
BUGT next6 ; IF ASCII value > 'z' THEN --> next6
MOVB #'l',WorkBuf[R0] ; otherwise replace with 'l'
BRUN next_char ;
next6 MOVB #'o',WorkBuf[R0] ; otherwise replace with 'o'
next_char NOOP
ADDB #1,R0 ; increment [i]
BRUN next0 ; replace next character
; /-----------------------------------------\
; | delay until the output buffer (outBuf) |
; | is empty |
; \-----------------------------------------/
outwait INPB 20h,R2 ; 20h = status register address
TSTB #1b,R2 ; OUT register: 1 = empty, 0 = full
BREQ outwait ; IF full THEN --> outwait
; /-----------------------------------------\
; | copy the string in WorkBuf into OutBuf |
; \-----------------------------------------/
SUBH R0,R0 ; use R0 as index [i]
copy CMPB #13,R0 ;
BUGE output ; IF [i] >= 13 THEN --> output
MOVB WorkBuf[R0],OutBuf[R0]
; copy string in WorkBuf to OutBuf
ADDH #1,R0 ; increment [i]
BRUN copy ; copy next character
output INTF 1010b ; enable output interrupts
OUTB #0b,24h ; [24h = output data reg add]
BRUN begin ; go back to beginning
done HALT ; input string = '#' only
ENDP
END