 P********************************
*                              *
*            HIRES             *
*                              *
* High resolution plotting and *
* line drawing routines for    *
* the C 128.                   *
*------------------------------*
*     All rights reserved!     *
*------------------------------*
*   Glen E. Bredon  10/28/85   *
*                              *
*    (Merlin 128 assembler)    *
*                              *
********************************

* Example Merlin source file.

* These are very fast routines (about 4 times the
* speed of the built in ones).  Assembly programs
* should access only the jump table and the list
* of defaults at the beginning of this utility.
*
* The routines include XPLOTing (EOR) as well as
* the usual overstrike mode.

          EXP OFF
          TR

* Hires temps (put in FAC & ARG):

DXL       = $61           ;Delta x low
DXH       = $62           ;Delta x high
DY        = $63           ;Delta y
EL        = $64           ;Epsilon low
EH        = $65           ;Epsilon high
DIRECTN   = $66           ;Direction of movement
HNDX      = $69           ;Horiz index (mod 8)
VNDX      = $6A           ;Vert index (mod 8)
COUNTL    = $6B           ;Dot countdown low
COUNTH    = $6C           ;Dot countdown high

BANK      = 2             ;BASIC bank
GRAPHM    = $D8           ;C128 text/graphics flag

BORDER    = $D020
BACKGND   = $D021
CHROUT    = $FFD2

* Hires permanents:

BASL      = $C3           ;Base adrs of 8 vert bytes
BASH      = BASL+1

          AST 50

MOVD      MAC
          LDA ]1
          STA ]2
          LDA ]1+1
          STA ]2+1
          <<<

PLOT      MAC             ;This must preserve carry
          LDA XFLG
          BMI AC
          LDA (BASL),Y
          EOR HCOLOR
AC        EOR XMASK
          AND MASK,X
          EOR (BASL),Y
          STA (BASL),Y
          <<<

          AST 50

          ORG $1300

          DS 3,$EA        ;Reserved entry
          JMP EXIT        ;Go back to basic warm
          JMP GR          ;Multi color hires init
          JMP HGR         ;Full hires init & clear
          JMP TEXT        ;Set text mode
          JMP HPLOT       ;Plot a point
          JMP XPLOT       ;Xplot a point
          JMP HLINE       ;Plot a line
          JMP COLOR       ;Set colors
          JMP DOTMASK     ;Set dot mask %00-%11

SCRMASK   HEX F0          ;Screen color
                          ; In full hires:
                          ;  low nib = color of off bit
                          ;  hig nib = color of on bit
                          ; In multicolor:
                          ;  low nib = color of %10
                          ;  hig nib = color of %01

MULMASK   HEX 03          ;Color memory (full hires)
                          ;In multi = color of %11

BORD      HEX 00          ;Border color (low nib)
                          ;In multi, high nib =
                          ; color of %00

HCOLOR    DFB $FF         ;In full hires:
                          ; $00 = turn dot off
                          ; $FF = turn dot on
                          ;In multicolor:
                          ; Repeated bit pairs with
                          ; desired color 00,01,10,11

X0L       DFB 0           ;Last plot X low
X0H       DFB 0           ; and high
Y0        DFB 0           ;Last plot Y
BASAV     DA $2000        ;Save for base ptr
XFLG      DFB 0           ;XPLOT flag (if -)
MMODE     DFB $FF         ;Minus for multi color
XMASK     DFB 0

          ASC ' Copyright 1985 by Glen Bredon '

EXIT      JSR TEXT
          LDA #0
          STA $FF00
          LDA #15
          STA BANK
          JMP $4003

TEXT      LDA #0
          STA GRAPHM      ;Set text mode
          LDA #$93        ;Send CLR
          JMP CHROUT

COLOR     STX SCRMASK
          STY BORD
          TAY
          LDA $FF00       ;Save mem config
          PHA
          LDA #0          ; and bank in I/O
          STA $FF00
          TYA             ;Retrieve A
          LDY BORD        ;Retrieve Y
          BIT MMODE
          BMI :ISM        ;Branch if multi mode
          TAX             ;In full hires use 0 or $FF
          BMI :WHITE
          LDA #0
          BEQ :SETCOL
:WHITE    LDA #-1
:SETCOL   STA HCOLOR
          JMP DOBACK

