include "inc/cmdsys.plh"
//
// Hardware addresses
//
const showgraphics = $C050
const showtext     = $C051
const showfull     = $C052
const showmix      = $C053
const showpage1    = $C054
const showpage2    = $C055
const showlores    = $C056
const showhires    = $C057
const keyboard     = $C000
const keystrobe    = $C010
const hgr1         = $2000
const hgr2         = $4000
const page1        = 0
const page2        = 1
//
// Apple III hardware constants.
//
const ENV_REG      = $FFDF
//
// Screen addresses
//
word hgrbuff[] = hgr1, hgr2
//word hgrscan[] = $0000,$0400,$0800,$0C00,$1000,$1400,$1800,$1C00
//word           = $0080,$0480,$0880,$0C80,$1080,$1480,$1880,$1C80
//word           = $0100,$0500,$0900,$0D00,$1100,$1500,$1900,$1D00
//word           = $0180,$0580,$0980,$0D80,$1180,$1580,$1980,$1D80
//word           = $0200,$0600,$0A00,$0E00,$1200,$1600,$1A00,$1E00
//word           = $0280,$0680,$0A80,$0E80,$1280,$1680,$1A80,$1E80
//word           = $0300,$0700,$0B00,$0F00,$1300,$1700,$1B00,$1F00
//word           = $0380,$0780,$0B80,$0F80,$1380,$1780,$1B80,$1F80
//word           = $0028,$0428,$0828,$0C28,$1028,$1428,$1828,$1C28
//word           = $00A8,$04A8,$08A8,$0CA8,$10A8,$14A8,$18A8,$1CA8
//word           = $0128,$0528,$0928,$0D28,$1128,$1528,$1928,$1D28
//word           = $01A8,$05A8,$09A8,$0DA8,$11A8,$15A8,$19A8,$1DA8
//word           = $0228,$0628,$0A28,$0E28,$1228,$1628,$1A28,$1E28
//word           = $02A8,$06A8,$0AA8,$0EA8,$12A8,$16A8,$1AA8,$1EA8
//word           = $0328,$0728,$0B28,$0F28,$1328,$1728,$1B28,$1F28
//word           = $03A8,$07A8,$0BA8,$0FA8,$13A8,$17A8,$1BA8,$1FA8
//word           = $0050,$0450,$0850,$0C50,$1050,$1450,$1850,$1C50
//word           = $00D0,$04D0,$08D0,$0CD0,$10D0,$14D0,$18D0,$1CD0
//word           = $0150,$0550,$0950,$0D50,$1150,$1550,$1950,$1D50
//word           = $01D0,$05D0,$09D0,$0DD0,$11D0,$15D0,$19D0,$1DD0
//word           = $0250,$0650,$0A50,$0E50,$1250,$1650,$1A50,$1E50
//word           = $02D0,$06D0,$0AD0,$0ED0,$12D0,$16D0,$1AD0,$1ED0
//word           = $0350,$0750,$0B50,$0F50,$1350,$1750,$1B50,$1F50
//word           = $03D0,$07D0,$0BD0,$0FD0,$13D0,$17D0,$1BD0,$1FD0
//word hmask     = $8081,$8082,$8084,$8088,$8090,$80A0,$80C0
//word           = $8180,$8280,$8480,$8880,$9080,$A080,$C080
byte hgrscanl[]= $00,$00,$00,$00,$00,$00,$00,$00
byte           = $80,$80,$80,$80,$80,$80,$80,$80
byte           = $00,$00,$00,$00,$00,$00,$00,$00
byte           = $80,$80,$80,$80,$80,$80,$80,$80
byte           = $00,$00,$00,$00,$00,$00,$00,$00
byte           = $80,$80,$80,$80,$80,$80,$80,$80
byte           = $00,$00,$00,$00,$00,$00,$00,$00
byte           = $80,$80,$80,$80,$80,$80,$80,$80
byte           = $28,$28,$28,$28,$28,$28,$28,$28
byte           = $A8,$A8,$A8,$A8,$A8,$A8,$A8,$A8
byte           = $28,$28,$28,$28,$28,$28,$28,$28
byte           = $A8,$A8,$A8,$A8,$A8,$A8,$A8,$A8
byte           = $28,$28,$28,$28,$28,$28,$28,$28
byte           = $A8,$A8,$A8,$A8,$A8,$A8,$A8,$A8
byte           = $28,$28,$28,$28,$28,$28,$28,$28
byte           = $A8,$A8,$A8,$A8,$A8,$A8,$A8,$A8
byte           = $50,$50,$50,$50,$50,$50,$50,$50
byte           = $D0,$D0,$D0,$D0,$D0,$D0,$D0,$D0
byte           = $50,$50,$50,$50,$50,$50,$50,$50
byte           = $D0,$D0,$D0,$D0,$D0,$D0,$D0,$D0
byte           = $50,$50,$50,$50,$50,$50,$50,$50
byte           = $D0,$D0,$D0,$D0,$D0,$D0,$D0,$D0
byte           = $50,$50,$50,$50,$50,$50,$50,$50
byte           = $D0,$D0,$D0,$D0,$D0,$D0,$D0,$D0
byte hgrscanh[]= $00,$04,$08,$0C,$10,$14,$18,$1C
byte           = $00,$04,$08,$0C,$10,$14,$18,$1C
byte           = $01,$05,$09,$0D,$11,$15,$19,$1D
byte           = $01,$05,$09,$0D,$11,$15,$19,$1D
byte           = $02,$06,$0A,$0E,$12,$16,$1A,$1E
byte           = $02,$06,$0A,$0E,$12,$16,$1A,$1E
byte           = $03,$07,$0B,$0F,$13,$17,$1B,$1F
byte           = $03,$07,$0B,$0F,$13,$17,$1B,$1F
byte           = $00,$04,$08,$0C,$10,$14,$18,$1C
byte           = $00,$04,$08,$0C,$10,$14,$18,$1C
byte           = $01,$05,$09,$0D,$11,$15,$19,$1D
byte           = $01,$05,$09,$0D,$11,$15,$19,$1D
byte           = $02,$06,$0A,$0E,$12,$16,$1A,$1E
byte           = $02,$06,$0A,$0E,$12,$16,$1A,$1E
byte           = $03,$07,$0B,$0F,$13,$17,$1B,$1F
byte           = $03,$07,$0B,$0F,$13,$17,$1B,$1F
byte           = $00,$04,$08,$0C,$10,$14,$18,$1C
byte           = $00,$04,$08,$0C,$10,$14,$18,$1C
byte           = $01,$05,$09,$0D,$11,$15,$19,$1D
byte           = $01,$05,$09,$0D,$11,$15,$19,$1D
byte           = $02,$06,$0A,$0E,$12,$16,$1A,$1E
byte           = $02,$06,$0A,$0E,$12,$16,$1A,$1E
byte           = $03,$07,$0B,$0F,$13,$17,$1B,$1F
byte           = $03,$07,$0B,$0F,$13,$17,$1B,$1F
byte hbmask    = $81,$82,$84,$88,$90,$A0,$C0
byte hlmask    = $FF,$FE,$FC,$F8,$F0,$E0,$C0
byte hrmask    = $81,$83,$87,$8F,$9F,$BF,$FF
word hcolor[]  = $0000,$552A,$2A55,$7F7F,$8080,$D5AA,$AAD5,$FFFF
word curhclr
byte drawpage  = 1
word drawbuff  = hgr2

