From 0b750d46c5dfb9096ecfc85e19184d8a05cd0ccf Mon Sep 17 00:00:00 2001
From: Dave Schmenk <dschmenk@gmail.com>
Date: Wed, 18 Dec 2019 18:59:24 -0800
Subject: [PATCH] Back to fun HGR stuff

---
 src/libsrc/line.pla        | 113 ++++++++++++++
 src/makefile               |   7 +-
 src/samplesrc/hgr1test.pla | 143 +++++++++++++++++-
 src/samplesrc/hgrtest.pla  | 300 +++++++++++++++++++++++++++++++++++++
 4 files changed, 561 insertions(+), 2 deletions(-)
 create mode 100644 src/libsrc/line.pla
 create mode 100644 src/samplesrc/hgrtest.pla

diff --git a/src/libsrc/line.pla b/src/libsrc/line.pla
new file mode 100644
index 0000000..b1ebd91
--- /dev/null
+++ b/src/libsrc/line.pla
@@ -0,0 +1,113 @@
+var hspan, vspan
+var err, shorterr, shortlen, longerr, longlen
+
+export def linespans(h, v)#0
+    hspan = h
+    vspan = v
+end
+def majorline(ps, major, majorend, minor, dir, majorspan)#0
+    //
+    // Initial half-span step
+    //
+    err = err + shorterr
+    repeat
+        majorspan(ps, major, minor)#0
+        minor = minor + dir     // Move to next span
+        ps    = major + 1       // Start of next span = end of previous + 1
+        if err >= 0             // Short span
+            err   = err   + shorterr
+            major = major + shortlen
+        else                    // Long span
+            err   = err   + longerr
+            major = major + longlen
+        fin
+    until major >= majorend
+    //
+    // Final half-span step
+    //
+    majorspan(ps, majorend, minor)#0
+end
+export def line(x1, y1, x2, y2)#0
+    var dx, dy, dx2, dy2, halflen, rem, sx, sy
+    
+    sx = 1
+    sy = 1
+    dx = x2 - x1
+    if dx < 0
+        sx  = -1; dx = -dx
+    fin
+    dy = y2 - y1
+    if dy < 0
+        sy  = -1; dy = -dy
+    fin
+    if dx >= dy
+        if sx < 0
+            x1, x2 = x2, x1; sy = -sy
+        fin
+        if dy == 0
+            hspan(x1, x2, y1)#0; return
+        fin
+        //
+        // Half-span length and error
+        //
+        dy2          = dy * 2
+        halflen, rem = divmod(dx, dy2)
+        err          = dy2 - rem
+        //
+        // Long-span length = half-span length * 2
+        //
+        longlen = (halflen + 1) * 2
+        longerr = err * 2
+        if longerr >= dy2
+            longerr = longerr - dy2
+            longlen--
+        fin
+        //
+        // Short-span length = long-span length - 1
+        //
+        shortlen = longlen - 1
+        shorterr = longerr - dy2
+        //
+        // Initial half-span step
+        //
+        err = err + shorterr
+        ps  = x1
+        x1  = x1 + halflen
+        //
+        // JIT optimize inner loop
+        //
+        majorline(x1, x1 + halflen, x2, y1, sy, hspan)
+        //
+        // Final half-span step
+        //
+        hspan(ps, x2, y2)#0
+    else
+        if sy < 0
+            x1, x2 = x2, x1; sx = -sx
+        fin
+        if dx == 0
+            vspan(y1, y2, x1)#0; return
+        fin
+        //
+        // Half-span length and error
+        //
+        dx2          = dx * 2
+        halflen, rem = divmod(dy, dx2)
+        err          = dx2 - rem
+        //
+        // Long-span length = half-span length * 2
+        //
+        longlen = (halflen + 1) * 2
+        longerr = err * 2
+        if longerr >= dx2
+            longerr = longerr - dx2
+            longlen--
+        fin
+        shortlen = longlen - 1
+        shorterr = longerr - dx2
+        //
+        // JIT optimize inner loop
+        //
+        majorline(y1, y1 + halflen, y2, x1, sx, vspan)
+    fin
+end
diff --git a/src/makefile b/src/makefile
index 9699cf1..b245a4f 100755
--- a/src/makefile
+++ b/src/makefile
@@ -57,6 +57,7 @@ ROGUEMAP   = rel/ROGUEMAP\#FE1000
 ROGUECOMBAT= rel/ROGUECOMBAT\#FE1000
 MON        = rel/apple/MON\#FE1000
 DGRTEST    = rel/apple/DGRTEST\#FE1000
