moved cx16 imageviewer into its own git repo. Version 6.0.

This commit is contained in:
Irmen de Jong 2021-01-23 23:31:50 +01:00
parent 997bc21feb
commit cdc6d9aa65
9 changed files with 23 additions and 946 deletions

View File

@ -1 +1 @@
6.0-SNAPSHOT
6.0

View File

@ -7,6 +7,7 @@ TODO
- why is there a beq _prog8_label_2_repeatend at the end of repeat loops? seems unused
- optimize swap of two memread values with index, using the same pointer expression/variable, like swap(@(ptr+1), @(ptr+2))
- implement the linked_list millfork benchmark
- use the 65c02 bit clear/set/test instructions for single-bit operations
- implement highres 4 color mode in gfx2
- make a retro amiga workbench 1.3 and/or 2.0 workbench "simulator" using that new gfx mode

View File

@ -12,43 +12,48 @@ main {
txt.lowercase()
repeat {
c64.CHROUT(19) ; HOME
txt.chrout(19) ; HOME
txt.print("\n yyyy-mm-dd HH:MM:SS.jj\n\n")
void cx16.clock_get_date_time()
c64.CHROUT(' ')
txt.chrout(' ')
print_date()
c64.CHROUT(' ')
txt.chrout(' ')
print_time()
}
txt.chrout('\n')
txt.chrout('\n')
uword jiffies = c64.RDTIM16()
txt.print_uw(jiffies)
}
}
sub print_date() {
txt.print_uw(1900 + lsb(cx16.r0))
c64.CHROUT('-')
txt.chrout('-')
if msb(cx16.r0) < 10
c64.CHROUT('0')
txt.chrout('0')
txt.print_ub(msb(cx16.r0))
c64.CHROUT('-')
txt.chrout('-')
if lsb(cx16.r1) < 10
c64.CHROUT('0')
txt.chrout('0')
txt.print_ub(lsb(cx16.r1))
}
sub print_time() {
if msb(cx16.r1) < 10
c64.CHROUT('0')
txt.chrout('0')
txt.print_ub(msb(cx16.r1))
c64.CHROUT(':')
txt.chrout(':')
if lsb(cx16.r2) < 10
c64.CHROUT('0')
txt.chrout('0')
txt.print_ub(lsb(cx16.r2))
c64.CHROUT(':')
txt.chrout(':')
if msb(cx16.r2) < 10
c64.CHROUT('0')
txt.chrout('0')
txt.print_ub(msb(cx16.r2))
c64.CHROUT('.')
txt.chrout('.')
if lsb(cx16.r3) < 10
c64.CHROUT('0')
txt.chrout('0')
txt.print_ub(lsb(cx16.r3))
}
}

View File

