;    Program to demonstrate simple use of the Nick chip.
;
;

RAM0        EQU     0FCH           ; First 16K of video RAM
RAM1        EQU     0FDH           ; Second ---- '' -------
RAM2        EQU     0FEH           ; Third  ---- '' -------
RAM3        EQU     0FFH           ; Fourth ---- '' -------

;                   Z80 SPACE ADDRESSES
;                   -------------------
SCREEN      EQU     08000H         ; Start address for pixel screen
LPT         EQU     0C000H         ; Start address of line parameter table
STACK       EQU     0D000H         ; Z-80 stack
;
;
;    Data areas used for the line drawing demo program
;
OFFSET      EQU     0D000H
COLOUR      EQU     0D002H
COUNT       EQU     0D003H
;
BLUE_TABLE  EQU     0D100H
RED_TABLE   EQU     0D200H
;
X1          EQU     0              ; Offsets into RED and BLUE tables
Y1          EQU     1
X2          EQU     2
Y2          EQU     3
DELTA_X1    EQU     4
DELTA_Y1    EQU     5
DELTA_X2    EQU     6
DELTA_Y2    EQU     7
TABLE       EQU     8              ; 16*4 byte table
;
;
;                   MISC. PARAMETERS
;                   ----------------
NUL         EQU     0              ; No use value

BLACK       EQU     00000000B      ; Some useful colours to put in the palette
RED         EQU     01001001B
GREEN       EQU     10010010B
YELLOW      EQU     11011011B
BLUE        EQU     00100100B
MAGENTA     EQU     01101101B
CYAN        EQU     10110110B
WHITE       EQU     11111111B

;                 LINE PARAMETER MASK BITS
;                 ------------------------
;MODE BYTE (byte 1)
;---------

RELOAD      EQU     001H           ; Reload line parameter counters
VBLANK      EQU     000H           ; Use margin for VSYNC
PIXEL       EQU     002H           ; Normal pixel mode
ATTR        EQU     004H           ; ATTRIBUTE mode
CH256       EQU     006H           ; 256 font CHAR mode
CH128       EQU     008H           ; 128 font CHAR mode
CH64        EQU     00AH           ;  64 font CHAR mode
TPIXEL      EQU     00CH           ; ------ future expansion -------
LPIXEL      EQU     00EH           ; half resolution pixel mode

VRES        EQU     010H           ; low vertical resolution

C2          EQU     000H           ; 2-colour mode
C4          EQU     020H           ; 4-colour mode
C16         EQU     040H           ; 16-colour mode
C256        EQU     060H           ; 256-colour mode

VINT        EQU     080H           ; Take INT low

; LEFT MARGIN  (byte 2)
; -----------
MSBALT      EQU     080H           ; Alt colours on D7 (pixel mode) 0->2
LSBALT      EQU     040H           ; Alt colours on D0 (pixel mode) 0->4

; RIGHT MARGIN (byte 3)
; ------------
ALTIND1     EQU     080H           ; Alt colours on MSB of character index 0->4
ALTIND0     EQU     040H           ; Alt colours on next MSB of char index 0->2

;                 NICK CHIP I/O PORTS
;                 -------------------

FIXBIAS     EQU     080H           ; Fixed colour bias
BORDER      EQU     081H           ; Border colour
LPL         EQU     082H           ; Line parameter pointer (A4-A11)
LPH         EQU     083H           ; Line parameter pointer (A12-A15)

;                 LPH MASK BITS
;                 -------------

LPLOAD      EQU     080H           ; Force LOAD of LP counter low
LPCLOCK     EQU     040H           ; Force CLK of LP counter high

