examples cleanup and improving c64 graphics module (shift bitmap to higher ram area)

This commit is contained in:
Irmen de Jong 2023-09-05 19:48:22 +02:00
parent c15c10a94e
commit 31458ffd81
13 changed files with 74 additions and 638 deletions

View File

@ -1,35 +1,42 @@
%import textio
; bitmap pixel graphics module for the C64
; only black/white monochrome 320x200 for now
; assumes bitmap screen memory is $2000-$3fff
;
; Sets character matrix and bitmap screen memory at a higher memory location $5c00-$7fff
; so that the program itself can be larger without starting to overwrite the graphics memory.
graphics {
%option no_symbol_prefixing
const uword BITMAP_ADDRESS = $2000
const uword WIDTH = 320
const ubyte HEIGHT = 200
const uword BITMAP_ADDRESS = $6000 ; MUST BE IN REGULAR RAM if you are not messing with ROM/RAM banking.
const uword CHARS_ADDRESS = $5c00 ; must be in same vic bank as the bitmap
sub enable_bitmap_mode() {
; enable bitmap screen, erase it and set colors to black/white.
c64.SCROLY = %00111011
c64.SCROLX = %00001000
c64.VMCSB = (c64.VMCSB & %11110000) | %00001000 ; $2000-$3fff
clear_screen(1, 0)
c64.SCROLY = %00111011 ; enable bitmap graphics mode
c64.SCROLX = %00001000 ; 40 column mode, no scrolling, multicolor bitmap off
c64.VMCSB = (lsb(CHARS_ADDRESS >> 6) & $F0) | (((BITMAP_ADDRESS & $3fff) / $0800) << 1) ; set bitmap address
c64.CIA2DDRA |= %11
c64.CIA2PRA = lsb(BITMAP_ADDRESS >> 14) ^ 3 ; set VIC bank.
}
sub disable_bitmap_mode() {
; enables text mode, erase the text screen, color white
c64.SCROLY = %00011011
c64.SCROLX = %00001000
c64.VMCSB = (c64.VMCSB & %11110000) | %00000100 ; $1000-$2fff
txt.fill_screen(' ', 1)
; enables erase the text screen, text mode
sys.memset(CHARS_ADDRESS, 40*25, sc:' ')
c64.SCROLY = %00011011 ; disable bitmap graphics mode
c64.SCROLX = %00001000 ; 40 column mode, no scrolling
c64.VMCSB = %00010100 ; screen addresses back to defaults
c64.CIA2DDRA |= %11
c64.CIA2PRA = %11 ; back to VIC bank 0.
}
sub clear_screen(ubyte pixelcolor, ubyte bgcolor) {
sys.memset(BITMAP_ADDRESS, 320*200/8, 0)
txt.fill_screen(pixelcolor << 4 | bgcolor, 0)
sys.memset(CHARS_ADDRESS, 40*25, pixelcolor << 4 | bgcolor)
sys.memset(cbm.Colors, 40*25, 255)
}
sub line(uword @zp x1, ubyte @zp y1, uword @zp x2, ubyte @zp y2) {
@ -352,7 +359,7 @@ _ormask .byte 128, 64, 32, 16, 8, 4, 2, 1
; the y lookup tables encodes this formula: BITMAP_ADDRESS + 320*(py>>3) + (py & 7) (y from 0..199)
; We use the 64tass syntax for range expressions to calculate this table on assembly time.
_plot_y_values := $2000 + 320*(range(200)>>3) + (range(200) & 7)
_plot_y_values := BITMAP_ADDRESS + 320*(range(200)>>3) + (range(200) & 7)
_y_lookup_lo .byte <_plot_y_values
_y_lookup_hi .byte >_plot_y_values

View File

@ -136,6 +136,7 @@ c64 {
%option no_symbol_prefixing
; the default locations of the 8 sprite pointers (store address of sprite / 64)
; (depending on the VIC bank and screen ram address selection these can be shifted around though)
&ubyte SPRPTR0 = 2040
&ubyte SPRPTR1 = 2041
&ubyte SPRPTR2 = 2042

View File

@ -29,7 +29,7 @@ graphics {
sub disable_bitmap_mode() {
; enables text mode, erase the text screen, color white
void cx16.screen_mode(0, false)
txt.fill_screen(' ', 1) ; doesn't seem to fully clear the text screen after returning from gfx mode
txt.clear_screen()
}

View File

@ -109,18 +109,14 @@ class TestCompilerOnExamplesCx16: FunSpec({
"colorbars",
"cube3d",
"cxlogo",
"datetime",
"diskspeed",
"fileseek",
"highresbitmap",
"kefrenbars",
"keyboardhandler",
"mandelbrot",
"mandelbrot-gfx-colors",
"multipalette",
"plasma",
"rasterbars",
"sincos",
"snow",
"spotlight",
"tehtriz",
@ -159,6 +155,7 @@ class TestCompilerOnExamplesBothC64andCx16: FunSpec({
"numbergame",
"primes",
"screencodes",
"sincos",
"sorting",
"swirl",
"swirl-float",

View File

@ -326,10 +326,9 @@ Bitmap graphics routines:
- drawing individual pixels
- drawing lines, rectangles, filled rectangles, circles, discs
This library is available both on the C64 and the Cx16.
This library is available both on the C64 and the cx16.
It uses the ROM based graphics routines on the latter, and it is a very small library because of that.
That also means though that it is constrained to 320*200 resolution on the Cx16 as well.
Use the ``gfx2`` library if you want full-screen graphics or non-monochrome drawing (only on Cx16). See below for that one.
On the cx16 there's also the ``gfx2`` library if you want full-screen graphics or non-monochrome drawing. See below for that one.
Read the `source code <https://github.com/irmen/prog8/tree/master/compiler/res/prog8lib/c64/graphics.p8>`_
to see what's in there. (Note: slight variations for different compiler targets)

View File

@ -13,10 +13,7 @@ main {
charset.make_custom_charset()
; activate the new charset in RAM
ubyte block = c64.CIA2PRA
const ubyte PAGE1 = ((cbm.Screen >> 6) & $F0) | ((charset.CHARSET >> 10) & $0E)
c64.CIA2PRA = (block & $FC) | (lsb(cbm.Screen >> 14) ^ $03)
c64.VMCSB = PAGE1
txt.print("\n @ @ @ @\n")

View File

@ -1,6 +1,5 @@
%import floats
%import graphics
%import test_stack
%zeropage floatsafe
@ -9,9 +8,10 @@ main {
sub start() {
graphics.enable_bitmap_mode()
turtle.init()
; turtle.pu()
; turtle.pos(150, 110)
; turtle.pd()
turtle.pu()
turtle.pos(150, 110)
turtle.pd()
ubyte i
for i in 0 to 100 {
@ -19,8 +19,6 @@ main {
turtle.rt(94)
}
; test_stack.test()
repeat {
}
}
@ -38,7 +36,11 @@ turtle {
angle = 0.0
pendown = true
c64.SPRPTR[0] = $0d00 / 64
const uword SPRITE_MEMORY = $5800
const uword SPRITE_ADDR_POINTERS = (graphics.CHARS_ADDRESS & $fc00) + 1016 ; no longer the default location 2040!
sys.memcopy(&turtlesprite, SPRITE_MEMORY, len(turtlesprite))
@(SPRITE_ADDR_POINTERS) = (SPRITE_MEMORY & $3fff) / 64
c64.SPENA = 1
c64.SP0COL = 5
@ -88,32 +90,26 @@ turtle {
sub pd() {
pendown = true
}
}
spritedata $0d00 {
; this memory block contains the sprite data
; it must start on an address aligned to 64 bytes.
%option force_output ; make sure the data in this block appears in the resulting program
ubyte[] balloonsprite = [ %00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%01111110,%00000000,
%00000000,%11000011,%00000000,
%00000000,%11000011,%00000000,
%00000000,%11000011,%00000000,
%00000000,%01111110,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000 ]
ubyte[] turtlesprite = [ %00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%01111110,%00000000,
%00000000,%11000011,%00000000,
%00000000,%11000011,%00000000,
%00000000,%11000011,%00000000,
%00000000,%01111110,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000,
%00000000,%00000000,%00000000 ]
}

View File

@ -69,12 +69,6 @@ main {
return sqrt(sqx + sqy)
}
; sub distance(ubyte cix) -> uword {
; float dx = x as float - circle_x[cix]
; float dy = y as float - circle_y[cix]
; return floats.sqrt(dx*dx + dy*dy) as uword
; }
sub not_edge() -> bool {
if x as word - radius < 0
return false

View File

@ -1,59 +0,0 @@
; CommanderX16 text datetime example!
%import textio
%zeropage basicsafe
main {
sub start() {
cx16.clock_set_date_time(mkword(8, 2022 - 1900), mkword(19, 27), mkword(30, 16), 0)
txt.lowercase()
repeat {
txt.chrout(19) ; HOME
txt.print("\n yyyy-mm-dd HH:MM:SS.jj\n\n")
void cx16.clock_get_date_time()
txt.spc()
print_date()
txt.spc()
print_time()
txt.nl()
txt.nl()
uword jiffies = cbm.RDTIM16()
txt.print_uw(jiffies)
}
}
sub print_date() {
txt.print_uw(1900 + lsb(cx16.r0))
txt.chrout('-')
if msb(cx16.r0) < 10
txt.chrout('0')
txt.print_ub(msb(cx16.r0))
txt.chrout('-')
if lsb(cx16.r1) < 10
txt.chrout('0')
txt.print_ub(lsb(cx16.r1))
}
sub print_time() {
if msb(cx16.r1) < 10
txt.chrout('0')
txt.print_ub(msb(cx16.r1))
txt.chrout(':')
if lsb(cx16.r2) < 10
txt.chrout('0')
txt.print_ub(lsb(cx16.r2))
txt.chrout(':')
if msb(cx16.r2) < 10
txt.chrout('0')
txt.print_ub(msb(cx16.r2))
txt.chrout('.')
if lsb(cx16.r3) < 10
txt.chrout('0')
txt.print_ub(lsb(cx16.r3))
}
}

View File

@ -1,88 +0,0 @@
%import textio
%import floats
%zeropage basicsafe
main {
const uword width = 256
const uword height = 240
const ubyte max_iter = 16 ; 32 actually looks pretty nice but takes longer
sub start() {
initialize()
mandel()
repeat {
; do nothing
}
}
sub mandel() {
const float XL=-2.200
const float XU=0.800
const float YL=-1.300
const float YU=1.300
const float dx = (XU-XL)/width
const float dy = (YU-YL)/height
ubyte pixelx
ubyte pixely
for pixely in 0 to height-1 {
float yy = YL+dy*(pixely as float)
cx16.FB_cursor_position(0, pixely)
for pixelx in 0 to width-1 {
float xx = XL+dx*(pixelx as float)
float xsquared = 0.0
float ysquared = 0.0
float x = 0.0
float y = 0.0
ubyte iter = 0
while iter<max_iter and xsquared+ysquared<4.0 {
y = x*y*2.0 + yy
x = xsquared - ysquared + xx
xsquared = x*x
ysquared = y*y
iter++
}
cx16.FB_set_pixel(max_iter-iter)
}
print_time()
}
}
sub initialize() {
void cx16.screen_mode($80, false)
txt.plot(32, 5)
txt.print("256*240")
txt.plot(32, 6)
txt.print("mandel-")
txt.plot(33, 7)
txt.print("brot")
txt.plot(32, 9)
txt.print("floats")
txt.plot(32, 10)
txt.print_b(max_iter)
txt.print(" iter")
cx16.clock_set_date_time(0, 0, 0, 0)
cx16.r0=0
cx16.FB_init()
}
sub print_time() {
void cx16.clock_get_date_time()
txt.plot(33, 12)
if lsb(cx16.r2) < 10
txt.chrout('0')
txt.print_ub(lsb(cx16.r2))
txt.chrout(':')
if msb(cx16.r2) < 10
txt.chrout('0')
txt.print_ub(msb(cx16.r2))
}
}

View File

@ -1,414 +0,0 @@
%import palette
%import gfx2
%option no_sysinit
main {
sub start() {
; palette.set_rgb(&colors, len(colors))
void cx16.screen_mode(128, false) ; low-res bitmap 256 colors
cx16.FB_init()
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00010000 ; enable only layer 0
cx16.VERA_L0_CONFIG = %00000110 ; 4 bpp = 16 colors
;cx16.VERA_L0_MAPBASE = 0
;cx16.VERA_L0_TILEBASE = 0
ubyte pix=0
ubyte ypos
cx16.FB_cursor_position(0, 0)
for ypos in 0 to 239 {
repeat 320/2 {
cx16.FB_set_pixel((pix&15)<<4 | (pix&15))
pix++
}
pix=0
}
; color index 0 can't be swapped - set it to black in both ranges
palette.set_color(0, 0)
palette.set_color(16, 0)
sys.set_rasterirq(&irq.irqhandler, 0)
repeat {
; don't exit
}
}
}
irq {
ubyte phase = 0
uword next_rasterline = 0
const ubyte increment = 4 ; 4 scanlines = 2 lores pixels per color swap (2 scanlines is too tight)
sub irqhandler() {
if phase & 1 == 0 {
%asm {{
lda #0 ; activate palette #0 (first set of colors)
sta cx16.VERA_L0_HSCROLL_H
stz cx16.VERA_CTRL
lda #<$fa00+32+2
sta cx16.VERA_ADDR_L
lda #>$fa00+32+2
sta cx16.VERA_ADDR_M
lda #%00010001
sta cx16.VERA_ADDR_H
; change 15 palette entries 1..15 (0 is fixed)
lda #<$e000
sta $02
lda #>$e000
sta $02
ldy #0
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$0f
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
}}
}
else {
%asm {{
lda #1 ; activate palette #1 (second set of colors)
sta cx16.VERA_L0_HSCROLL_H
stz cx16.VERA_CTRL
lda #<$fa00+2
sta cx16.VERA_ADDR_L
lda #>$fa00+2
sta cx16.VERA_ADDR_M
lda #%00010001
sta cx16.VERA_ADDR_H
; change 15 palette entries 1..15 (0 is fixed)
lda #<$f000
sta $02
lda #>$f000
sta $02
ldy #0
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
iny
lda (2),y
sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
; lda #$ff
; sta cx16.VERA_DATA0
; lda #0
; sta cx16.VERA_DATA0
}}
}
phase++
next_rasterline += increment
if next_rasterline >= 480 {
next_rasterline = 0
phase = 0
}
sys.set_rasterline(next_rasterline)
;
; uword[16] colors1 = 0
; uword[16] colors2 = 200
;
; palette.set_rgb(colors1, len(colors1))
; palette.set_rgb(colors2, len(colors2))
}
}

View File

@ -1,4 +1,5 @@
%import math
%import textio
%import palette
; use the mouse to move the cursor around the screen
@ -16,6 +17,7 @@ main {
ubyte yy
void cx16.screen_mode(128, false)
cx16.mouse_config2(1)
txt.print("move the mouse for the spotlight.")
; prefill
for yy in 0 to HEIGHT-1 {

View File

@ -1,13 +1,12 @@
%import graphics
%import math
%import textio
%zeropage basicsafe
; Draw sine and cosine graphs. The sine and cosine functions are table lookups
; where the tables are generated by 64tass list functions.
; Note: this program is compatible with CX16 only.
; it doesn't work correctly on C64 because the bitmap screen data overlaps
; the program itself in memory $2000-...
; This uses the graphics library which works on multiple targets (C64, CX16)
main {
const uword width = 320
@ -17,18 +16,19 @@ main {
graphics.enable_bitmap_mode()
sincos255()
sys.wait(120)
sys.wait(60)
graphics.clear_screen(1, 0)
sincos180()
sys.wait(120)
sys.wait(60)
graphics.clear_screen(1, 0)
circles()
sys.wait(60)
repeat {
}
graphics.disable_bitmap_mode()
txt.print("done\n")
}
sub sincos255() {
@ -38,6 +38,7 @@ main {
ubyte pixelxb
byte pixelys
; unsigned
for pixelxb in 0 to 255 {
pixelyb = math.cos8u(pixelxb) / 2
graphics.plot(pixelxb, pixelyb+20)
@ -45,11 +46,12 @@ main {
graphics.plot(pixelxb, pixelyb+20)
}
; signed
for pixelxb in 0 to 255 {
pixelys = math.cos8(pixelxb) / 2
graphics.plot(pixelxb, pixelys as uword + 90)
graphics.plot(pixelxb, pixelys as ubyte + 90)
pixelys = math.sin8(pixelxb) / 2
graphics.plot(pixelxb, pixelys as uword + 90)
graphics.plot(pixelxb, pixelys as ubyte + 90)
}
}
@ -60,6 +62,7 @@ main {
ubyte pixelxb
byte pixelys
; signed
for pixelxb in 0 to 179 {
pixelyb = math.cosr8u(pixelxb) / 2
graphics.plot(pixelxb, pixelyb+20)
@ -67,11 +70,12 @@ main {
graphics.plot(pixelxb, pixelyb+20)
}
; unsigned
for pixelxb in 0 to 179 {
pixelys = math.cosr8(pixelxb) / 2
graphics.plot(pixelxb, pixelys as uword + 90)
graphics.plot(pixelxb, pixelys as ubyte + 90)
pixelys = math.sinr8(pixelxb) / 2
graphics.plot(pixelxb, pixelys as uword + 90)
graphics.plot(pixelxb, pixelys as ubyte + 90)
}
}