:ISM      TAX             ;Save color1
          LUP 4
          LSR
          --^
          STA MULMASK     ;High nib = color mem
          TYA             ;Get color3
          LUP 4
          LSR
          --^
          STA BACKGND     ;High nib = bckgnd
          TXA             ;Color1 back
          AND #%11        ;Isolate color designator
          TAX
          LDA CTBL,X      ;Get proper HCOLOR mask
          JMP :SETCOL

GR        SEC             ;Full hires
          BCC *
          DS -1
HGR       CLC             ;Multicolor hires
          LDA #0
          LDX #$A0
          ROR MMODE       ;Set/clr multicolor flag
          BMI :ISM
          LDA #4
          LDX #$20
:ISM      STA RTBL+3
          STX GRAPHM
          LDX #$20
          STX BASH
          LDA $FF00       ;Save memory config
          PHA
          LDA #0
          STA $FF00       ;Set ROM & I/O
          STA BASL
          TAY
:CL       STA (BASL),Y    ;Clear hires screen
          INY
          BNE :CL
          INC BASH
          DEX
          BNE :CL
DOBACK    LDX #$1C
          STX BASH
          LDX #4
          LDY #0
          STY BASL
          LDA SCRMASK
:RCL      STA (BASL),Y    ;Set color matrix 1 to SCRMASK
          INY
          BNE :RCL
          INC BASH
          DEX
          BNE :RCL
          JSR SETMASK     ;Set up correct mask tabla
          BIT MMODE
          BPL :SETB       ;Branch if full hires
          LDA #$D8
          STA BASH
          LDY #0
          STY BASL
          LDA 1
          PHA
          AND #$FE        ;Enable access to matrix 2
          STA 1
          LDX #4
          LDA MULMASK
:SCL      STA (BASL),Y    ;Set color matrix 2 to MULMASK
          INY
          BNE :SCL
          INC BASH
          DEX
          BNE :SCL
          PLA
          STA 1           ;Fix port
:SETB     LDA BORD
          STA BORDER      ;Set border to current value
          PLA
          STA $FF00       ;Reset mem config as it was
          RTS

DOTMASK   LDA CTBL,X      ;Assumes X = 0-3 (color source)
          STA HCOLOR
          RTS

*-----------------------------
* Entry conditions for HPLOT:
*
* A = Y COOR, X=XL, Y = XH

XPLOT     SEC
          BCC *
          DS -1
HPLOT     CLC
          ROR XFLG        ;Set X mode for ML entry
          STY X0H         ;Save dot pos for line
          STX X0L
          EOR #$FF
          CLC             ;Reflect vertically
          ADC #200
          STA Y0
          LSR
          LSR
          LSR             ;Y/8
          TAX
          LDA BASTBLL,X
          CLC
          ADC X0L
          AND #%11111000
          STA BASL        ;Address of (vertical)
          LDA BASTBLH,X   ; 8 byte segment of screen
          ADC X0H
          STA BASH
          LDY #0
          TYA
          BIT XFLG
          BPL :SX
          DEY
          LDA HCOLOR
          EOR #$FF
:SX       STY XFLG
          STA XMASK
          LDA Y0
          AND #7
          TAY             ;Y has Y0 (mod 8)
          LDA X0L
          AND #7          ;X has X0 (mod 8)
          BIT MMODE       ; in full hires
          BPL :TX
          LSR X0H         ; (mod 4) in multi
          ROR X0L         ;Divide X0 by 2 in multi
          LSR
:TX       TAX
          PLOT
          MOVD BASL       ;BASAV ;Keep for line plot
          RTS

*-----------------------------------
* Entry conditions for HLINE:
*
* A = XL, X = XH, Y = Y coor
*
* (Based on algorithm of S. Wozniak)

HLINE     PHA             ;Save Xcoor low
          LDA X0L
          AND #7
          STA HNDX        ;For picking up correct X
          BIT MMODE
          BPL :LY0        ;Branch if not multicolor
          AND #3
          STA HNDX
          TXA             ;Divide x coor by 2
          LSR             ; in multi color mode
          TAX
          PLA
          ROR
          PHA             ;Xcoor low
:LY0      LDA Y0
          AND #7
          STA VNDX        ;For picking up correct Y
          PLA             ;Get X coor low
          PHA
          SEC
          SBC X0L         ;X distance
          PHA
          TXA
          SBC X0H         ;Now sign gives X direction
          STA DIRECTN     ; will rotate to V bit
          BCS :HL2        ;Branch if X => X0
          PLA
          EOR #$FF
          ADC #1
          PHA             ;Abs (X-X0)
          LDA #0
          SBC DIRECTN
