# CHAPTER 15 - General Purpose Programmable Peripheral Devices¶

## EXAMPLE 15.1 - PG NO: 449¶

In [1]:
## page no 449
## example no 15.1
print ('1 Port Address \n \n')#
print ('Port A                  =    8000H  (A1=0,A0=0) \n')#
print ('Port B                  =    8001H  (A1=0,A0=1) \n')#
print ('Port C                  =    8002H  (A1=1,A0=0) \n')#
print ('Control Register        =    8003H  (A1=1,A0=1) \n \n')#

print ('2 Control Word \n \n')#
print ('D7 D6 D5 D4 D3 D2 D1 D0 \n')#
print ('1  0  0  0  0  0  1  1         = 83H \n \n')#
print ('D7=1     I#O Function \n')#
print ('D6,D5=0  Port A in Mode 0 \n')#
print ('D4=0     Port A= output \n')#
print ('D3=0     Port C upper= output \n')#
print ('D2=0     Port B in Mode 0 \n')#
print ('D1=1     Port B= input \n')#
print ('D0=1     Port C1= input \n \n')#

print ('3 Program \n \n')#
print ('MVI A,83H \n')#  ## load accumulator with the control word.
print ('STA 8003H \n')#  ## write word in the control register to initialize the ports.
print ('LDA 8001H \n')#  ## reads switches at port B.
print ('STA 8000H \n')#  ## display the reading at port A.
print ('LDA 8002H \n')#  ## read switches at port C.
print ('ANI 0FH \n')#    ## mask the upper four bits of port C, these bits are not input data.
print ('RLC \n')#        ## rotate and place the data in the upper half of the accumulator.
print ('RLC \n')#
print ('RLC \n')#
print ('RLC \n')#
print ('STA 8002H    Display data at port C upper\n')#  ## display data at port C upper.
print ('HLT \n')#

1 Port Address

Port A                  =    8000H  (A1=0,A0=0)

Port B                  =    8001H  (A1=0,A0=1)

Port C                  =    8002H  (A1=1,A0=0)

Control Register        =    8003H  (A1=1,A0=1)

2 Control Word

D7 D6 D5 D4 D3 D2 D1 D0

1  0  0  0  0  0  1  1         = 83H

D7=1     I#O Function

D6,D5=0  Port A in Mode 0

D4=0     Port A= output

D3=0     Port C upper= output

D2=0     Port B in Mode 0

D1=1     Port B= input

D0=1     Port C1= input

3 Program

MVI A,83H

STA 8003H

LDA 8001H

STA 8000H

LDA 8002H

ANI 0FH

RLC

RLC

RLC

RLC

STA 8002H    Display data at port C upper

HLT



## EXAMPLE 15.2 - PG NO: 453¶

In [2]:
## page no 453
## example no 15.2
## BSR CONTROL WORD SUBROUTINE
print ('BSR Control Words \n \n')#
print ('D7 D6 D5 D4 D3 D2 D1 D0 \n')#
print ('0  0  0  0  1  1  1  1         = 0FH      To set bit PC7 \n')#
print ('0  0  0  0  1  1  1  0         = 0EH      To reset bit PC7 \n')#
print ('0  0  0  0  0  1  1  1         = 07H      To set bit PC3 \n')#
print ('0  0  0  0  0  1  1  0         = 06H      To reset bit PC3 \n \n')#

print ('Control Register Address = 83H \n \n')#

print ('Subroutine \n \n')#
print('BSR: \n')
print ('\n MVI A,0FH \n')#       ## load byte in accumulator to set PC7
print ('\n OUT 83H \n')#         ## set PC7=1
print ('\n MVI A,07H \n')#       ## load byte in accumulator to set PC3.
print ('\n OUT 83H \n')#         ## set PC3=1.
print ('\n CALL DELAY \n')#      ## this is a 10 microsec delay.
print ('\n MVI A,06H \n')#       ## load byte in accumulator to reset PC3
print ('\n OUT 83H \n')#         ## reset PC3
print ('\n MVI A,0EH \n')#       ## load byte in accumulator to reset PC7.
print ('\n OUT 83H \n')#         ## reset PC7
print ('\n RET')#

