<item>_textframe
 <item>_textframexy
 <item><ref id="get_ostype" name="get_ostype">
+<item><ref id="videomode" name="videomode">
 </itemize>
 
 
 <quote>
 <descrip>
 <tag/Function/Switch to either 40 or 80 column mode.
-<tag/Header/<tt/<ref id="c128.h" name="c128.h">/
+<tag/Header/<tt/<ref id="apple2enh.h" name="apple2enh.h">,
+<ref id="c128.h" name="c128.h">/
 <tag/Declaration/<tt/unsigned __fastcall__ videomode (unsigned Mode);/
 <tag/Description/Switch to 40 or 80 column mode depending on the argument. If
 the requested mode is already active, nothing happens. The old mode is returned
 from the call.
 <tag/Limits/<itemize>
-<item>The function is specific to the C128.
-<item>This function is replaces <ref id="toggle_videomode"
+<item>The function is specific to the C128 and enhanced Apple //e.
+<item>This function replaces <ref id="toggle_videomode"
 name="toggle_videomode">.
 <item>The function is only available as fastcall function, so it may only be
 used in presence of a prototype.
 </itemize>
-<tag/Availability/C128
+<tag/Availability/C128 and enhanced Apple //e
 <tag/See also/
 <ref id="fast" name="fast">,
 <ref id="slow" name="slow">,
 
 #define _TEXTFRAME_WIDE        0x00
 #define _TEXTFRAME_TALL        0x04
 
+/* Video modes */
+#define VIDEOMODE_40x24 0x0011
+#define VIDEOMODE_80x24 0x0012
+#define VIDEOMODE_40COL VIDEOMODE_40x24
+#define VIDEOMODE_80COL VIDEOMODE_80x24
+
 
 
 /*****************************************************************************/
 void __fastcall__ _textframe (unsigned char width, unsigned char height,
                              unsigned char style);
 /* Output a frame on the text screen with the given width and height
- * starting at the current cursor position and using the given style
+ * starting at the current cursor position and using the given style.
  */
 
 void __fastcall__ _textframexy (unsigned char x, unsigned char y,
                                unsigned char style);
 /* Same as "gotoxy (x, y); _textframe (width, height, style);" */
 
+unsigned __fastcall__ videomode (unsigned mode);
+/* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx
+ * constants.
+ */
+
 
 
 /* End of apple2enh.h */
 
--- /dev/null
+;
+; Oliver Schmidt, 07.09.2009
+;
+; unsigned __fastcall__ videomode (unsigned mode);
+;
+
+       .export         _videomode
+        .import         COUT
+
+        .include        "apple2.inc"
+
+        .segment        "LOWCODE"
+
+_videomode:
+        ; Get and save current videomode flag
+        bit     RD80VID
+        php
+        
+        ; If we are in 80 column mode then the 80 column firmware is
+        ; known to be active so we can just print the ctrl-char code
+        ; (even if this only means staying in the current videomode)
+        bpl     :+
+        jsr     COUT
+        bra     done
+
+        ; If we are in 40 column mode and want to set 40 column mode
+        ; then we explicitly do nothing as we neither know about the
+        ; current state of the 80 column firmware nor want to fix it
+:       cmp     #$11            ; Ctrl-char code for 40 cols
+        beq     done
+        
+        ; If we are in 40 column mode and want to set 80 column mode
+        ; then we first presume the 80 column firmware being already
+        ; active and print the ctrl-char code (this causes a garbage
+        : char to be printed on the screen if isn't already active)
+        jsr     COUT
+        
+        ; If we successfully switched to 80 column mode then the 80
+        ; column firmware was in fact already active and we're done
+        bit     RD80VID
+        bmi     done
+        
+        ; The 80 column firmware isn't already active so we need to
+        ; initialize it - causing the screen to be cleared and thus
+        ; the garbage char printed above to be erased (but for some
+        ; reason the cursor horizontal position not not be zeroed)
+        stz     CH
+
+        ; Initializing the 80 column firmware needs the ROM switched
+        ; in, otherwise it would copy the F8 ROM to the LC (@ $CEF4)
+        bit     $C082
+
+        ; Initialize 80 column firmware
+        jsr     $C300           ; PR#3
+
+        ; Switch in LC bank 2 for R/O
+        bit     $C080
+                
+        ; Return ctrl-char code for setting previous
+        ; videomode using the saved videomode flag
+done:   lda     #$11            ; Ctrl-char code for 40 cols
+        plp
+        bpl     :+
+        lda     #$12            ; Ctrl-char code for 80 cols
+:       rts                     ; X was preserved all the way
 
         sysuname.o      \
        textframe.o     \
         tgi_mode_table.o\
+        videomode.o     \
         vtabz.o         \
        wherex.o        \
                wherey.o        \