;*********************************************************************
;* Title: code-vdgsg4-v00.asm
;*********************************************************************
;* Author: R. Allen Murphey
;*
;* License: Copyright (c) 2020-2022 R. Allen Murphey. All Rights Reserved.
;*
;* Description: Setup CoCo 1/2 VDG SG4 Screen
;*
;* Documentation:
;* VIDRAM:     equ   $0400       ; START OF SCREEN MEM
;* ENDVID:     equ   $0600       ; END OF SCREEN MEM
;*
;* Include Files: PIA, SAM
;*
;* Assembler: lwasm 1.4.2
;*
;* Revision History:
;* Rev #     Date      Who     Comments
;* -----  -----------  ------  ---------------------------------------
;* 00     2020-2021    RAM     Created
;*********************************************************************

SG4:
            ldx   $FFFE       ; check reset vector
            cmpx  #$A027      ; CoCo 1/2 reset vector
            beq   SG4010      ; It's CoCo 1/2, go straight there

            lda   ACVCINIT0   ; get current ACVC configuration
            ora   #%10000000  ; force CoCo 1/2 bit 7 on
            sta   ACVCINIT0   ; get ACVC INIT0 register setup
            lda   #%00000110  ; configure video mode register
            sta   ACVCVIDM    ; configure 12 lines per row
            lda   #%00000001  ; -,00=LPF 192,000=HRES32,01=CRES32
            sta   ACVCVIDR    ; Configure LPF,HRES,CRES
            ldd   #$E080      ; setup memory location for $0400 VIDRAM
            std   ACVCVOFF1   ; store MSB/LSB to offset register
            lda   #$0F        ; initialize vertical scroll for coco1/2
            sta   ACVCVSCRL   ; store in ACVC vertical scroll register

SG4010:                       ; Setup for drawing on 32x16x9 alpha/semigraphics 4
            pshs  A,X,CC      ; SAVE MODIFIED REGISTERS ON STACK
            lda   #1          ; Arbitrary video driver #1
            sta   VIDDRV      ; Save this for use elsewhere for which screen we're on
            ldx   #$0400      ; We are going to drop .5K screen here
            stx   VIDRAM      ; Our video RAM base address
            ldx   #$0600      ; The screen is going to be .5K
            stx   ENDVID      ; The ending video address
            ldx   #SG4        ; Now we start loading pointers to SG4 functions
            stx   IINIT       ; Address of this SG4 label goes in IINIT
            ldx   #SG4CLR     ; Address of SG4 clear screen ...
            stx   ICLEAR      ; Goes in ICLEAR
            ldx   #SG4DRAWCH  ; Address of SG4-specific draw character function ...
            stx   IDRAWCH     ; Goes in IDRAWCH
            ldx   #SG4SCREEN  ; Address of SG4-specific screen paint/refresh ...
            stx   ISCREEN     ; Goes in ISCREEN

            lda   #%00000000  ; SETUP FOR SG4 ALPHANUMERIC/SEMIGRAPHIC SCREEN IN VDG
            sta   PIA1BD      ; SET VDG MODE IN PIA1 DATA PORT B $FF22

                              ; SET VDG MODE IN SAM  %000=AI
            sta   SAMCV0      ; SAM CLR VDG V0 $FFC0
            sta   SAMCV1      ; SAM CLR VDG V1 $FFC2
            sta   SAMCV2      ; SAM CLR VDG V2 $FFC4

                              ; SETUP VDG SCREEN OFFSET  %0000010=$0400
            sta   SAMCF0      ; SAM CLR VDG F0 $FFC6
            sta   SAMSF1      ; SAM SET VDG F1 $FFC9
            sta   SAMCF2      ; SAM CLR VDG F2 $FFCA
            sta   SAMCF3      ; SAM CLR VDG F3 $FFCC
            sta   SAMCF4      ; SAM CLR VDG F4 $FFCE
            sta   SAMCF5      ; SAM CLR VDG F5 $FFD0
            sta   SAMCF6      ; SAM CLR VDG F6 $FFD2

            puls  A,X,CC,PC   ; LOAD AND RESTORE MODIFIED REGISTERS

;*********************************************************************
;* SG4CLR
;*
;* Entry Values
;*
;* Exit Values
;*          None
;* Control Register Modifications
;*          None
;* Subroutines Called
;*          None
;*********************************************************************

SG4CLR:
            pshs  X,D,CC      ; SAVE REGISTERS ON STACK
            ldx   VIDRAM      ; START OF CLEAR SCREEN ROUTINE
            ldd   #$6060      ; TWO SPACES IN A ROW
CLRSPC:
            std   ,X++        ; STORE TWO SPACES AT ONCE
            cmpx  ENDVID      ; CHECK END OF SCREEN RAM
            bne   CLRSPC      ; NOPE, KEEP LOOPIN
            puls  X,D,CC,PC   ; LOAD REGISTERS FROM STACK AND RETURN