@ -1,109 +0,0 @@
%target cx16
%import gfx2
%import diskio
bmp_module {
sub show_image(uword filenameptr) -> ubyte {
ubyte load_ok = false
ubyte[$36] header
uword size
uword width
uword height
ubyte bpp
uword offsetx
uword offsety
uword palette = memory("palette", 256*4)
uword total_read = 0
if diskio.f_open(8, filenameptr) {
size = diskio.f_read(header, $36)
if size==$36 {
total_read = $36
if header[0]=='b' and header[1]=='m' {
uword bm_data_offset = mkword(header[11], header[10])
uword header_size = mkword(header[$f], header[$e])
width = mkword(header[$13], header[$12])
height = mkword(header[$17], header[$16])
bpp = header[$1c]
uword num_colors = header[$2e]
if num_colors == 0
num_colors = 2**bpp
uword skip_hdr = header_size - 40
repeat skip_hdr
void c64.CHRIN()
total_read += skip_hdr
size = diskio.f_read(palette, num_colors*4)
if size==num_colors*4 {
total_read += size
repeat bm_data_offset - total_read
void c64.CHRIN()
gfx2.clear_screen()
custompalette.set_bgra(palette, num_colors)
decode_bitmap()
load_ok = true
}
}
}
diskio.f_close()
}
return load_ok
sub start_plot() {
offsetx = 0
offsety = 0
if width < gfx2.width
offsetx = (gfx2.width - width - 1) / 2
if height < gfx2.height
offsety = (gfx2.height - height - 1) / 2
if width > gfx2.width
width = gfx2.width
if height > gfx2.height
height = gfx2.height
}
sub decode_bitmap() {
start_plot()
uword bits_width = width * bpp
ubyte pad_bytes = (((bits_width + 31) >> 5) << 2) - ((bits_width + 7) >> 3) as ubyte
uword x
uword y
ubyte b
for y in height-1 downto 0 {
gfx2.position(offsetx, offsety+y)
when bpp {
8 -> {
for x in 0 to width-1
gfx2.next_pixel(c64.CHRIN())
}
4 -> {
for x in 0 to width-1 step 2 {
b = c64.CHRIN()
gfx2.next_pixel(b>>4)
gfx2.next_pixel(b&15)
}
}
2 -> {
for x in 0 to width-1 step 4 {
b = c64.CHRIN()
gfx2.next_pixel(b>>6)
gfx2.next_pixel(b>>4 & 3)
gfx2.next_pixel(b>>2 & 3)
gfx2.next_pixel(b & 3)
}
}
1 -> {
for x in 0 to width-1 step 8
gfx2.set_8_pixels_from_bits(c64.CHRIN(), 1, 0)
}
}
repeat pad_bytes
void c64.CHRIN()
}
}
}
}

View File