export asm divmod7(x)#2
!SOURCE    "vmsrc/plvmzp.inc"
        LDA     ESTKL+0,X   ; X COORDL
        LDY     ESTKH+0,X   ; X COORDH
        BPL     +
        TYA                 ; DEAL WITH NEG X COORD
        EOR     #$FF
        TAY
        LDA     ESTKL+0,X
        EOR     #$FF
+       CPY     #$01
        BEQ     ++          ; MUST BE >= 140
        BCC     +
        LDY     #40         ; > 512 SO CLIP AT MAX
        LDA     #00
        BEQ     +++
+       CMP     #140
        BCC     +
++      SEC
        SBC     #140
        LDY     #20
+       CMP     #70
        BCC     +
        SBC     #70
        STA     ESTKL+0,X
        TYA
        ADC     #9
        TAY
        LDA     ESTKL+0,X
+       CMP     #35
        BCC     +
        SBC     #35
        STA     ESTKL+0,X
        TYA
        ADC     #4
        TAY
        LDA     ESTKL+0,X
+
-       CMP     #7
        BCC     +++
        SBC     #7
        INY
        BNE     -
+++     DEX
        ASL     ESTKH+1,X   ; CHECK SIGN OF XCOORD
        BCS     +
        STA     ESTKL+0,X   ; REMAINDERL
        STY     ESTKL+1,X   ; QUOTIENTL
        LDY     #$00
        STY     ESTKH+0,X
        STY     ESTKH+1,X
        RTS
+       EOR     #$07
        SBC     #$01
        STA     ESTKL+0,X   ; REMAINDERL
        TYA
        EOR     #$FF
        STA     ESTKL+1,X   ; QUOTIENTL
        LDY     #$00
        STY     ESTKH+0,X
        DEY
        STY     ESTKH+1,X
        RTS
end
asm clipsrc(ofst, y, w, h, srcptr)#0
        LDA     ESTKL+0,X   ; SRC PTR
        STA     SRCL
        LDA     ESTKH+0,X
        STA     SRCH
        LDA     ESTKL+2,X   ; WIDTH (SRC PITCH)
        STA     TMPH        ; WIDTH (DRAW WIDTH)
; CLPTOP
        LDY     ESTKH+3,X   ; Y COORDH
        BPL     CLPBOTM
        INY
;        STY     ESTKH+3,X   ; Y COORDH
        BNE     CLPPED
        LDY     ESTKL+3,X   ; Y COORDL
-       LDA     SRCL
        CLC
        ADC     ESTKL+2,X   ; PITCH
        STA     SRCL
        BCC     +
        INC     SRCH
+       DEC     ESTKL+1,X   ; HEIGHT
        BEQ     CLPPED
        INY                 ; Y COORDL
        BNE     -
        STY     ESTKL+3,X   ; Y COORDL
        BEQ     CLPLEFT     ; BETTER BE ZERO
CLPBOTM BNE     CLPPED
        LDA     ESTKL+3,X   ; YCOORDL
        CMP     #192
        BCS     CLPPED
;        CLC
        ADC     ESTKL+1,X   ; HEIGHT
        SBC     #191
        BCC     CLPLEFT
        STA     TMPL
        LDA     ESTKL+1,X   ; HEIGHT
        SBC     TMPL
        STA     ESTKL+1,X   ; HEIGHT
        BEQ     CLPPED
CLPLEFT LDY     ESTKH+4,X   ; HORIZ OFFSETH
        BPL     CLPRGHT
        INY
;        STY     ESTKH+4,X
        BNE     CLPPED
        LDY     ESTKL+4,X   ; HORIZ OFFSETL
