changeset 3249:6ea55a46a963

Updated vtio.asm for some optimizations that can be shared between grfdrv.asm, covdg.asm. Updated grfdrv.asm to take advantage of the vector changes in vtio.asm Updated covdg.asm to take advantage of the vecor changes in vtio.asm
author David Ladd <drencor-xeen@users.sourceforge.net>
date Mon, 12 Mar 2018 19:35:56 -0500
parents 1d7d6a09a973
children 13737f3608e6
files level1/cmds/grfdrv.asm level1/modules/covdg.asm level1/modules/vtio.asm
diffstat 3 files changed, 749 insertions(+), 581 deletions(-) [+]
line wrap: on
line diff
--- a/level1/cmds/grfdrv.asm	Sun Mar 11 01:40:13 2018 -0600
+++ b/level1/cmds/grfdrv.asm	Mon Mar 12 19:35:56 2018 -0500
@@ -8,6 +8,7 @@
 * ------------------------------------------------------------------
 *   1      ????/??/??
 * From Tandy OS-9 Level One VR 02.00.00.
+*   2      2018/03/06  Various minor optimizations, and some 6309 optimizations
 
          nam   GrfDrv
          ttl   Graphics module
@@ -22,7 +23,7 @@
 tylg     set   Systm+Objct
 atrv     set   ReEnt+rev
 rev      set   $00
-edition  set   1
+edition  set   2
 
          mod   eom,name,tylg,atrv,start,size
 
@@ -242,24 +243,33 @@
          bsr   DrwPt2
          bra   L014A
 
-DrwPt2   jsr   [<V.CnvVct,u]  Get offset into screen memory & bit mask for pixel
+* Draw a single point. Called by set point/erase point, and circle
+* Entry: A=pixel X position to draw
+*        B=pixel Y position to draw
+DrwPt2   jsr   [<V.CnvVct,u]  Get offset into screen memory (X) & bit mask for pixel (A)
+* Draw single point w/o needing conversion of address/mask. Called by Line and Flood Fill
 L0081    tfr   a,b            Duplicate pixel mask
+       IFNE  H6309
+         comb                 Flip to keep background pixels
+         andb  ,x
+         anda  <V.Msk1,u      and pixel mask with color mask
+         orr   b,a            Merge foreground pixel onto background
+         sta   ,x             Save it to screen
+       ELSE
          comb                 Flip to keep background pixels
          andb  ,x
          stb   ,x
          anda  <V.Msk1,u      and pixel mask with color mask
          ora   ,x             Merge foreground pixel onto background
          sta   ,x             Save it to screen
+       ENDC
          rts
 
-
 Circle   leas  -4,s           make room on stack
-* 6809/6309 - Chg next 4 lines to clra / ldb <V.NChr2,u / std ,s
          clra
-         ldb   <V.NChr2,u     get radius
-         std   ,s             store b store on stack and make D=radius (both D and on stack)
-         addb  1,s            Add to itself (D=diameter)
-         adca  #$00
+         ldb   <V.NChr2,u     get radius into D
+         std   ,s             store on stack and make D=radius (both D and on stack)
+         addd  ,s
        IFNE  H6309
          negd                 Invert sign of D
        ELSE
@@ -271,11 +281,11 @@
          std   2,s            Save that
 L0179    lda   ,s
          cmpa  1,s
-         bcc   L01AB
+         bhs   L01AB
          ldb   1,s
          bsr   L01B9
          clra
-         ldb   $02,s
+         ldb   2,s
          bpl   L0193
          ldb   ,s
          lslb
@@ -357,53 +367,83 @@
          leas  8,s            Eat temp stack & return
          rts
 
-L0202    pshs  d
+* Not sure on these, but I think:
+* Entry: D=X coord of some sort
+*        X=Y coord of some sort
+L0202  
+       IFNE  H6309
+         tfr   d,w
+       ELSE
+         pshs  d
+       ENDC
          ldb   <V.GCrsY,u     Get Y coord of graphics cursor (center of circle)
-* 6809/6309 - B is unsigned, so an abx instead of clra / leax d,x should work (-2 bytes/-7 cyc)
-*         clra
-*         leax  d,x
          abx
          cmpx  #$0000         Off bottom of screen?
          bmi   L0214          Yes, return
          cmpx  #191           Off top of screen?
          ble   L0216          No, go draw pixels
-L0214    puls  pc,d           Off screen vertically, return
-
+L0214
+       IFNE  H6309
+         rts
+       ELSE
+         puls  pc,d           Off screen vertically, return
+       ENDC
+       
 L0216    ldb   <V.GCrsX,u     Get X coord of graphics cursor (center of circle) into D
          clra
          tst   <V.Mode,u      Check graphics mode
          bmi   L0221          2 color, skip ahead
          lslb                 4 color, Shift left 1 bit
          rola
-L0221    addd  ,s++           Add to ?
+L0221  
+       IFNE  H6309
+         addr  w,d            Add to ?
+       ELSE
+         addd  ,s++           Add to ?
+       ENDC
          tsta                 If <256, continue
          beq   L0227
          rts                  Else return
 