@ -1,362 +0,0 @@
%target cx16
%import gfx2
%import textio
%import diskio
iff_module {
uword cmap
uword num_colors
uword[16] cycle_rates
uword[16] cycle_rate_ticks
ubyte[16] cycle_reverseflags
ubyte[16] cycle_lows
ubyte[16] cycle_highs
ubyte num_cycles
sub show_image(uword filenameptr) -> ubyte {
ubyte load_ok = false
uword size
ubyte[32] buffer
uword camg = 0
str chunk_id = "????"
uword chunk_size_hi
uword chunk_size_lo
uword scanline_data_ptr = sys.progend()
uword width
uword height
ubyte num_planes
ubyte compression
ubyte have_cmap = false
ubyte cycle_crng = false
ubyte cycle_ccrt = false
num_cycles = 0
cmap = memory("palette", 256*4) ; only use 768 of these, but this allows re-use of the same block that the bmp module allocates
if diskio.f_open(8, filenameptr) {
size = diskio.f_read(buffer, 12)
if size==12 {
if buffer[0]=='f' and buffer[1]=='o' and buffer[2]=='r' and buffer[3]=='m'
and buffer[8]=='i' and buffer[9]=='l' and buffer[10]=='b' and buffer[11]=='m'{
while read_chunk_header() {
if chunk_id == "bmhd" {
void diskio.f_read(buffer, chunk_size_lo)
width = mkword(buffer[0], buffer[1])
height = mkword(buffer[2], buffer[3])
num_planes = buffer[8]
num_colors = 2 ** num_planes
compression = buffer[10]
}
else if chunk_id == "camg" {
void diskio.f_read(buffer, chunk_size_lo)
camg = mkword(buffer[2], buffer[3])
if camg & $0800 {
txt.print("ham mode not supported!\n")
break
}
}
else if chunk_id == "cmap" {
have_cmap = true
void diskio.f_read(cmap, chunk_size_lo)
}
else if chunk_id == "crng" {
; DeluxePaint color cycle range
if not cycle_ccrt {
cycle_crng = true
void diskio.f_read(buffer, chunk_size_lo)
ubyte flags = buffer[5]
if flags & 1 {
cycle_rates[num_cycles] = mkword(buffer[2], buffer[3])
cycle_rate_ticks[num_cycles] = 1
cycle_lows[num_cycles] = buffer[6]
cycle_highs[num_cycles] = buffer[7]
cycle_reverseflags[num_cycles] = flags & 2 != 0
num_cycles++
}
} else
skip_chunk()
}
else if chunk_id == "ccrt" {
; Graphicraft color cycle range
if not cycle_crng {
cycle_ccrt = true
void diskio.f_read(buffer, chunk_size_lo)
ubyte direction = buffer[1]
if direction {
; delay_sec = buffer[4] * 256 * 256 * 256 + buffer[5] * 256 * 256 + buffer[6] * 256 + buffer[7]
; delay_micro = buffer[8] * 256 * 256 * 256 + buffer[9] * 256 * 256 + buffer[10] * 256 + buffer[11]
; We're ignoring the delay_sec field for now. Not many images will have this slow of a color cycle anyway (>1 sec per cycle)
; rate = int(16384 // (60*delay_micro/1e6))
; float rate = (65*16384.0) / (mkword(buffer[9], buffer[10]) as float) ; fairly good approximation using float arithmetic
cycle_rates[num_cycles] = 33280 / (mkword(buffer[9], buffer[10]) >> 5) ; reasonable approximation using only 16-bit integer arithmetic
cycle_rate_ticks[num_cycles] = 1
cycle_lows[num_cycles] = buffer[2]
cycle_highs[num_cycles] = buffer[3]
cycle_reverseflags[num_cycles] = direction == 1 ; TODO weird, the spec say that -1 = reversed but several example images that I have downloaded are the opposite
num_cycles++
}
} else
skip_chunk()
}
else if chunk_id == "body" {
gfx2.clear_screen()
if camg & $0004
height /= 2 ; interlaced: just skip every odd scanline later
if camg & $0080 and have_cmap
make_ehb_palette()
palette.set_rgb8(cmap, num_colors)
if compression
decode_rle()
else
decode_raw()
load_ok = true
break ; done after body
}
else {
skip_chunk()
}
}
} else
txt.print("not an iff ilbm file!\n")
}
diskio.f_close()
}
return load_ok
sub read_chunk_header() -> ubyte {
size = diskio.f_read(buffer, 8)
if size==8 {
chunk_id[0] = buffer[0]
chunk_id[1] = buffer[1]
chunk_id[2] = buffer[2]
chunk_id[3] = buffer[3]
chunk_size_hi = mkword(buffer[4], buffer[5])
chunk_size_lo = mkword(buffer[6], buffer[7])
return true
}
return false
}
sub skip_chunk() {
repeat lsb(chunk_size_hi)*8 + (chunk_size_lo >> 13)
void diskio.f_read(scanline_data_ptr, $2000)
void diskio.f_read(scanline_data_ptr, chunk_size_lo & $1fff)
}
sub make_ehb_palette() {
; generate 32 additional Extra-Halfbrite colors in the cmap
uword palletteptr = cmap
uword ehbptr = palletteptr + 32*3
repeat 32 {
@(ehbptr) = @(palletteptr)>>1
ehbptr++
palletteptr++
@(ehbptr) = @(palletteptr)>>1
ehbptr++
palletteptr++
@(ehbptr) = @(palletteptr)>>1
ehbptr++
palletteptr++
}
}
ubyte bitplane_stride
uword interleave_stride
uword offsetx
uword offsety
sub start_plot() {
bitplane_stride = lsb(width>>3)
interleave_stride = (bitplane_stride as uword) * num_planes
offsetx = 0
offsety = 0
if width < gfx2.width
offsetx = (gfx2.width - width - 1) / 2
if height < gfx2.height
offsety = (gfx2.height - height - 1) / 2
if width > gfx2.width
width = gfx2.width
if height > gfx2.height
height = gfx2.height
}
sub decode_raw() {
start_plot()
ubyte interlaced = (camg & $0004) != 0
uword y
for y in 0 to height-1 {
void diskio.f_read(scanline_data_ptr, interleave_stride)
if interlaced
void diskio.f_read(scanline_data_ptr, interleave_stride)
gfx2.position(offsetx, offsety+y)
planar_to_chunky_scanline()
}
}
sub decode_rle() {
start_plot()
ubyte interlaced = (camg & $0004) != 0
uword y
for y in 0 to height-1 {
decode_rle_scanline()
if interlaced
decode_rle_scanline()
gfx2.position(offsetx, offsety+y)
planar_to_chunky_scanline()
}
}
sub decode_rle_scanline() {
uword x = interleave_stride
uword plane_ptr = scanline_data_ptr
while x {
ubyte b = c64.CHRIN()
if b > 128 {
ubyte b2 = c64.CHRIN()
repeat 2+(b^255) {
@(plane_ptr) = b2
plane_ptr++
x--
}
} else if b < 128 {
repeat b+1 {
@(plane_ptr) = c64.CHRIN()
plane_ptr++
x--
}
} else
break
}
}
sub planar_to_chunky_scanline() {
; ubyte[8] masks = [128,64,32,16,8,4,2,1]
uword x
for x in 0 to width-1 {
; ubyte mask = masks[lsb(x) & 7]
uword pixptr = x/8 + scanline_data_ptr
ubyte bits = 0
%asm {{
bra +
_masks .byte 128, 64, 32, 16, 8, 4, 2, 1
+ lda pixptr
sta P8ZP_SCRATCH_W1
lda pixptr+1
sta P8ZP_SCRATCH_W1+1
lda x
and #7
tay
lda _masks,y
sta P8ZP_SCRATCH_B1 ; mask
phx
ldx num_planes
ldy #0
- lda (P8ZP_SCRATCH_W1),y
clc
and P8ZP_SCRATCH_B1
beq +
sec
+ ror bits ; shift planar bit into chunky byte
lda P8ZP_SCRATCH_W1
; clc
adc bitplane_stride
sta P8ZP_SCRATCH_W1
bcc +
inc P8ZP_SCRATCH_W1+1
+ dex
bne -
plx
lda #8
sec
sbc num_planes
beq +
tay
- lsr bits
dey
bne -
+
}}
; the assembly above is the optimized version of this:
; repeat num_planes {
; clear_carry()
; if @(pixptr) & mask
; set_carry()
; ror(bits) ; shift planar bit into chunky byte
; pixptr += bitplane_stride
; }
; bits >>= 8-num_planes
gfx2.next_pixel(bits)
}
}
}
sub cycle_colors_each_jiffy() {
if num_cycles==0
return
; TODO implement Blend Shifting see http://www.effectgames.com/demos/canvascycle/palette.js
ubyte changed = false
ubyte ci
for ci in 0 to num_cycles-1 {
cycle_rate_ticks[ci]--
if cycle_rate_ticks[ci]==0 {
changed = true
cycle_rate_ticks[ci] = 16384 / cycle_rates[ci]
do_cycle(cycle_lows[ci], cycle_highs[ci], cycle_reverseflags[ci])
}
}
if changed
palette.set_rgb8(cmap, num_colors) ; set the new palette
sub do_cycle(uword low, uword high, ubyte reversed) {
low *= 3
high *= 3
uword bytecount = high-low
uword cptr
ubyte red
ubyte green
ubyte blue
if reversed {
cptr = cmap + low
red = @(cptr)
green = @(cptr+1)
blue = @(cptr+2)
repeat bytecount {
@(cptr) = @(cptr+3)
cptr++
}
@(cptr) = red
cptr++
@(cptr) = green
cptr++
@(cptr) = blue
} else {
cptr = cmap + high
red = @(cptr)
cptr++
green = @(cptr)
cptr++
blue = @(cptr)
repeat bytecount {
@(cptr) = @(cptr-3)
cptr--
}
@(cptr) = blue
cptr--
@(cptr) = green
cptr--
@(cptr) = red
}
}
}
}

View File

@ -1,164 +0,0 @@
%target cx16
%import gfx2
%import textio
%import diskio
%import string
%import koala_module
%import iff_module
%import pcx_module
%import bmp_module
%zeropage basicsafe
main {
sub start() {
cx16.rombank(0) ; switch to kernal rom (for faster file i/o)
; trick to check if we're running on sdcard or host system shared folder
txt.print("\nimage viewer for commander x16\nformats supported: .iff, .pcx, .bmp, .koa (c64 koala)\n\n")
if string.length(diskio.status(8)) {
txt.print("enter image file name or just enter for all on disk: ")
ubyte i = txt.input_chars(diskio.filename)
gfx2.screen_mode(1) ; 320*240, 256c
if i
attempt_load(diskio.filename)
else
show_pics_sdcard()
; txt.print("\nnothing more to do.\n")
}
else
txt.print("files are read with sequential file loading.\nin the emulator this currently only works with files on an sd-card image.\nsorry :(\n")
gfx2.screen_mode(255) ; back to default text mode and palette
txt.print("that was all folks!\n")
cx16.rombank(4) ; switch back to basic rom
}
sub show_pics_sdcard() {
; load and show the images on the disk with the given extensions.
; this only works in the emulator V38 with an sd-card image with the files on it.
str[40] filename_ptrs
ubyte num_files = diskio.list_files(8, 0, &filename_ptrs, len(filename_ptrs))
if num_files {
while num_files {
num_files--
attempt_load(filename_ptrs[num_files])
}
} else
txt.print("no files in directory!\n")
}
sub attempt_load(uword filenameptr) {
;txt.print(">> ")
;txt.print(filenameptr)
;txt.nl()
uword extension = filenameptr + rfind(filenameptr, '.')
if string.compare(extension, ".iff")==0 {
;txt.print("loading ")
;txt.print("iff\n")
if iff_module.show_image(filenameptr) {
if iff_module.num_cycles {
repeat 500 {
sys.wait(1)
iff_module.cycle_colors_each_jiffy()
}
}
else
sys.wait(180)
} else {
load_error(filenameptr)
}
}
else if string.compare(extension, ".pcx")==0 {
;txt.print("loading ")
;txt.print("pcx\n")
if pcx_module.show_image(filenameptr) {
sys.wait(180)
} else {
load_error(filenameptr)
}
}
else if string.compare(extension,".koa")==0 {
;txt.print("loading ")
;txt.print("koala\n")
if koala_module.show_image(filenameptr) {
sys.wait(180)
} else {
load_error(filenameptr)
}
}
else if string.compare(extension, ".bmp")==0 {
;txt.print("loading ")
;txt.print("bmp\n")
if bmp_module.show_image(filenameptr) {
sys.wait(180)
} else {
load_error(filenameptr)
}
}
}
sub load_error(uword filenameptr) {
gfx2.screen_mode(255) ; back to default text mode and palette
txt.print(filenameptr)
txt.print(": load error\n")
sys.exit(1)
}
sub extension_equals(uword stringptr, uword extensionptr) -> ubyte {
ubyte ix = rfind(stringptr, '.')
return ix<255 and string.compare(stringptr+ix, extensionptr)==0
}
sub rfind(uword stringptr, ubyte char) -> ubyte {
ubyte i
for i in string.length(stringptr)-1 downto 0 {
if @(stringptr+i)==char
return i
}
return 0
}
}
custompalette {
sub set_bgra(uword palletteptr, uword num_colors) {
uword vera_palette_ptr = $fa00
ubyte red
ubyte greenblue
; 4 bytes per color entry (BGRA), adjust color depth from 8 to 4 bits per channel.
repeat num_colors {
red = @(palletteptr+2) >> 4
greenblue = @(palletteptr+1) & %11110000
greenblue |= @(palletteptr+0) >> 4 ; add Blue
palletteptr+=4
cx16.vpoke(1, vera_palette_ptr, greenblue)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, red)
vera_palette_ptr++
}
}
sub set_grayscale256() {
; grays $000- $fff stretched out over all the 256 colors
ubyte c = 0
uword vera_palette_ptr = $fa00
repeat 16 {
repeat 16 {
cx16.vpoke(1, vera_palette_ptr, c)
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, c)
vera_palette_ptr++
}
c += $11
}
}
}