-       INC     SRCL
        BNE     +
        INC     SRCH
+       DEC     TMPH        ; WIDTH
        BEQ     CLPPED
        INY                 ; HORIZ OFFSETL
        BNE     -
        STY     ESTKL+4,X   ; HORIZ OFFSETL
        BEQ     CLPDONE     ; BETTER BE ZERO
CLPRGHT BNE     CLPPED
        LDA     ESTKL+4,X   ; HORIZ OFFSETL
        CMP     #40
        BCS     CLPPED
;        CLC
        ADC     TMPH         ; WIDTH
        SBC     #39
        BCC     CLPDONE
        STA     TMPL
        LDA     TMPH        ; WIDTH
        SBC     TMPL
        STA     TMPH        ; WIDTH
CLPDONE LDA     TMPH
        STA     ESTKH+2,X   ; WIDTH (DRAW WIDTH)
;        LDA     SRCL
;        STA     ESTKL+0,X   ; SRC PTR
;        LDA     SRCH
;        STA     ESTKH+0,X
        RTS
CLPPED  INX
        INX
        INX
        INX
        INX
        PLA
        PLA
        RTS
end
//export def hgrColor(c)#0
//    curhclr = hcolor[c & $07]
//end
export asm hgrColor(c)#0
        LDA     ESTKL+0,X   ; COLOR
        AND     #$07
        ASL
        TAY
        LDA     $1000,Y     ; HCOLORL
        STA     $2000       ; CURHCLRL
        LDA     $1001,Y     ; HCOLORH
        STA     $2001       ; CRHCLRH
        INX
        RTS
end
//export def hgrCopyDst(ofst, y, w, h, dstptr)#0
//    word j, srcptr
//
//    ofst = ofst + drawbuff
//    for j = y to y + h - 1
//        srcptr = hgrscan[j] + ofst
//        memcpy(dstptr, srcptr, w)
//        dstptr = dstptr + w
//    next
//end
export asm hgrCopyDst(ofst, y, w, h, dstptr)#0
        JSR     $C000       ; CLIPSRC
;        LDA     ESTKL+0,X   ; DST PTR
        LDA     SRCL
        STA     DSTL
;        LDA     ESTKH+0,X
        LDA     SRCH
        STA     DSTH
--      LDY     ESTKL+3,X   ; Y COORD
        LDA     ESTKL+4,X   ; HORIZ OFFSET
        CLC
end
asm     _hgrCopyDst
        ADC     $8000,Y     ; HGRSCANL
        STA     SRCL
        LDA     $1000       ; DRAWBUFFH
        ADC     $9000,Y     ; HGRSCANH
        STA     SRCH
        LDY     ESTKH+2,X   ; WIDTH
        DEY
-       LDA     (SRC),Y
        STA     (DST),Y
        DEY
        BPL     -
        LDA     DSTL
        CLC
        ADC     ESTKL+2,X   ; PITCH
        STA     DSTL
        BCC     +
        INC     DSTH
+       INC     ESTKL+3,X   ; Y COORD
        DEC     ESTKL+1,X   ; HEIGHT
        BNE     --
        INX
        INX
        INX
        INX
        INX
        RTS
end
//export def hgrCopySrc(ofst, y, w, h, srcptr)#0
//    word j, dstptr
//
//    ofst = ofst + drawbuff
//    for j = y to y + h - 1
//        dstptr = hgrscan[j] + ofst
//        memcpy(dstptr, srcptr, w)
//        srcptr = srcptr + w
//    next
//end
export asm hgrCopySrc(ofst, y, w, h, srcptr)#0
        JSR     $C000       ; CLIPSRC
;        LDA     ESTKL+0,X   ; SRC PTR
;        STA     SRCL
;        LDA     ESTKH+0,X
;        STA     SRCH
--      LDY     ESTKL+3,X   ; Y COORD
        LDA     ESTKL+4,X   ; HORIZ OFFSET
        CLC
end
asm     _hgrCopySrc
        ADC     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ADC     $9000,Y     ; HGRSCANH
        STA     DSTH
        LDY     ESTKH+2,X   ; WIDTH
        DEY
-       LDA     (SRC),Y
        STA     (DST),Y
        DEY
        BPL     -
        LDA     SRCL
        CLC
        ADC     ESTKL+2,X   ; PITCH
        STA     SRCL
        BCC     +
        INC     SRCH
+       INC     ESTKL+3,X   ; Y COORD
        DEC     ESTKL+1,X   ; HEIGHT
        BNE     --
        INX
        INX
        INX
        INX
        INX
        RTS
end
//export def hgrAndSrc(ofst, y, w, h, srcptr)#0
//    word j, dstptr
//    byte i
//
//    ofst = ofst + drawbuff
//    for j = y to y + h - 1
//        dstptr = hgrscan[j] + ofst
//        for i = 0 to w - 1
//            dstptr->[i] = dstptr->[i] & srcptr->[i]
//        next
//        srcptr = srcptr + w
//    next
//end
export asm hgrAndSrc(ofst, y, w, h, srcptr)#0
        JSR     $C000       ; CLIPSRC
;        LDA     ESTKL+0,X   ; SRC PTR
;        STA     SRCL
;        LDA     ESTKH+0,X
;        STA     SRCH
--      LDY     ESTKL+3,X   ; Y COORD
        LDA     ESTKL+4,X   ; HORIZ OFFSET
        CLC
end
asm     _hgrAndSrc
        ADC     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ADC     $9000,Y     ; HGRSCANH
        STA     DSTH
        LDY     ESTKH+2,X   ; WIDTH
        DEY
