--- /dev/null
+Title: INTRODUCTION TO MODE X (XINTRO.TXT)\r
+\r
+Version: 1.8\r
+\r
+Author: Robert Schmidt <robert@stud.unit.no>\r
+\r
+Copyright: (C) 1993 of Ztiff Zox Softwear - refer to Status below.\r
+\r
+Last revision: 25-Nov-93\r
+\r
+Figures: 1. M13ORG - memory organization in mode 13h\r
+ 2. MXORG - memory organization in unchained modes\r
+\r
+ The figures are available both as 640x480x16 bitmaps\r
+ (in GIF format), and as 7-bit ASCII text (ASC) files.\r
+\r
+C sources: 1. LIB.C v1.2 - simple graphics library for planar,\r
+ 256-color modes - optionally self-testing.\r
+\r
+ Excerpts from the source(s) appear in this article.\r
+ Whenever there are conflicts, the external source file(s)\r
+ are correct (or, at least, newest), _not_ the excerpts\r
+ provided here.\r
+\r
+Status: This article, its associated figures and source listings\r
+ named above, are all donated to the public domain.\r
+ Do with it whatever you like, but give credit where\r
+ credit is due. I would prefer it if this archive was\r
+ distributed in its entirety, including the files\r
+ mentioned above.\r
+\r
+ The standard disclaimer applies.\r
+\r
+Index: 0. ABSTRACT\r
+ 1. INTRODUCTION TO THE VGA AND ITS 256-COLOR MODE\r
+ 2. GETTING MORE PAGES AND PUTTING YOUR FIRST PIXEL\r
+ 3. THE ROAD FROM HERE\r
+ 4. BOOKS ON THE SUBJECT\r
+ 5. BYE - FOR NOW\r
+\r
+\r
+0. ABSTRACT\r
+\r
+This text gives a fairly basic, yet technical, explanation to what, why\r
+and how Mode X is. It first tries to explain the layout of the VGA\r
+memory and the shortcomings of the standard 320x200 256-color mode,\r
+then gives instructions on how one can progress from mode 13h to a\r
+multipage, planar 320x200 256-color mode, and from there to the\r
+quasi-standard 320x240 mode, known as Mode X.\r
+\r
+A little experience in programming the standard VGA mode 13h\r
+(320x200 in 256 colors) is assumed. Likewise a good understanding of\r
+hexadecimal notation and the concepts of segments and I/O ports is\r
+assumed. Keep a VGA reference handy, which at least should have\r
+definitions of the VGA registers at bit level.\r
+\r
+Throughout the article, a simple graphics library for unchained (planar)\r
+256-color modes is developed. The library supports the 320x200 and\r
+320x240 modes, active and visible pages, and writing and reading\r
+individual pixels.\r
+\r
+\r
+1. INTRODUCTION TO THE VGA AND ITS 256-COLOR MODE\r
+\r
+Since its first appearance on the motherboards of the IBM PS/2 50, 60\r
+and 80 models in 1987, the Video Graphics Array has been the de facto\r
+standard piece of graphics hardware for IBM and compatible personal\r
+computers. The abbreviation, VGA, was to most people synonymous with\r
+acceptable resolution (640x480 pixels), and a stunning rainbow of colors\r
+(256 from a palette of 262,144), at least compared to the rather gory\r
+CGA and EGA cards.\r
+\r
+Sadly, to use 256 colors, the VGA BIOS limited the users to 320x200\r
+pixels, i.e. the well-known mode 13h. This mode has one good and one\r
+bad asset. The good one is that each one of the 64,000 pixels is easily\r
+addressable in the 64 Kb video memory segment at 0A000h. Simply calculate\r
+the offset using this formula:\r
+\r
+offset = (y * 320) + x;\r
+\r
+Set the byte at this address (0A000h:offset) to the color you want, and\r
+the pixel is there. Reading a pixel is just as simple: just read the\r
+corresponding byte. This was heaven, compared to the havoc of planes and\r
+masking registers needed in 16-color modes. Suddenly, the distance from a\r
+graphics algorithm on paper to an implemented graphics routine in assembly\r
+was cut down to a fraction. The results were impressively fast, too!\r
+\r
+The bad asset is that mode 13h is also limited to only one page, i.e.\r
+the VGA can hold only one screenful at any one time (plus 1536 pixels, or\r
+about four lines). Most 16-color modes let the VGA hold more than one page,\r
+and this enables you to show one of the pages to the user, while drawing on\r
+another page in the meantime. Page flipping is an important concept in making\r
+flicker free animations. Nice looking and smooth scrolling is also almost\r
+impossible in mode 13h using plain VGA hardware.\r
+\r
+Now, the alert reader might say: "Hold on a minute! If mode 13h enables\r
+only one page, this means that there is memory for only one page. But I\r
+know for a fact that all VGAs have at least 256 Kb RAM, and one 320x200\r
+256-color page should consume only 320*200=64000 bytes, which is less\r
+than 64 Kb. A standard VGA should room a little more than four 320x200\r
+pages!" Quite correct, and to see how the BIOS puts this limitation on\r
+mode 13h, I'll elaborate a little on the memory organization of the VGA.\r
+\r
+The memory is separated into four bit planes. The reason for this stems\r
+from the EGA, where graphics modes were 16-color. Using bit planes, the\r
+designers chose to let each pixel on screen be addressable by a single\r
+bit in a single byte in the video segment. Assuming the palette has\r
+not been modified from the default, each plane represent one of the EGA\r
+primary colors: red, green, blue and intensity. When modifying the bit\r
+representing a pixel, the Write Plane Enable register is set to the\r
+wanted color. Reading is more complex and slower, since you can\r
+only read from a single plane at a time, by setting the Read Plane\r
+Select register. Now, since each address in the video segment can\r
+access 8 pixels, and there are 64 Kb addresses, 8 * 65,536 = 524,288\r
+16-color pixels can be accessed. In a 320x200 16-color mode, this makes\r
+for about 8 (524,288/(320*200)) pages, in 640x480 you get nearly 2\r
+(524,288/(640*480)) pages.\r
+\r
+In a 256-color mode, the picture changes subtly. The designers decided\r
+to fix the number of bit planes to 4, so extending the logic above to 8\r
+planes and 256 colors does not work. Instead, one of their goals was to\r
+make the 256-color mode as easily accessible as possible. Comparing the\r
+8 pixels/address in 16-color modes to the 1-to-1 correspondence of\r
+pixels and addresses of mode 13h, one can say that they have\r
+succeeded, but at a certain cost. For reasons I am not aware of, the\r
+designers came up with the following effective, but memory-wasting\r
+scheme:\r
+\r
+The address space of mode 13h is divided evenly across the four bit\r
+planes. When an 8-bit color value is written to a 16-bit address in the\r
+VGA segment, a bit plane is automatically selected by the 2 least\r
+significant bits of the address. Then all 8 bits of the data is written\r
+to the byte at the 16-bit address in the selected bitplane (have a look at\r
+figure 1). Reading works exactly the same way. Since the bit planes are so\r
+closely tied to the address, only every fourth byte in the video memory is\r
+accessible, and 192 Kb of a 256 Kb VGA go to waste. Eliminating the\r
+need to bother about planes sure is convenient and beneficial, but to\r
+most people the loss of 3/4 of the total VGA memory sounds just hilarious.\r
+\r
+To accomodate this new method of accessing video memory, the VGA\r
+designers introduced a new configuration bit called Chain-4, which\r
+resides as bit number 3 in index 4 of the Sequencer. In 16-color modes,\r
+the default state for this bit is off (zero), and the VGA operates as\r
+described earlier. In the VGA's standard 256-color mode, mode 13h, this\r
+bit is turned on (set to one), and this turns the tieing of bit\r
+planes and memory address on.\r
+\r
+In this state, the bit planes are said to be chained together, thus mode\r
+13h is often called a _chained mode_.\r
+\r
+Note that Chain-4 in itself is not enough to set a 256-color mode -\r
+there are other registers which deals with the other subtle changes in\r
+nature from 16 to 256 colors. But, as we now will base our work with\r
+mode X on mode 13h, which already is 256-color, we won't bother about\r
+these for now.\r
+\r
+\r
+\r
+2. GETTING MORE PAGES AND PUTTING YOUR FIRST PIXEL\r
+\r
+The observant reader might at this time suggest that clearing the\r
+Chain-4 bit after setting mode 13h will give us access to all 256 Kb of\r
+video memory, as the two least significant bits of the byte address\r
+won't be `wasted' on selecting a bit plane. This is correct. You might\r
+also start feeling a little uneasy, because something tells you that\r
+you'll instantly loose the simple addressing scheme of mode 13h. Sadly,\r
+that is also correct.\r
+\r
+At the moment Chain-4 is cleared, each byte offset addresses *four*\r
+sequential pixels, corresponding to the four planes addressed in 16-color\r
+modes. Every fourth pixel belong in the same plane. Before writing to a byte\r
+offset in the video segment, you should make sure that the 4-bit mask in the\r
+Write Plane Enable register is set correctly, according to which of the four\r
+addressable pixels you want to modify. In essence, it works like a 16-color\r
+mode with a twist. See figure 2.\r
+\r
+So, is this mode X? Not quite. We need to elaborate to the VGA how to\r
+fetch data for refreshing the monitor image. Explaining the logic\r
+behind this is beyond the scope of this getting-you-started text, and it\r
+wouldn't be very interesting anyway. Also, mode 13h has only 200 lines,\r
+while I promised 240 lines. I'll fix that later below. Here is the minimum\r
+snippet of code to initiate the 4 page variant of mode 13h (320x200), written\r
+in plain C, using some DOS specific features (see header for a note about the\r
+sources included):\r
+\r
+----8<-------cut begin------\r
+\r
+/* width and height should specify the mode dimensions. widthBytes\r
+ specify the width of a line in addressable bytes. */\r
+\r
+int width, height, widthBytes;\r
+\r
+/* actStart specifies the start of the page being accessed by\r
+ drawing operations. visStart specifies the contents of the Screen\r
+ Start register, i.e. the start of the visible page */\r
+\r
+unsigned actStart, visStart;\r
+\r
+/*\r
+ * set320x200x256_X()\r
+ * sets mode 13h, then turns it into an unchained (planar), 4-page\r
+ * 320x200x256 mode.\r
+ */\r
+\r
+set320x200x256_X()\r
+ {\r
+\r
+ union REGS r;\r
+\r
+ /* Set VGA BIOS mode 13h: */\r
+\r
+ r.x.ax = 0x0013;\r
+ int86(0x10, &r, &r);\r
+\r
+ /* Turn off the Chain-4 bit (bit 3 at index 4, port 0x3c4): */\r
+\r
+ outport(SEQU_ADDR, 0x0604);\r
+\r
+ /* Turn off word mode, by setting the Mode Control register\r
+ of the CRT Controller (index 0x17, port 0x3d4): */\r
+\r
+ outport(CRTC_ADDR, 0xE317);\r
+\r
+ /* Turn off doubleword mode, by setting the Underline Location\r
+ register (index 0x14, port 0x3d4): */\r
+\r
+ outport(CRTC_ADDR, 0x0014);\r
+\r
+ /* Clear entire video memory, by selecting all four planes, then\r
+ writing 0 to the entire segment. */\r
+\r
+ outport(SEQU_ADDR, 0x0F02);\r
+ memset(vga+1, 0, 0xffff); /* stupid size_t exactly 1 too small */\r
+ vga[0] = 0;\r
+\r
+ /* Update the global variables to reflect the dimensions of this\r
+ mode. This is needed by most future drawing operations. */\r
+\r
+ width = 320;\r
+ height = 200;\r
+\r
+ /* Each byte addresses four pixels, so the width of a scan line\r
+ in *bytes* is one fourth of the number of pixels on a line. */\r
+\r
+ widthBytes = width / 4;\r
+\r
+ /* By default we want screen refreshing and drawing operations\r
+ to be based at offset 0 in the video segment. */\r
+\r
+ actStart = visStart = 0;\r
+\r
+ }\r
+\r
+----8<-------cut end------\r
+\r
+As you can see, I've already provided some of the mechanics needed to\r
+support multiple pages, by providing the actStart and visStart variables.\r
+Selecting pages can be done in one of two contexts:\r
+\r
+ 1) selecting the visible page, i.e. which page is visible on\r
+ screen, and\r
+\r
+ 2) selecting the active page, i.e. which page is accessed by\r
+ drawing operations\r
+\r
+Selecting the active page is just a matter of offsetting our graphics\r
+operations by the address of the start of the page, as demonstrated in\r
+the put pixel routine below. Selecting the visual page must be passed\r
+in to the VGA, by setting the Screen Start register. Sadly enough, the\r
+resolution of this register is limited to one addressable byte, which\r
+means four pixels in unchained 256-color modes. Some further trickery is \r
+needed for 1-pixel smooth, horizontal scrolling, but I'll make that a subject \r
+for later. The setXXXStart() functions provided here accept byte\r
+offsets as parameters, so they'll work in any mode. If widthBytes and\r
+height are set correctly, so will the setXXXPage() functions.\r
+\r
+----8<-------cut begin------\r
+\r
+/*\r
+ * setActiveStart() tells our graphics operations which address in video\r
+ * memory should be considered the top left corner.\r
+ */\r
+\r
+setActiveStart(unsigned offset)\r
+ {\r
+ actStart = offset;\r
+ }\r
+\r
+/*\r
+ * setVisibleStart() tells the VGA from which byte to fetch the first\r
+ * pixel when starting refresh at the top of the screen. This version\r
+ * won't look very well in time critical situations (games for\r
+ * instance) as the register outputs are not synchronized with the\r
+ * screen refresh. This refresh might start when the high byte is\r
+ * set, but before the low byte is set, which produces a bad flicker.\r
+ * I won't bother with this now.\r
+ */\r
+\r
+setVisibleStart(unsigned offset)\r
+ {\r
+ visStart = offset;\r
+ outport(CRTC_ADDR, 0x0C); /* set high byte */\r
+ outport(CRTC_ADDR+1, visStart >> 8);\r
+ outport(CRTC_ADDR, 0x0D); /* set low byte */\r
+ outport(CRTC_ADDR+1, visStart & 0xff);\r
+ }\r
+\r
+/*\r
+ * setXXXPage() sets the specified page by multiplying the page number\r
+ * with the size of one page at the current resolution, then handing the\r
+ * resulting offset value over to the corresponding setXXXStart()\r
+ * function. The first page number is 0.\r
+ */\r
+\r
+setActivePage(int page)\r
+ {\r
+ setActiveStart(page * widthBytes * height);\r
+ }\r
+\r
+setVisiblePage(int page)\r
+ {\r
+ setVisibleStart(page * widthBytes * height);\r
+ }\r
+\r
+----8<-------cut end------\r
+\r
+Due to the use of bit planes, the graphics routines tend to get more\r
+complex than in mode 13h, and your first versions will generally tend to\r
+be a little slower than mode 13h algorithms. Here's a put pixel routine\r
+for any unchained 256-color mode (it assumes that the 'width' variable\r
+from the above code is set correctly). Optimizing is left as an exercise\r
+to you, the reader. This will be the only drawing operation I'll cover\r
+in this article, but all general primitives like lines and circles can be \r
+based on this routine. (You'll probably not want to do that though, due\r
+to the inefficiency.)\r
+\r
+----8<-------cut begin------\r
+\r
+putPixel_X(int x, int y, char color)\r
+ {\r
+\r
+ /* Each address accesses four neighboring pixels, so set\r
+ Write Plane Enable according to which pixel we want\r
+ to modify. The plane is determined by the two least\r
+ significant bits of the x-coordinate: */\r
+\r
+ outportb(0x3c4, 0x02);\r
+ outportb(0x3c5, 0x01 << (x & 3));\r
+\r
+ /* The offset of the pixel into the video segment is\r
+ offset = (width * y + x) / 4, and write the given\r
+ color to the plane we selected above. Heed the active\r
+ page start selection. */\r
+\r
+ vga[(unsigned)(widthBytes * y) + (x / 4) + actStart] = color;\r
+\r
+ }\r
+\r
+char getPixel_X(int x, int y)\r
+ {\r
+\r
+ /* Select the plane from which we must read the pixel color: */\r
+\r
+ outport(GRAC_ADDR, 0x04);\r
+ outport(GRAC_ADDR+1, x & 3);\r
+\r
+ return vga[(unsigned)(widthBytes * y) + (x / 4) + actStart];\r
+\r
+ }\r
+\r
+----8<-------cut end------\r
+\r
+\r
+However, by now you should be aware of that the Write Plane Enable\r
+register isn't limited to selecting just one bit plane, like the\r
+Read Plane Select register is. You can enable any combination of all\r
+four to be written. This ability to access 4 pixels with one\r
+instruction helps quadrupling the speed in certain respects, especially when \r
+drawing horizontal lines and filling polygons of a constant color. Also, most \r
+block algorithms can be optimized in various ways so that they need only\r
+a constant number of OUTs (typically four) to the Write Plane Enable\r
+register. OUT is a relatively slow instruction.\r
+\r
+The gained ability to access the full 256 Kb of memory on a standard\r
+VGA enables you to do paging and all the goodies following from that:\r
+smooth scrolling over large maps, page flipping for flicker free\r
+animation... and I'll leave something for your own imagination.\r
+\r
+In short, the stuff gained from unchaining mode 13h more than \r
+upweighs the additional complexity of using a planar mode. \r
+\r
+Now, the resolution of the mode is of little interest in this\r
+context. Nearly any 256-color resolution from (about) 80x8 to 400x300\r
+is available for most VGAs. I'll dwell particularly by 320x240, as this\r
+is the mode that Michael Abrash introduced as 'Mode X' in his DDJ\r
+articles. It is also the resolution that most people refer to when\r
+using that phrase.\r
+\r
+The good thing about the 320x240 mode is that the aspect ratio is\r
+1:1, which means that each pixel is 'perfectly' square, i.e. not\r
+rectangular like in 320x200. An ellipse drawn with the same number of\r
+pixels along both main axes will look like a perfect circle in 320x240,\r
+but like a subtly tall ellipse in 320x200.\r
+\r
+Here's a function which sets the 320x240 mode. You'll notice that\r
+it depends on the first piece of code above:\r
+\r
+----8<-------cut begin------\r
+\r
+set320x240x256_X()\r
+ {\r
+\r
+ /* Set the unchained version of mode 13h: */\r
+\r
+ set320x200x256_X();\r
+\r
+ /* Modify the vertical sync polarity bits in the Misc. Output\r
+ Register to achieve square aspect ratio: */\r
+\r
+ outportb(0x3C2, 0xE3);\r
+\r
+ /* Modify the vertical timing registers to reflect the increased\r
+ vertical resolution, and to center the image as good as\r
+ possible: */\r
+\r
+ outport(0x3D4, 0x2C11); /* turn off write protect */\r
+ outport(0x3D4, 0x0D06); /* vertical total */\r
+ outport(0x3D4, 0x3E07); /* overflow register */\r
+ outport(0x3D4, 0xEA10); /* vertical retrace start */\r
+ outport(0x3D4, 0xAC11); /* vertical retrace end AND wr.prot */\r
+ outport(0x3D4, 0xDF12); /* vertical display enable end */\r
+ outport(0x3D4, 0xE715); /* start vertical blanking */\r
+ outport(0x3D4, 0x0616); /* end vertical blanking */\r
+\r
+ /* Update mode info, so future operations are aware of the\r
+ resolution: */\r
+\r
+ height = 240;\r
+\r
+ }\r
+\r
+----8<-------cut end------\r
+\r
+\r
+As you've figured out, this mode will be completely compatible with the\r
+utility functions presented earlier, thanks to the global variable\r
+'height'. Boy, am I foreseeing or what!\r
+\r
+Other resolutions are achieved through giving other values to the sync\r
+timing registers of the VGA, but this is quite a large and complex\r
+subject, so I'll postpone this to later, if ever.\r
+\r
+Anyway, I hope I've helped getting you started using mode X. As far as\r
+I know, the two modes I've used above should work on *any* VGA and Super\r
+VGA available, so this is pretty stable stuff. Let me know of any \r
+trouble, and - \r
+ good luck!\r
+\r
+\r
+\r
+3. THE ROAD FROM HERE\r
+\r
+I'm providing information on various libraries and archives which relate\r
+to what this article deals with. If you want me to add anything to this\r
+list (for future articles), let me know, although I can't promise anything.\r
+I am assuming you have ftp access.\r
+\r
+\r
+wuarchive.wustl.edu:/pub/MSDOS_UPLOADS/programming/xlib06.zip\r
+\r
+This is the current de facto C/assembler library for programming\r
+unchained modes (do not confuse with a X Windows library). All sources\r
+are included, and the library is totally free. It has functions for\r
+pixels, lines, circles, bezier curves, mouse handling, sprites (bitmaps),\r
+compiled bitmaps, and supports a number of resolutions. The version number\r
+('06') is current as of November 1993.\r
+\r
+\r
+graphprg.zip\r
+\r
+Michael Abrash' articles in Doctor Dobbs Journal is always mentioned\r
+with awe. In this 350 Kb archive, most of his interesting stuff has\r
+been gathered. Read about Mode X development and techniques from month\r
+to month. Included is also all the individual source code snippets from\r
+each article, and also the full XSHARP library providing linedrawing,\r
+polygons, bitmaps, solid 3D projection and speedy rendering, and even an\r
+implementation of 2D texture mapping (can be used for quasi-3D texture\r
+mapping), plus an article on assembly optimization on the i86 processor\r
+family. Definitely recommended.\r
+\r
+\r
+oak.oakland.edu:/pub/msdos/vga/vgadoc2.zip\r
+\r
+This is a bare bones VGA register reference. It also contains register\r
+references for the CGA, EGA and Hercules cards, in addition to dozens of\r
+SuperVGAs. Check out the BOOKS section for some decent VGA references\r
+though - you don't want to start tweaking without a real one.\r
+\r
+\r
+wuarchive.wustl.edu:/pub/MSDOS_UPLOADS/programming/tweak15b.zip\r
+\r
+TWEAK might be of interest to the more adventurous reader. TWEAK lets you\r
+play around with the registers of the VGA in an interactive manner.\r
+Various testing screens for viewing your newmade modes are applied at\r
+the press of a key. Version 1.5 adds a test screen which autodetects your \r
+graphics mode and displays various information about resolutions etc.\r
+Keep a VGA reference handy. Don't try it if this is the first time you've \r
+heard of 'registers' or 'mode X' or 'tweaking'. I was planning a version\r
+based on the Turbo Vision interface, but time has been short. Maybe later!\r
+\r
+\r
+\r
+\r
+4. BOOKS ON THE SUBJECT\r
+\r
+Extremely little has been published in written form about using\r
+'Mode X'-style modes. Below are some books which cover VGA programming\r
+at varying degrees of technical level, but the only one to mention\r
+unchained modes and Mode X, is Michael Abrash'. I'd get one of the VGA\r
+references first, though.\r
+\r
+ o George Sutty & Steve Blair : "Advanced Pogrammer's Guide to the\r
+ EGA/VGA" from Brady. A bit old perhaps, but covers all *standard*\r
+ EGA/VGA registers, and discusses most BIOS functions and other\r
+ operations. Contains disk with C/Pascal/assembler source code.\r
+ There's a sequel out for SuperVGAs, which I haven't seen.\r
+\r
+ o Michael Abrash : "Power Graphics Programming" from QUE/Programmer's\r
+ Journal. Collections of (old) articles from Programmer's Journal on\r
+ EGA/VGA, read modes and write modes, animation, tweaking (320x400\r
+ and 360x480). His newer ravings in DDJ covers fast 256-color\r
+ bitmaps, compiled bitmaps, polygons, 3D graphics, texture mapping\r
+ among other stuff.\r
+\r
+ o Richard F. Ferraro : "Programmer's Guide to the EGA and VGA video\r
+ cards including Super VGA". I don't have this one, but heard it's\r
+ nice. Detailed coverage of all EGA/VGA registers. The Super VGA\r
+ reference makes it attractive.\r
+\r
+ o Richard Wilton : "Programmer's Guide to PC & PS/2 Video Systems"\r
+ Less technical, more application/algorithm oriented. Nice enough,\r
+ even though it is a bit outdated, in that he discusses CGA and\r
+ Hercules cards just as much as EGA/VGA.\r
+\r
+\r
+\r
+\r
+5. BYE - FOR NOW\r
+\r
+I am considering writing a text describing in more detail the process of\r
+using TWEAK to achieve the VGA resolution you want or need. However, I\r
+thought I'd let this document go first, and see if I get any reactions.\r
+If I don't, I'll stop. Feel free to forward any suggestions,\r
+criticisms, bombs and beers.\r
+\r
+I can be reached via:\r
+\r
+ o e-mail: robert@stud.unit.no\r
+\r
+ o land mail:\r
+\r
+ Robert Schmidt\r
+ Stud.post 170\r
+ NTH\r
+ N-7034 Trondheim\r
+ NORWAY\r
+\r
+Nothing would encourage or please me more than a postcard from where you\r
+live!\r