BSR Control Words

D7 D6 D5 D4 D3 D2 D1 D0

0  0  0  0  1  1  1  1         = 0FH      To set bit PC7

0  0  0  0  1  1  1  0         = 0EH      To reset bit PC7

0  0  0  0  0  1  1  1         = 07H      To set bit PC3

0  0  0  0  0  1  1  0         = 06H      To reset bit PC3

Subroutine

BSR:

MVI A,0FH

OUT 83H

MVI A,07H

OUT 83H

CALL DELAY

MVI A,06H

OUT 83H

MVI A,0EH

OUT 83H

RET


## EXAMPLE 15.3 - PG NO:483¶

In [3]:
## page no 483
## example no 15.3
## INSTRUCTIONS TO GENERATE A PULSE FROM COUNTER 0
def dec2hex(n):
return "%X" % n

print ('Control Word \n \n')#
print ('D7 D6 D5 D4 D3 D2 D1 D0 \n')#
print ('0  0  0  1  0  1  0  0         = 14H \n \n')#
print ('D7,D6=0        Select counter 0 \n')#
print ('D5,D4=01       Load 8 bit count \n')#
print ('D3,D2,D1=010   Mode 2 \n')#
print ('D0=0           Binary Count \n \n')#

print ('Count \n \n')#
count=(50.*10.**-6.)/(0.5*10.**-6.)#
print ('Count= ')#
print'%d' %(count)#
print('\n')
print (dec2hex(count))#

print ('Instructions \n \n')#
print ('PULSE: \n')
print ('\n MVI A,00010100B')#    ## control word mode 2 & counter 0.
print ('\n OUT 83H')#            ## write in 8254 control register.
print ('\n MVI A,64H')#          ## low order byte of the count.
print ('\n OUT 80H')#            ## load counter 0 with low order byte
print ('\n HLT')#

Control Word

D7 D6 D5 D4 D3 D2 D1 D0

0  0  0  1  0  1  0  0         = 14H

D7,D6=0        Select counter 0

D3,D2,D1=010   Mode 2

D0=0           Binary Count

Count

Count=
100

64

Instructions

PULSE:

MVI A,00010100B

OUT 83H

MVI A,64H

OUT 80H

HLT


## EXAMPLE 15.4 - PG NO:484¶

In [4]:
## page no 484
## example no 15.4
## INSTRUCTIONS TO GENERATE SQUARE WAVE PULSE FROM COUNTER 1
def dec2hex(n):
return "%X" % n

print ('Control Word \n \n')#
print ('D7 D6 D5 D4 D3 D2 D1 D0 \n')#
print ('0  1  1  1  0  1  1  0         = 76H \n \n')#
print ('D7,D6=01       Select counter 1 \n')#
print ('D5,D4=11       Load 16 bit count \n')#
print ('D3,D2,D1=011   Mode 3 \n')#
print ('D0=0           Binary Count \n \n')#

print ('Count \n \n')#
count=(1*10**-3)/(0.5*10**-6)#
print ('Count= ')#
print'%d' %(count)#
b=dec2hex(2000)#
print('\n')
print (b)#

print ('Instructions :\n \n')#
print ('SQWAVE: \n')#
print ('\n MVI A,01110110B')#    ## control word mode 3 & counter 1.
print ('\n OUT 83H ')#            ## write in 8254 control register.
print ('\n MVI A,D0H ')#          ## low order byte of the count.
print ('\n OUT 81H ')#            ## load counter 1 with low order byte.
print ('\n MVI A,07H ')#          ## high order byte of the count.
print ('\n OUT 81H ')#            ## load counter 1 with high order byte
print ('\n HLT')#