PAGE0       EQU     0B0H           ; Page in 4M of 0000H-3FFFH in Z80 space
PAGE1       EQU     0B1H           ; Page in 4M of 4000H-7FFFH in Z80 space
PAGE2       EQU     0B2H           ; Page in 4M of 8000H-BFFFH in Z80 space
PAGE3       EQU     0B3H           ; Page in 4M of C000H-FFFFH in Z80 space

            ORG     0100H

            DI

            LD      A,RAM2         ; PUT VIDEO RAM IN PAGES 2 AND 3
            OUT     (PAGE2),A      ; (PAGE 1 NOT USED, PAGE 0 ALREADY
            INC     A              ;  HAS THIS CODE IN)
            OUT     (PAGE3),A

            LD      A,0            ; SET BORDER COLOUR
            OUT     (BORDER),A
            LD      A,067H         ; ANY OLD VALUE FOR FIXED COLOUR BIAS
            OUT     (FIXBIAS),A

            LD      SP,STACK       ; SET UP STACK POINTER

            LD      BC,ENTAB-LPTAB ; COPY LINE PARAMETER TABLE INTO VIDEO RAM
            LD      HL,LPTAB
            LD      DE,LPT
            LDIR

            LD      A,low(LPT/16)
            OUT     (LPL),A        ; SET UP LINE PARAMETER POINTER
            LD      A,high(LPT/16)
            OUT     (LPH),A        ; ENSURE LP COUNTER IS LOADED (CLK=0, LOAD=0
            OR      LPCLOCK        ; CLK=1
            OUT     (LPH),A
            OR      LPLOAD         ; LOAD=1
            OUT     (LPH),A        ; THEN LET IT RUN
            LD      HL,SCREEN      ; CLEAR THE SCREEN
            LD      DE,SCREEN+1
            LD      BC,256*64-1
            LD      (HL),0
            LDIR

;---------------------------------------------------------------------------

;   The code from here is just a moving line demo program which uses
; the RAM from SCREEN upwards as a 4 colour 256*256 pixel bit mapped display
;

            LD      DE,RED_TABLE
            LD      HL,RED_INITIAL
            CALL    SETUP_TABLE

            LD      DE,BLUE_TABLE
            LD      HL,BLUE_INITIAL
            CALL    SETUP_TABLE


LOOP:       LD      A,11110000B
            LD      (COLOUR),A
            LD      HL,BLUE_TABLE
            CALL    ITERATE

            LD      A,00001111B
            LD      (COLOUR),A
            LD      HL,RED_TABLE
            CALL    ITERATE

            LD      A,(COUNT)
            INC     A
            AND     0FH
            LD      (COUNT),A

            JR      LOOP

;-----------------------------------------

ITERATE:    PUSH    HL
            CALL    NEW_XY
            INC     HL
            INC     HL
            CALL    NEW_XY

            POP     HL
            PUSH    HL
            LD      A,(COUNT)
            ADD     A,A
            ADD     A,A
            ADD     A,TABLE
            LD      E,A
            LD      D,0
            ADD     HL,DE

            PUSH    HL
            CALL    LINE

            POP     DE
            POP     HL
            PUSH    DE
            LD      BC,4
            LDIR

            POP     HL

            JP      LINE

;-------------------------------------

SETUP_TABLE:        LD       BC,9
                    LDIR
                    LD       H,D
                    LD       L,E
                    DEC      HL
                    LD       BC,16*4-1
                    LDIR
                    RET


RED_INITIAL:        DB      0,0,0,0,7,5,5,3,0
BLUE_INITIAL        DB      255,0,255,0,256-5,5,256-9,3,0

;-------------------------------------

NEW_XY:             PUSH     HL
                    POP      IY
                    CALL     NEW_X_OR_Y
                    INC      IY


NEW_X_OR_Y:         LD       A,R
                    AND      0FH
                    LD       C,A
                    OR       0F0H
                    LD       D,A

                    LD       A,(IY+0)
                    LD       B,(IY+4)
                    BIT      7,B
                    JR NZ    DELTA_MINUS

                    ADD      A,B
                    JR C     OVERFLOW_PLUS
                    CP       D
                    JR C     NO_OVERFLOW
                    CPL
OVERFLOW_PLUS:      CPL
                    JR       OVERFLOW

DELTA_MINUS         ADD      A,B
                    JR NC    OVERFLOW_MINUS
                    CP       C
                    JR NC    NO_OVERFLOW
OVERFLOW_MINUS:     NEG

OVERFLOW:           LD       (IY+0),A
                    XOR      A
                    SUB      B
                    LD       (IY+4),A
                    RET

NO_OVERFLOW:        LD       (IY+0),A
                    RET

;----------------------------------------

LINE:               LD       E,(HL)        ; GET TWO CO-ORDINATE PAIRS
                    INC      HL            ;  INTO DE AND HL
                    LD       D,(HL)
                    INC      HL
                    LD       A,(HL)
                    INC      HL
                    LD       H,(HL)
                    LD       L,A

                    LD       A,H           ; START FROM LOWEST Y CO-ORD
                    CP       D             ;     (in DE)
                    JR NC    NO_REVERSE
                    EX       DE,HL

NO_REVERSE:         LD       IX,NORMAL_X   ; If starting X is higher than
                    LD       A,L           ;  finishing X then flag
                    SUB      E             ;  reflection is required and
                    JR NC    NO_REFLECT_X  ;  negate both X co-ordinates
                    LD       IX,REFLECT_X
                    SUB      L
                    LD       E,A           ; E = starting X
                    NEG
                    SUB      L
NO_REFLECT_X:       EXX
                    LD       C,A           ; C'= DELTA_X
                    EXX

                    LD       A,H
                    SUB      D             ; D = starting Y
                    EXX
                    LD       B,A           ; B'= DELTA_Y

                    LD       IY,NORMAL_XY  ; If DELTA_Y is more than
                    CP       C             ; DELTA_X then flag XY reflection
                    JR C     NO_REFLECT_XY ; and swap DELTA_X and DELTA_Y
                    LD       IY,REFLECT_XY
                    LD       B,C
                    LD       C,A
                    EXX
                    LD       A,E
                    LD       E,D
                    LD       D,A
                    EXX
NO_REFLECT_XY:      LD       L,C
                    SRL      L
                    LD       H,0
                    LD       A,C
                    EXX
                    ADD      A,E
                    EX       AF,AF'

                    LD       B,D
                    LD       C,E

LINE_LOOP:          JP       (IY)
NORMAL_X:           XOR      A
                    SRL      D
                    RR       E
                    RLA
                    SRL      D
                    RR       E
                    RLA
                    SET      7,D

                    LD       HL,MASK_TAB
                    ADD      A,L
                    LD       L,A
                    LD       A,(COLOUR)
                    AND      (HL)
                    EX       DE,HL
                    XOR      (HL)
                    LD       (HL),A

                    EX       AF,AF'
                    CP       C
                    RET      Z
                    EX       AF,AF'

                    INC      C
                    EXX
                    XOR      A
                    LD       D,A
                    LD       E,B
                    SBC      HL,DE
                    EXX
                    JP P     LINE_LOOP
                    EXX
                    LD       E,C
                    ADD      HL,DE
                    EXX
                    INC      B
                    JP       LINE_LOOP

REFLECT_X:          XOR      A
                    SUB      E
                    LD       E,A
                    JP       NORMAL_X

NORMAL_XY:          LD       D,B
                    LD       E,C
                    JP       (IX)

REFLECT_XY:         LD       D,C
                    LD       E,B
                    JP       (IX)


MASK_TAB:           DB       10001000B
                    DB       00100010B
                    DB       01000100B
                    DB       00010001B

LPTAB:

;
                    DB       256-256,PIXEL+C4+VRES,14,14+32
                    DW       SCREEN,0
                    DB       BLACK,RED,BLUE,MAGENTA,0,0,0,0
;
                    DB       256-5,LPIXEL,63,0
                    DB       0,0,0,0,0,0,0,0,0,0,0,0
;
                    DB       256-10,LPIXEL,4,63
                    DB       0,0,0,0,0,0,0,0,0,0,0,0
;
                    DB       256-4,VBLANK,4,63
                    DB       0,0,0,0,0,0,0,0,0,0,0,0
;
                    DB       256-1,VBLANK,63,4
                    DB       0,0,0,0,0,0,0,0,0,0,0,0
;
                    DB       256-30,LPIXEL,4,63
                    DB       0,0,0,0,0,0,0,0,0,0,0,0
;
                    DB       256-6,RELOAD+LPIXEL,63,0
                    DB       0,0,0,0,0,0,0,0,0,0,0,0

ENTAB:              DB       0