-       LDA     (SRC),Y
        AND     (DST),Y
        STA     (DST),Y
        DEY
        BPL     -
        LDA     SRCL
        CLC
        ADC     ESTKL+2,X   ; PITCH
        STA     SRCL
        BCC     +
        INC     SRCH
+       INC     ESTKL+3,X   ; Y COORD
        DEC     ESTKL+1,X   ; HEIGHT
        BNE     --
        INX
        INX
        INX
        INX
        INX
        RTS
end
//export def hgrXorSrc(ofst, y, w, h, srcptr)#0
//    word j, dstptr
//    byte i
//
//    ofst = ofst + drawbuff
//    for j = y to y + h - 1
//        dstptr = hgrscan[j] + ofst
//        for i = 0 to w - 1
//            dstptr->[i] = dstptr->[i] ^ srcptr->[i]
//        next
//        srcptr = srcptr + w
//    next
//end
export asm hgrXorSrc(ofst, y, w, h, srcptr)#0
        JSR     $C000       ; CLIPSRC
;        LDA     ESTKL+0,X   ; SRC PTR
;        STA     SRCL
;        LDA     ESTKH+0,X
;        STA     SRCH
--      LDY     ESTKL+3,X   ; Y COORD
        LDA     ESTKL+4,X   ; HORIZ OFFSET
        CLC
end
asm     _hgrXorSrc
        ADC     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ADC     $9000,Y     ; HGRSCANH
        STA     DSTH
        LDY     ESTKH+2,X   ; WIDTH
        DEY
-       LDA     (SRC),Y
        EOR     (DST),Y
        STA     (DST),Y
        DEY
        BPL     -
        LDA     SRCL
        CLC
        ADC     ESTKL+2,X   ; PITCH
        STA     SRCL
        BCC     +
        INC     SRCH
+       INC     ESTKL+3,X   ; Y COORD
        DEC     ESTKL+1,X   ; HEIGHT
        BNE     --
        INX
        INX
        INX
        INX
        INX
        RTS
end
//export def hgrOrSrc(ofst, y, w, h, srcptr)#0
//    word j, dstptr
//    byte i
//
//    ofst = ofst + drawbuff
//    for j = y to y + h - 1
//        dstptr = hgrscan[j] + ofst
//        for i = 0 to w - 1
//            dstptr->[i] = dstptr->[i] ^ srcptr->[i]
//        next
//        srcptr = srcptr + w
//    next
//end
export asm hgrOrSrc(ofst, y, w, h, srcptr)#0
        JSR     $C000       ; CLIPSRC
;        LDA     ESTKL+0,X   ; SRC PTR
;        STA     SRCL
;        LDA     ESTKH+0,X
;        STA     SRCH
--      LDY     ESTKL+3,X   ; Y COORD
        LDA     ESTKL+4,X   ; HORIZ OFFSET
        CLC
end
asm     _hgrOrSrc
        ADC     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ADC     $9000,Y     ; HGRSCANH
        STA     DSTH
        LDY     ESTKH+2,X   ; WIDTH
        DEY
-       LDA     (SRC),Y
        ORA     (DST),Y
        STA     (DST),Y
        DEY
        BPL     -
        LDA     SRCL
        CLC
        ADC     ESTKL+2,X   ; PITCH
        STA     SRCL
        BCC     +
        INC     SRCH
+       INC     ESTKL+3,X   ; Y COORD
        DEC     ESTKL+1,X   ; HEIGHT
        BNE     --
        INX
        INX
        INX
        INX
        INX
        RTS
end
//export def hgrPlot(x, y)#0
//    word pixptr
//    byte ofst, pixofst, pmask
//
//    ofst, pixofst = divmod7(x)
//    pixptr = hgrscan[y] + drawbuff + ofst
//    pmask = hbmask[pixofst]
//    ^pixptr = (^pixptr & ~pmask) | (curhclr.[ofst & 1] & pmask)
//end
export asm hgrPlot(x, y)#0
        LDY     ESTKL+0,X   ; Y COORD
        CPY     #192
        BCS     +
end
asm     _hgrPlotA
        LDA     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ORA     $9000,Y     ; HGRSCANH
        STA     DSTH
        INX
end
asm     _hgrPlotB
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; PIXEL OFFSET
end
asm     _hgrPlotC
        LDA     $1000,Y     ; HBMASK
        STA     TMPL
        LDA     ESTKL+1,X   ; HORIZ OFFSET
        CMP     #40
        BCS     +
        AND     #$01
        TAY
end
asm     _hgrPlotD
        LDA     $2000,Y     ; CURHCLR
        LDY     ESTKL+1,X   ; HORIZ OFFSET
        EOR     (DST),Y
        AND     TMPL
        EOR     (DST),Y
        STA     (DST),Y
+       INX
        INX
        RTS
end
//export def hgrXorPlot(x, y)#0
//    word pixptr
//    byte ofst, pixofst, pmask
//
//    ofst, pixofst = divmod7(x)
//    pixptr = hgrscan[y] + drawbuff + ofst
//    pmask = hbmask[pixofst]
//    ^pixptr = ^pixptr ^ (curhclr.[ofst & 1] & pmask)
//end
export asm hgrXorPlot(x, y)#0
        LDY     ESTKL+0,X   ; Y COORD
        CPY     #192
        BCS     +
end
asm     _hgrXorPlotA
        LDA     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ORA     $9000,Y     ; HGRSCANH
        STA     DSTH
        INX
