view level1/modules/covdg.asm @ 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 (2018-03-13)
parents fd4c50256e05
children 13737f3608e6
line wrap: on
line source
********************************************************************
* CoVDG - VDG Console Output Subroutine for VTIO
*
* $Id$
*
* Edt/Rev  YYYY/MM/DD  Modified by
* Comment
* ------------------------------------------------------------------
*   1      ????/??/??
* From Tandy OS-9 Level One VR 02.00.00
*
*          2003/09/22  Rodney Hamilton
* recoded dispatch table fcbs, fixed cursor color bug
*
*          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

* Disassembled 98/08/23 17:47:40 by Disasm v1.6 (C) 1988 by RML

         ifp1
         use   defsfile
         use   cocovtio.d
         endc

tylg     set   Systm+Objct   
atrv     set   ReEnt+rev
rev      set   $00
edition  set   2

         mod   eom,name,tylg,atrv,start,size

		 IFNE  COCOVGA
COLSIZE  equ   64
ROWSIZE  equ   32
MODFLAG  equ   ModCoVGA
		 ELSE
COLSIZE  equ   32
ROWSIZE  equ   16
MODFLAG  equ   ModCoVDG
		 ENDC

u0000    rmb   0
size     equ   .
         fcb   $07 

name     equ   *
		IFNE	COVGA
         fcs   /CoVGA/
		ELSE
         fcs   /CoVDG/
		ENDC
         fcb   edition

* Init
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
         pshs  y
         leay  -$0E,y
         clra  
         clrb  
         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 ??

     IFNE	COCOVGA
***** START OF COCOVGA 64x32 MODE
         clr   <V.Caps,u      lowercase mode
         pshs  cc,u
         orcc  #IntMasks
         leax  VGASetup,pcr
         ldu   <V.CrsrA,u
         ldb   #VGASetupLen
x@       lda   ,x+
         sta   ,u+
         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

* 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
* 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@

* Restore PIA state and return to text mode - restore original video mode, SAM page
* VDG -> CG2:
         lda   $FF22
         anda  #$8F
         ora   #$A0
         sta   $FF22

* SAM -> CG2:
         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
* Setup page to
         ldb   <V.COLoad,u
         orb   #ModCoVDG      set to CoVDG found (?)
L0086    stb   <V.COLoad,u
         clrb  
         puls  pc,y,x

     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
VGASetupLen equ *-VGASetup
***** END OF COCOVGA 64x32 MODE         
     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                 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

* 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    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   

* 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  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?
         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  -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  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

* $0C - clear screen
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     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     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    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

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

* $02 XX YY - move cursor to col XX-32, row YY-32
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       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     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 to D
         andb  #COLSIZE-1     number of characters put on this line
         pshs  b
         ldb   #COLSIZE       Calculate # of chars left in line
         subb  ,s+
         bra   L0223          and clear that many

* $03 - erase line
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     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                 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

* 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
         bra   SaveA

* SS.Cursr getstat
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  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                 By 64 is CocoVGA (64x32)
       ENDC
         clra  
         andb  #ROWSIZE-1     lines on the screen
         addb  #COLSIZE
         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           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           Switch to uppercase
         bra   SaveA

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           Replace with ASCII tilde
SaveA    sta   R$A,x
         clrb  
         rts   

         emod
eom      equ   *
         end