:HL2      STA DXH
          STA EH
          PLA
          STA DXL         ;E = Abs(X-X0) = delta X
          STA EL
          PLA
          STA X0L         ;Set next start point
          STX X0H
          TYA
          EOR #$FF        ;Convert so Y=0 is bottom of
          CLC             ; screen.
          ADC #200
          TAY
          CLC
          SBC Y0          ;Calculate -delta Y - 1
          BCC :HL3        ; where delta Y = Abs(Y-Y0)
          EOR #-1
          ADC #-2
:HL3      STA DY
          STY Y0
          ROR DIRECTN     ;S bit = Y direction, V = X
          SEC
          SBC DXL
          STA COUNTL      ;Count = -(delta X + delta Y)-1
          LDA #-1         ; counts up # of dots to plot
          SBC DXH
          STA COUNTH
          MOVD BASAV      ;BASL
          SBC #$40        ;Safety check
          CMP #$E0
          BLT :ABORT      ;Abort if not on screen
          LDY VNDX        ;Get index in 8 byte chunk
          LDX HNDX        ; and bit index in byte
          BCS :FRST       ;Always taken
:MOVEX    BVC :RIGHT
          DEX             ;Left one dot
          BPL :DOPLOT     ;Ok if same byte
          LDA BASL        ;Else point to byte on left
          SBC #8          ;Carry is set
          STA BASL
          BCS :NC
          DEC BASH
:NC       LDA RTBL+3      ;Point to rightmost dot in byte
          ORA #3
          TAX
          BNE :DOPLOT     ;Always taken

:ABORT    RTS

:RIGHT    LDA RTBL,X      ;Move right one dot
          TAX
          BNE :DOPLOT     ;Branch if in same byte
          LDA BASL        ;Else point to next byte
          ADC #7          ;Carry is set
          STA BASL
          BCC :DOPLOT
          INC BASH
:DOPLOT   PLOT            ;Plot the dot
          SEC
:FRST     LDA EL          ;Update the count
          ADC DY
          STA EL
          LDA EH
          ADC #$FF
:HCOUNT   STA EH
          INC COUNTL
          BEQ :INCNTH
:BQ       BIT DIRECTN
          BCS :MOVEX
          BMI :DOWN
          DEY             ;Move up
          BPL :DP         ;Branch if same 8 bytes
          SEC             ;Else correct base adrs
          LDA BASL
          SBC #320
          STA BASL
          LDA BASH
          SBC #>320
          STA BASH
          CLC
          LDY #7          ;Point to 8th byte
          BNE :DP
:DOWN     INY             ;Move down
          CPY #8
          BLT :DP         ;Branch if same 8 bytes
          CLC             ;Else correct base adrs
          LDA BASL
          ADC #320
          STA BASL
          LDA BASH
          ADC #>320
          STA BASH
          LDY #0          ;1st byte of 8
:DP       PLOT            ;Plot the dot
          LDA EL          ;Update count
          ADC DXL         ;Carry is clear
          STA EL
          LDA EH
          ADC DXH
          BVC :HCOUNT     ;Always
:INCNTH   INC COUNTH
          BNE :BQ         ;Loop till done
          MOVD BASL       ;BASAV ;Save for next line
          RTS

SETMASK   LDX #3
          LDY #3          ;Use 1st 4 bytes of HMASK
          BIT MMODE
          BPL :SM         ;Branch if not multicolor
          LDY #7          ;No, use last 4 bytes
:SM       LDA HMASK,Y
          STA MASK,X
          DEY
          DEX
          BPL :SM
          RTS

HMASK     DFB %10000000
          DFB %01000000
          DFB %00100000
          DFB %00010000

          DFB %11000000
          DFB %00110000
          DFB %00001100
          DFB %00000011

BASTBLL  
          LUP 6
          HEX 00,40,80,C0
          --^
          HEX 00

BASTBLH  
          HEX 20,21,22,23
          HEX 25,26,27,28
          HEX 2A,2B,2C,2D
          HEX 2F,30,31,32
          HEX 34,35,36,37
          HEX 39,3A,3B,3C
          HEX 3E

MASK      DFB %10000000   ;The 1st 4 bytes are
          DFB %01000000   ; set by COLOR routines
          DFB %00100000
          DFB %00010000
          DFB %00001000
          DFB %00000100
          DFB %00000010
          DFB %00000001

CTBL      DFB %00000000
          DFB %01010101
          DFB %10101010
          DFB %11111111

RTBL      DFB 1,2,3,4,5,6,7,0

          ERR ^$1C00