View File

@ -1,84 +0,0 @@
%target cx16
%import gfx2
%import diskio
%import palette
koala_module {
const uword load_location = $6000
sub show_image(uword filenameptr) -> ubyte {
ubyte load_ok=false
if diskio.f_open(8, filenameptr) {
uword size = diskio.f_read(load_location, 2) ; skip the first 2 bytes (load address)
if size==2 {
if diskio.f_read(load_location, 10001)==10001 {
; set a better C64 color palette, the Cx16's default is too saturated
palette.set_c64pepto()
convert_koalapic()
load_ok = true
}
}
diskio.f_close()
}
return load_ok
}
sub convert_koalapic() {
ubyte cy
ubyte @zp cx
uword @zp cy_times_forty = 0
ubyte @zp d
uword bitmap_ptr = load_location
; theoretically you could put the 8-pixel array in zeropage to squeeze out another tiny bit of performance
ubyte[8] pixels
gfx2.clear_screen()
uword offsety = (gfx2.height - 200) / 2
for cy in 0 to 24*8 step 8 {
uword posy = cy + offsety
for cx in 0 to 39 {
uword posx = cx as uword * 8
for d in 0 to 7 {
gfx2.position(posx, posy + d)
get_8_pixels()
gfx2.next_pixels(pixels, 8)
}
}
cy_times_forty += 40
}
sub get_8_pixels() {
ubyte bm = @(bitmap_ptr)
ubyte @zp m = mcol(bm)
pixels[7] = m
pixels[6] = m
bm >>= 2
m = mcol(bm)
pixels[5] = m
pixels[4] = m
bm >>= 2
m = mcol(bm)
pixels[3] = m
pixels[2] = m
bm >>= 2
m = mcol(bm)
pixels[1] = m
pixels[0] = m
bitmap_ptr++
sub mcol(ubyte b) -> ubyte {
ubyte @zp color
when b & 3 {
0 -> color = @(load_location + 8000 + 1000 + 1000) & 15
1 -> color = @(load_location + 8000 + cy_times_forty + cx) >>4
2 -> color = @(load_location + 8000 + cy_times_forty + cx) & 15
else -> color = @(load_location + 8000 + 1000 + cy_times_forty + cx) & 15
}
return color
}
}
}
}