Control Word

D7 D6 D5 D4 D3 D2 D1 D0

0  1  1  1  0  1  1  0         = 76H

D7,D6=01       Select counter 1

D3,D2,D1=011   Mode 3

D0=0           Binary Count

Count

Count=
2000

7D0

Instructions :

SQWAVE:

MVI A,01110110B

OUT 83H

MVI A,D0H

OUT 81H

MVI A,07H

OUT 81H

HLT


## EXAMPLE 15.5 - PG NO: 486¶

In [5]:
## page no 486
## example no 15.5
## SUBROUTINE TO GENERATE AN INTERRUPT
print ('Control Word \n \n')#
print ('D7 D6 D5 D4 D3 D2 D1 D0 \n')#
print ('0  1  1  1  0  1  0  0         = 74H      Counter 1 \n')#
print ('1  0  0  1  0  1  0  0         = 94H      Counter 2 \n \n')#
print ('D7,D6          Select counter  \n')#
print ('D3,D2,D1=010   Mode 2 \n')#
print ('D0=0           Binary Count \n \n')#

print ('Instructions \n \n')#
print ('CNT1LO  EQU 50H \n')#
print ('CNT1HI  EQU C3H \n')#
print ('COUNT2  EQU 40H \n')#
print ('SECOND:  MVI A,01110100B \n')#    ## control word mode 2 & counter 1.
print ('        OUT 83H \n')#            ## write in 8254 control register.
print ('        MVI A,10010100B \n')#    ## control word mode 2 & counter 2.
print ('        OUT 83H \n')#            ## write in 8254 control register.
print ('        MVI A,CNT1LO \n')#       ## Low order byte of count 50000
print ('        OUT 81H \n')#            ## Load counter 1 with low order byte
print ('        MVI A,CNT1HI \n')#       ## high order byte of count 50000.
print ('        OUT 81H \n')#            ## load counter 1 with high order byte
print ('        MVI A,COUNT2 \n')#       ## Count for Counter 2.
print ('        OUT 82H \n')#            ## load counter 2.
print ('        RET')#

Control Word

D7 D6 D5 D4 D3 D2 D1 D0

0  1  1  1  0  1  0  0         = 74H      Counter 1

1  0  0  1  0  1  0  0         = 94H      Counter 2

D7,D6          Select counter

D3,D2,D1=010   Mode 2

D0=0           Binary Count

Instructions

CNT1LO  EQU 50H

CNT1HI  EQU C3H

COUNT2  EQU 40H

SECOND:  MVI A,01110100B

OUT 83H

MVI A,10010100B

OUT 83H

MVI A,CNT1LO

OUT 81H

MVI A,CNT1HI

OUT 81H

MVI A,COUNT2

OUT 82H

RET


## EXAMPLE 15.6 - PG NO:493¶

In [6]:
## page no 493
## example no 15.6
## EXPLANATION OF INSTRUCTIONS
print ('1) DI instruction disables the interrupts. \n \n');
print ('2) Command word 76H specifies the following parameters \n');
print ('A7 A6 A5 A4 A3 A2 A1 A0 \n');
print ('0  1  1  1  0  1  1  0       =76H \n');
print ('A7,A6,A5    Low order address bits \n');
print ('A3          Edge triggered \n');
print ('A2          Call address interval is four locations \n');
print ('A1          Single 8259A \n \n');
print ('Low order byte of the IR0 call address \n');
print ('A7 A6 A5 A4 A3 A2 A1 A0 \n');
print ('0  1  1  0  0  0  0  0       =60H \n');
print ('The address bits A4-A0 are supplied by 8259A. \n');
print ('Subsequent addresses are four locations apart (eg. IR1=64H)')
print ('3) Port address of the 8259SA for ICW1 is 80H, A0 should be at \n logic 0 & the other bits are determined by the decoder. \n \n');
print ('4) Command word ICW2 is 20H. \n which specifies the high-order byte of the call address \n \n');
print ('5) Port address of ICW2 is 81H, A0 should be at logic 1.');

