Once memory-mapped I/O is in place, the algorithm for communicating with a peripheral is essentially no different from the earlier example that used IN and OUT. Instead of IN, the CPU issues a LOD instruction to fetch a word from "memory" and instead of OUT, it issues a STD instruction. The addresses given are the mapped addresses of the control, status and data registers of the peripheral's controller. Fig. 18.7.4 is a reprise of Fig. 18.2.2, with the substitution of LOD and STD for IN and OUT. In order to translate from the isolated I/O version to memory-mapped I/O, we have to know where the "registers" are in memory. Following is an assignment of three memory words to the three registers needed for a tape reader: memory address register writer reader function ------ -------- ------ ------ -------- 128 0 CPU TR status of CPU 129 1 TR CPU status of tape reader 130 2 CPU TR command 131 3 TR CPU data sent from tape reader Here's the program: LDI 001b ;form the code for the START command STD 130 ;send the START command to the tape reader LDI 01b ;put the CPU's status into its status port STD 128 ;which the TR reads as "Go read for me now!" WHILE1: LOD 129 ;read data ready bit from status register SUB DATAREADY ;compare to "01"b JZ ENDWHILE1 ;if equal, then done JMP WHILE1 ;else go back to top of loop ENDWHILE1:NOP ;this is outside the loop, ready to go on LOD 131 ;read data byte in data register STD X ;store into main memory somewhere (X) LDI 10b ;get ready to write 1 into data accepted STD 128 ;write to the CPU's status register ;the tape reader is now spinning, waiting for CPU LDI 100 ;pause the loop to allow the tape reader ;to catch up WHILE2: JZ ENDWHILE2 ;waste 100 time units here SUB ONE ;by counting down from 100 JMP WHILE2 ;to 0 by subtracting 1 ;... sometime inside here the tape reader sets ; its status register back to "00" ENDWHILE2:NOP JMP WHILE1 ;do it all over again to read next byte DATAREADY:NUM 01b ; 01b is the code for the CPU saying "I'm waiting!" ONE: NUM 1 Fig. 18.7.4: Polling program to read bytes from device A, using memory-mapped I/O |