View File

@ -1,170 +0,0 @@
%target cx16
%import gfx2
%import textio
%import diskio
pcx_module {
sub show_image(uword filenameptr) -> ubyte {
ubyte load_ok = false
if diskio.f_open(8, filenameptr) {
ubyte[128] header
uword size = diskio.f_read(header, 128)
if size==128 {
if header[0] == $0a and header[2] == 1 {
ubyte bits_per_pixel = header[3]
if bits_per_pixel==1 or bits_per_pixel==4 or bits_per_pixel==8 {
uword width = mkword(header[$09], header[$08]) - mkword(header[$05], header[$04]) + 1
uword height = mkword(header[$0b], header[$0a]) - mkword(header[$07], header[$06]) + 1
ubyte number_of_planes = header[$41]
uword palette_format = mkword(header[$45], header[$44])
uword num_colors = 2**bits_per_pixel
if number_of_planes == 1 {
if (width & 7) == 0 {
gfx2.clear_screen()
if palette_format==2
custompalette.set_grayscale256()
else if num_colors == 16
palette.set_rgb8(&header + $10, 16)
else if num_colors == 2
palette.set_monochrome()
when bits_per_pixel {
8 -> load_ok = bitmap.do8bpp(width, height)
4 -> load_ok = bitmap.do4bpp(width, height)
1 -> load_ok = bitmap.do1bpp(width, height)
}
if load_ok {
load_ok = c64.CHRIN()
if load_ok == 12 {
; there is 256 colors of palette data at the end
uword palette_mem = sys.progend()
load_ok = false
size = diskio.f_read(palette_mem, 3*256)
if size==3*256 {
load_ok = true
palette.set_rgb8(palette_mem, num_colors)
}
}
}
} else
txt.print("width not multiple of 8!\n")
} else
txt.print("has >256 colors!\n")
}
}
}
diskio.f_close()
}
return load_ok
}
}
bitmap {
uword offsetx
uword offsety
uword py
uword px
ubyte y_ok
ubyte status
sub start_plot(uword width, uword height) {
offsetx = 0
offsety = 0
y_ok = true
py = 0
px = 0
if width < gfx2.width
offsetx = (gfx2.width - width) / 2
if height < gfx2.height
offsety = (gfx2.height - height) / 2
status = (not c64.READST()) or (c64.READST()&64==64)
}
sub next_scanline() {
px = 0
py++
y_ok = py < gfx2.height
gfx2.position(offsetx, offsety+py)
status = (not c64.READST()) or (c64.READST()&64==64)
}
sub do1bpp(uword width, uword height) -> ubyte {
start_plot(width, height)
gfx2.position(offsetx, offsety)
while py < height and status {
ubyte b = c64.CHRIN()
if b>>6==3 {
b &= %00111111
ubyte dat = c64.CHRIN()
repeat b {
if y_ok
gfx2.set_8_pixels_from_bits(dat, 1, 0)
px += 8
}
} else {
if y_ok
gfx2.set_8_pixels_from_bits(b, 1, 0)
px += 8
}
if px==width
next_scanline()
}
return status
}
sub do4bpp(uword width, uword height) -> ubyte {
start_plot(width, height)
gfx2.position(offsetx, offsety)
while py < height and status {
ubyte b = c64.CHRIN()
if b>>6==3 {
b &= %00111111
ubyte dat = c64.CHRIN()
if y_ok
repeat b {
gfx2.next_pixel(dat>>4)
gfx2.next_pixel(dat & 15)
}
px += b*2
} else {
if y_ok {
gfx2.next_pixel(b>>4)
gfx2.next_pixel(b & 15)
}
px += 2
}
if px==width
next_scanline()
}
return status
}
sub do8bpp(uword width, uword height) -> ubyte {
start_plot(width, height)
gfx2.position(offsetx, offsety)
while py < height and status {
ubyte b = c64.CHRIN()
if b>>6==3 {
b &= %00111111
ubyte dat = c64.CHRIN()
if y_ok
repeat b
gfx2.next_pixel(dat)
px += b
} else {
if y_ok
gfx2.next_pixel(b)
px++
}
if px==width
next_scanline()
}
return status
}
}

View File

@ -1,50 +1,10 @@
%import textio
%import diskio
%import string
%import floats
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
struct SaveData {
ubyte galaxy
ubyte planet
uword cash
float flt
ubyte fuel
}
SaveData data
txt.print("size of struct: ")
txt.print_ub(sizeof(SaveData))
txt.chrout(';')
txt.print_ub(sizeof(data))
txt.chrout('\n')
txt.print("offset of galaxy: ")
txt.print_ub(offsetof(data.galaxy))
txt.chrout('\n')
txt.print("offset of planet: ")
txt.print_ub(offsetof(data.planet))
txt.chrout('\n')
txt.print("offset of cash: ")
txt.print_ub(offsetof(data.cash))
txt.chrout('\n')
txt.print("offset of flt: ")
txt.print_ub(offsetof(data.flt))
txt.chrout('\n')
txt.print("offset of fuel: ")
txt.print_ub(offsetof(data.fuel))
txt.chrout('\n')
txt.print("hello\n")
}
}