1) DI instruction disables the interrupts.

2) Command word 76H specifies the following parameters

A7 A6 A5 A4 A3 A2 A1 A0

0  1  1  1  0  1  1  0       =76H

A3          Edge triggered

A2          Call address interval is four locations

A1          Single 8259A

Low order byte of the IR0 call address

A7 A6 A5 A4 A3 A2 A1 A0

0  1  1  0  0  0  0  0       =60H

The address bits A4-A0 are supplied by 8259A.

Subsequent addresses are four locations apart (eg. IR1=64H)
3) Port address of the 8259SA for ICW1 is 80H, A0 should be at
logic 0 & the other bits are determined by the decoder.

4) Command word ICW2 is 20H.
which specifies the high-order byte of the call address

5) Port address of ICW2 is 81H, A0 should be at logic 1.


## EXAMPLE 15.8 - PG NO: 502¶

In [7]:
## page no 502
## example no 15.8
## INITIALIZATION INSTRUCTIONS FOR DMA
print ('MVI A,00000100B \n \n');
print ('A7 A6 A5 A4 A3 A2 A1 A0 \n');
print ('0  0  0  0  0  1  0  0 \n');
print ('A2=1        Disable DMA \n \n');
print ('OUT 08H \n');
print ('MVI A,00000111B \n \n');
print ('A7 A6 A5 A4 A3 A2 A1 A0 \n');
print ('0  0  0  0  0  1  1  1 \n');
print ('A7,A6=00    Demand mode  \n');
print ('A4=0        Disable auto load \n');
print ('A3,A2=01    Write \n');
print ('A1,A0=11    Ch 3 \n \n');
print ('OUT 0BH \n');            ## Send to mode reg.
print ('MVI A,75H \n');          ## Low order byte of starting address
print ('OUT 06H \n');            ## Output to CH3 memory address reg.
print ('MVI A,40H \n');          ## High order byte of starting address
print ('OUT 06H \n');            ## Output to CH3 memory address reg.
print ('MVI A,FFH \n');          ## Low order byte of the count 03FFH
print ('OUT 07H \n');            ## Output to CH3 count reg.
print ('MVI A,03H \n');          ## High order byte of the count 03FFH
print ('OUT 07H \n');            ## Output to CH3 count reg.
print ('MVI A,10000000B \n \n');
print ('A7 A6 A5 A4 A3 A2 A1 A0 \n');
print ('1  0  0  0  0  0  0  0 \n');
print ('A7,A6=10    DACK DREQ High  \n');
print ('A5=0        Late write \n');
print ('A4=0        Fixed priority \n');
print ('A3=0        Normal time \n');
print ('A2=0        DMA enable \n')
print ('A0=0        Disable mem to mem \n \n');
print ('OUT 08H \n');

MVI A,00000100B

A7 A6 A5 A4 A3 A2 A1 A0

0  0  0  0  0  1  0  0

A2=1        Disable DMA

OUT 08H

MVI A,00000111B

A7 A6 A5 A4 A3 A2 A1 A0

0  0  0  0  0  1  1  1

A7,A6=00    Demand mode

A3,A2=01    Write

A1,A0=11    Ch 3

OUT 0BH

MVI A,75H

OUT 06H

MVI A,40H

OUT 06H

MVI A,FFH

OUT 07H

MVI A,03H

OUT 07H

MVI A,10000000B

A7 A6 A5 A4 A3 A2 A1 A0

1  0  0  0  0  0  0  0

A7,A6=10    DACK DREQ High

A5=0        Late write

A4=0        Fixed priority

A3=0        Normal time

A2=0        DMA enable

A0=0        Disable mem to mem

OUT 08H