-L0227    pshs  b              Save 8 bit version of value
+L0227  
+       IFNE  H6309
+         tfr   b,e            Save Y coord in E         (3 tfr's in native mode 2 cyc faster)
+         tfr   x,d            Move low byte of X to B
+         tfr   e,a            Move Y coord to A
+       ELSE
+         pshs  b              Save 8 bit version of value
          tfr   x,d            Move low byte of X to B
          puls  a              And restore value, this time as A
+       ENDC
          tst   <V.Mode,u      Check graphics mode
          lbmi  DrwPt2         If 2 color, draw pixel on screen & return from there
          lsra                 4 color, shift 1 more first
          lbra  DrwPt2
 
 * $1D - flood fill
+* Change by LCB - keep V.Mode in E, since it gets checked. A lot.
 Do1D     clr   <V.FFFlag,u    Clear flag
-         leas  -$07,s
+         leas  -7,s
          lbsr  L03AB          Allocate 512 byte Flood fill stack, if not already allocated
          lbcs  L0346          Not allocated, and couldn't get it, exit with error
-         lda   #$FF
+       IFNE  H6309
+         lde   <V.Mode,u      Get gfx mode, so we can keep in E for faster checking
+       ENDC
+         lda   #-1            $FF Set direction flag to -1 (X direction, I think)
          sta   <V.4F,u
-         ldd   <V.GCrsX,u
+         ldd   <V.GCrsX,u     Get graphics cursor X,Y coords
          lbsr  L0351
          lda   <V.4C,u
          sta   <V.4D,u
+       IFNE  H6309
+         tste                 which mode?
+       ELSE
          tst   <V.Mode,u      which mode?
+       ENDC
          bpl   L0261          branch if 128x192
          tsta
-         beq   L0267
-         lda   #$FF
+         beq   L0267          Color 0 byte mask for 2 color
+         lda   #$FF           Color 1 byte mask for 2 color
          bra   L0267
 
 * 128x192 4 color pixel table - NOTE THIS IS DUPLICATED IN VTIO
@@ -412,11 +452,11 @@
 * Entry: A=color # 0-3
 L0261    leax  <Mode1Clr,pcr  Point to 4 color color mask table
          lda   a,x            Get mask for selected color
-L0267    sta   <V.4E,u        Save copy of it
+L0267    sta   <V.4E,u        Save copy of color mask
          cmpa  <V.Msk1,u
          lbeq  L0346
-         ldd   <V.GCrsX,u
-L0274    suba  #$01
+         ldd   <V.GCrsX,u     Get gfx cursor cursory X,Y coords
+L0274    suba  #$01           
          bcs   L027F          Wrapped negative, skip ahead
          lbsr  L0351
          beq   L0274
@@ -424,22 +464,22 @@
          std   1,s
 L0282    lbsr  L0384
          adda  #$01
-         bcs   L0290
+         bcs   L0290          Wrapped past 256, skip ahead
          lbsr  L0351
          bcs   L0290
          beq   L0282
 L0290    deca
          ldx   1,s
          lbsr  L03D3
-         neg   <V.4F,u
+         neg   <V.4F,u        Flip X direction
          lbsr  L03D3
 L029C    lbsr  L03F9
          lbcs  L0346
-         tst   <V.4F,u
-         bpl   L02B3
-         subb  #$01
-         bcs   L029C
-         std   3,s
+         tst   <V.4F,u        Check current X direction
+         bpl   L02B3          If +1, go increment
+         subb  #$01           negative, so subtract 1
+         bcs   L029C          If wrapped, go back
+         std   3,s            Save coords
          tfr   x,d
          decb
          bra   L02BD
@@ -475,7 +515,7 @@
          decb
          cmpd  5,s
          beq   L02FB
-         neg   <V.4F,u
+         neg   <V.4F,u        ?? Maybe direction flag?
          ldx   5,s
          lbsr  L03D3
          neg   <V.4F,u
@@ -529,7 +569,11 @@
 L0351    pshs  d
          cmpb  #191
          bhi   L0380          If past top of screen, exit with carry set
-         tst   <V.Mode,u      which gfx mode?
+       IFNE  H6309
+         tste                 which mode?
+       ELSE
+         tst   <V.Mode,u      which mode?
+       ENDC
          bmi   L0360          2 color, skip ahead
          cmpa  #127           4 color, check if we are past right side of screen
          bhi   L0380          Yes, exit with carry set
@@ -540,7 +584,11 @@
          bne   L0376          Yes, exit with carry clear and other flags set (zero, negative,etc.)
          lsra                 No, shift pixel masks right 1 bit
          lsrb
-         tst   <V.Mode,u      If 2 color, check again
+       IFNE  H6309
+         tste                 which mode?
+       ELSE
+         tst   <V.Mode,u      which mode?
+       ENDC
          bmi   L0367
          lsra                 If 4 color, shift once more (2 bits/pixel) and check again
          lsrb
@@ -564,7 +612,11 @@
          ldb   <V.Msk1,u
          stb   ,x
          puls  d
+       IFNE  H6309
+         tste                 2 color mode?
+       ELSE
          tst   <V.Mode,u      2 color mode?
+       ENDC
          bmi   L03A3          Yes, skip ahead
          adda  #$03
          rts
@@ -597,7 +649,7 @@
          clrb
          rts
 
-* Add FFill stack entry (4 bytes)
+* Add FFill stack entry (4 bytes). Max of 128 entries allowed.
 L03D3    pshs  d
          ldd   <V.FFSPt,u     Get current FFill stack ptr
          subd  #$0004         Add 4 bytes to it
@@ -605,7 +657,7 @@
          blo   L03F2          Yes, error out
          std   <V.FFSPt,u     No, Save new FFill stack ptr
          tfr   d,y            Move new ptr to indexable register
-         lda   <V.4F,u        Get?
+         lda   <V.4F,u        Get? (direction flag, maybe?)
          sta   ,y             Save on stack
          stx   1,y            Save (mem ptr on screen, I think?)
          puls  d              Get ?? back
--- a/level1/modules/covdg.asm	Sun Mar 11 01:40:13 2018 -0600
+++ b/level1/modules/covdg.asm	Mon Mar 12 19:35:56 2018 -0500
@@ -14,6 +14,12 @@
 *
 *          2017/12/20  Boisy Pitre
 * Added support for CoCoVGA 64x32 mode
+*
+*   2      2018/03/02  David Ladd
+*                      L. Curtis Boyle
+* General optimizations, and support for new V.ClrBlk and V.CpyBlk
+*   vector calls (from VTIO) for either 6309 TFM for mini-stack blasting
+*   (4 bytes/chunk) for screen scroll and screen clears (full & partial)
 
          nam   CoVDG
          ttl   VDG Console Output Subroutine for VTIO
@@ -28,7 +34,7 @@
 tylg     set   Systm+Objct   
 atrv     set   ReEnt+rev
 rev      set   $00
-edition  set   1
+edition  set   2
 
          mod   eom,name,tylg,atrv,start,size
 
@@ -54,54 +60,41 @@
 		ENDC
          fcb   edition
 
-start    equ   *
-         lbra  Init
-         lbra  Write
-         lbra  GetStat
-         lbra  SetStat
-Term     pshs  y,x
-         pshs  u		save U
-         ldd   #COLSIZE*ROWSIZE		VDG memory size
-         ldu   <V.ScrnA,u 	get pointer to memory
-         os9   F$SRtMem 	return to system
-         puls  u		restore U
-         ldb   <V.COLoad,u
-         andb  #~ModCoVDG
-         bra   L0086
 * Init
-Init     pshs  y,x		save regs
+Init     pshs  y,x            save regs
          lda   #$AF
-         sta   <V.CColr,u	save default color cursor
-         pshs  u		save static ptr
-         ldd   #COLSIZE*ROWSIZE+256		allocate screen + 256 bytes for now
-         os9   F$SRqMem 	get it
-         tfr   u,d		put ptr in D
-         leax  ,u		and X
-         bita  #$01		odd page?
-         beq   L0052		branch if not
-         leax  >256,x		else move X up 256 bytes
-         bra   L0056		and return first 256 bytes
-L0052    leau  >COLSIZE*ROWSIZE,u		else move X up 512 bytes
-L0056    ldd   #256		and return last 256 bytes
-         os9   F$SRtMem 	free it!
-         puls  u		restore static ptr
-         stx   <V.ScrnA,u 	save VDG screen memory
+         sta   <V.CColr,u     save default color cursor
+         pshs  u              save static ptr
+         ldd   #COLSIZE*ROWSIZE+256 allocate screen + 256 bytes for now
+         os9   F$SRqMem       get it
+         tfr   u,d            put ptr in D
+         leax  ,u             and X
+         bita  #$01           odd page?
+         beq   L0052          branch if not
+         leax  >256,x         else move X up 256 bytes
+         bra   L0056          and return first 256 bytes
+
+L0052    leau  >COLSIZE*ROWSIZE,u   else move X up 512 bytes
+L0056    ldd   #256           and return last 256 bytes
+         os9   F$SRtMem       free it!
+         puls  u              restore static ptr
+         stx   <V.ScrnA,u     save VDG screen memory
          pshs  y
          leay  -$0E,y
          clra  
          clrb  
-         jsr   [<V.DspVct,u]	display screen (routine in VTIO)
+         jsr   [<V.DspVct,u]  display screen (routine in VTIO)
          puls  y
-         stx   <V.CrsrA,u 	save start cursor position
-         leax  >COLSIZE*ROWSIZE,x		point to end of screen
-         stx   <V.ScrnE,u 	save it
-LDClrCh  lda   #$60		get default character
-         sta   <V.CChar,u 	put character under the cursor
-         sta   <V.Chr1,u	only referenced here ??
+         stx   <V.CrsrA,u     save start cursor position
+         leax  >COLSIZE*ROWSIZE,x   point to end of screen
+         stx   <V.ScrnE,u     save it
+LDClrCh  lda   #$60           get default character
+         sta   <V.CChar,u     put character under the cursor
+         sta   <V.Chr1,u      only referenced here ??
 
-         IFNE	COCOVGA
+     IFNE	COCOVGA
 ***** START OF COCOVGA 64x32 MODE
-         clr   <V.Caps,u    lowercase mode
+         clr   <V.Caps,u      lowercase mode
          pshs  cc,u
          orcc  #IntMasks
          leax  VGASetup,pcr
@@ -112,415 +105,450 @@
          decb
          bne   x@
 
-         lda   $FF02 clear any pending vsync
-tlp@     lda   $FF03 wait for flag to indicate
-         bpl   tlp@ falling edge of FS
-         lda   $FF02 clear vsync interrupt flag
-
+         lda   $FF02          clear any pending vsync
+tlp@     lda   $FF03          wait for flag to indicate
+         bpl   tlp@           falling edge of FS
+         lda   $FF02          clear vsync interrupt flag
 
 * PROGRAM THE COCOVGA COMBO LOCK
-BT13	lda		$FF22	GET CURRENT PIA VALUE
-		tfr		A,B		COPY TO B REG TOO
-		anda	#$07	MASK OFF BITS WE'LL CHANGE
-		ora		#$90	SET COMBO LOCK 1 BITS
-		sta		$FF22	WRITE TO PIA FOR COCOVGA
-		anda	#$07	CLEAR UPPER BITS
-		ora		#$48	SET COMBO LOCK 2 BITS
-		sta		$FF22	WRITE TO PIA
-		anda	#$07	CLEAR UPPER BITS
-		ora		#$A0	SET COMBO LOCK 3 BITS
-		sta		$FF22	WRITE TO PIA
-		anda	#$07	CLEAR UPPER BITS
-		ora		#$F8	SET COMBO LOCK 4 BITS
-		sta		$FF22	WRITE TO PIA
-		anda	#$07	CLEAR UPPER BITS
-		ora		#$00	SET REGISTER BANK 0 FOR COCOVGA
-		sta		$FF22	WRITE TO PIA
+BT13     lda   $FF22          GET CURRENT PIA VALUE
+         tfr   A,B            COPY TO B REG TOO
+         anda  #$07           MASK OFF BITS WE'LL CHANGE
+         ora   #$90           SET COMBO LOCK 1 BITS
+         sta   $FF22          WRITE TO PIA FOR COCOVGA
+         anda  #$07           CLEAR UPPER BITS
+         ora   #$48           SET COMBO LOCK 2 BITS
+         sta   $FF22          WRITE TO PIA
+         anda  #$07           CLEAR UPPER BITS
+         ora   #$A0           SET COMBO LOCK 3 BITS
+         sta   $FF22          WRITE TO PIA
+         anda  #$07           CLEAR UPPER BITS
+         ora   #$F8           SET COMBO LOCK 4 BITS
+         sta   $FF22          WRITE TO PIA
+         anda  #$07           CLEAR UPPER BITS
+* 6809/6309 - Isn't this next line useless? It does not change any bits, ever
+         ora   #$00           SET REGISTER BANK 0 FOR COCOVGA
+         sta   $FF22          WRITE TO PIA
 
 * Wait for next VSYNC so CoCoVGA can process data from the current video page
-tlp@	lda		$FF03
-		bpl		tlp@
+tlp@     lda   $FF03
+         bpl   tlp@
 
 * Restore PIA state and return to text mode - restore original video mode, SAM page
 * VDG -> CG2:
-		lda		$FF22
-		anda	#$8F
-		ora		#$A0
-		sta		$FF22
+         lda   $FF22
+         anda  #$8F
+         ora   #$A0
+         sta   $FF22
 
 * SAM -> CG2:
-		sta		$FFC0	clear GM0
-		sta		$FFC3	set GM1
-		sta		$FFC4	clear GM2
-
+         sta   $FFC0          clear GM0
+         sta   $FFC3          set GM1
+         sta   $FFC4          clear GM2
          puls  u,cc
 ***** END OF COCOVGA 64x32 MODE
-		 ENDC
-
-         lbsr  ClrScrn		clear the screen
-
+     ENDC
+         lbsr  ClrScrn        clear the screen
 * Setup page to
          ldb   <V.COLoad,u
-         orb   #ModCoVDG	set to CoVDG found (?)
+         orb   #ModCoVDG      set to CoVDG found (?)
 L0086    stb   <V.COLoad,u
          clrb  
          puls  pc,y,x
 
-         IFNE  COCOVGA
+     IFNE  COCOVGA
 ***** START OF COCOVGA 64x32 MODE         
-VGASetup fcb   $00              Reset register
-         fcb   $81              Edit mask
-         fcb   $00              Reserved
-         fcb   $03              Font
-         fcb   $00              Artifact
-         fcb   $00              Extras
-         fcb   $00              Reserved
-         fcb   $00              Reserved
-         fcb   $02              Enhanced Modes
+VGASetup fcb   $00            Reset register
+         fcb   $81            Edit mask
+         fcb   $00            Reserved
+         fcb   $03            Font
+         fcb   $00            Artifact
+         fcb   $00            Extras
+         fcb   $00            Reserved
+         fcb   $00            Reserved
+         fcb   $02            Enhanced Modes
 VGASetupLen equ *-VGASetup
 ***** END OF COCOVGA 64x32 MODE         
-		 ENDC
+     ENDC
 
+start    bra   Init
+         nop                  Can be used for a constant
+         bra   Write
+         nop                  Can be used for a constant
+         lbra  GetStat
+         lbra  SetStat
+Term     pshs  y,x
+         pshs  u              save U
+         ldd   #COLSIZE*ROWSIZE  VDG memory size
+         ldu   <V.ScrnA,u     get pointer to memory
+         os9   F$SRtMem       return to system
+         puls  u              restore U
+         ldb   <V.COLoad,u
+         andb  #~ModCoVDG
+         bra   L0086
 * Write
 * Entry: A = char to write
 *        Y = path desc ptr
-Write    tsta
-         bmi   L00D0
-         cmpa  #$1F		byte $1F?
-         bls   Dispatch		branch if lower or same
-         ldb   <V.CFlag,u
-         beq   L00B0
-         cmpa  #$5E
-         bne   L00A0
-         clra
-         bra   L00D0
-L00A0    cmpa  #$5F
-         bne   L00A8
-         lda   #$1F
-         bra   L00D0
-L00A8    cmpa  #$60
-         bne   L00C0
-         lda   #$67
+Write    tsta                 Alt (hi bit) char?
+         bmi   L00D0          Yes, go straight to print
+         cmpa  #$1F           Ctrl char? ($00-$1F)?
+         bls   Dispatch       Yes, special handling
+         ldb   <V.CFlag,u     regular ASCII char; get true lowercase flag
+         beq   L00B0          Not set, skip ahead
+* VDG-T1 translations
+         cmpa  #$5E           ^ symbol?
+         bne   L00A0          Nope, check next 
+         clra                 0 char on VDG
+         bra   L00D0          Put on screen
+
+L00A0    cmpa  #$5F           _ Underline char?
+         bne   L00A8          No, check next
+         lda   #$1F           $1F char on VDG
+         bra   L00D0          Put on screen
+
+L00A8    cmpa  #$60           ' Single quote?
+         bne   L00C0          No, skip ahead to common translations
+         lda   #$67           $67 char on VDG
          bra   L00D0
-L00B0    cmpa  #$7C
-         bne   L00B8
-         lda   #$21
-         bra   L00D0
-L00B8    cmpa  #$7E
-         bne   L00C0
-         lda   #$2D
-         bra   L00D0
-L00C0    cmpa  #$60
-         bcs   L00C8
-         suba  #$60
-         bra   L00D0
-L00C8    cmpa  #$40
-         bcs   L00CE
-         suba  #$40
-L00CE    eora  #$40
-L00D0    ldx   <V.CrsrA,u	get cursor address in X
-         sta   ,x+		store character at address
-         stx   <V.CrsrA,u 	update cursor address
-         cmpx  <V.ScrnE,u 	end of screen?
-         bcs   L00DF		branch if not
-         bsr   SScrl		else if at end of screen, scroll it
-L00DF    bra   ShowCrsr		ends with a CLRB/RTS anyhow
+
+* Regular VDG translations
+L00B0    cmpa  #$7C           | Pipe symbol?
+         bne   L00B8          No, check next
+         lda   #$21           Yes, change to ! pipe symbol
+         bra   L00D0          Put on screen
+
+L00B8    cmpa  #$7E           ~ Tilde symbol?
+         bne   L00C0          Nope, go do common translations
+         lda   #$2D           Tilde symbol for VDG
+         bra   L00D0          Put on screen
+
+* Common translation to both VDG chips
+L00C0    cmpa  #$60           Char below $60?
+         blo   L00C8          Yes, check next range
+         suba  #$60           Drop by $60 for VDG translation
+         bra   L00D0          Put on screen
+
+L00C8    cmpa  #$40           Char below $40?
+         blo   L00CE          Yes, Flip case bit only
+         suba  #$40           Drop for VDG
+L00CE    eora  #$40           Force to non-inverse chars on regular VDG
+L00D0    ldx   <V.CrsrA,u     get cursor address in X
+         sta   ,x+            store character at address
+         stx   <V.CrsrA,u     update cursor address
+         cmpx  <V.ScrnE,u     end of screen?
+         blo   L00DF          No, just display the cursor
+         bsr   SScrl          Yes, scroll the screen first
+L00DF    bra   ShowCrsr       And turn the cursor back on
 
 * Screen Scroll Routine
-SScrl
-         IFNE  H6309
-         ldx   <V.ScrnA,u       get address of screen
-         ldd   #COLSIZE*256+$60
-         leay  a,x              down one line
-         ldw   #COLSIZE*ROWSIZE-COLSIZE
-         tfm   y+,x+            scroll screen up
-         stx   <V.CrsrA,u       save new cursor address
-         ELSE
-         ldy   <V.ScrnA,u       get address of screen
-         ldx   <V.ScrnE,u       get address of end of screen
-         pshs  u,y,x            save u y x on stack
-         leau  <COLSIZE,y       get address of second line
-ScrlLp@  pulu  d,x              pull D and X off of U stack for line two
-         std   ,y++             write D into new location
-         stx   ,y++             write X into new location
-         cmpu  ,s               compare U to end of screen
-         bls   ScrlLp@          check if we reached end of line if not do more
-         puls  x,y,u            restore U X and D registers
-         leax  -COLSIZE,x
-         stx   <V.CrsrA,u
-         ldd   #COLSIZE*256+$60  A=clear out row... B= with spaces
-         ENDC
-L00FD    stb   ,x+		do it...
-         deca  			end of rope?
-         bne   L00FD		branch if not
+SScrl    ldd   #COLSIZE*ROWSIZE-COLSIZE  Size of screen minus one line
+         ldx   >V.ClrBlk,u    Get Clear block vector for later
+         pshs  u,x            Save static mem ptr & Clear block vector
+         ldx   >V.CpyBlk,u    Get vector to Copy block
+         ldy   <V.ScrnA,u     Get ptr to start of text screen
+         leau  <COLSIZE,y     Point to start of 2nd line
+         jsr   ,x             Call copy block vector (U will point to end of screen+1)
+         ldx   #COLSIZE       Size of block to clear (bottom line)
+         ldb   #$60           VDG Space char
+         puls  y              Get clear block vector
+         jsr   ,y             Clear last line (U was pointing to end of last line from above, so it picks up where it left off. I think)
+* Since 6309 returns with U=ptr to end of screen, and 6809 returns with ptr to start of last line,
+*   we need to differentiate here
+       IFNE  H6309
+         leax  -COLSIZE,u     6309 - Bump back to start of last line
+       ELSE
+         leax  ,u             6809 - already pointing to start of last line
+       ENDC
+         puls  u              Get back static mem ptr
+         stx   <V.CrsrA,u     Save new cursor position (Start of last line)
+         rts                  & return
+
+* Ctrl char ($00-$1F) special char dispatch
+Dispatch cmpa  #$1B           escape code?
+         bhs   bad@           branch if same or greater (special control codes for screen controls)
+         cmpa  #$0E           $0E?
+         bhi   L0102          branch if higher than
+         leax  <DCodeTbl,pcr  deal with screen codes
+         lsla                 adjust for table entry size
+         ldd   a,x            get address in D
+         jmp   d,x            and jump to routine
+bad@     comb  
+         ldb   #E$Write
 L0102    rts   
 
-Dispatch cmpa  #$1B		escape code?
-         bcc   bad@		branch if same or greater
-         cmpa  #$0E		$0E?
-         bhi   L0102		branch if higher than
-         leax  <DCodeTbl,pcr	deal with screen codes
-         lsla  			adjust for table entry size
-         ldd   a,x		get address in D
-         jmp   d,x		and jump to routine
-bad@     comb  
-         ldb   #E$Write
-         rts   
-
-* display functions dispatch table
-DCodeTbl fdb   NoOp-DCodeTbl		$00:no-op (null)
-         fdb   CurHome-DCodeTbl		$01:HOME cursor
-         fdb   CurXY-DCodeTbl		$02:CURSOR XY
-         fdb   DelLine-DCodeTbl		$03:ERASE LINE
-         fdb   ErEOLine-DCodeTbl	$04:CLEAR TO EOL
-         fdb   Do05-DCodeTbl		$05:CURSOR ON/OFF
-         fdb   CurRght-DCodeTbl		$005e  $06:CURSOR RIGHT
-         fdb   NoOp-DCodeTbl		$07:no-op (bel:handled in VTIO)
-         fdb   CurLeft-DCodeTbl		$0050  $08:CURSOR LEFT
-         fdb   CurUp-DCodeTbl		$0119  $09:CURSOR UP
-         fdb   CurDown-DCodeTbl		$0038  $0A:CURSOR DOWN
-         fdb   ErEOScrn-DCodeTbl	$006c  $0B:ERASE TO EOS
-         fdb   ClrScrn-DCodeTbl		$0070  $0C:CLEAR SCREEN
-         fdb   Retrn-DCodeTbl		$001e  $0D:RETURN
-         fdb   DoAlpha-DCodeTbl		$012a  $0E:DISPLAY ALPHA
+* display functions dispatch table.
+DCodeTbl fdb   L014D-DCodeTbl     $00:no-op (null)
+         fdb   CurHome-DCodeTbl   $01:HOME cursor
+         fdb   CurXY-DCodeTbl     $02:CURSOR XY
+         fdb   DelLine-DCodeTbl   $03:ERASE LINE
+         fdb   ErEOLine-DCodeTbl  $04:CLEAR TO EOL
+         fdb   Do05-DCodeTbl      $05:CURSOR ON/OFF
+         fdb   CurRght-DCodeTbl   $06:CURSOR RIGHT
+         fdb   L014D-DCodeTbl     $07:no-op (bel:handled in VTIO)
+         fdb   CurLeft-DCodeTbl   $08:CURSOR LEFT
+         fdb   CurUp-DCodeTbl     $09:CURSOR UP
+         fdb   CurDown-DCodeTbl   $0A:CURSOR DOWN
+         fdb   ErEOScrn-DCodeTbl  $0B:ERASE TO EOS
+         fdb   ClrScrn-DCodeTbl   $0C:CLEAR SCREEN
+         fdb   Retrn-DCodeTbl     $0D:RETURN
+         fdb   DoAlpha-DCodeTbl   $0E:DISPLAY ALPHA
 
 * $0D - move cursor to start of line (carriage return)
-Retrn    bsr   HideCrsr		hide cursor
-         IFNE  H6309
-         aim   #$E0,<V.CrsAL,u
-         ELSE
-         tfr   x,d		put cursor address in D
-         andb  #~(COLSIZE-1)		place at start of line
-         stb   <V.CrsAL,u	and save low cursor address
-         ENDC
-ShowCrsr ldx   <V.CrsrA,u 	get cursor address
-         lda   ,x		get char at cursor position
-         sta   <V.CChar,u 	save it
-         lda   <V.CColr,u 	get cursor character
-         beq   L014D		branch if none
-L014B    sta   ,x		else turn on cursor
-NoOp
-L014D    clrb  
+Retrn    bsr   HideCrsr       hide cursor
+       IFNE  H6309
+         aim   #$E0,<V.CrsAL,u  Force cursor to beginning of current line (clear low 5 bits of address)
+       ELSE
+         tfr   x,d            put cursor address in D
+         andb  #~(COLSIZE-1)  place at start of line
+         stb   <V.CrsAL,u     and save low cursor address
+       ENDC
+ShowCrsr ldx   <V.CrsrA,u     get cursor address
+         lda   ,x             get char at cursor position
+         sta   <V.CChar,u     save it
+         lda   <V.CColr,u     get cursor character
+         beq   L014D          If cursor off, don't put on screen
+L014B    sta   ,x             else turn on cursor
+L014D    clrb                 & exit w/o error
          rts   
 
 * $0A - cursor down (line feed)
-CurDown  bsr   HideCrsr		hide cursor
-         leax  <COLSIZE,x		move X down one line
-         cmpx  <V.ScrnE,u 	at end of screen?
-         bcs   L0162		branch if not
-         leax  <-COLSIZE,x		else go back up one line
-         pshs  x		save X
-         lbsr  SScrl		and scroll the screen
-         puls  x		restore pointer
-L0162    stx   <V.CrsrA,u 	save cursor pointer
-         bra   ShowCrsr		show cursor
+CurDown  bsr   HideCrsr       hide cursor
+         leax  <COLSIZE,x     move X down one line
+         cmpx  <V.ScrnE,u     at end of screen?
+         blo   L0162          branch if not
+         leax  <-COLSIZE,x    else go back up one line
+         pshs  x              save cursor position
+         lbsr  SScrl          & scroll the screen
+         puls  x              restore pointer
+L0162    stx   <V.CrsrA,u     save cursor pointer
+         bra   ShowCrsr       show cursor
 
 * $08 - cursor left
-CurLeft  bsr   HideCrsr		hide cursor
-         cmpx  <V.ScrnA,u 	compare against start of screen
-         bls   L0173		ignore it if at the screen start
-         leax  -$01,x		else back up one
-         stx   <V.CrsrA,u 	save updated pointer
-L0173    bra   ShowCrsr		and show cursor
+CurLeft  bsr   HideCrsr       hide cursor
+         cmpx  <V.ScrnA,u     compare against start of screen
+         bls   L0173          ignore it if at the screen start
+         leax  -1,x           else back up one
+         stx   <V.CrsrA,u     save updated pointer
+L0173    bra   ShowCrsr       and show cursor
 
 * $06 - cursor right
-CurRght  bsr   HideCrsr		hide cursor
-         leax  $01,x		move to the right
-         cmpx  <V.ScrnE,u 	compare against end of screen
-         bcc   L0181		if past end, ignore it
-         stx   <V.CrsrA,u 	else save updated pointer
-L0181    bra   ShowCrsr		and show cursor
+CurRght  bsr   HideCrsr       hide cursor
+         leax  1,x            move to the right
+         cmpx  <V.ScrnE,u     compare against end of screen
+         bhs   L0181          if past end, ignore it
+         stx   <V.CrsrA,u     else save updated pointer
+L0181    bra   ShowCrsr       and show cursor
 
 * $0B - erase to end of screen
-ErEOScrn bsr   HideCrsr		kill the cusror
-         bra   L0189		and clear rest of the screen
+ErEOScrn bsr   HideCrsr       kill the cusror
+         bra   L0189          and clear rest of the screen
 
 * $0C - clear screen
-ClrScrn  bsr   CurHome		home cursor
-L0189    equ   *
-         IFNE  H6309
-         ldw <V.ScrnE,u
-         subr x,w
-         leay LDClrCh+1,pc
-         tfm y,x+
-         ELSE
-         lda   #$60		get default char
-L018B    sta   ,x+		save at location
-         cmpx  <V.ScrnE,u 	end of screen?
-         bcs   L018B		branch if not
-         ENDC
-         bra   ShowCrsr		now show cursor
+ClrScrn  bsr   CurHome        home cursor (and set X=ptr to start of screen)
+* Entry point for partial screen clear
+* Entry: X=ptr to start address to clear from
+* For V.ClrBlk,u, entry is: B=value to clear with, X=size to clear, U=End of clear block address+1
+L0189    
+       IFNE  H6309
+         pshs  u              Save static mem ptr
+         ldy   <V.ScrnE,u     Get ptr to end of screen
+         subr  x,y            Calc size of clear by subtracting current cursor address
+         leax  ,y             X=size to clear
+         ldy   >V.ClrBlk,u    Get Clear Block subroutine address
+       ELSE
+         pshs  x              Save start addr to clear from
+         ldd   <V.ScrnE,u     Get ptr to end of screen
+         subd  ,s++           Calc size of clear (subtract start addr)
+         tfr   d,x            Move size to X
+         ldy   >V.ClrBlk,u    Get Clear Block subroutine address
+         pshs  u              Save static mem ptr
+       ENDC
+         ldu   <V.ScrnE,u     Point to end address of screen
+         ldb   #$60           VDG Space char
+         jsr   ,y             Go clear
+         puls  u              Get static mem ptr back
+         bra   ShowCrsr       Turn cursor back on
 
+         
 * $01 - home cursor
-CurHome  bsr   HideCrsr		hide cursor
-         ldx   <V.ScrnA,u $1D	get pointer to screen
-         stx   <V.CrsrA,u $21	save as new cursor position
-         bra   ShowCrsr		and show it
+CurHome  bsr   HideCrsr       hide cursor
+         ldx   <V.ScrnA,u     get pointer to screen
+         stx   <V.CrsrA,u     save as new cursor position
+         bra   ShowCrsr       and show it
 
 * Hides the cursor from the screen
 * Exit: X = address of cursor
-HideCrsr ldx   <V.CrsrA,u $21	get address of cursor in X
-         lda   <V.CChar,u $23	get value of char under cursor
-         sta   ,x		put char in place of cursor
-         clrb  			must be here, in general, for [...] BRA HideCrsr
+HideCrsr ldx   <V.CrsrA,u     get address of cursor in X
+         lda   <V.CChar,u     get value of char under cursor
+         sta   ,x             put char in place of cursor
+NoErr1   clrb                 must be here, in general, for [...] BRA HideCrsr
          rts   
 
 * $05 XX - set cursor off/on/color per XX-32
-Do05     ldb   #$01		need additional byte
-         leax  <CrsrSw,pcr	
-         bra   L01E5
+Do05     ldb   #$01           need additional byte
+         leax  <CrsrSw,pcr    Get vector to return to after we get byte
+         bra   L01E5          Save vector, and go get parameter byte
+
+CrsrSw   lda   <V.NChr2,u     get next char
+         suba  #C$SPAC        take out ASCII space
+         bne   L01BB          branch if not zero
+         sta   <V.CColr,u     else save cursor color zero (no cursor)
+         bra   HideCrsr       and hide cursor
 
-CrsrSw   lda   <V.NChr2,u 	get next char
-         suba  #C$SPAC		take out ASCII space
-         bne   L01BB		branch if not zero
-         sta   <V.CColr,u 	else save cursor color zero (no cursor)
-         bra   HideCrsr		and hide cursor
-L01BB    cmpa  #$0B		greater than $0B?
-         bge   L014D		yep, just ignore byte
-         cmpa  #$01		is it one?
-         bgt   L01C7		branch if greater
-         lda   #$AF		else get default blue cursor color
-         bra   L01D7		and save cursor color
-L01C7    cmpa  #$02		is it two?
-         bgt   L01CF		branch if larger
-         lda   #$A0		else get black cursor color
-         bra   L01D7		and save it
-** BUG ** BUG ** BUG ** BUG
-L01CF    suba  #$03		** BUG FIXED! ** !!! Was SUBB
-         lsla  			shift into upper nibble
+L01BB    cmpa  #11            >=11?
+         bge   NoErr1          yep, ignore & return w/o error
+         cmpa  #1             is it one (Blue cursor from level 1)?
+         bgt   L01C7          No, try next
+         lda   #$AF           Yes, default blue cursor color
+         bra   L01D7          and save it
+         
+L01C7    cmpa  #2             is it two (black cursor from level 1)?
+         bgt   L01CF          branch if larger
+         lda   #$A0           else get black cursor color
+         bra   L01D7          and save it
+         
+L01CF    lsla                 shift into upper nibble
          lsla  
          lsla  
          lsla  
          ora   #$8F
-L01D7    sta   <V.CColr,u 	save new cursor
-         ldx   <V.CrsrA,u 	get cursor address
-         lbra  L014B		branch to save cursor in X
+L01D7    sta   <V.CColr,u     save new cursor
+         ldx   <V.CrsrA,u     get cursor address
+         lbra  L014B          branch to save cursor in X
 
 * $02 XX YY - move cursor to col XX-32, row YY-32
-CurXY    ldb   #$02		we want to claim next two chars
-         leax  <DoCurXY,pcr	point to processing routine
-L01E5    stx   <V.RTAdd,u	store routine to return to
-         stb   <V.NGChr,u	get two more chars
-         clrb  
+CurXY    ldb   #2             we neeed two more parameters
+         leax  <DoCurXY,pcr   Get vector to return to after we get params
+L01E5    stx   <V.RTAdd,u     Save it
+         stb   <V.NGChr,u     Save # chars needed as params
+         clrb                 No error, and go get missing param bytes
          rts   
 
-DoCurXY  bsr   HideCrsr		hide cursor
-         ldb   <V.NChr2,u 	get ASCII Y-pos
-         subb  #C$SPAC		take out ASCII space
-         lda   #COLSIZE		go down
-         mul   			multiply it
-         addb  <V.NChar,u 	add in X-pos
+DoCurXY  bsr   HideCrsr       hide cursor
+         ldb   <V.NChr2,u     get ASCII Y-pos
+         subb  #C$SPAC        take out ASCII space
+         lda   #COLSIZE       Calculate vertical offset from start of screen to line we want
+         mul                  multiply it
+         addb  <V.NChar,u     add in X-pos
          adca  #$00
-         subd  #C$SPAC		take out another ASCII space
-         addd  <V.ScrnA,u 	add top of screen address
-         cmpd  <V.ScrnE,u 	at end of the screen?
-         lbcc  L014D		exit if off the screen
-         std   <V.CrsrA,u 	otherwise save new cursor address
-         lbra  ShowCrsr		and show cursor
+         subd  #C$SPAC        take out another ASCII space
+         addd  <V.ScrnA,u     add top of screen address
+         cmpd  <V.ScrnE,u     past end of screen?
+         bhs   NoErr1         Yes, ignore & exit w/o error
+         std   <V.CrsrA,u     otherwise save new cursor address
+         lbra  ShowCrsr       and show cursor
 
 * $04 - erase to end of line
-ErEOLine bsr   HideCrsr		hide cursor
-         tfr   x,d		move current cursor position in D
-         andb  #COLSIZE-1		number of characters put on this line
+ErEOLine bsr   HideCrsr       hide cursor
+         tfr   x,d            move current cursor position to D
+         andb  #COLSIZE-1     number of characters put on this line
          pshs  b
-         ldb   #COLSIZE
+         ldb   #COLSIZE       Calculate # of chars left in line
          subb  ,s+
-         bra   L0223		and clear one line
+         bra   L0223          and clear that many
 
 * $03 - erase line
-DelLine  lbsr  Retrn		do a CR
-         ldb   #COLSIZE		line length
-L0223    lda   #$60		get default character
-         ldx   <V.CrsrA,u 	get cursor address
-L0228    sta   ,x+		fill screen line with 'space'
-         decb  			decrement
-         bne   L0228		and branch if not end
-         lbra  ShowCrsr		else show cursor
+DelLine  lbsr  Retrn          do a CR
+         ldb   #COLSIZE       line length
+* Entry: B=# of bytes to erase, X=ptr to start of copy
+L0223    ldy   >V.ClrBlk,u    Get ClrBlk vector (before we destroy u)
+         pshs  u              Save static mem ptr
+         leau  b,x            Point U to end of line
+         clra                 D=size
+         tfr   d,x            Move to X for ClrBlk
+         ldb   #$60           VDG space char
+         jsr   ,y             Call ClrBlk
+         puls  u              Get static mem back
+         lbra  ShowCrsr       Turn cursor back on & return from there
 
 * $09 - cursor up
-CurUp    lbsr  HideCrsr		hide cursor
-         leax  <-COLSIZE,x		move X up one line
-         cmpx  <V.ScrnA,u 	compare against start of screen
-         bcs   L023E		branch if we went beyond
-         stx   <V.CrsrA,u 	else store updated X
-L023E    lbra  ShowCrsr		and show cursor
+CurUp    lbsr  HideCrsr       hide cursor
+         leax  <-COLSIZE,x    move X up one line
+         cmpx  <V.ScrnA,u     We past top of screen?
+         blo   L023E          Yes, leave cursor pos along and turn it back on
+         stx   <V.CrsrA,u     No, save new cursor Y position
+L023E    lbra  ShowCrsr       Show cursor & return from there
 
 * $0E - switch screen to alphanumeric mode
-DoAlpha  clra  
-         clrb  
-         jmp   [<V.DspVct,u]	display screen (routine in VTIO)
+DoAlpha  clra                 
+         clrb                 Text mode
+         jmp   [<V.DspVct,u]  display screen (routine in VTIO)
 
 * GetStat
-GetStat  ldx   PD.RGS,y		get caller's regs
-         cmpa  #SS.AlfaS	AlfaS?
-         beq   Rt.AlfaS		branch if so
-         cmpa  #SS.Cursr	Cursr?
-         beq   Rt.Cursr		branch if so
+GetStat  ldx   PD.RGS,y       get caller's regs
+         cmpa  #SS.AlfaS      AlfaS?
+         beq   Rt.AlfaS       branch if so
+         cmpa  #SS.Cursr      Cursr?
+         beq   Rt.Cursr       branch if so
 
-* SetStat
+* SetStat - All SetStat calls return "Unknown Service" error
 SetStat  comb  
          ldb   #E$UnkSvc
          rts   
 
 * SS.AlfaS getstat
-Rt.AlfaS ldd   <V.ScrnA,u 	memory address of buffer
-         std   R$X,x		save in caller's X
-         ldd   <V.CrsrA,u 	get cursor address
-         std   R$Y,x		save in caller's Y
-         lda   <V.Caps,u 	save caps lock status in A and exit
+Rt.AlfaS ldd   <V.ScrnA,u   memory address of buffer
+         std   R$X,x        save in caller's X
+         ldd   <V.CrsrA,u   get cursor address
+         std   R$Y,x        save in caller's Y
+         lda   <V.Caps,u    save caps lock status in A and exit
          bra   SaveA
 
 * SS.Cursr getstat
-Rt.Cursr ldd   <V.CrsrA,u	get address of cursor
-         subd  <V.ScrnA,u	subtract screen address
-         pshs  b,a		D now holds cursor position relative to screen
+Rt.Cursr ldd   <V.CrsrA,u     get address of cursor
+         subd  <V.ScrnA,u     subtract screen address
+         pshs  d              D now holds cursor position relative to screen
          clra  
          andb  #COLSIZE-1
-         addb  #COLSIZE		compute column position
-         std   R$X,x		save column position to caller's X
-         puls  b,a		then divide by 32
-         lsra  
+         addb  #COLSIZE       compute column position
+         std   R$X,x          save column position to caller's X
+         puls  d              then divide by 32
+* NOTE: will COCOVGA need more 16 bit shifts? It's a 2K screen. 
+         lsra                 
          rolb  
          rolb  
          rolb  
          rolb  
-         IFNE  COCOVGA
-         rolb  
-         ENDC
+       IFNE  COCOVGA
+         rolb                 By 64 is CocoVGA (64x32)
+       ENDC
          clra  
-         andb  #ROWSIZE-1		lines on the screen
+         andb  #ROWSIZE-1     lines on the screen
          addb  #COLSIZE
-         std   R$Y,x		and save column to caller's Y
-         ldb   <V.CFlag,u
-         lda   <V.CChar,u	get character under cursor
-         bmi   SaveA		if hi bit set, go on
-         cmpa  #$60		VDG space?
-         bcc   L02A5		branch if greater than
-         cmpa  #$20		
-         bcc   L02A9
-         tstb 
-         beq   L02A3
-         cmpa  #$00
-         bne   L029B
-         lda   #$5E
-         bra   SaveA		save it and exit
+         std   R$Y,x          and save column to caller's Y
+         ldb   <V.CFlag,u     Get true lowercase flag
+         lda   <V.CChar,u     get character under cursor
+         bmi   SaveA          if hi bit set, return that value to caller
+         cmpa  #$60           Lowercase?
+         bhs   L02A5          Yes, skip ahead
+         cmpa  #$20           #, uppercase, some punctuation?
+         bhs   L02A9          Yes, Change if VDG-T1
+         tstb                 Real lowercase enabled?
+         beq   L02A3          No, convert to ASCII from VDG code
+         tsta                 VDG caret?
+         bne   L029B          No, try some other special ones
+         lda   #$5E           Replace with ASCII caret ^
+         bra   SaveA          save it and exit
 
-L029B    cmpa  #$1F
-         bne   L02A3
-         lda   #$5F
+L029B    cmpa  #$1F           VDG underscore?
+         bne   L02A3          No, done special checks
+         lda   #$5F           Yes, replace with underscore
          bra   SaveA
-L02A3    ora   #$20		turn it into ASCII from VDG codes
-L02A5    eora  #$40
+
+L02A3    ora   #$20           turn it into ASCII from VDG codes
+L02A5    eora  #$40           Switch to uppercase
          bra   SaveA
-L02A9    tstb  
-         bne   SaveA
-         cmpa  #$21		remap specific codes
-         bne   L02B4
-         lda   #$7C
+
+L02A9    tstb                 True lowercase on with VDG-T1?      
+         bne   SaveA          yes, save char
+         cmpa  #$21           No, remap specific codes - exclamation/pipe?
+         bne   L02B4          No, try one more special one
+         lda   #$7C           Replace with actual ASCII pipe
          bra   SaveA
+
 L02B4    cmpa  #$2D
          bne   SaveA
-         lda   #$7E
+         lda   #$7E           Replace with ASCII tilde
 SaveA    sta   R$A,x
          clrb  
          rts   
--- a/level1/modules/vtio.asm	Sun Mar 11 01:40:13 2018 -0600
+++ b/level1/modules/vtio.asm	Mon Mar 12 19:35:56 2018 -0500
@@ -39,6 +39,18 @@
 *                      L. Curtis Boyle
 * Fixed bug with SS.Ready GetStat call - it was not saving the # of chars
 * available in the keyboard buffer to caller's B register
+*
+*   4      2018/03/02  David Ladd
+*                      L. Curtis Boyle
+* Fixed SS.ComSt call so that changing Coco 3 or Coco2B T1 VDG between real
+* lowercase and inverse video takes effect as soon as the call is made (it
+* setting flags, but not updating the hardware until the next switch to Graphics
+* mode and back to text mode happened.
+* Also some more general optimizations, and installed the V.ClrBlk and V.CpyBlk
+* vectors calls (to use 6309 TFM and 6809 mini-stack blasting) for memory clears
+* and memory copies. These will also be accessible from VTIO's other co-modules,
+* for a speed increase.
+
          nam   VTIO
          ttl   OS-9 Level One V2 CoCo I/O driver
 
@@ -51,7 +63,7 @@
 tylg     set   Drivr+Objct
 atrv     set   ReEnt+rev
 rev      set   $00
-edition  set   1
+edition  set   2
 
          mod   eom,name,tylg,atrv,start,size
 
@@ -62,13 +74,6 @@
 name     fcs   /VTIO/
          fcb   edition
 
-start    lbra  Init
-         lbra  Read
-         lbra  Write
-         lbra  GetStat
-         lbra  SetStat
-         lbra  Term
-
 * Init
 *
 * Entry:
@@ -93,7 +98,7 @@
 L002E    sta   ,x+            clear mem
          decb                 decrement counter
          bne   L002E          continue if more
-         leax  FlashCursor,pcr Point to dummy cursor flash (just an rts). 
+         leax  <FlashCursor,pcr Point to dummy cursor flash (just an rts). 
          stx   V.Flash,u      Setup cursor flash
          coma                 A = $FF
          comb                 B = $FF
@@ -107,30 +112,19 @@
 * I presume this should also get IFEQ to specify 50 for PAL systems
          lda   #60            Init clock ctr to 60
          sta   <V.ClkCnt,u
-         leax  >AltIRQ,pcr    get IRQ routine ptr
+         leax  <AltIRQ,pcr    get IRQ routine ptr
          stx   >D.AltIRQ      store in AltIRQ
          leax  >SetDsply,pcr  get display vector
          stx   <V.DspVct,u    store in vector address
          leax  >XY2Addr,pcr   get address of XY2Addr
          stx   <V.CnvVct,u    Save as vector get mem location and pixel mask based on X,Y coords on gfx screen
+         leax  >ClrBlk,pcr    get address for mini-stack blast clear mem routine
+         stx   >V.ClrBlk,u    Save as vector
+         leax  >CpyBlk,pcr    get address for mini-stack blast mem copy (scroll) routine
+         stx   >V.CpyBlk,u    Save as vector
          ldd   <IT.PAR,y      get parity and baud
          lbra  SetupTerm      process them
 
-* Term
-*
-* Entry:
-*    U  = address of device memory area
-*
-* Exit:
-*    CC = carry set on error
-*    B  = error code
-*
-Term     pshs  cc
-         orcc  #IRQMask       mask interrupts
-         ldx   >D.Clock       get clock vector
-         stx   >D.AltIRQ      and put back in AltIRQ
-         puls  pc,cc          Restore interrups & return
-
 * Read
 *
 * Entry:
@@ -147,38 +141,38 @@
 *       ldy     #$aa57
 *       puls    y
 
-         leax  V.InBuf,u  point X to input buffer
-         ldb   V.IBufT,u  get tail pointer
-         orcc  #IRQMask   mask IRQ
-         cmpb  V.IBufH,u  same as head pointer
-         beq   Put2Bed    if so, buffer is empty, branch to sleep
-         abx              X now points to curr char
-         lda   ,x         get char
-         bsr   L009D      check for tail wrap
-         stb   V.IBufT,u  store updated tail
+         leax  V.InBuf,u      point X to input buffer
+         ldb   V.IBufT,u      get tail pointer
+         orcc  #IRQMask       mask IRQ
+         cmpb  V.IBufH,u      same as head pointer
+         beq   Put2Bed        if so, buffer is empty, branch to sleep
+         abx                  X now points to curr char
+         lda   ,x             get char
+         bsr   L009D          check for tail wrap
+         stb   V.IBufT,u      store updated tail
          andcc  #^(IRQMask+Carry) unmask IRQ
 FlashCursor
          rts
 
-Put2Bed  lda   V.BUSY,u   get calling process ID
-         sta   V.WAKE,u   store in V.WAKE
-         andcc  #^IRQMask  clear interrupts
+Put2Bed  lda   V.BUSY,u       get calling process ID
+         sta   V.WAKE,u       store in V.WAKE
+         andcc  #^IRQMask     clear interrupts
          ldx   #$0000
-         os9   F$Sleep    sleep forever
-         clr   V.WAKE,u   clear wake
-         ldx   <D.Proc    get pointer to current proc desc
-         ldb   <P$Signal,x get signal recvd
-         beq   Read       branch if no signal
-         cmpb  #S$Window  window signal?
-         bcc   Read       branch if so
-         coma
+         os9   F$Sleep        sleep forever
+         clr   V.WAKE,u       clear wake
+         ldx   <D.Proc        get pointer to current proc desc
+         ldb   <P$Signal,x    get signal recvd
+         beq   Read           branch if no signal
+         cmpb  #S$Window      window signal?
+         bhs   Read           Window signal or higher (none of the main system ones), go read
+         coma                 Otherwise, return with signal code as error
          rts
 
 * Check if we need to wrap around tail pointer to zero
-L009D    incb             increment pointer
-         cmpb  #$7F       at end?
-         bls   L00A3      branch if not
-         clrb             else clear pointer (wrap to head)
+L009D    incb                 increment pointer
+         cmpb  #$7F           at end?
+         bls   L00A3          branch if not
+         clrb                 else clear pointer (wrap to head)
 L00A3    rts
 
 *
@@ -573,8 +567,8 @@
          lslb
          lslb
          lslb
-         pshs  b              Save shifted version
-         ora   ,s+            Combine shifted version with original & remove from stack
+         pshs  b
+         ora   ,s+
          ldb   ,s             Get original dragon formatted one back (-2 cyc)
          andb  #%00111100     Shift middle 4 rows down 2 places
          lsrb
@@ -617,6 +611,22 @@
          fcb   $32,$34,$36 F2 key
 
 
+start    lbra  Init
+         lbra  Read
+         bra   Write
+         nop                  Could be used for a constant
+         lbra  GetStat
+         lbra  SetStat
+* Term
+* Entry: U  = address of device memory area
+* Exit:  CC = carry set on error
+*        B  = error code
+Term     pshs  cc
+         orcc  #IRQMask       mask interrupts
+         ldx   >D.Clock       get clock vector
+         stx   >D.AltIRQ      and put back in AltIRQ
+         puls  pc,cc          Restore interrupts & return
+
 * Write - move to just after initial jump table to make short branch, since this
 *  will be the most often used routine in VTIO
 *
@@ -679,7 +689,7 @@
 
 Escape   beq   L03C5          if $1E, we conveniently ignore it
          leax  <COEscape,pcr  else it's $1F... set up to get next char
-L03BD    ldb   #$01
+L03BD    ldb   #$01           This entry point requests 1 byte of parameters
 L03BF    stx   <V.RTAdd,u
          stb   <V.NGChr,u
 L03C5    clrb
@@ -690,6 +700,7 @@
 
 * Show VDG or Graphics screen. Set up as a vector (V.DspVct)
 * Entry: B = 0 for VDG, 1 for Graphics
+*        A = color setting of some sort 
 SetDsply pshs  x,a
          stb   <V.Alpha,u     save passed flag in B
          lda   >PIA1Base+2
@@ -700,22 +711,22 @@
          ora   <V.CFlag,u
 L03DE    sta   >PIA1Base+2
          sta   <V.PIA1,u
+         ldx   #$FFC6         Point to SAM to set up where to map
          tstb                 display graphics?
          bne   DoGfx          Yes, do that
 * Set up VDG screen for text
-DoVDG    stb   >$FFC0         No, set up for 32x16 text screen
-         stb   >$FFC2
-         stb   >$FFC4
+         stb   -6,x           $FFC0  No, set up for 32x16 text screen
+         stb   -4,x           $FFC2
+         stb   -2,x           $FFC4
          lda   <V.ScrnA,u     get pointer to alpha screen
-         bra   L0401
+        bra   L0401
 
 * Set up VDG screen for graphics
-DoGfx    stb   >$FFC0
-         stb   >$FFC3
-         stb   >$FFC5
+DoGfx    stb   -6,x           $FFC0
+         stb   -3,x           $FFC3
+         stb   -1,x           $FFC5
          lda   <V.SBAdd,u     get pointer to graphics screen (just need hi byte-VDG needs 512 byte boundaries)
 L0401    ldb   #$07           7 SAM double-byte settings to do
-         ldx   #$FFC6         Point to SAM to set up where to map
          lsra
 L0407    lsra
          bcs   L0410          If bit set, store on odd byte
@@ -729,16 +740,22 @@
          clrb                 Return w/o error
          puls  pc,x
 
-* Comodule filename list. 6809/6309 - Try to move elsewhere to allow some 8 bit ,pcr's
-GrfDrv   fcs   /GrfDrv/
-CoVDG    fcs   /CoVDG/
-CoWP     fcs   /CoWP/
-CoHR     fcs   /CoHR/
-Co42     fcs   /Co42/
-CoVGA    fcs   /CoVGA/
+* Return key sense information
+SSKYSNS  ldb   <V.KySns,u get key sense info
+         stb   R$A,x      put in caller's A
+         clrb
+         rts
+
+* Return screen size
+SSSCSIZ  clra                 clear upper 8 bits of D
+         ldb   <V.Col,u       get column count
+         std   R$X,x          save in X
+         ldb   <V.Row,u       get row count
+         std   R$Y,x          save in Y
+         clrb                 no error
+         rts
 
 * GetStat
-*
 * Entry:
 *    A  = function code
 *    Y  = address of path descriptor
@@ -761,9 +778,6 @@
 SSEOF    clrb
          rts
 
-*6809/6309 note: If we move a call or two before GetStat above, may be able to eliminate a
-*  couple of long branch instructions below
-
 L0439    cmpa  #SS.Joy        joystick?
          beq   SSJOY          branch if so
          cmpa  #SS.ScSiz      screen size?
@@ -771,26 +785,13 @@
          cmpa  #SS.KySns      keyboard sense?
          beq   SSKYSNS        branch if so
          cmpa  #SS.DStat      display status?
-         lbeq  SSDSTAT        branch if so
+         beq   SSDSTAT        branch if so
          ldb   #$06           getstat entry into CO-module
          lbra  JmpCO
 
-* Return key sense information
-SSKYSNS  ldb   <V.KySns,u get key sense info
-         stb   R$A,x      put in caller's A
-         clrb
-         rts
-
-* Return screen size
-SSSCSIZ  clra                 clear upper 8 bits of D
-         ldb   <V.Col,u       get column count
-         std   R$X,x          save in X
-         ldb   <V.Row,u       get row count
-         std   R$Y,x          save in Y
-         clrb                 no error
-         rts
-
-* Get joystick values
+* Get joystick values. Could move ldy up to just after ORCC, and then ldx #PIA0Base+1
+* then, for the 8 references to PIA0Base, use no offset/5 bit offset (saves 8 bytes,
+* and 3 cycles - hopefully that doesn't screw up joystick reads with jitter, etc.
 SSJOY    pshs  y,cc
          orcc  #IRQMask       mask interrupts
          lda   #$FF
@@ -808,29 +809,30 @@
 L0486    sta   R$A,x
          lda   >PIA0Base+3
          ora   #$08
-         ldy   R$X,x
+         leay  ,y 
          bne   L0494
          anda  #$F7
-L0494    sta   >PIA0Base+3
-         lda   >PIA0Base+1
+L0494    ldy   #PIA0Base+1    Point to PIA most used address in following routine
+         sta   2,y            PIA0Base+3
+         lda   ,y             PIA0Base+1
          anda  #$F7
          bsr   L04B3
-         std   R$X,x
-         lda   >PIA0Base+1
+         std   R$X,x          Save X coord of joystick
+         lda   ,y             PIA0Base+1
          ora   #$08
          bsr   L04B3
          pshs  d
          ldd   #63
          subd  ,s++
-         std   R$Y,x
+         std   R$Y,x          Save Y coord of joystick
          clrb
          puls  pc,y,cc
 
-L04B3    sta   >PIA0Base+1
+L04B3    sta   ,y             PIA0Base+1
          ldd   #$7F40
 L04C7    pshs  b
          sta   >PIA1Base
-         tst   >PIA0Base
+         tst   -1,y           PIA0Base
          bpl   L04D5
          adda  ,s+
 L04BC    lsrb
@@ -880,8 +882,8 @@
          clrb
 L050E    rts
 
-* This vector also gets called from Grfdrv
-* Entry: A = X coor, B = Y coor
+* This vector also gets called from Grfdrv via V.CnvVct
+* Entry: A = X coord, B = Y coord
 * Exit: Y=Base address of screen, X=ptr to byte on screen, A=pixel mask for specific pixel
 XY2Addr  pshs  y,d            save off regs
          ldb   <V.Mode,u      get video mode
@@ -889,23 +891,21 @@
          lsra                 else divide by 8
 L0517    lsra
          lsra
-         pshs  a              save on stack
+         pshs  a              save on stack (A=horizontal byte on line pixel will be on)
          ldb   #191           get max Y
          subb  2,s            subtract from Y on stack
          lda   #32            bytes per line
          mul
          addb  ,s+            add offset on stack
          adca  #$00
-* 6809/6309 - since we are going to pull X & Y off the stack anyways, use X here (byte shorter, cycle
-*  faster for both ldy and sty)
-         ldx   <V.SBAdd,u     get base address
-         leax  d,x            move D bytes into address
-         lda   ,s             pick up original X coor
+         ldx   <V.SBAdd,u     get base address of gfx screen
+         leax  d,x            Point to byte pixel will be drawing on
+         lda   ,s             pick up original X coord
          stx   ,s             put offset addr on stack
-         anda  <V.PixBt,u
-         ldx   <V.MTabl,u
-         lda   a,x
-         puls  pc,y,x         X = offset address, Y = base
+         anda  <V.PixBt,u     Just keep X pixel 0-7 (or 0-3)
+         ldx   <V.MTabl,u     Get ptr to pixel mask table (already set up for 4 or 8)
+         lda   a,x            Get mask for specific pixel we will be drawing
+         puls  pc,y,x         X = offset address, Y = base, A=pixel mask
 
 * SetStat
 *
@@ -957,7 +957,6 @@
          leay  2,y            else move to next entry
          inc   ,s             increment B on stack
          ldd   ,y             second entry empty?
-* 6809/6309 - change to bne BadMode2
          bne   L059E          if not, no room for more... error out
 L058E    lbsr  GetMem         allocate graphics buffer memory
          bcs   L05A1          branch if error
@@ -969,12 +968,8 @@
          clrb                 call is ok
          rts                  and return
 
-* 6809/6309 - after above change done, delete these 2 lines
 L059E    ldb   #E$BMode
          coma
-
-*6809/6309 - After above changes, move label L05A1 to just before BadMode label,
-* change line to puls a
 L05A1    puls  pc,a
 
 * Select a graphics buffer
@@ -1011,7 +1006,7 @@
          lda   #ModCoVDG      CoVDG is loaded bit
          ldx   #$2010         32x16
          pshs  u,y,x,a
-         leax  >CoVDG,pcr
+         leax  <CoVDG,pcr
          bsr   LoadCoModule
          puls  u,y,x,a
          bcs   L0600
@@ -1021,6 +1016,14 @@
          bne   NoError
          lbra  SetDsply
 
+* All co-modules except grfdrv
+
+CoVDG    fcs   /CoVDG/
+CoWP     fcs   /CoWP/
+CoHR     fcs   /CoHR/
+Co42     fcs   /Co42/
+CoVGA    fcs   /CoVGA/
+         
 GoCoWP   bita  #ModCoWP       CoWP needed ?
          beq   GOCo42         No, try next co-module
          stb   <V.CFlag,u     allow lowercase
@@ -1028,7 +1031,7 @@
          lda   #ModCoWP       'CoWP is loaded' bit
          ldx   #$5019         80x25 WordPark RS supports 25 lines
          pshs  u,y,x,a
-         leax  >CoWP,pcr
+         leax  <CoWP,pcr
 * 6809/6309 - Try embedding LoadCoModule since short and only called from here.
 * Entry: X=ptr to co-module name
 SetupCoModule
@@ -1047,7 +1050,7 @@
          lda   #ModCo42       'Co42 is loaded' bit
          ldx   #$2A18         42x24
          pshs  u,y,x,a
-         leax  >Co42,pcr
+         leax  <Co42,pcr
          bra   SetupCoModule
 
 GOCoHR   ldb   #$10
@@ -1056,7 +1059,7 @@
          lda   #ModCoHR       'CoHR is loaded' bit
          ldx   #$3318         51x24
          pshs  u,y,x,a
-         leax  >CoHR,pcr
+         leax  <CoHR,pcr
          bra   SetupCoModule
 
 LoadCoModule
@@ -1109,9 +1112,6 @@
          os9   F$Load
          puls  pc,u
 
-* 128x192 color mask table for 4 color modes
-Mode1Clr fcb   $00,$55,$aa,$ff
-
 GfxDispatch
          cmpa  #$15           GrfDrv-handled code?
          bhs   GoGrfo         Yep, pass code over to it
@@ -1120,17 +1120,10 @@
          suba  #$10
          bsr   GfxActv        check if first gfx screen was alloc'ed
          bcs   L0663          if not, return with error
-         leax  <gfxtbl,pcr    else point to jump table
-         lsla                 multiply by two
-         ldd   a,x            get address of routine
-         jmp   d,x            jump to it
+         leax  gfxtbl,pcr     else point to jump table
+         ldb   a,x            get address of routine
+         jmp   b,x            jump to it
 
-* Jump table for graphics codes $10-$14
-gfxtbl   fdb   Do10-gfxtbl    $10 - Preset Screen
-         fdb   Do11-gfxtbl    $11 - Set Color
-         fdb   Do12-gfxtbl    $12 - End Graphics
-         fdb   Do13-gfxtbl    $13 - Erase Graphics
-         fdb   Do14-gfxtbl    $14 - Home Graphics Cursor
 
 GfxActv  ldb   <V.Rdy,u       gfx screen allocated?
          bne   L0606          Yes, exit with no error
@@ -1143,14 +1136,16 @@
          ldx   <V.GrfDrvE,u   get GrfDrv entry point
          bne   L0681          branch if not zero
          pshs  y,a            else preserve regs
-         leax  >GrfDrv,pcr    get pointer to name string
+         leax  <GrfDrv,pcr    get pointer to name string
          bsr   LinkSub        link to GrfDrv
          bcc   L067B          branch if ok
-         leax  >GrfDrv,pcr    get pointer to name string
+         leax  <GrfDrv,pcr    get pointer to name string
          bsr   LoadSub
          bcc   L067B
          puls  pc,y,a         else exit with error
 
+GrfDrv   fcs   /GrfDrv/
+
 L067B    sty   <V.GrfDrvE,u   save module entry pointer
 L067F    puls  y,a            restore regs
 L0681    clra                 A = GrfDrv address offset in statics
@@ -1191,34 +1186,29 @@
 DispGfx  ldb   <V.Rdy,u       already allocated initial buffer?
          bne   L06D1          Yes, skip allocating
          bsr   GetMem         else get graphics memory
-* 6809/6309 - after below E$BMode is change to LBRA, change this to bcs L06B3
          bcs   L06B3          Couldn't get RAM; return with error
          std   <V.SBAdd,u     save ptr to graphics RAM
          std   <V.GBuff,u     And again
          inc   <V.Rdy,u       ok, we're ready
-         lbsr  EraseGfx       clear gfx mem
-L06D1    lda   <V.NChr2,u     get character after next
+         lbsr  Do13           clear gfx mem
+L06D1    lda   <V.NChr2,u     get 2nd parm (color set/foreground/background color selection)
          sta   <V.PMask,u     save color set (0-15)
          anda  #%00000011     mask out all but lower 2 bits
-         leax  >Mode1Clr,pcr  point to color mask table
+         leax  <Mode1Clr,pcr  point to color mask table
          lda   a,x            get byte
          sta   <V.Msk1,u      save mask byte here
          sta   <V.Msk2,u      and here
-         lda   <V.NChar,u     get next char, mode byte (0-1)
+         lda   <V.NChar,u     get 1st parm (gfx mode) mode byte (0-1)
          cmpa  #$01           compare against max
          bls   L06F0          branch if valid
          lbra  BadMode        else invalid mode specified, send error
 
-* 6809/6309 tsta redundant if we change beq L0710 to blo L0710 (lower than cmpa#1 above)
-L06F0    tsta                 test user supplied mode byte
-         beq   L0710          branch if 256x192
+L06F0    blo   L0710          branch if 256x192
 * NOTE: CHECK CO-MODULES; I DON'T SEE V.MCol or V.MCol+1 being used ANYWHERES in VTIO
          ldd   #$C003         4 color mode; Make pixel masks for start and end pixels in a byte  
          std   <V.MCol,u      Save them for re-use
-* 6809/6309 - change next 3 lines to: ldd #$E001 / stb <V.Mode,u
-         lda   #$01
-         sta   <V.Mode,u      128x192 mode
-         lda   #$E0
+         ldd   #$E001
+         stb   <V.Mode,u      128x192 4 color mode
          ldb   <V.NChr2,u
          andb  #$08
          beq   L0709
@@ -1235,22 +1225,26 @@
          sta   <V.Msk1,u
          sta   <V.Msk2,u
 L0723    sta   <V.Mode,u      256x192 mode
-* 6809/6309 - LDD #$F007
-         lda   #$F0
-         ldb   #$07           Base 0 # pixels in a byte
+         ldd   #$F007         ? & Base 0 # pixels in a byte
          leax  <L0746,pcr     Point to 2 color pixel masks table
 L072D    stb   <V.PixBt,u     Save base 0 # pixels in a byte
          stx   <V.MTabl,u     Save ptr to pixel mask table
          ldb   <V.NChr2,u
          andb  #$04
          lslb
-* 6309 - orr b,a replaces two lines
+       IFNE  H6309
+         orr   b,a
+       ELSE
          pshs  b
          ora   ,s+
+       ENDC
          ldb   #$01
 * Indicate screen is current
          lbra  SetDsply
 
+* 128x192 color mask table for 4 color modes
+Mode1Clr fcb   $00,$55,$aa,$ff
+
 * 4 color pixel masks
 L0742    fcb   $c0,$30,$0c,$03
 
@@ -1267,10 +1261,15 @@
          inc   <V.NChar,u
 L075F    lbra  L06D1
 
-* $12 - end graphics
+* $12 - end graphics. This needs to be modified to properly handle CoHR/Co42 co-modules;
+* since they *replace* the original alpha mode, they should never be de-allocated. Only
+* extra pages should be de-allocated.
 Do12     leax  <V.GBuff,u     point to first buffer
-* 6309 - TFR 0,y (same speed, 2 bytes smaller)
+       IFNE  H6309
+         tfr   0,y            Same speed/2 bytes smaller on 6309
+       ELSE
          ldy   #0             Y = 0
+       ENDC
          ldb   #3             free 3 gfx screens max
          pshs  u,b
 L076D    ldd   #6144          size of graphics screen
@@ -1289,50 +1288,46 @@
          sta   <V.Rdy,u       gfx mem no longer allocated
          lbra  SetDsply
 
+* Jump table for graphics codes $10-$14
+gfxtbl   fcb   Do10-gfxtbl    $10 - Preset Screen
+         fcb   Do11-gfxtbl    $11 - Set Color
+         fcb   Do12-gfxtbl    $12 - End Graphics
+         fcb   Do13-gfxtbl    $13 - Erase Graphics
+         fcb   Do14-gfxtbl    $14 - Home Graphics Cursor
+
 Do10     leax  <Preset,pcr set up return address
          lbra  L03BD
 
-* NOTE! Shouldn't this be lda <V.NChar,u ??
-Preset   lda   <V.NChr2,u     get next char
+Preset   lda   <V.NChr2,u     get param byte
          tst   <V.Mode,u      which mode?
          bpl   L07A7          branch if 128x192 4 color
          ldb   #$FF           assume we will clear with $FF
          anda  #$01           mask out all but 1 bit (2 colors)
-         beq   EraseGfx       erase graphic screen with color $00
+         beq   Do13           erase graphic screen with color $00
          bra   L07B2          else erase screen with color $FF
 
 L07A7    anda  #$03           mask out all but 2 bits (4 colors)
-         leax  >Mode1Clr,pcr  point to color table
+         leax  <Mode1Clr,pcr  point to color table
          ldb   a,x            get appropriate byte
          bra   L07B2          and start the clearing
 
-* Erase graphics screen. Change to mini stack blast for 6809, TFM for 6309
-* NOTE: Make a vector, so that all the various co-modules (including grfdrv)
-* can share this, and make more entry parameters (color mask, start addr of
-* clear, and size). V.ClrBlk or something like that will need to be added
-* to cocovtio.d
+* Erase graphics screen. Changed to use new V.ClrBlk vector (mini stack blast
+* for 6809, TFM for 6309)
 * Long term - make a system call for this, so that all system modules (and
 * even user programs) can use it. Mini-stack blast for 6809, tfm for 6309)
 * This would clear a contiguous chunk of RAM (in 4 byte chunks only).
-* NOTE: FOLLOWING CODE IS FOR TESTING CONCEPT AND SPEED. IF IT WORKS, WE WILL
-* MAKE IT MORE GENERIC (CURRENTLY HARDCODED FOR 6K SCREENS ONLY) AND MAKE IT
-* A VECTOR THAT CAN BE CALLED FROM VTIO,CO***, AND GRFDRV)
-Do13
-EraseGfx clrb                 Color 0 to clear with
-L07B2    pshs  y,x,u          Save regs
-         tfr b,a              Dupe color to D
-         tfr d,x              Move to X&Y
-         leay ,x
-         ldu  <V.SBAdd,u      Get base address for screen
-         leau >6144,u         Point to end of screen+1
-         ldd  #$0600          6 blocks of 256 (how many 4 byte chunks to clear)
-InCLSLp  pshu x,y             4 bytes cleared
-         decb
-         bne  InCLSLp         Not done 256*4 (1k) bytes
-         deca                 Dec 1K blocks ctr
-         bne  InCLSLp         Do till done
-         puls x,y,u           Restore regs
-
+* Entry for clearing with color 0
+Do13     clrb                 Color 0 to clear with
+* Entry for clearing with color in B
+L07B2    pshs  b,u            Save color code & static mem ptr
+         ldy   >V.ClrBlk,u    Get ptr to ClrBlk routine
+         ldd   #6144          Size of gfx screen to clear
+         addd  <V.SBAdd,u     Add size to ptr to start of screen
+         tfr   d,u            U=ptr to end of screen+1
+         ldx   #6144          Size to clear into register for vector
+         puls  b              Get color code back
+         jsr   ,y             Call ClrBlk vector
+         puls  u              Get back static mem ptr
 * Home Graphics cursor
 Do14     clra
          clrb
@@ -1341,21 +1336,27 @@
 
 *
 * Ding - tickle CoCo's PIA to emit a sound
-*
-Ding     pshs  d
-         lda   >PIA0Base+1
-         ldb   >PIA0Base+3
+* 6809/6309 - preserve X as well, and then ldx #PIA0Base+3 and used ,x offsets
+* NOTE: This is much more sophisticated than the Dragon version. Not sure if
+* it has to be. (See DoBell in CoHR/Co42)
+Ding     pshs  d,x
+         ldx   #PIA0Base+3    Point to most common address we will be using
+         lda   -2,x           >PIA0Base+1
+         ldb   ,x             >PIA0Base+3
          pshs  d
-* 6309 - ANDD #$F7F7
+       IFNE  H6309
+         andd  #$F7F7
+       ELSE
          anda  #$F7
          andb  #$F7
-         sta   >PIA0Base+1
-         stb   >PIA0Base+3
+       ENDC
+         sta   -2,x           >PIA0Base+1
+         stb   ,x             >PIA0Base+3
          lda   >PIA1Base+3
          pshs  a
          ora   #$08
          sta   >PIA1Base+3
-         ldb   #$0A
+         ldb   #10            Outside loop ctr
 L07E6    lda   #$FE
          bsr   DingDuration
          lda   #$02
@@ -1365,9 +1366,9 @@
          puls  a
          sta   >PIA1Base+3
          puls  d
-         sta   >PIA0Base+1
-         stb   >PIA0Base+3
-         puls  pc,d
+         sta   -2,x           >PIA0Base+1
+         stb   ,x             >PIA0Base+3
+         puls  pc,x,d
 
 DingDuration
          sta   >PIA1Base
@@ -1376,6 +1377,93 @@
          bne   L0805
          rts
 
+* Since these are called by a JSR vector, they doesn't need to be near anything, so put
+* both ClrBlk & CpyBlk at end of VTIO, and set up vectors to them in VTIO Init routine
+
+* ClrBlk - Clear contiguous block of memory with a byte value (grfdrv level II text mode
+* patches will need 16 bit word value to cover attribute/character bytes)
+* HOPEFULLY OPTIMIZED SMALLER FOR 6809 03/12/2018 LCB
+* Entry: B=byte value to clear with
+*        X=size
+*        U=ptr to end+1 of memory to clear up to
+*  Exit: U=Ptr to start of block of memory cleared (if 6809) OR
+*          Ptr to end of block of memory cleared (if 6309)
+*        NOTE that D and X are destroyed in 6809 version
+* Will need to check all calling routines from various modules, to see which of above
+*  should be default (if ptr is needed), and adjust the other to match
+* ClrBlk (aside from set up and/or leftover bytes) takes 3 cyc/byte in 6309 mode, and
+*   3.5 cyc/byte in 6809 mode (except every 1,024th byte takes a few extra)
+* Since these are called by a JSR vector, they doesn't need to be near anything, so put
+* both ClrBlk & CpyBlk at end of VTIO, and set up vectors to them in VTIO Init routine
+ClrBlk
+       IFNE  H6309
+         pshs  b              Save value to clear with
+         tfr   x,w            Move size to TFM size register
+         subr  w,u            Calc start ptr of block (TFM can't do 1 location to decrementing address)
+         tfm   s,u+           Clear mem
+         puls  b,pc           Eat stack & return
+       ELSE
+         tfr   b,a            D=double copy of value to clear memory with
+         exg   x,d            D=Size to clear (in bytes), X=2 byte value to clear with
+         pshs  b,x            Save 16 bit value to clear with, & LSB of size (to check for leftover bytes)
+         lsra                 Divide size by 4 (since we are doing 4 bytes at a time)
+         rorb
+         lsra
+         rorb
+         pshs  d              Save mini-stackblast counters
+         ldd   2,s            Get A=LSB of # of bytes to clear, B=byte to clear with
+         anda  #$3            Non-even multiple of 4?
+         beq   NoOdd          Even, skip single byte cleanup copy
+OverLp   stb   ,-u            Save odd bytes
+         deca
+         bne   OverLp
+NoOdd    ldd   ,s++           Get Mini-stack blast ctrs back
+         beq   ExitClrB       No 4 byte blocks, done
+         tsta                 Special case: Is A=0?
+         bne   NormClr        No, start stack blasting
+         inca                 If A=0, bump to 1 so we don't wrap and try to do 256 1K copies
+NormClr  leay  ,x             Dupe 16 bit clear value to Y
+ClrLp    pshu  x,y            Clear 4 bytes
+         decb                 Dec "leftover" (<256) 4 byte block counter
+         bne   ClrLp          Keep doing till that chunk is done
+         deca                 Dec 1Kbyte counter
+         bne   ClrLp          Still going (B has been set to 0, so inner loop is 256 now)
+ExitClrB puls  b,x,pc         Eat temp regs & return
+       ENDC
+       
+* CpyBlk - Copy contiguous block of memory with a byte value (for screen scrolling, insert/delete line,etc.)
+* New, more optimized version (I hope) as of March 12, 2018
+* Entry: D=size of copy
+*        Y=ptr to destination of copy
+*        U=ptr to source of copy (PULU from here on 6809 version)
+*  Exit: U=Ptr to end of source copy+1
+*        Y=Ptr to end of dest copy+1
+*        D=NOTE: NEW CODE WILL HAVE D AS END ADDRESS OF SOURCE OF COPY
+* NOTE: No routines in VTIO use this call - it will be called from sub-modules. Putting it in here
+* since VTIO always gets initialized first.
+       IFNE  H6309
+CpyBlk   tfr   d,w            Copy size to TFM size register
+         tfm   u+,y+          Copy memory
+         rts
+       ELSE
+CpyBlk   leax  d,u            Calculate source end address
+         pshs  x              Save on stack to compare with so we know when to stop
+         andb  #$03           Check if we have odd bytes leftover (1-3)
+         beq   CpyLpSt        No, skip to check if copy is done, and stack blast 4 byte chunks if yes
+CpyLp2   lda   ,u+            (6) Copy extra 1-3 bytes
+         sta   ,y+            (6)
+         decb                 (2)
+         bne   CpyLp2         (3)
+         bra   CpyLpSt        Start with cmpu to end of copy (if copy was only 1-3 bytes, we are done already)
+         
+* Now, copy all 4 byte chunks. End address remains the same, so we can eliminate some stuff we had before
+CpyLp    pulu  d,x            Get 4 bytes from source (ascending order)
+         std   ,y++           Copy to destination
+         stx   ,y++
+CpyLpSt  cmpu  ,s             Done 4 byte blast copy?
+         blo   CpyLp          No, keep doing until done
+         puls  pc,d           Get end address of source copy and return
+       ENDC
          emod
 eom      equ   *
          end