end
asm     _hgrXorPlotB
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; PIXEL OFFSET
end
asm     _hgrXorPlotC
        LDA     $1000,Y     ; HBMASK
        STA     TMPL
        LDA     ESTKL+1,X   ; HORIZ OFFSET
        CMP     #40
        BCS     +
        AND     #$01
        TAY
end
asm     _hgrXorPlotD
        LDA     $2000,Y     ; CURHCLR
        LDY     ESTKL+1,X   ; HORIZ OFFSET
        AND     TMPL
        EOR     (DST),Y
        STA     (DST),Y
+       INX
        INX
        RTS
end
//export def hgrOrPlot(x, y)#0
//    word pixptr
//    byte ofst, pixofst, pmask
//
//    ofst, pixofst = divmod7(x)
//    pixptr = hgrscan[y] + drawbuff + ofst
//    pmask = hbmask[pixofst]
//    ^pixptr = ^pixptr | (curhclr.[ofst & 1] & pmask)
//end
export asm hgrOrPlot(x, y)#0
        LDY     ESTKL+0,X   ; Y COORD
        CPY     #192
        BCS     +
end
asm     _hgrOrPlotA
        LDA     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ORA     $9000,Y     ; HGRSCANH
        STA     DSTH
        INX
end
asm     _hgrOrPlotB
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; PIXEL OFFSET
end
asm     _hgrOrPlotC
        LDA     $1000,Y     ; HBMASK
        STA     TMPL
        LDA     ESTKL+1,X   ; HORIZ OFFSET
        CMP     #40
        BCS     +
        AND     #$01
        TAY
end
asm     _hgrOrPlotD
        LDA     $2000,Y     ; CURHCLR
        LDY     ESTKL+1,X   ; HORIZ OFFSET
        AND     TMPL
        ORA     (DST),Y
        STA     (DST),Y
+       INX
        INX
        RTS
end
//export def hgrHLin(x1, x2, y)#0
//    word pixptr, x
//    byte lofst, lpixofst, lpmask
//    byte rofst, rpixofst, rpmask
//
//    if x1 == x2
//        hgrPlot(x1, y)
//    else
//        lofst, lpixofst = divmod7(x1)
//        pixptr = hgrscan[y] + drawbuff + lofst
//        rofst, rpixofst = divmod7(x2)
//        lpmask = hlmask[lpixofst]
//        rpmask = hrmask[rpixofst]
//        if lofst == rofst
//            lpmask = lpmask & rpmask
//            ^pixptr = (^pixptr & ~lpmask) | (curhclr.[pixptr.0 & 1] & lpmask)
//        else
//            ^pixptr = (^pixptr & ~lpmask) | (curhclr.[pixptr.0 & 1] & lpmask)
//            pixptr++
//            for x = lofst + 1 to rofst - 1
//                ^pixptr = curhclr.[pixptr.0 & 1]
//                pixptr++
//            next
//            ^pixptr = (^pixptr & ~rpmask) | (curhclr.[pixptr.0 & 1] & rpmask)
//        fin
//    fin
//end
export asm hgrHLin(x1, x2, y)#0
        LDA     ESTKL+1
        CMP     ESTKL+2
        BNE     +
        LDA     ESTKH+1
        CMP     ESTKH+2
        BNE     +
end
asm     _hgrHLinA
        JSR     $F000
        INX
        RTS
+       LDY     ESTKL+0,X   ; Y COORD
end
asm     _hgrHLinB
        LDA     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ORA     $9000,Y     ; HGRSCANH
        STA     DSTH
        LDA     ESTKL+1,X
        STA     ESTKL+0,X
        LDA     ESTKH+1,X
        STA     ESTKH+0,X
end
asm     _hgrHLinC
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; RIGHT PIXEL OFFSET
end
asm     _hgrHLinD
        LDA     $1000,Y     ; HRMASK
        STA     TMPH
        LDY     ESTKL+1,X   ; RIGHT HORIZ OFFSET
        STY     IPY         ; STEAL THIS ZP FOR A MOMENT
        INX
        INX
        INX
end
asm     _hgrHLinE
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; LEFT PIXEL OFFSET
end
asm     _hgrHLinF
        LDA     $1000,Y     ; HLMASK
        STA     TMPL
        LDY     ESTKL+1,X   ; LEFT HORIZ OFFSET
        TYA
        LSR
        BCS     +
end
asm     _hgrHLinG
        LDA     $2001       ; CURHCLRH
        STA     SRCH
        LDA     $2000       ; CURHCLRL
        STA     SRCL
        BCC     ++
+       LDA     $2000       ; CURHCLRL
        STA     SRCH
        LDA     $2001       ; CURHCLRH
        STA     SRCL
++      CPY     IPY         ; RIGHT HORIZ OFFSET
        BNE     +
        EOR     (DST),Y
        AND     TMPL
        AND     TMPH
        EOR     (DST),Y
        STA     (DST),Y
        INX
        INX
        RTS
+       EOR     (DST),Y
        AND     TMPL
        EOR     (DST),Y
-       STA     (DST),Y
        LDA     SRCH
        INY
        CPY     IPY         ; RIGHT HORIZ OFFSET
        BCS     +
        STA     (DST),Y
        LDA     SRCL
        INY
        CPY     IPY         ; RIGHT HORIZ OFFSET
        BCC     -
+       EOR     (DST),Y
        AND     TMPH
        EOR     (DST),Y
        STA     (DST),Y
        INX
        INX
        RTS
