From 648a1b5427ba269b3c0c0f29180a398fb568c453 Mon Sep 17 00:00:00 2001
From: "ol.sc" <ol.sc@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Date: Thu, 10 Sep 2009 09:04:05 +0000
Subject: [PATCH] Added support for switching between 40/80 columns. As the
 Apple //e 80 column firmware features converting the current screen content
 on switching if was already active before the idea is to keep the 80 column
 firmware active and initialize it (which clears the screen) only if
 necessary.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4140 b7a2c559-68d2-44c3-8de9-860c34a00d81
---
 doc/funcref.sgml          | 10 +++---
 include/apple2enh.h       | 13 +++++++-
 libsrc/apple2/videomode.s | 65 +++++++++++++++++++++++++++++++++++++++
 libsrc/apple2enh/Makefile |  1 +
 4 files changed, 84 insertions(+), 5 deletions(-)
 create mode 100644 libsrc/apple2/videomode.s

diff --git a/doc/funcref.sgml b/doc/funcref.sgml
index 294265c78..bc49e0828 100644
--- a/doc/funcref.sgml
+++ b/doc/funcref.sgml
@@ -77,6 +77,7 @@ function.
 <item>_textframe
 <item>_textframexy
 <item><ref id="get_ostype" name="get_ostype">
+<item><ref id="videomode" name="videomode">
 </itemize>
 
 
@@ -5031,19 +5032,20 @@ used in presence of a prototype.
 <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">,
diff --git a/include/apple2enh.h b/include/apple2enh.h
index 5185fd693..39aefdd9f 100644
--- a/include/apple2enh.h
+++ b/include/apple2enh.h
@@ -76,6 +76,12 @@
 #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
+
 
 
 /*****************************************************************************/
@@ -87,7 +93,7 @@
 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,
@@ -95,6 +101,11 @@ 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 */
diff --git a/libsrc/apple2/videomode.s b/libsrc/apple2/videomode.s
new file mode 100644
index 000000000..bf99819eb
--- /dev/null
+++ b/libsrc/apple2/videomode.s
@@ -0,0 +1,65 @@
+;
+; 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
diff --git a/libsrc/apple2enh/Makefile b/libsrc/apple2enh/Makefile
index d3da3ca62..d030d2436 100644
--- a/libsrc/apple2enh/Makefile
+++ b/libsrc/apple2enh/Makefile
@@ -100,6 +100,7 @@ S_OBJS=	_scrsize.o	\
         sysuname.o      \
 	textframe.o	\
         tgi_mode_table.o\
+        videomode.o     \
         vtabz.o         \
      	wherex.o       	\
        	wherey.o        \