+HGRTEST    = rel/apple/HGRTEST\#FE1000
 MEMMGR     = rel/MEMMGR\#FE1000
 MEMTEST    = rel/MEMTEST\#FE1000
 FIBERTEST  = rel/FIBERTEST\#FE1000
@@ -86,7 +87,7 @@ TXTTYPE	= .TXT
 #SYSTYPE	= \#FF2000
 #TXTTYPE	= \#040000
 
-apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(PRIMEGAP) $(MOUSE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(TFTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(LZ4) $(LZ4CAT) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
+apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(PRIMEGAP) $(MOUSE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(TFTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(HGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(LZ4) $(LZ4CAT) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
 	-rm vmsrc/plvmzp.inc
 
 c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64) 
@@ -384,6 +385,10 @@ $(DGRTEST): samplesrc/dgrtest.pla $(PLVM02) $(PLASM)
 	./$(PLASM) -AMOW < samplesrc/dgrtest.pla > samplesrc/dgrtest.a
 	acme --setpc 4094 -o $(DGRTEST) samplesrc/dgrtest.a
 
+$(HGRTEST): samplesrc/hgrtest.pla $(PLVM02) $(PLASM)
+	./$(PLASM) -AMOW < samplesrc/hgrtest.pla > samplesrc/hgrtest.a
+	acme --setpc 4094 -o $(HGRTEST) samplesrc/hgrtest.a
+
 $(MON): samplesrc/mon.pla $(PLVM02) $(PLASM)
 	./$(PLASM) -AMOW < samplesrc/mon.pla > samplesrc/mon.a
 	acme --setpc 4094 -o $(MON) samplesrc/mon.a
diff --git a/src/samplesrc/hgr1test.pla b/src/samplesrc/hgr1test.pla
index 97ace56..be149cc 100644
--- a/src/samplesrc/hgr1test.pla
+++ b/src/samplesrc/hgr1test.pla
@@ -93,9 +93,140 @@ 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 hcolor[]  = $0000,$552A,$2A55,$7F7F,$8080,$D5AA,$AAD5,$FFFF
-
+word hmask     = $8081,$8082,$8084,$8088,$8090,$80A0,$80C0
+               = $8180,$8280,$8480,$8880,$9080,$A080,$C080
+word curhclr
 word ball0[9] = $0000, $1800, $3C00, $7E00, $7E00, $3C00, $1800, $0000
 
+var hspan, vspan
+export def spans(h, v)#0
+    hspan = h
+    vspan = v
+end
+export def line(x1, y1, x2, y2)#0
+    var dx2, dy2, err, sx, sy, ps
+    var shorterr, shortlen, longerr, longlen, halflen
+
+    sx = sy = 1
+    dx2 = (x2 - x1) * 2
+    if dx2 < 0
+        sx  = -1; dx2 = -dx2
+    fin
+    dy2 = (y2 - y1) * 2
+    if dy2 < 0
+        sy  = -1; dy2 = -dy2
+    fin
+    if dx2 >= dy2
+        if sx < 0
+            x1, x2 = x2, x1; sy = -sy
+        fin
+        if dy2 == 0
+            hspan(x1, x2, y1)#0; return
+        fin
+        ps  = x1
+        for err = dy2 - dx2 / 2 to 0 step dy2 // Find first half-span length and error
+            x1++
+        next
+        longlen = (x1 - ps + 1) * 2 // Long-span length = half-span length * 2
+        longerr = err * 2
+        if longerr >= dy2
+            longerr = longerr - dy2
+            longlen--
+        fin
+        shortlen = longlen - 1 // Short-span length = long-span length - 1
+        shorterr = longerr - dy2
+        err      = err + shorterr // Do a short-span step
+        while x1 < x2
+            hspan(ps, x1, y1)#0
+            y1 = y1 + sy     // Move to next span
+            ps = x1 + 1 // Start of next span = end of previous span + 1
+            if err >= 0 // Short span
+                err = err + shorterr
+                x1  = x1  + shortlen
+            else          // Long span
+                err = err + longerr
+                x1  = x1  + longlen
+            fin
+        loop
+        hspan(ps, x2, y2)#0 // Final span
+    else
+        if sy < 0
+            x1, x2 = x2, x1; sx = -sx
+        fin
+        if dx2 == 0
+            vspan(x1, y1, y2)#0; return
+        fin
+        ps  = y1
+        for err = dx2 - dy2 / 2 to 0 step dx2 // Find first half-span length and error
+            y1++
+        next
+        longlen = (y1 - ps + 1) * 2
+        longerr = err * 2
+        if longerr >= dx2
+            longerr -= longerr - dx2
+            longlen--
+        fin
+        shortlen = longlen - 1
+        shorterr = longerr - dx2
+        err      = err + shorterr
+        while y1 < y2
+            vspan(x1, ps, y1)#0
+            x1 = x1 + sx
+            ps  = y1 + 1
+            if err >= 0 // Short span
+                err = err + shorterr
+                y1  = y1  + shortlen
+            else          // Long span
+                err = err + longerr
+                y1  = y1  + longlen
+            fin
+        loop
+        vspan(x2, ps, y2)#0 // Final span
+    fin
+end
+def hgrPlot(x, y)#0
+    var pscan, bytofst, pixofst, pmask, pword
+    
+    pscan = hgrscan[y] | hgr1
+    wrdofst, pixofst = divmod(x, 14)
+    pmask = hmask[pixofst]
+    pword = pscan=>[wrdofst] & ~pmask
+    pscan=>[wrdofst] = pword | (curhclr & pmask)
+end
+def hgrHlin(x1, x2, y)#0
+    var pscan, bytofst, pixofst, pmask, pword
+    
+    pscan = hgrscan[y] | hgr1
+    wrdofst, pixofst = divmod(x1, 14)
+    repeat
+        pmask = hmask[pixofst]
+        pword = pscan=>[wrdofst] & ~pmask
+        pscan=>[wrdofst] = pword | (curhclr & pmask)
+        pixofst++
+        if pixofst > 13
+            pixofst = 0
+            wrdofst++
+        fin
+        x1++
+    until x1 > x2
+end
+def hgrVlin(x, y1, y2)#0
+    var pscan, bytofst, pixofst, pmask, pword, cmask
+    
+    wrdofst, pixofst = divmod(x, 14)
+    pmask = hmask[pixofst]
+    cmask = curhclr & pmask
+    pmask = ~pmask
+    repeat
+        pscan = hgrscan[y1] | hgr1
+        pword = pscan=>[wrdofst] & pmask
+        pscan=>[wrdofst] = pword | cmask
+        y1++
+    until y1 > y2
+end
+def hgrColor(c)#0
+    curhclr = hcolor[c & 0x07]
+end
 def hgrBLT(page, x, y, w, h, pSrc)#0
     word pDst
     byte i
@@ -110,11 +241,21 @@ def hgrBLT(page, x, y, w, h, pSrc)#0
         h--
     until not h
 end
+def testline
+    var i
+    
+    spans(@hgrHlin, @hgrVlin)
+    hgrColor(7)
+    for i = 0 to 100
+        hgrPlot(i, i)
+    next
+end
 memset(hgr1, 0, $2000) // Clear HGR page 1
 ^showpage1
 ^showfull
 ^showhires
 ^showgraphics
+testline
 hgrBlt(hgrpage[0], 20, 100, 2, 8, @ball0)
 getc
 ^showpage1
diff --git a/src/samplesrc/hgrtest.pla b/src/samplesrc/hgrtest.pla
new file mode 100644
index 0000000..1d48881
--- /dev/null
+++ b/src/samplesrc/hgrtest.pla
@@ -0,0 +1,300 @@
+include "inc/cmdsys.plh"
+sysflags reshgr1 // Reserve HGR page 1
+//
+// 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
+word hgrpage[] = 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 hcolor[]  = $0000,$552A,$2A55,$7F7F,$8080,$D5AA,$AAD5,$FFFF
+word hmask     = $8081,$8082,$8084,$8088,$8090,$80A0,$80C0
+word           = $8180,$8280,$8480,$8880,$9080,$A080,$C080
+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 curhclr
+word ball0[9] = $0000, $1800, $3C00, $7E00, $7E00, $3C00, $1800, $0000
+
+var pixel, hspan, vspan
+var err, shorterr, shortlen, longerr, longlen
+var dx2, dy2, sx, sy
+
+export def linefuncs(p, h, v)#0
+    pixel = p
+    hspan = h
+    vspan = v
+end
+def phline(x1, x2, y)#0
+    var x
+    
+    if sx < 0
+        sy = -sy; x1, x2 = x2, x1
+    fin
+    err = dy2 - dx2 / 2
+    for x = x1 to x2
+        pixel(x, y)#0
+        if err >= 0
+            err = err - dx2
+            y  = y + sy
+        fin
+        err = err + dy2
+    next
+end
+def pvline(y1, y2, x)#0
+    var y
+    
+    if sy < 0
+        sx = -sx; y1, y2 = y2, y1
+    fin
+    err = dx2 - dy2 / 2
+    for y = y1 to y2
+        pixel(x, y)#0
+        if err >= 0
+            err = err - dy2
+            x   = x + sx
+        fin
+        err = err + dx2
+    next
+end
+def pline(x1, y1, x2, y2)#0
+    sx = 1
+    sy = 1
+    dx2 = (x2 - x1) * 2
+    if dx2 < 0
+        sx  = -1; dx2 = -dx2
+    fin
+    dy2 = (y2 - y1) * 2
+    if dy2 < 0
+        sy  = -1; dy2 = -dy2
+    fin
+    if dx2 >= dy2
+        phline(x1, x2, y1)
+   else
+        pvline(y1, y2, x1)
+    fin
+end
+def majorline(ps, major, majorend, minor, dir, majorspan)#0
+    //
+    // Initial half-span step
+    //
+    err   = err + shorterr
+    repeat
+        majorspan(ps, major, minor)#0
+        minor = minor + dir     // Move to next span
+        ps    = major + 1       // Start of next span = end of previous + 1
+        if err >= 0             // Short span
+            err   = err   + shorterr
+            major = major + shortlen
+        else                    // Long span
+            err   = err   + longerr
+            major = major + longlen
+        fin
+    until major >= majorend
+    //
+    // Final half-span step
+    //
+    majorspan(ps, majorend, minor)#0
+end
+export def sline(x1, y1, x2, y2)#0
+    var dx, dy, dx2, dy2, halflen, rem, sx, sy
+    
+    sx = 1
+    sy = 1
+    dx = x2 - x1
+    if dx < 0
+        sx  = -1; dx = -dx
+    fin
+    dy = y2 - y1
+    if dy < 0
+        sy  = -1; dy = -dy
+    fin
+    if dx >= dy
+        if sx < 0
+            x1, x2 = x2, x1; sy = -sy
+        fin
+        if dy == 0
+            hspan(x1, x2, y1)#0; return
+        fin
+        //
+        // Half-span length and error
+        //
+        dy2          = dy * 2
+        halflen, rem = divmod(dx, dy2)
+        err          = dy2 - rem
+        //
+        // Long-span length = half-span length * 2
+        //
+        longlen = (halflen + 1) * 2
+        longerr = err * 2
+        if longerr >= dy2
+            longerr = longerr - dy2
+            longlen--
+        fin
+        //
+        // Short-span length = long-span length - 1
+        //
+        shortlen = longlen - 1
+        shorterr = longerr - dy2
+        //
+        // JIT optimize inner loop
+        //
+        majorline(x1, x1 + halflen, x2, y1, sy, hspan)
+    else
+        if sy < 0
+            x1, x2 = x2, x1; sx = -sx
+        fin
+        if dx == 0
+            vspan(y1, y2, x1)#0; return
+        fin
+        //
+        // Half-span length and error
+        //
+        dx2          = dx * 2
+        halflen, rem = divmod(dy, dx2)
+        err          = dx2 - rem
+        //
+        // Long-span length = half-span length * 2
+        //
+        longlen = (halflen + 1) * 2
+        longerr = err * 2
+        if longerr >= dx2
+            longerr = longerr - dx2
+            longlen--
+        fin
+        shortlen = longlen - 1
+        shorterr = longerr - dx2
+        //
+        // JIT optimize inner loop
+        //
+        majorline(y1, y1 + halflen, y2, x1, sx, vspan)
+    fin
+end
+
+def hgrPlot(x, y)#0
+    word pptr
+    byte ofst, pixofst, pmask
+    
+    ofst, pixofst = divmod(x, 7)
+    pptr = (hgrscan[y] | hgr1) + ofst
+    pmask = hbmask[pixofst]
+    ^pptr = (^pptr & ~pmask) | (curhclr.[ofst & 1] & pmask)
+end
+def hgrHlin(x1, x2, y)#0
+    word pptr, x
+    byte lofst, lpixofst, lpmask, clr
+    byte rofst, rpixofst, rpmask
+    
+    if x1 == x2
+        hgrPlot(x1, y)
+    else
+        lofst, lpixofst = divmod(x1, 7)
+        pptr = (hgrscan[y] | hgr1) + lofst
+        rofst, rpixofst = divmod(x2, 7)
+        lpmask = hlmask[lpixofst]
+        rpmask = hrmask[rpixofst]
+        if lofst == rofst
+            lpmask = lpmask & rpmask
+            ^pptr = (^pptr & ~lpmask) | (curhclr.[pptr.0 & 1] & lpmask)
+        else
+            ^pptr = (^pptr & ~lpmask) | (curhclr.[pptr.0 & 1] & lpmask)
+            pptr++
+            for x = lofst + 1 to rofst - 1
+                ^pptr = curhclr.[pptr.0 & 1]
+                pptr++
+            next
+            ^pptr = (^pptr & ~rpmask) | (curhclr.[pptr.0 & 1] & rpmask)
+        fin
+    fin
+end
+def hgrVlin(y1, y2, x)#0
+    word pptr, y
+    byte ofst, pixofst, pmask, cmask
+    
+    ofst, pixofst = divmod(x, 7)
+    pmask = hbmask[pixofst]
+    cmask = curhclr.[ofst & 1] & pmask
+    pmask = ~pmask
+    for y = y1 to y2
+        pptr = (hgrscan[y] | hgr1) + ofst
+        ^pptr = (^pptr & pmask) | cmask
+    next
+end
+def hgrColor(c)#0
+    curhclr = hcolor[c & $07]
+end
+def hgrBLT(page, x, y, w, h, pSrc)#0
+    word pDst
+    byte i
+
+    repeat
+        pDst = hgrscan[y] | page + x
+        for i = 0 to w - 1
+            pDst->[i] = pSrc->[i]
+        next
+        pSrc = pSrc + w
+        y++
+        h--
+    until not h
+end
+def testline#0
+    var i
+    
+    linefuncs(@hgrPlot, @hgrHlin, @hgrVlin)
+    hgrColor(3)
+    for i = 0 to 191
+        pline(0, 0, i, 191)
+        pline(0, 0, 191, i)
+    next
+    hgrColor(0);
+    for i = 0 to 191
+        sline(0, 0, i, 191)
+        sline(0, 0, 191, i)
+    next
+end
+memset(hgr1, 0, $2000) // Clear HGR page 1
+^showpage1
+^showfull
+^showhires
+^showgraphics
+testline
+hgrBlt(hgrpage[0], 20, 100, 2, 8, @ball0)
+getc
+^showpage1
+^showtext
+done