+\r
+//king_crimson's code\r
+void hScroll(int Cols) {\r
+ inp(0x3DA);\r
+ outp(0x3C0, 0x13);\r
+ outp(0x3C0, Cols & 3);\r
+ outp(0x3D4, 0x13);\r
+ outp(0x3D5, Cols/* >> 2*/);\r
+ //setVisibleStart(visStart + (Cols * height));\r
+ setVisibleStart(visStart + (Cols * width));\r
+}\r
+\r
+/*To implement smooth horizontal scrolling, you would do the following:\r
+-------------- Horizontal Scrolling ------------\r
+FOR X = 0 TO 319 DO\r
+ SET HPP TO ( X MOD 4 )\r
+ SET VGA OFFSET TO ( X/4 )\r
+END FOR\r
+------------------------------------------------\r
+\r
+Okay, no problem at all (although I think you might have to fiddle\r
+around with the HPP a bit to get it right...try different values and\r
+see what works :).\r
+\r
+So, the next problem is with drawing the images off the screen where\r
+they aren't visible and then scrolling them on!!! As it turns out,\r
+there's yet ANOTHER register to accomplish this. This one's called the\r
+offset register (no, not the one I was talking about before, that one\r
+was actually the "start address" register) and it's at\r
+\r
+ PORT: 3D4H/3D5H\r
+ OFFSET: 13H\r
+\r
+and here's how to use it\r
+\r
+-------------- Offset Register ---------------\r
+OUT 13H TO PORT 3D4H\r
+OUT value TO PORT 3D5H\r
+----------------------------------------------\r
+\r
+Now, what my VGA reference says is that this register holds the number\r
+of bytes (not pixels) difference between the start address of each row.\r
+So, in X-mode it normally contains the value 80 (as we remember,\r
+80 bytes * 4 planes = 320 pixels). This register does not affect the\r
+VISIBLE width of the display, only the difference between addresses on\r
+each row.\r
+\r
+When we scroll horizontally, we need a little bit of extra working space\r
+so we can draw off the edge of the screen.\r
+\r
+Perhaps a little diagram will clarify it. The following picture is of a\r
+standard X-mode addressing scheme with the OFFSET register set to 80.\r
+\r
+ ROW OFFSET\r
+ 0 0 ========================\r
+ 1 80 [ ]\r
+ 2 160 [ ]\r
+ .. .. [ VISIBLE ]\r
+ [ SCREEN ]\r
+ [ ]\r
+ [ ]\r
+ .. .. [ ]\r
+ 199 15920 ========================\r
+\r
+and the next diagram is of a modified addressing scheme with the OFFSET\r
+register set to 82 (to give us 4 extra pixels on each side of the screen)\r
+\r
+ROW OFFSET\r
+0 0 ------========================------\r
+1 82 | V [ ] V |\r
+2 164 | I [ ] I |\r
+.. .. | N S [ VISIBLE ] N S |\r
+ | O I [ SCREEN ] O I |\r
+ | T B [ ] T B |\r
+ | L [ ] L |\r
+.. .. | E [ ] E |\r
+199 16318 ------========================------\r
+\r
+Beautiful!!!\r
+\r
+As with vertical scrolling, however, you still have the problem of when\r
+you reach the bottom of page 4...and it's fixed in the same manner.\r
+\r
+I haven't actually managed to get infinite horizontal scrolling working,\r
+but the method I have just stated will give you a horizontal scrolling\r
+range of over 200 screens!!!! So if you need more (which is extremely\r
+unlikely), figure it out yourself.\r
+\r
+\r
+------------------\r
+COMBINED SCROLLING\r
+------------------\r
+To do both horizontal and vertical scrolling, all you have to do is combine\r
+the two methods with a few little extras (it's always the way isn't it).\r
+\r
+You have to start off with the original screen on the current page and the\r
+next page as well. When you scroll horizontally, you have to draw the edge\r
+that's coming in to the screen to BOTH pages (that means you'll be drawing\r
+the incoming edge twice, once for each page). You do this so that when you\r
+have scrolled vertically down through a complete page, you can jump back\r
+to the first page and it will (hopefully) have an identical copy, and you\r
+can then continue scrolling again.\r
+\r
+I'm sorry about this being so confusing but it's a bit difficult to explain.\r
+\r
+\r