end
//export def hgrXorHLin(x1, x2, y)#0
//    word pixptr, x
//    byte lofst, lpixofst, lpmask
//    byte rofst, rpixofst, rpmask
//
//    if x1 == x2
//        hgrPlot(x1, y)
//    else
//        lofst, lpixofst = divmod7(x1)
//        pixptr = hgrscan[y] + drawbuff + lofst
//        rofst, rpixofst = divmod7(x2)
//        lpmask = hlmask[lpixofst]
//        rpmask = hrmask[rpixofst]
//        if lofst == rofst
//            lpmask = lpmask & rpmask
//            ^pixptr = ^pixptr ^ (curhclr.[pixptr.0 & 1] & lpmask)
//        else
//            ^pixptr = ^pixptr ^ (curhclr.[pixptr.0 & 1] & lpmask)
//            pixptr++
//            for x = lofst + 1 to rofst - 1
//                ^pixptr = ^pixptr ^ curhclr.[pixptr.0 & 1]
//                pixptr++
//            next
//            ^pixptr = ^pixptr ^ (curhclr.[pixptr.0 & 1] & rpmask)
//        fin
//    fin
//end
export asm hgrXorHLin(x1, x2, y)#0
        LDA     ESTKL+1
        CMP     ESTKL+2
        BNE     +
        LDA     ESTKH+1
        CMP     ESTKH+2
        BNE     +
end
asm     _hgrXHLinA
        JSR     $F000
        INX
        RTS
+       LDY     ESTKL+0,X   ; Y COORD
end
asm     _hgrXHLinB
        LDA     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ORA     $9000,Y     ; HGRSCANH
        STA     DSTH
        LDA     ESTKL+1,X
        STA     ESTKL+0,X
        LDA     ESTKH+1,X
        STA     ESTKH+0,X
end
asm     _hgrXHLinC
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; RIGHT PIXEL OFFSET
end
asm     _hgrXHLinD
        LDA     $1000,Y     ; HRMASK
        STA     TMPH
        LDY     ESTKL+1,X   ; RIGHT HORIZ OFFSET
        STY     IPY         ; STEAL THIS ZP FOR A MOMENT
        INX
        INX
        INX
end
asm     _hgrXHLinE
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; LEFT PIXEL OFFSET
end
asm     _hgrXHLinF
        LDA     $1000,Y     ; HLMASK
        STA     TMPL
        LDY     ESTKL+1,X   ; LEFT HORIZ OFFSET
        TYA
        LSR
        BCS     +
end
asm     _hgrXHLinG
        LDA     $2001       ; CURHCLRH
        STA     SRCH
        LDA     $2000       ; CURHCLRH
        STA     SRCL
        BCC     ++
+       LDA     $2000       ; CURHCLRL
        STA     SRCH
        LDA     $2001       ; CURHCLRH
        STA     SRCL
++      CPY     IPY         ; RIGHT HORIZ OFFSET
        BNE     +
        AND     TMPL
        AND     TMPH
        EOR     (DST),Y
        STA     (DST),Y
        INX
        INX
        RTS
+       AND     TMPL
-       EOR     (DST),Y
        STA     (DST),Y
        LDA     SRCH
        INY
        CPY     IPY         ; RIGHT HORIZ OFFSET
        BCS     +
        EOR     (DST),Y
        STA     (DST),Y
        LDA     SRCL
        INY
        CPY     IPY         ; RIGHT HORIZ OFFSET
        BCC     -
+       AND     TMPH
        EOR     (DST),Y
        STA     (DST),Y
        INX
        INX
        RTS
end
//export def hgrVlin(y1, y2, x)#0
//    word pixptr, y, ofst
//    byte pixofst, pmask, cmask
//
//    if y1 == y2
//        hgrPlot(x, y1)
//    else
//        ofst, pixofst = divmod7(x)
//        ofst  = ofst + drawbuff
//        pmask = hbmask[pixofst]
//        cmask = curhclr.[ofst & 1] & pmask
//        pmask = ~pmask
//        for y = y1 to y2
//            pixptr = hgrscan[y] + ofst
//            ^pixptr = (^pixptr & pmask) | cmask
//        next
//    fin
//end
export asm hgrVlin(y1, y2, x)#0
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; PIXEL OFFSET
end
asm     _hgrVLinA
        LDA     $1000,Y     ; HBMASK
        STA     TMPL
        EOR     #$FF
        STA     TMPH
        LDA     ESTKL+1,X   ; HORIZ OFFSET
        AND     #$01
        TAY
end
asm     _hgrVLinB
        LDA     $2000,Y     ; CURHCLR
        AND     TMPL
        STA     TMPL
        LDY     ESTKL+3,X   ; Y1 COORD
end
asm     _hgrVLinC
-       LDA     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ORA     $9000,Y     ; HGRSCANH
        STA     DSTH
        LDY     ESTKL+1,X   ; HORIZ OFFSET
        LDA     (DST),Y
        AND     TMPH
        ORA     TMPL
        STA     (DST),Y
        LDY     ESTKL+3,X   ; Y1 COORD
        TYA
        INY
        STY     ESTKL+3,X   ; Y1 COORD
        CMP     ESTKL+2,X   ; Y2 COORD
        BNE     -
        INX
        INX
        INX
        INX
        RTS
end
//export def hgrXVlin(y1, y2, x)#0
//    word pixptr, y, ofst
//    byte pixofst, pmask, cmask
//
//    if y1 == y2
//        hgrXorPlot(x, y1)
//    else
//        ofst, pixofst = divmod7(x)
//        ofst  = ofst + drawbuff
//        pmask = hbmask[pixofst]
//        cmask = curhclr.[ofst & 1] & pmask
//        pmask = ~pmask
//        for y = y1 to y2
//            pixptr = hgrscan[y] + ofst
//            ^pixptr = ^pixptr ^ cmask
//        next
//    fin
//end
export asm hgrXorVlin(y1, y2, x)#0
        JSR     1000        ; DIVMOD7
        LDY     ESTKL+0,X   ; PIXEL OFFSET