;*********************************************************************
;* SG4DRAWCH
;* DRAW TEXT TO SG4 - SWITCH CHAR TO UPPERCASE IF NEEDED
;*
;* Entry Values
;* SCRNPTR = OFFSET TO SCREEN MEMORY FOR CHARACTER
;* VIDRAM:     equ   $0400       ; START OF SCREEN MEM
;* ENDVID:     equ   $0600       ; END OF SCREEN MEM
;* COUNT:      rmb   1           ; COUNT FROM 0 TO 255
;* SX:         rmb   1           ; SCREEN X COLUMN TO DRAW ON 0-31
;* SY:         rmb   1           ; SCREEN Y ROW TO DRAW ON 0-15
;* ROW:        rmb   1           ; CHARACTER BITMAP ROW TO DRAW
;* OFFSET:     rmb   2           ; SCREEN RAM OFFSET
;*
;* Exit Values
;*          None
;* Control Register Modifications
;*          None
;* Subroutines Called
;*          None
;*********************************************************************

SG4DRAWCH:
            pshs  A,B,Y,CC    ; SAVE REGISTERS FOR RESTORE AT END OF FUNCTION
            pshs  B           ; SAVE B SPECIALLY SO WE CAN USE THEN RESTORE IT
            lda   #$20        ; ROWS ARE 32 BYTES WIDE
            ldb   TY          ; GET THE TILE ROW
            mul               ; MUL A*B (THE ROW)
            addb  TX          ; NOW ADD X OFFSET
            addd  VIDRAM      ; NOW ADD VIDEO OFFSET
            std   SCRNPTR     ; SAVE THE RESULT
            tfr   D,Y         ; LOAD CALCULATED OFFSET INTO Y
            
            puls  B           ; GET BACK OUR SAVED CHARACTER TO DRAW AND START DRAWING
            cmpb  #$80        ; IS THIS GRAPHICS?
            bpl   SG4DRAWCH10 ; YES
            cmpb  #$20        ; IS THIS LOWERCASE?
            bpl   SG4DRAWCH10 ; NO
            addb  #$40        ; YES, UPPERCASE IT
SG4DRAWCH10:
            stb   ,Y          ; AND WRITE IT OUT TO ADDRESS Y
            puls  A,B,Y,CC,PC  ; RESTORE REGISTERS AND RETURN

;*********************************************************************
;* SG4SCREEN
;* DRAW AN SG4 TILE SCREEN TILES 0 TO 511
;*
;* Entry Values
;*
;* Exit Values
;*          None
;* Control Register Modifications
;*          None
;* Subroutines Called
;*          None
;*********************************************************************

; FIXME USES FIXED FOREGROUND/BACKGROUND PALETTE SLOTS ON COCO3

SG4SCREEN:
            pshs  A,B,X,CC    ; SAVE ALL THE REGISTERS WE SMASH
            ldd   #$040C      ; PICK DEFAULT PALETTE SLOTS FOR FORE/BACK
            sta   CLRFORE     ; SETUP DEFAULT FOREGROUN
            stb   CLRBACK     ; SETUP DEFAULT BACKGROUND
            clra              ; ZERO A TO CLEAR HALF OF D
            clrb              ; ZERO B TO CLEAR HALF OF D
            std   COUNTER     ; ZERO OUT OUR COUNTER FOR 0-511 TILES DRAWN
            std   SCRNPTR     ; ZERO OUT OUR SCREEN MEMORY POINTER
            sta   ROW         ; ZERO OUT THE ROW COUNTER
            sta   TX          ; ZERO OUT THE TILE X
            sta   TY          ; ZERO OUT THE TILE Y
            tfr   D,X         ; ZERO OUT OUR INDEX TOO

SG4ALOOP:
            ldb   [MAPPTR]    ; LOAD THE CHARACTER TO DRAW FROM TILE MAP
            jsr   SG4DRAWCH   ; DRAW IT
        
            inc   TX          ; MOVE RIGHT ONE TILE
            lda   TX          ; GET NEW TILE COLUMN
            cmpa  #$20        ; ARE WE AT THE END OF A ROW OF TILES?
            bne   SG4BLOOP    ; NO, KEEP GOING
            clr   TX          ; YES, CLEAR X POSITION TO START OF LINE
            lda   TY          ; GET CURRENT ROW
           ;adda  #12         ; ADD A TILE HEIGHT
            adda  #1          ; ADD A ROW
            sta   TY          ; SAVE AS NEW ROW

SG4BLOOP:
            ldd   MAPPTR      ; MOVE CHARACTER CURSOR POSITION ...
            addd  #$01        ; TO NEXT CHARACTER TILE TO DRAW AND ...
            std   MAPPTR      ; SAVE IT
            ldd   COUNTER     ; MOVE SCREEN COUNTER POSITION ...
            addd  #$01        ; TO NEXT SCREEN LOCATION TO DRAW AND ...
            std   COUNTER     ; SAVE IT
            ldd   COUNTER     ; CHECK TO SEE IF SCREEN COUNTER ...
            cmpd  #512        ; IS AT THE END OF THE SCREEN
            bne   SG4ALOOP    ; NOPE, GO BACK AND DRAW MORE
            puls  A,B,X,CC,PC ; YEP, CLEAN UP REGISTERS AND RETURN

;*********************************************************************
;* End of code-vdgsg4-v00.asm
;*********************************************************************