23 Character Handling

Buffering for character special devices is provided via a set of four word blocks, each of which provides storage for six characters. The prototype storage block is “cblock” (8140) which incorporates a word pointer (to a similar structure) along with the six characters.

Structures of type “clist” (7908) which contain a character counter plus a head and tail pointer are used as “headers” for lists of blocks of type “cblock”.

“cblock”s which are not in current use are linked via their head pointers into a list whose head is the pointer “cfreelist” (3149). The head pointer for the last element of the list has the value “NULL”.

A list of “cblock”s provides storage for a list of characters. The procedure “putc” may be used to add a character to the tail of such a list, and “getc”, to remove a character from the head of such a list.

Figures 23.1 through 23.4 illustrate the development of a list as characters are deleted and added.

\begin{picture}(245,155)(40,525) \thicklines \put(185,540){\framebox(25,140){}} \put(195,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm g}}} \put(195,629){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm h}}} \put(195,608){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm i}}} \put(195,587){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm j}}} \put(195,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm k}}} \put(195,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm l}}} \put(240,540){\framebox(25,140){}} \put(250,629){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm n}}} \put(250,608){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm o}}} \put(250,587){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm p}}} \put(250,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm q}}} \put(250,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm r}}} \put(247,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm m}}} \put( 40,540){\framebox(60,60){}} \put( 90,570){\vector( 1, 0){ 40}} \put(130,540){\framebox(25,140){}} \put(140,670){\vector( 1, 0){ 45}} \put(195,670){\vector( 1, 0){ 45}} \put( 90,550){\line( 0,-1){ 25}} \put( 90,525){\line( 1, 0){195}} \put(285,525){\line( 0, 1){ 25}} \put(285,550){\vector(-1, 0){ 20}} \put( 48,584){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm 14}}} \put( 49,564){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm head}}} \put( 49,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm tail}}} \put(140,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm e}}} \put(140,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm f}}} \end{picture}
Figure 23.1
\begin{picture}(245,155)(40,525) \thicklines \put(185,540){\framebox(25,140){}} \put(195,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm g}}} \put(195,629){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm h}}} \put(195,608){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm i}}} \put(195,587){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm j}}} \put(195,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm k}}} \put(195,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm l}}} \put(240,540){\framebox(25,140){}} \put(250,629){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm n}}} \put(250,608){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm o}}} \put(250,587){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm p}}} \put(250,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm q}}} \put(250,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm r}}} \put(247,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm m}}} \put( 40,540){\framebox(60,60){}} \put( 90,570){\vector( 3,-1){ 40.500}} \put(130,540){\framebox(25,140){}} \put(140,670){\vector( 1, 0){ 45}} \put(195,670){\vector( 1, 0){ 45}} \put( 90,550){\line( 0,-1){ 25}} \put( 90,525){\line( 1, 0){195}} \put(285,525){\line( 0, 1){ 25}} \put(285,550){\vector(-1, 0){ 20}} \put( 49,564){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm head}}} \put( 49,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm tail}}} \put(140,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm f}}} \put( 48,584){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm 13}}} \end{picture}
Figure 23.2

Initially the list is assumed to contain the fourteen characters “efghijklmnopqr”. Note that the head and tail pointers point to characters. If the first character, “e”, is removed by “getc”, the situation portrayed in Figure 23.1 changes to that of Figure 23.2. The character count has been decremented and the head pointer has been advanced by one character position.

If a further character, “f”, is removed from the head of the list, the situation becomes as in Figure 23.3. The character count has been decremented; the first “cblock” no longer contains any useful information and has been returned to “cfreelist”; and the head pointer now points to the first character in the second “cblock”.

\begin{picture}(245,155)(40,525) \thicklines \put(185,540){\framebox(25,140){}} \put(195,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm g}}} \put(195,629){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm h}}} \put(195,608){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm i}}} \put(195,587){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm j}}} \put(195,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm k}}} \put(195,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm l}}} \put(240,540){\framebox(25,140){}} \put(250,629){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm n}}} \put(250,608){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm o}}} \put(250,587){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm p}}} \put(250,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm q}}} \put(250,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm r}}} \put(247,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm m}}} \put( 40,540){\framebox(60,60){}} \put(195,670){\vector( 1, 0){ 45}} \put( 90,550){\line( 0,-1){ 25}} \put( 90,525){\line( 1, 0){195}} \put(285,525){\line( 0, 1){ 25}} \put(285,550){\vector(-1, 0){ 20}} \put( 90,570){\line( 1, 0){ 50}} \put(140,570){\line( 0, 1){ 85}} \put(140,655){\vector( 1, 0){ 45}} \put( 49,564){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm head}}} \put( 49,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm tail}}} \put( 48,584){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm 12}}} \end{picture}
Figure 23.3

The question now poses itself: “how is the difference between the first and second situations detected so that the action taken is always appropriate?”:

The answer (if you have not already guessed) involves looklng at the value of the pointer address modulo 8. Since division by eight is easily performed on a binary computer, the reason for the choice of six characters per “cblock” should now also be apparent.

The addition of a character to the list is illustrated in the change between Figure 23.3 and Figure 23.4.

\begin{picture}(305,155)(60,525) \thicklines \put(185,540){\framebox(25,140){}} \put(195,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm g}}} \put(195,629){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm h}}} \put(195,608){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm i}}} \put(195,587){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm j}}} \put(195,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm k}}} \put(195,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm l}}} \put(240,540){\framebox(25,140){}} \put(250,629){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm n}}} \put(250,608){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm o}}} \put(250,587){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm p}}} \put(250,566){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm q}}} \put(250,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm r}}} \put(247,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm m}}} \put( 40,540){\framebox(60,60){}} \put(195,670){\vector( 1, 0){ 45}} \put( 90,570){\line( 1, 0){ 50}} \put(140,570){\line( 0, 1){ 85}} \put(140,655){\vector( 1, 0){ 45}} \put(295,540){\framebox(25,140){}} \put(250,670){\vector( 1, 0){ 45}} \put( 90,550){\line( 0,-1){ 25}} \put( 90,525){\line( 1, 0){255}} \put(345,525){\line( 0, 1){130}} \put(345,655){\vector(-1, 0){ 25}} \put( 49,564){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm head}}} \put( 49,545){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm tail}}} \put(305,650){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm s}}} \put( 48,584){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm 13}}} \end{picture}
Figure 23.4

Since the last “cblock” ln Figure 23.3 was full, a new one has been obtained from “cfreelist” and linked into the list of “cblock”s. The character count and tail pointer have been adjusted appropriately.