end
asm     _hgrXVLinA
        LDA     $1000,Y     ; HBMASK
        STA     TMPL
        EOR     #$FF
        STA     TMPH
        LDA     ESTKL+1,X   ; HORIZ OFFSET
        AND     #$01
        TAY
end
asm     _hgrXVLinB
        LDA     $2000,Y     ; CURHCLR
        AND     TMPL
        STA     TMPL
        LDY     ESTKL+3,X   ; Y1 COORD
end
asm     _hgrXVLinC
-       LDA     $8000,Y     ; HGRSCANL
        STA     DSTL
        LDA     $1000       ; DRAWBUFFH
        ORA     $9000,Y     ; HGRSCANH
        STA     DSTH
        LDY     ESTKL+1,X   ; HORIZ OFFSET
        LDA     TMPL
        EOR     (DST),Y
        STA     (DST),Y
        LDY     ESTKL+3,X   ; Y1 COORD
        TYA
        INY
        STY     ESTKL+3,X   ; Y1 COORD
        CMP     ESTKL+2,X   ; Y2 COORD
        BNE     -
        INX
        INX
        INX
        INX
        RTS
end
//
// Masked BLT scanline of pixmap
//
asm scanBLT(x, y, w, srcptr)#0
        LDA     ESTKL+0,X   ; SRC PTR
        STA     SRCL
        LDA     ESTKH+0,X
        STA     SRCH
        LDA     #$00
-       PHA
        LSR
        TAY
        LDA     (SRC),Y
        LSR
        LSR
        LSR
        LSR
        PHA
        DEX
        STA     ESTKL+0,X
end
asm     _scanBLTA
        JSR     $C000       ; HCOLOR
        DEX
        DEX
        LDA     ESTKL+5,X   ; X COORDL
        STA     ESTKL+1,X
        LDA     ESTKH+5,X   ; X COORDH
        STA     ESTKH+1,X
        LDA     ESTKL+4,X   ; Y COORDL
        STA     ESTKL+0,X
        LDA     ESTKH+4,X   ; Y COORDH
        STA     ESTKH+0,X
        PLA
        AND     #$08
        BEQ     +
end
asm     _scanBLTB
        JSR     $D000       ; HPLOT
        BEQ     ++
        BNE     ++
+       JSR     $E000       ; HPLOTOR
++      INC     ESTKL+3,X   ; X COORDL
        BNE     +
        INC     ESTKH+3,X   ; X COORDH
+       PLA
        CLC
        ADC     #$01
        CMP     ESTKL+1,X   ; WIDTH
        BEQ     BLTDONE
        PHA
        LSR
        TAY
        LDA     (SRC),Y
        PHA
        DEX
        STA     ESTKL+0,X
end
asm     _scanBLTC
        JSR     $C000       ; HCOLOR
        DEX
        DEX
        LDA     ESTKL+5,X   ; X COORDL
        STA     ESTKL+1,X
        LDA     ESTKH+5,X   ; X COORDH
        STA     ESTKH+1,X
        LDA     ESTKL+4,X   ; Y COORDL
        STA     ESTKL+0,X
        LDA     ESTKH+4,X   ; Y COORDH
        STA     ESTKH+0,X
        PLA
        AND     #$08
        BEQ     +
end
asm     _scanBLTD
        JSR     $D000       ; HPLOT
        BEQ     ++
        BNE     ++
+       JSR     $E000       ; HPLOTOR
++      INC     ESTKL+3,X   ; X COORDL
        BNE     +
        INC     ESTKH+3,X   ; X COORDH
+       PLA
        CLC
        ADC     #$01
        CMP     ESTKL+1,X   ; WIDTH
        BNE     -
BLTDONE INX
        INX
        INX
        INX
        RTS
end
export def hgrRect(x1, y1, x2, y2)#0
    word y

    if x1 == x2
        hgrVLin(y1, y2, x1)
    else
        for y = y1 to y2
            hgrHLin(x1, x2, y)
        next
    fin
end
export def hgrXorRect(x1, y1, x2, y2)#0
    word y

    if x1 == x2
        hgrXorVLin(y1, y2, x1)
    else
        for y = y1 to y2
            hgrXorHLin(x1, x2, y)
        next
    fin
end
export def hgrBLT(x, y, w, h, srcptr)#0
    word i, j
    word saveclr
    byte c

    saveclr = curhclr
    for j = y to y + h - 1
    scanBLT(x, j, w, srcptr)
//        for i = 0 to w - 1
//            c = srcptr->[i >> 1]
//            if i & 1
//                hgrColor(c)
//                if c & $08
//                    hgrOrPlot(x + i, j)
//                else
//                    hgrPlot(x + i, j)
//                fin
//            else
//                hgrColor(c >> 4)
//                if c & $80
//                    hgrXorPlot(x + i, j)
//                else
//                    hgrPlot(x + i, j)
//                fin
//            fin
//        next
        srcptr = srcptr + (w + 1) / 2
    next
    curhclr = saveclr
end
export def hgrMode(mode)#1
    when mode
        is page1
            //
            // Set HGR1 mode
            //
            memset(hgr1, 0, $2000) // Clear HGR1
            ^showpage1
            ^showfull
            ^showhires
            ^showgraphics
            drawpage = page2
            drawbuff = hgrbuff[page2]
            break
        is page2
            //
            // Set HGR2 mode
            //
            memset(hgr2, 0, $2000) // Clear HGR2
            ^showpage2
            ^showfull
            ^showhires
            ^showgraphics
            drawpage = page1
            drawbuff = hgrbuff[page1]
            break
        otherwise
            //
            // Show text mode
            //
            ^showpage1
            ^showtext
    wend
    return mode
end
export def hgrClear#0
    memset(drawbuff, curhclr, drawbuff) // Clear current HGR page
end
//
// Set display page, return other page
//
export def hgrShow(page)#1
    page = page & 1
    ^(showpage1 + page)
    return page ^ 1
end
export def hgrSwap#1
    ^(showpage1 + drawpage)
    drawpage = drawpage ^ 1
    drawbuff = hgrbuff[drawpage]
    return drawpage
end
export def hgrDrawBuf(page)#1
    drawpage = page & 1
    drawbuff = hgrbuff[drawpage]
    return drawpage
end
//
// Machine compatibility check
//
if MACHID & MACHID_MODEL == MACHID_III or MACHID & MACHID_MODEL == MACHID_I
    puts("Apple II compatible only.\n")
    return -1
fin
//
// Assembly fixups
//
hgrCopyDst:1   = @clipsrc
_hgrCopyDst:1  = @hgrscanl
_hgrCopyDst:6  = @drawbuff.1
_hgrCopyDst:9  = @hgrscanh
hgrCopySrc:1   = @clipsrc
_hgrCopySrc:1  = @hgrscanl
_hgrCopySrc:6  = @drawbuff.1
_hgrCopySrc:9  = @hgrscanh
hgrAndSrc:1    = @clipsrc
_hgrAndSrc:1   = @hgrscanl
_hgrAndSrc:6   = @drawbuff.1
_hgrAndSrc:9   = @hgrscanh
hgrXorSrc:1    = @clipsrc
_hgrXorSrc:1   = @hgrscanl
_hgrXorSrc:6   = @drawbuff.1
_hgrXorSrc:9   = @hgrscanh
hgrOrSrc:1     = @clipsrc
_hgrOrSrc:1    = @hgrscanl
_hgrOrSrc:6    = @drawbuff.1
_hgrOrSrc:9    = @hgrscanh
_hgrPlotA:1    = @hgrscanl
_hgrPlotA:6    = @drawbuff.1
_hgrPlotA:9    = @hgrscanh
_hgrPlotB:1    = @divmod7
_hgrPlotC:1    = @hbmask
_hgrPlotD:1    = @curhclr
_hgrXorPlotA:1 = @hgrscanl
_hgrXorPlotA:6 = @drawbuff.1
_hgrXorPlotA:9 = @hgrscanh
_hgrXorPlotB:1 = @divmod7
_hgrXorPlotC:1 = @hbmask
_hgrXorPlotD:1 = @curhclr
_hgrOrPlotA:1  = @hgrscanl
_hgrOrPlotA:6  = @drawbuff.1
_hgrOrPlotA:9  = @hgrscanh
_hgrOrPlotB:1  = @divmod7
_hgrOrPlotC:1  = @hbmask
_hgrOrPlotD:1  = @curhclr
_hgrHLinA:1    = @hgrPlot
_hgrHLinB:1    = @hgrscanl
_hgrHLinB:6    = @drawbuff.1
_hgrHLinB:9    = @hgrscanh
_hgrHLinC:1    = @divmod7
_hgrHLinD:1    = @hrmask
_hgrHLinE:1    = @divmod7
_hgrHLinF:1    = @hlmask
_hgrHLinG:1    = @curhclr.1
_hgrHLinG:6    = @curhclr
_hgrHLinG:13   = @curhclr
_hgrHLinG:18   = @curhclr.1
_hgrXHLinA:1   = @hgrXorPlot
_hgrXHLinB:1   = @hgrscanl
_hgrXHLinB:6   = @drawbuff.1
_hgrXHLinB:9   = @hgrscanh
_hgrXHLinC:1   = @divmod7
_hgrXHLinD:1   = @hrmask
_hgrXHLinE:1   = @divmod7
_hgrXHLinF:1   = @hlmask
_hgrXHLinG:1   = @curhclr.1
_hgrXHLinG:6   = @curhclr
_hgrXHLinG:13  = @curhclr
_hgrXHLinG:18  = @curhclr.1
hgrVLin:1      = @divmod7
_hgrVLinA:1    = @hbmask
_hgrVLinB:1    = @curhclr
_hgrVLinC:1    = @hgrscanl
_hgrVLinC:6    = @drawbuff.1
_hgrVLinC:9    = @hgrscanh
hgrXorVLin:1   = @divmod7
_hgrXVLinA:1   = @hbmask
_hgrXVLinB:1   = @curhclr
_hgrXVLinC:1   = @hgrscanl
_hgrXVLinC:6   = @drawbuff.1
_hgrXVLinC:9   = @hgrscanh
hgrColor:7     = @hcolor
hgrColor:10    = @curhclr
hgrColor:13    = @hcolor.1
hgrColor:16    = @curhclr.1
_scanBLTA:1    = @hgrColor
_scanBLTB:1    = @hgrPlot
_scanBLTB:8    = @hgrOrPlot
_scanBLTC:1    = @hgrColor
_scanBLTD:1    = @hgrPlot
_scanBLTD:8    = @hgrOrPlot
//
// Keep module in memory
//
return modkeep
done
