examples: add ==0 or !=0 to expressions that depend on implicit conversion from byte to bool

This commit is contained in:
Irmen de Jong 2024-02-04 23:18:11 +01:00
parent c48012c385
commit 92527b4c1d
37 changed files with 219 additions and 284 deletions

View File

@ -333,8 +333,8 @@ Provides string manipulation routines.
``endswith (string, suffix) -> bool``
Returns true if string ends with suffix, otherwise false
``pattern_match (string, pattern) -> ubyte`` (not on Virtual target)
Returns 1 (true) if the string matches the pattern, 0 (false) if not.
``pattern_match (string, pattern) -> bool`` (not on Virtual target)
Returns true if the string matches the pattern, false if not.
'?' in the pattern matches any one character. '*' in the pattern matches any substring.
``hash (string) -> ubyte``

View File

@ -1,106 +1,57 @@
TODO
====
larger programs:
dirlist
bobs
cobramk3-gfx
automatons
mandelbrot (quite a bit larger)
mandelbrot-gfx
maze
textelite
rockrunner is quite a bit larger
ConstantFoldingOptimizer (after merging master):
after(numLiteral..) : check that cast to/from BOOL is not done??
optimize optimizedPlusMinExpr for when comparing to simple things like number and identifier.
replace Takes by Http4k in httpCompilerService project. https://github.com/http4k/examples/blob/master/hello-world/README.md
...
Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^
Compiler:
- IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register. Replace all LOADM+CMPI #0 / LOAD #0+LOADM+CMP+BRANCH by this instruction
- can we support signed % (remainder) somehow?
- instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead.
that will allow them to be reused from custom user written assembly code as well.
- Multidimensional arrays and chained indexing, purely as syntactic sugar over regular arrays.
- make a form of "manual generics" possible like: varsub routine(T arg)->T where T is expanded to a specific type
(this is already done hardcoded for several of the builtin functions)
- [much work:] more support for (64tass) SEGMENTS ?
- (What, how, isn't current BSS support enough?)
- Add a mechanism to allocate variables into golden ram (or segments really) (see GoldenRam class)
- maybe treat block "golden" in a special way: can only contain vars, every var will be allocated in the Golden ram area?
- maybe or may not needed: the variables can NOT have initialization values, they will all be set to zero on startup (simple memset)
just initialize them yourself in start() if you need a non-zero value .
- OR.... do all this automatically if 'golden' is enabled as a compiler option? So compiler allocates in ZP first, then Golden Ram, then regular ram
- OR.... make all this more generic and use some %segment option to create real segments for 64tass?
- (need separate step in codegen and IR to write the "golden" variables)
- do we need (array)variable alignment tag instead of block alignment tag? You want to align the data, not the code in the block?
- VM: implement diskio support (let's start with the basics load, save, delete, rename, status?. no streaming, no directory listing)
- ir: related to the one above: block alignment doesn't translate well to variables in the block (the actual stuff that needs to be aligned in memory) but: need variable alignment tag instead of block alignment tag, really
- ir: proper code gen for the CALLI instruction and that it (optionally) returns a word value that needs to be assigned to a reg
- ir: idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
global initialization values are simply a list of LOAD instructions.
Variables replaced include all subroutine parameters! So the only variables that remain as variables are arrays and strings.
- ir: fix call() return value handling
- ir: add more optimizations in IRPeepholeOptimizer
- ir: the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line.
maybe another representation is needed once actual codegeneration is done from the IR...?
- ir: getting it in shape for code generation...
- [problematic due to using 64tass:] better support for building library programs, where unused .proc are NOT deleted from the assembly.
Perhaps replace all uses of .proc/.pend/.endproc by .block/.bend will fix that with a compiler flag?
But all library code written in asm uses .proc already..... (textual search/replace when writing the actual asm?)
Once new codegen is written that is based on the IR, this point is mostly moot anyway as that will have its own dead code removal on the IR level.
- Zig-like try-based error handling where the V flag could indicate error condition? and/or BRK to jump into monitor on failure? (has to set BRK vector for that) But the V flag is also set on certain normal instructions
- generate WASM to eventually run prog8 on a browser canvas? Use binaryen toolkit and/or my binaryen kotlin library?
- split words arrays all()
- split words arrays sort()
===== ====== =======
VM 6502 what
===== ====== =======
ok ok boolean const
ok ok boolean variables value
ok ok static bool var (block scope) with initializer value (staticVariable2asm)
ok ok boolean arrays value, list and single value
ok ok type error for bool[3] derp = 99 and also for init value [1,0,1] and also for [true, false, 1, 0, 222]
ok ok return boolean value from sub
ok . make sure that and,or,xor,not aren't getting replaced by the bitwise versions
ok . and, or, xor, not work in expressions: print_ub((bb and true) as ubyte)
ok . logical not works, also inplace
ok . logical xor works, also inplace
- . efficient code for manipulating bools in an array (normal and agumented assigns)
ok ok bitwise logical ops on bools give type error, including invert
ok ok arithmetic ops on bools give type error
ok ok boolean values in ubyte array should give type error
ok ok while booleanvar==42 should give type error
ok ok do..until booleanvar==42 should give type error
ok ok while not <integervar> should give type error
ok . while boolean should produce identical code as while integer!=0
ok . while not guessed -> can we get rid of the cmp?
ok . if someint==0 / ==1 should stil produce good asm same as what it used to be with if not someint/if someint
ok . if not X -> test all variations with and without else
yes . is this De Morgan's optimization still useful in this branch? : not a1 or not a2 -> not(a1 and a2) likewise for and.
yes . is it beneficial to somehow have DeMorgan's law also work on integer types if b1==0 and b2==0 -> if (b1 & b2)==0
ok . check program sizes vs. master branch
===== ====== =======
Libraries:
- monogfx: add EOR mode support next to Stipple. See PAINT for inspiration. Can this also be added to gfx2? Self modifying code to keep it optimized?
- conv: the routines could return the address of conv.string_out, and/or there could be versions that take the address of a different buffer and use it instead.
- once kernal rom v47 is released, remove most of the workarounds in cx16 floats.parse_f() . Prototype parse routine in examples/cx16/floatparse.p8
- fix the problems in atari target, and flesh out its libraries.
- c128 target: make syslib more complete (missing kernal routines)?
- pet32 target: make syslib more complete (missing kernal routines)?
check that the flood fill routine in gfx2 and paint still works.
re-allow typecast of const true/false back to ubytes 1 and 0.
re-allow typecast of const ubyte 0/1 to false/true boolean.
Optimizations:
boolean trick to go from a compare >= value, to a bool
cmp #value
rol a
and #1
- VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served?
for instance, vars used inside loops first, then loopvars, then uwords used as pointers, then the rest
- various optimizers skip stuff if compTarget.name==VMTarget.NAME. Once 6502-codegen is done from IR code,
those checks should probably be removed, or be made permanent
- optimizeCommonSubExpressions: currently only looks in expressions on a single line, could search across multiple expressions
maze 6502:
if cell & UP!=0 and @(celladdr(cx,cy-1)) & (WALKED|BACKTRACKED) ==0
^^ adding this !=0 caused a weird beq + / lda #1 / + to appear in front of the shortcircuit beq...
STRUCTS again?
--------------
What if we were to re-introduce Structs in prog8? Some thoughts:
- can contain only numeric types (byte,word,float) - no nested structs, no reference types (strings, arrays) inside structs
- only as a reference type (uword pointer). This removes a lot of the problems related to introducing a variable length value type.
- arrays of struct is just an array of uword pointers. Can even be @split?
- need to introduce typed pointer datatype in prog8
- str is then syntactic sugar for pointer to character/byte?
- arrays are then syntactic sugar for pointer to byte/word/float?
Other language/syntax features to think about
---------------------------------------------
- support for assigning multiple return values from romsub/asmsub to multiple variables.
- add (rom/ram)bank support to romsub. A call will then automatically switch banks, use callfar and something else when in banked ram.
challenges: how to not make this too X16 specific? How does the compiler know what bank to switch (ram/rom)?
How to make it performant when we want to (i.e. NOT have it use callfar/auto bank switching) ?
IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register.
replace all LOADM+CMPI #0 / LOAD #0+LOADM+CMP+BRANCH by this instruction

View File

@ -57,12 +57,12 @@ main {
while not guessed {
txt.print(questions[current_question])
txt.print("? ")
if txt.input_chars(userinput) {
if txt.input_chars(userinput)!=0 {
txt.nl()
ubyte animal_number
if userinput[0]=='y' {
animal_number = msb(answers_animals[current_question])
if animal_number {
if animal_number!=0 {
guess(current_question, true, animal_number)
guessed = true
} else {
@ -71,7 +71,7 @@ main {
}
else if userinput[0]=='n' {
animal_number = lsb(answers_animals[current_question])
if animal_number {
if animal_number!=0 {
guess(current_question, false, animal_number)
guessed = true
} else {
@ -87,7 +87,7 @@ main {
}
}
sub guess(ubyte question_number, ubyte given_answer_yesno, ubyte animal_number) {
sub guess(ubyte question_number, bool given_answer_yesno, ubyte animal_number) {
txt.print("is it a ")
txt.print(animals[animal_number])
txt.print("? ")

View File

@ -14,7 +14,7 @@ main {
txt.nl()
}
txt.waitkey()
void txt.waitkey()
}
uword fib_prev = 0

View File

@ -12,7 +12,7 @@
main {
ubyte perform_scroll = false
bool perform_scroll = false
sub start() {
c64.set_sprite_ptr(0, $0f00) ; alternatively, set directly: c64.SPRPTR[0] = $0f00 / 64
@ -57,7 +57,7 @@ main {
txt.scroll_left(true)
; float the balloon
if math.rnd() & %10000
if math.rnd() & %10000 !=0
c64.SPXY[1] ++
else
c64.SPXY[1] --

View File

@ -65,7 +65,7 @@ main {
@(starfieldPtr3) = 0
@(starfieldPtr4) = 0
if rasterCount & 1 {
if rasterCount & 1 !=0 {
starfieldPtr1++
if starfieldPtr1==star1Limit
starfieldPtr1=star1Reset

View File

@ -208,14 +208,14 @@ waitkey:
txt.setcc(x, linepos, sc:'▒', 1)
}
}
if num_lines {
if num_lines!=0 {
if num_lines>3
sound.lineclear_big()
else
sound.lineclear()
sys.wait(20) ; slight delay to flash the line
for linepos in complete_lines
if linepos and blocklogic.isLineFull(linepos)
if linepos!=0 and blocklogic.isLineFull(linepos)
blocklogic.collapse(linepos)
lines += num_lines
uword[] scores = [10, 25, 50, 100] ; can never clear more than 4 lines at once
@ -390,7 +390,7 @@ waitkey:
ubyte @zp i
for i in 15 downto 0 {
ubyte @zp c=blocklogic.currentBlock[i]
if c
if c!=0
txt.setcc((i&3)+x, (i/4)+y, character, c)
}
}
@ -538,7 +538,7 @@ blocklogic {
sub noCollision(ubyte xpos, ubyte ypos) -> bool {
ubyte @zp i
for i in 15 downto 0 {
if currentBlock[i] and txt.getchr(xpos + (i&3), ypos+i/4)!=32
if currentBlock[i]!=0 and txt.getchr(xpos + (i&3), ypos+i/4)!=32
return false
}
return true

View File

@ -49,7 +49,7 @@ turtle {
sub update_turtle_sprite() {
uword xx = xpos as uword
c64.SPXY[0] = lsb(xx) + 12
c64.MSIGX = msb(xx) > 0
c64.MSIGX = msb(xx)!=0 as ubyte
c64.SPXY[1] = ypos as ubyte + 40
}

View File

@ -58,7 +58,7 @@ irq {
ubyte @zp y = math.sin8u(angle2-spri*16) / 2 + 70
c64.SPXYW[spri] = mkword(y, lsb(x))
c64.MSIGX <<= 1
if msb(x) c64.MSIGX++
if msb(x)!=0 c64.MSIGX++
}
c64.EXTCOL-=8
return true

View File

@ -99,7 +99,7 @@ main {
}
sub blit(ubyte vmembase) {
ubyte bank = vmembase>=32
ubyte bank = vmembase>=32 as ubyte
uword vmem = vmembase * 2048 ; mkword(vmembase,0) * 8
uword blit_x = (math.cos8u(msb(anim1)) as uword) + math.sin8u(msb(anim2))/6
ubyte blit_y = math.sin8u(msb(anim3))/2 + math.cos8u(msb(anim4))/5
@ -177,7 +177,7 @@ main {
sub draw_number(ubyte vmembase, uword number) {
uword vmem = vmembase * 2048 ; mkword(vmembase,0) * 8
ubyte bank = vmembase>=32
ubyte bank = vmembase>=32 as ubyte
vmem += 35
conv.str_uw0(number)
uword pixelsptr = &numberpixels + (conv.string_out[1] & 15)*7

View File

@ -151,14 +151,14 @@ processchunk_call jsr $ffff ; modified
cx16.VERA_ADDR_L = lsb(address)
cx16.VERA_ADDR_M = msb(address)
cx16.VERA_ADDR_H = bank | %00010000 ; enable vera auto increment
while size {
while size!=0 {
size -= readblock(size, &cx16.VERA_DATA0, true)
}
}
sub blockload_dummy(uword size) {
ubyte buffer
while size {
while size!=0 {
size -= readblock(size, &buffer, true)
}
}
@ -167,7 +167,7 @@ processchunk_call jsr $ffff ; modified
ubyte orig_ram_bank = cx16.getrambank()
cx16.rambank(bank)
cx16.r3 = address
while size {
while size!=0 {
cx16.r2 = readblock(size, cx16.r3, false)
size -= cx16.r2
cx16.r3 += cx16.r2
@ -178,7 +178,7 @@ processchunk_call jsr $ffff ; modified
sub blockload_bonkram(uword size, ubyte bonk, uword address) {
ubyte orig_rom_bank = cx16.getrombank()
cx16.r3 = address
while size {
while size!=0 {
ubyte readsize = 255
if msb(size)==0
readsize = lsb(size)
@ -194,7 +194,7 @@ processchunk_call jsr $ffff ; modified
sub readblock(uword size, uword address, bool dontAdvance) -> uword {
if msb(size)>=2
return cx16.MACPTR(0, address, dontAdvance) ; read 512 bytes
if msb(size)
if msb(size)!=0
return cx16.MACPTR(255, address, dontAdvance) ; read 255 bytes
return cx16.MACPTR(lsb(size), address, dontAdvance) ; read remaining number of bytes
}

View File

@ -86,7 +86,7 @@ main {
sub draw_lines_hiddenremoval() {
; complex drawing routine that draws the ship model based on its faces,
; where it uses the surface normals to determine visibility.
sys.memset(edgestodraw, shipdata.totalNumberOfEdges, true)
sys.memset(edgestodraw, shipdata.totalNumberOfEdges, 1)
ubyte @zp edgeIdx = 0
ubyte @zp pointIdx = 0
ubyte faceNumber
@ -131,7 +131,7 @@ main {
}
}
ubyte[shipdata.totalNumberOfEdges] edgestodraw
bool[shipdata.totalNumberOfEdges] edgestodraw
sub draw_edge(ubyte edgeidx) {
edgestodraw[edgeidx] = false

View File

@ -57,7 +57,7 @@ irq {
if shift_counter == 32+32+32 {
make_new_gradient()
shift_counter = 0
} else if shift_counter & 1 {
} else if shift_counter & 1 !=0 {
shift_gradient()
}
} else if next_irq_line & 15 == 0 {

View File

@ -23,8 +23,6 @@ main {
sub start() {
txt.print("\n\ndisk benchmark on drive 8.\n\n")
uword batchtotaltime
txt.print("writing 64kb using save()")
cbm.SETTIM(0,0,0)
; save 2 times 32Kb to make it 64Kb total
@ -46,13 +44,13 @@ main {
txt.print("\nreading 64kb using load() into hiram")
cbm.SETTIM(0,0,0)
cx16.rambank(4)
if not diskio.load("benchmark.dat", $a000)
if diskio.load("benchmark.dat", $a000)==0
sys.exit(1)
print_speed(cbm.RDTIM16())
txt.print("\nreading 64kb using vload() into vram")
cbm.SETTIM(0,0,0)
if not diskio.vload("benchmark.dat", 0, $0000)
if diskio.vload("benchmark.dat", 0, $0000)==0
sys.exit(1)
print_speed(cbm.RDTIM16())
@ -60,7 +58,7 @@ main {
if diskio.f_open("benchmark.dat") {
cbm.SETTIM(0,0,0)
repeat 65536/255 {
if not diskio.f_read(buffer, 255)
if diskio.f_read(buffer, 255)==0
sys.exit(1)
}
diskio.f_close()

View File

@ -128,7 +128,7 @@ main {
}
done:
if exponent
if exponent!=0
result *= floats.pow(10, exponent)
if negative

View File

@ -24,60 +24,60 @@ main {
yy = 20
xx = 20
monogfx.stipple(false)
monogfx.rect(xx, yy, 250, 80, 1)
monogfx.rect(xx, yy, 250, 80, true)
monogfx.stipple(true)
monogfx.fillrect(xx+2, yy+2, 250-4, 80-4, 1)
monogfx.fillrect(xx+2, yy+2, 250-4, 80-4, true)
monogfx.stipple(false)
monogfx.fillrect(xx+20, yy+20, 200, 30, 1)
monogfx.rect(xx+21, yy+21, 200-2, 30-2, 0)
monogfx.fillrect(xx+20, yy+20, 200, 30, true)
monogfx.rect(xx+21, yy+21, 200-2, 30-2, false)
monogfx.text(xx+30, yy+32, 0, sc:"High Res Bitmap Example")
monogfx.text(xx+30, yy+32, false, sc:"High Res Bitmap Example")
; monogfx.stipple(true)
monogfx.horizontal_line(10, 240, 620, 1)
monogfx.vertical_line(320, 10, 460, 1)
monogfx.text(320, 242, 1, sc:"0,0")
monogfx.text(322, 10, 1, sc:"Y-axis")
monogfx.text(590, 242, 1, sc:"X-axis")
monogfx.horizontal_line(10, 240, 620, true)
monogfx.vertical_line(320, 10, 460, true)
monogfx.text(320, 242, true, sc:"0,0")
monogfx.text(322, 10, true, sc:"Y-axis")
monogfx.text(590, 242, true, sc:"X-axis")
for ww in -10 to 10 {
xx = (ww*30) + 320 as uword
monogfx.vertical_line(xx, 239, 3, 1)
monogfx.vertical_line(xx, 239, 3, true)
}
for ww in -7 to 7 {
yy = (ww*30) + 240 as uword
monogfx.horizontal_line(319, yy, 3, 1)
monogfx.horizontal_line(319, yy, 3, true)
}
monogfx.stipple(false)
float y_f
for ww in -600 to 600 {
y_f = floats.sin(ww as float / 60.0)*150
monogfx.plot(ww/2 + 320 as uword, (y_f + 240) as uword, 1)
monogfx.plot(ww/2 + 320 as uword, (y_f + 240) as uword, true)
}
monogfx.text(480, 100, 1, sc:"sin(x)")
monogfx.text(480, 100, true, sc:"sin(x)")
for ww in -300 to 300 {
y_f = floats.cos(ww as float/30.0)*60 - (ww as float)/1.7
monogfx.plot(ww + 320 as uword, (y_f + 240) as uword, 1)
monogfx.plot(ww + 320 as uword, (y_f + 240) as uword, true)
}
monogfx.text(80, 420, 1, sc:"cos(x)+x")
monogfx.text(80, 420, true, sc:"cos(x)+x")
sys.wait(3*60)
monogfx.circle(320, 240, 220, 1)
monogfx.circle(320, 240, 210, 1)
monogfx.circle(320, 240, 200, 1)
monogfx.circle(320, 240, 190, 1)
monogfx.circle(320, 240, 220, true)
monogfx.circle(320, 240, 210, true)
monogfx.circle(320, 240, 200, true)
monogfx.circle(320, 240, 190, true)
monogfx.stipple(true)
monogfx.disc(320, 240, 140, 1)
monogfx.disc(320, 240, 140, true)
monogfx.stipple(false)
monogfx.disc(320, 240, 90, 1)
monogfx.disc(320, 240, 40, 0)
monogfx.disc(320, 240, 90, true)
monogfx.disc(320, 240, 40, false)
sys.wait(2*60)
repeat 255
monogfx.line(math.rndw() % 640, math.rndw() % 480, math.rndw() % 640, math.rndw() % 480, 1)
monogfx.line(math.rndw() % 640, math.rndw() % 480, math.rndw() % 640, math.rndw() % 480, true)
sys.wait(1*60)
}

View File

@ -34,7 +34,7 @@ main {
; loop figure out what to do with it, rather than putting it all in the handler routine
txt.print_ubhex(keynum, true)
txt.spc()
if keynum & $80
if keynum & $80 !=0
txt.chrout('u')
else
txt.chrout('d')

View File

@ -70,20 +70,20 @@ adpcm {
; Note that the generated assembly from this is pretty efficient,
; rewriting it by hand in asm seems to improve it only 5-10%
cx16.r0s = 0 ; difference
if nibble & %0100
if nibble & %0100 !=0
cx16.r0s += pstep
pstep >>= 1
if nibble & %0010
if nibble & %0010 !=0
cx16.r0s += pstep
pstep >>= 1
if nibble & %0001
if nibble & %0001 !=0
cx16.r0s += pstep
pstep >>= 1
cx16.r0s += pstep
if nibble & %1000
predict -= cx16.r0s
if nibble & %1000 !=0
predict -= cx16.r0
else
predict += cx16.r0s
predict += cx16.r0
; NOTE: the original C/Python code uses a 32 bits prediction value and clips it to a 16 bit word
; but for speed reasons we only work with 16 bit words here all the time (with possible clipping error)
@ -106,20 +106,20 @@ adpcm {
; Note that the generated assembly from this is pretty efficient,
; rewriting it by hand in asm seems to improve it only 5-10%
cx16.r0s = 0 ; difference
if nibble & %0100
if nibble & %0100 !=0
cx16.r0s += pstep_2
pstep_2 >>= 1
if nibble & %0010
if nibble & %0010 !=0
cx16.r0s += pstep_2
pstep_2 >>= 1
if nibble & %0001
if nibble & %0001 !=0
cx16.r0s += pstep_2
pstep_2 >>= 1
cx16.r0s += pstep_2
if nibble & %1000
predict_2 -= cx16.r0s
if nibble & %1000 !=0
predict_2 -= cx16.r0
else
predict_2 += cx16.r0s
predict_2 += cx16.r0
; NOTE: the original C/Python code uses a 32 bits prediction value and clips it to a 16 bit word
; but for speed reasons we only work with 16 bit words here all the time (with possible clipping error)

View File

@ -165,7 +165,7 @@ mono {
}
sub irq_handler() {
if cx16.VERA_ISR & %00001000 {
if cx16.VERA_ISR & %00001000 !=0 {
; AFLOW irq.
;; cx16.vpoke(1,$fa0c, $a0) ; paint a screen color
@ -284,7 +284,7 @@ stereo {
}
sub irq_handler() {
if cx16.VERA_ISR & %00001000 {
if cx16.VERA_ISR & %00001000 !=0 {
; AFLOW irq.
;; cx16.vpoke(1,$fa0c, $a0) ; paint a screen color

View File

@ -172,7 +172,7 @@ interrupts {
}
sub handler() {
if cx16.VERA_ISR & %00001000 {
if cx16.VERA_ISR & %00001000 !=0 {
; Filling the fifo is the only way to clear the Aflow irq.
; So we do this here, otherwise the aflow irq will keep triggering.
; Note that filling the buffer with fresh audio samples is NOT done here,
@ -182,7 +182,7 @@ interrupts {
cx16.restore_virtual_registers()
aflow = true
}
if cx16.VERA_ISR & %00000001 {
if cx16.VERA_ISR & %00000001 !=0 {
cx16.VERA_ISR = %00000001
vsync = true
}

View File

@ -13,7 +13,7 @@ main {
repeat {
txt.print("\nenter bmx image filename: ")
if txt.input_chars(&filename) {
if txt.input_chars(&filename)!=0 {
if bmx.open(8, filename) {
txt.print("\nsize: ")
@ -66,7 +66,7 @@ main {
cbm.CINT() ; reset screen
if bmx.error_message {
if bmx.error_message!=0 {
txt.print("load error:\n")
txt.print(bmx.error_message)
txt.nl()

View File

@ -46,7 +46,7 @@ main {
if snowx!=0 and snowx!=319 { ; check to avoid x coordinate under/overflow
uword pilex1
uword pilex2
if math.rnd() & 1 {
if math.rnd() & 1 !=0 {
pilex1 = snowx-1
pilex2 = snowx+1
} else {
@ -73,7 +73,7 @@ main {
flakes1_yy[idx]++
when math.rnd() & 3 {
1 -> {
if flakes1_xx[idx]
if flakes1_xx[idx]!=0
flakes1_xx[idx]--
}
2 -> {
@ -103,7 +103,7 @@ main {
flakes2_yy[idx]+=1
when math.rnd() & 3 {
1 -> {
if flakes2_xx[idx]
if flakes2_xx[idx]!=0
flakes2_xx[idx]--
}
2 -> {

View File

@ -41,7 +41,7 @@ main {
for sprite_num in 0 to NUM_DRAGONS*2-2 step 2 {
xpositions[sprite_num]++
xpositions[sprite_num+1]++
if sprite_num & 2 {
if sprite_num & 2 !=0 {
xpositions[sprite_num]++
xpositions[sprite_num+1]++
}

View File

@ -287,7 +287,7 @@ waitkey:
txt.setcc2(x, linepos, 160, 1)
}
}
if num_lines {
if num_lines!=0 {
if num_lines>3 {
sound.lineclear_big()
sys.wait(25) ; slight delay to flash the line
@ -297,7 +297,7 @@ waitkey:
sys.wait(15) ; slight delay to flash the line
}
for linepos in complete_lines
if linepos and blocklogic.isLineFull(linepos)
if linepos!=0 and blocklogic.isLineFull(linepos)
blocklogic.collapse(linepos)
lines += num_lines
uword[] scores = [10, 25, 50, 100] ; can never clear more than 4 lines at once
@ -481,7 +481,7 @@ waitkey:
ubyte @zp i
for i in 15 downto 0 {
ubyte @zp c=blocklogic.currentBlock[i]
if c {
if c!=0 {
if erase
c=0
else {
@ -639,7 +639,7 @@ blocklogic {
sub noCollision(ubyte xpos, ubyte ypos) -> bool {
ubyte @zp i
for i in 15 downto 0 {
if currentBlock[i] and txt.getchr(xpos + (i&3), ypos+i/4)!=32
if currentBlock[i]!=0 and txt.getchr(xpos + (i&3), ypos+i/4)!=32
return false
}
return true

View File

@ -202,7 +202,7 @@ main {
ubyte tp
for tp in 0 to 15 {
monogfx.text(19+tp,20+tp*11, 7, sc:"ScreenCODE text! 1234![]<>#$%&*()")
monogfx.text(19+tp, 20+tp*11, true, sc:"ScreenCODE text! 1234![]<>#$%&*()")
}
}

View File

@ -47,12 +47,12 @@ main {
sub store_logo() {
vtui.gotoxy(0, 0)
vtui.save_rect($80, 1, $0000, 7, 7)
vtui.save_rect($80, true, $0000, 7, 7)
}
sub store_where_logo_was() {
vtui.gotoxy(0, 0)
vtui.save_rect($80, 1, $0100, 7, 7)
vtui.save_rect($80, true, $0100, 7, 7)
}
sub logo_mover() {
@ -67,12 +67,12 @@ main {
char_loop:
ubyte char = cbm.GETIN()
if not char
if char==0
goto char_loop
when char {
$91 -> {
if newy {
if newy!=0 {
newy--
move_logo()
}
@ -84,7 +84,7 @@ char_loop:
}
}
$9d -> {
if newx {
if newx!=0 {
newx--
move_logo()
}
@ -101,11 +101,11 @@ char_loop:
sub move_logo() {
vtui.gotoxy(xcoord, ycoord)
vtui.rest_rect($80, 1, $0100, 7, 7)
vtui.rest_rect($80, true, $0100, 7, 7)
vtui.gotoxy(newx, newy)
vtui.save_rect($80, 1, $0100, 7, 7)
vtui.save_rect($80, true, $0100, 7, 7)
vtui.gotoxy(newx, newy)
vtui.rest_rect($80, 1, $0000, 7, 7)
vtui.rest_rect($80, true, $0000, 7, 7)
xcoord = newx
ycoord = newy
}

View File

@ -54,12 +54,12 @@ zsound_lib:
cbm.SETMSG(%10000000) ; enable kernal status messages for load
cx16.rambank(song_bank)
if not diskio.load_raw("colony.zsm", song_address) {
if diskio.load_raw("colony.zsm", song_address)==0 {
txt.print("?can't load\n")
return
}
cx16.rambank(digi_bank)
if not diskio.load_raw("terminator2.zcm", digi_address) {
if diskio.load_raw("terminator2.zcm", digi_address)==0 {
txt.print("?can't load\n")
return
} else {
@ -79,7 +79,7 @@ zsound_lib:
zsm_init()
pcm_init()
zsm_setcallback(&end_of_song_cb)
if zsm_start(song_bank, song_address)==0 {
if zsm_start(song_bank, song_address)==false {
txt.print("\nmusic speed: ")
txt.print_uw(zsm_get_music_speed())
txt.print(" hz\nplaying song! hit enter to also play a digi sample!\n")

View File

@ -39,7 +39,7 @@ zsound_lib:
const ubyte zcm_DIGITAB_size = 8 ; header size
const uword ram_bank_size = $2000
ubyte load_ok = false
bool load_ok = false
sub prebuffer() {
txt.print("prebuffering...")
@ -64,7 +64,7 @@ zsound_lib:
txt.print("\nstreaming from file, playback in irq!\n")
uword size = 1
while size {
while size!=0 {
size = diskio.f_read(digi_address, ram_bank_size) ; load next bank
txt.print_ub(cx16.getrambank())
txt.spc()

View File

@ -31,7 +31,7 @@ main {
rect(6, 0, 16, 20, true)
sub rect(ubyte x1, ubyte y1, ubyte x2, ubyte y2, ubyte fill) {
sub rect(ubyte x1, ubyte y1, ubyte x2, ubyte y2, bool fill) {
ubyte x
ubyte y
if fill {

View File

@ -40,7 +40,7 @@ main {
iter++
}
if iter & 1
if iter & 1 !=0
graphics.plot(pixelx, pixely)
}
}

View File

@ -87,7 +87,7 @@ carve_restart_after_repath:
if stackptr==255 {
; stack empty.
; repath if we are not done yet. (this is a workaround for the prog8 256 array lenght limit)
if cells_to_carve {
if cells_to_carve!=0 {
if repath()
goto carve_restart_after_repath
}
@ -102,7 +102,7 @@ carve_restart_after_repath:
if stackptr==0 {
; stack overflow, we can't track our path any longer.
; repath if we are not done yet. (this is a workaround for the prog8 256 array lenght limit)
if cells_to_carve {
if cells_to_carve!=0 {
if repath()
goto carve_restart_after_repath
}
@ -141,8 +141,8 @@ carve_restart_after_repath:
do {
cx = math.rnd() % numCellsHoriz
cy = math.rnd() % numCellsVert
} until not @(celladdr(cx, cy)) & STONE
if available_uncarved()
} until @(celladdr(cx, cy)) & STONE ==0
if available_uncarved()!=0
return true
}
return false
@ -150,25 +150,25 @@ carve_restart_after_repath:
sub available_uncarved() -> ubyte {
ubyte candidates = 0
if cx>0 and @(celladdr(cx-1, cy)) & STONE
if cx>0 and @(celladdr(cx-1, cy)) & STONE !=0
candidates |= LEFT
if cx<numCellsHoriz-1 and @(celladdr(cx+1, cy)) & STONE
if cx<numCellsHoriz-1 and @(celladdr(cx+1, cy)) & STONE !=0
candidates |= RIGHT
if cy>0 and @(celladdr(cx, cy-1)) & STONE
if cy>0 and @(celladdr(cx, cy-1)) & STONE !=0
candidates |= UP
if cy<numCellsVert-1 and @(celladdr(cx, cy+1)) & STONE
if cy<numCellsVert-1 and @(celladdr(cx, cy+1)) & STONE !=0
candidates |= DOWN
return candidates
}
sub choose_uncarved_direction() -> ubyte {
ubyte candidates = available_uncarved()
if not candidates
if candidates==0
return 0
repeat {
ubyte choice = candidates & directionflags[math.rnd() & 3]
if choice
if choice!=0
return choice
}
}
@ -176,7 +176,6 @@ carve_restart_after_repath:
sub openpassages() {
; open just a few extra passages, so that multiple routes are possible in theory.
ubyte cell
ubyte numpassages
ubyte cx
ubyte cy
@ -184,33 +183,33 @@ carve_restart_after_repath:
do {
cx = math.rnd() % (numCellsHoriz-2) + 1
cy = math.rnd() % (numCellsVert-2) + 1
} until not @(celladdr(cx, cy)) & STONE
} until @(celladdr(cx, cy)) & STONE ==0
ubyte direction = directionflags[math.rnd() & 3]
if not @(celladdr(cx, cy)) & direction {
if @(celladdr(cx, cy)) & direction == 0 {
when direction {
LEFT -> {
if not @(celladdr(cx-1,cy)) & STONE {
if @(celladdr(cx-1,cy)) & STONE == 0 {
@(celladdr(cx,cy)) |= LEFT
drawCell(cx,cy)
numpassages++
}
}
RIGHT -> {
if not @(celladdr(cx+1,cy)) & STONE {
if @(celladdr(cx+1,cy)) & STONE == 0 {
@(celladdr(cx,cy)) |= RIGHT
drawCell(cx,cy)
numpassages++
}
}
UP -> {
if not @(celladdr(cx,cy-1)) & STONE {
if @(celladdr(cx,cy-1)) & STONE == 0 {
@(celladdr(cx,cy)) |= UP
drawCell(cx,cy)
numpassages++
}
}
DOWN -> {
if not @(celladdr(cx,cy+1)) & STONE {
if @(celladdr(cx,cy+1)) & STONE == 0 {
@(celladdr(cx,cy)) |= DOWN
drawCell(cx,cy)
numpassages++
@ -244,22 +243,22 @@ solve_loop:
}
ubyte cell = @(celladdr(cx,cy))
if cell & UP and not @(celladdr(cx,cy-1)) & (WALKED|BACKTRACKED) {
if cell & UP!=0 and @(celladdr(cx,cy-1)) & (WALKED|BACKTRACKED) ==0 {
@(pathstack + pathstackptr) = UP
txt.setcc(cx*2+1, cy*2, 81, 3)
cy--
}
else if cell & DOWN and not @(celladdr(cx,cy+1)) & (WALKED|BACKTRACKED) {
else if cell & DOWN !=0 and @(celladdr(cx,cy+1)) & (WALKED|BACKTRACKED) ==0 {
@(pathstack + pathstackptr) = DOWN
txt.setcc(cx*2+1, cy*2+2, 81, 3)
cy++
}
else if cell & LEFT and not @(celladdr(cx-1,cy)) & (WALKED|BACKTRACKED) {
else if cell & LEFT !=0 and @(celladdr(cx-1,cy)) & (WALKED|BACKTRACKED) ==0 {
@(pathstack + pathstackptr) = LEFT
txt.setcc(cx*2, cy*2+1, 81, 3)
cx--
}
else if cell & RIGHT and not @(celladdr(cx+1,cy)) & (WALKED|BACKTRACKED) {
else if cell & RIGHT !=0 and @(celladdr(cx+1,cy)) & (WALKED|BACKTRACKED) ==0 {
@(pathstack + pathstackptr) = RIGHT
txt.setcc(cx*2+2, cy*2+1, 81, 3)
cx++
@ -311,22 +310,22 @@ solve_loop:
ubyte x = cx * 2 + 1
ubyte y = cy * 2 + 1
ubyte doors = @(celladdr(cx,cy))
if doors & UP
if doors & UP !=0
txt.setcc(x, y-1, ' ', EMPTYCOLOR)
if doors & RIGHT
if doors & RIGHT !=0
txt.setcc(x+1, y, ' ', EMPTYCOLOR)
if doors & DOWN
if doors & DOWN !=0
txt.setcc(x, y+1, ' ', EMPTYCOLOR)
if doors & LEFT
if doors & LEFT !=0
txt.setcc(x-1, y, ' ', EMPTYCOLOR)
if doors & STONE
if doors & STONE !=0
txt.setcc(x, y, 160, WALLCOLOR)
else
txt.setcc(x, y, 32, EMPTYCOLOR)
if doors & WALKED
if doors & WALKED !=0
txt.setcc(x, y, 81, 1)
if doors & BACKTRACKED
if doors & BACKTRACKED !=0
txt.setcc(x, y, 81, 2)
}

View File

@ -49,7 +49,7 @@ main {
return
sub ending(ubyte success) {
sub ending(bool success) {
if success
txt.print("\n\nYou guessed it, impressive!\n")
else {

View File

@ -9,7 +9,7 @@ main {
ubyte candidate_prime = 2 ; is increased in the loop
sub start() {
sys.memset(sieve, 256, false) ; clear the sieve, to reset starting situation on subsequent runs
sys.memset(sieve, 256, 0) ; clear the sieve, to reset starting situation on subsequent runs
; calculate primes
txt.print("prime numbers up to 255:\n\n")

View File

@ -1,37 +1,24 @@
%import textio
%option no_sysinit
%zeropage basicsafe
%option no_sysinit
main {
sub rrrr() -> ubyte {
cx16.r0L++
return cx16.r0L
}
sub start() {
cx16.r0L = rrrr() >= 128
bool[3] barr
bool @shared bb
; ubyte[] flakes = [1,2,3]
;
; ubyte @shared idx = 2
;
; if flakes[idx]==239 {
; txt.print("yes")
; } else {
; txt.print("nope")
; }
;
; ubyte @shared xx = 16
; ubyte @shared yy = 20
;
; txt.print_ub(xx>79 or yy > 49)
barr[1] = barr[0] and barr[2]
barr[1] = barr[0] or barr[2]
barr[1] = barr[0] xor barr[2]
barr[1] = not barr[0]
barr[1] = not barr[1]
barr[1] = barr[1] and bb
barr[1] = barr[1] or bb
barr[1] = barr[1] xor bb
; if xx>79 or yy > 49 {
; if xx>79 or yy > 49 {
; txt.print("no\n")
; }
; else {
; txt.print("yes\n")
; }
bb = bb and barr[1]
bb = bb or barr[1]
bb = bb xor barr[1]
bb = not bb
}
}

View File

@ -37,7 +37,7 @@ main {
txt.print("\nCommand (?=help): ")
ubyte num_chars = txt.input_chars(input)
txt.nl()
if num_chars {
if num_chars!=0 {
when input[0] {
'?' -> {
txt.print("\nCommands are:\n"+
@ -86,7 +86,7 @@ trader {
sub do_load() {
txt.print("\nLoading universe... (drive 8)")
if diskio.load(Savegame, &savedata) {
if diskio.load(Savegame, &savedata)!=0 {
txt.print("ok\n")
} else {
txt.print("\ni/o error: ")
@ -163,7 +163,7 @@ trader {
str commodity = "???????????????"
void txt.input_chars(commodity)
ubyte ci = market.match(commodity)
if ci & 128 {
if ci & 128 !=0 {
txt.print("Unknown\n")
} else {
txt.print("\nHow much? ")
@ -191,7 +191,7 @@ trader {
str commodity = "???????????????"
void txt.input_chars(commodity)
ubyte ci = market.match(commodity)
if ci & 128 {
if ci & 128 !=0 {
txt.print("Unknown\n")
} else {
txt.print("\nHow much? ")
@ -247,7 +247,7 @@ trader {
sub do_info() {
txt.print("\nSystem name (empty=current): ")
num_chars = txt.input_chars(input)
if num_chars {
if num_chars!=0 {
ubyte current_planet = planet.number
ubyte x = planet.x
ubyte y = planet.y
@ -270,7 +270,7 @@ trader {
sub do_map() {
txt.print("\n(l)ocal or (g)alaxy starmap? ")
num_chars = txt.input_chars(input)
if num_chars {
if num_chars!=0 {
galaxy.starmap(input[0]=='l')
}
}
@ -342,7 +342,7 @@ market {
product = planet.economy as word * gradients[ci]
changing = fluct & maskbytes[ci] as byte
ubyte q = (basequants[ci] as word + changing - product) as ubyte
if q & $80
if q & $80 !=0
q = 0 ; clip to positive 8-bit
current_quantity[ci] = q & $3f
q = (baseprices[ci] + changing + product) as ubyte
@ -430,13 +430,13 @@ galaxy {
market.init(lsb(seed[0])+msb(seed[2]))
}
sub search_closest_planet(uword nameptr) -> ubyte {
sub search_closest_planet(uword nameptr) -> bool {
ubyte x = planet.x
ubyte y = planet.y
ubyte current_planet_num = planet.number
init(number)
ubyte found = false
bool found = false
ubyte current_closest_pi
ubyte current_distance = 127
ubyte pi
@ -575,11 +575,11 @@ galaxy {
ubyte pn_pair2
ubyte pn_pair3
ubyte pn_pair4
ubyte longname
bool longname
sub generate_next_planet() {
determine_planet_properties()
longname = lsb(seed[0]) & 64
longname = lsb(seed[0]) & 64 !=0
; Always four iterations of random number
pn_pair1 = (msb(seed[2]) & 31) * 2
@ -647,7 +647,7 @@ galaxy {
planet.economy = (planet.economy | 2)
planet.techlevel = (msb(seed[1]) & 3) + (planet.economy ^ 7)
planet.techlevel += planet.govtype >> 1
if planet.govtype & 1
if planet.govtype & 1 !=0
planet.techlevel++
planet.population = 4 * planet.techlevel + planet.economy
planet.population += planet.govtype + 1
@ -655,7 +655,7 @@ galaxy {
planet.productivity *= planet.population * 8
ubyte seed2_msb = msb(seed[2])
planet.radius = mkword((seed2_msb & 15) + 11, planet.x)
planet.species_is_alien = lsb(seed[2]) & 128 ; bit 7 of w2_lo
planet.species_is_alien = lsb(seed[2]) & 128 !=0 ; bit 7 of w2_lo
if planet.species_is_alien {
planet.species_size = (seed2_msb >> 2) & 7 ; bits 2-4 of w2_hi
planet.species_color = seed2_msb >> 5 ; bits 5-7 of w2_hi
@ -765,7 +765,7 @@ planet {
ubyte population
uword productivity
uword radius
ubyte species_is_alien ; otherwise "Human Colonials"
bool species_is_alien ; otherwise "Human Colonials"
ubyte species_size
ubyte species_color
ubyte species_look
@ -866,7 +866,7 @@ planet {
else {
if c <= $a4 {
ubyte rnr = goatsoup_rnd_number()
ubyte wordNr = (rnr >= $33) + (rnr >= $66) + (rnr >= $99) + (rnr >= $CC)
ubyte wordNr = ((rnr >= $33) as ubyte) + ((rnr >= $66) as ubyte) + ((rnr >= $99) as ubyte) + ((rnr >= $CC) as ubyte)
source_stack[stack_ptr] = source_ptr
stack_ptr++
source_ptr = getword(c, wordNr)
@ -928,7 +928,7 @@ planet {
sub display(bool compressed, ubyte distance) {
if compressed {
print_name_uppercase()
if distance {
if distance!=0 {
txt.print(" (")
util.print_10s(distance)
txt.print(" LY)")
@ -950,7 +950,7 @@ planet {
txt.spc()
txt.chrout('#')
txt.print_ub(number)
if distance {
if distance!=0 {
txt.print("\nDistance: ")
util.print_10s(distance)
txt.print(" LY")
@ -1025,7 +1025,7 @@ planet {
}
util {
sub prefix_matches(uword prefixptr, uword stringptr) -> ubyte {
sub prefix_matches(uword prefixptr, uword stringptr) -> bool {
repeat {
ubyte pc = @(prefixptr)
ubyte sc = @(stringptr)

View File

@ -17,11 +17,11 @@ main {
sys.memset(flags_ptr, SIZEPL, 1)
count = 0
for i in 0 to SIZEPL-1 {
if flags_ptr[i] {
if flags_ptr[i]!=0 {
prime = i + i + 3
k = i + prime
while k <= SIZEPL-1 {
flags_ptr[k] = false
flags_ptr[k] = 0 ; false
k += prime
}
txt.print_uw(prime)

View File

@ -30,7 +30,7 @@ main {
txt.print("\nCommand (?=help): ")
ubyte num_chars = txt.input_chars(input)
txt.nl()
if num_chars {
if num_chars!=0 {
when input[0] {
'?' -> {
txt.print("\nCommands are:\n"+
@ -104,7 +104,7 @@ trader {
str commodity = "???????????????"
void txt.input_chars(commodity)
ubyte ci = market.match(commodity)
if ci & 128 {
if ci & 128 !=0 {
txt.print("Unknown\n")
} else {
txt.print("\nHow much? ")
@ -132,7 +132,7 @@ trader {
str commodity = "???????????????"
void txt.input_chars(commodity)
ubyte ci = market.match(commodity)
if ci & 128 {
if ci & 128 !=0 {
txt.print("Unknown\n")
} else {
txt.print("\nHow much? ")
@ -188,7 +188,7 @@ trader {
sub do_info() {
txt.print("\nSystem name (empty=current): ")
num_chars = txt.input_chars(input)
if num_chars {
if num_chars!=0 {
ubyte current_planet = planet.number
ubyte x = planet.x
ubyte y = planet.y
@ -211,7 +211,7 @@ trader {
sub do_map() {
txt.print("\n(l)ocal or (g)alaxy starmap? ")
num_chars = txt.input_chars(input)
if num_chars {
if num_chars!=0 {
galaxy.starmap(input[0]=='l')
}
}
@ -283,7 +283,7 @@ market {
product = planet.economy as word * gradients[ci]
changing = fluct & maskbytes[ci] as byte
ubyte q = (basequants[ci] as word + changing - product) as ubyte
if q & $80
if q & $80 !=0
q = 0 ; clip to positive 8-bit
current_quantity[ci] = q & $3f
q = (baseprices[ci] + changing + product) as ubyte
@ -371,13 +371,13 @@ galaxy {
market.init(lsb(seed[0])+msb(seed[2]))
}
sub search_closest_planet(uword nameptr) -> ubyte {
sub search_closest_planet(uword nameptr) -> bool {
ubyte x = planet.x
ubyte y = planet.y
ubyte current_planet_num = planet.number
init(number)
ubyte found = false
bool found = false
ubyte current_closest_pi
ubyte current_distance = 127
ubyte pi
@ -558,7 +558,7 @@ galaxy {
ni++
}
if longname {
if longname!=0 {
if pn_pairs[pn_pair4] != '.' {
name[ni] = pn_pairs[pn_pair4]
ni++
@ -584,7 +584,7 @@ galaxy {
planet.economy = (planet.economy | 2)
planet.techlevel = (msb(seed[1]) & 3) + (planet.economy ^ 7)
planet.techlevel += planet.govtype >> 1
if planet.govtype & 1
if planet.govtype & 1 !=0
planet.techlevel++
planet.population = 4 * planet.techlevel + planet.economy
planet.population += planet.govtype + 1
@ -592,7 +592,7 @@ galaxy {
planet.productivity *= planet.population * 8
ubyte seed2_msb = msb(seed[2])
planet.radius = mkword((seed2_msb & 15) + 11, planet.x)
planet.species_is_alien = lsb(seed[2]) & 128 ; bit 7 of w2_lo
planet.species_is_alien = lsb(seed[2]) & 128 !=0 ; bit 7 of w2_lo
if planet.species_is_alien {
planet.species_size = (seed2_msb >> 2) & 7 ; bits 2-4 of w2_hi
planet.species_color = seed2_msb >> 5 ; bits 5-7 of w2_hi
@ -690,7 +690,7 @@ planet {
ubyte population
uword productivity
uword radius
ubyte species_is_alien ; otherwise "Human Colonials"
bool species_is_alien ; otherwise "Human Colonials"
ubyte species_size
ubyte species_color
ubyte species_look
@ -791,7 +791,7 @@ planet {
else {
if c <= $a4 {
ubyte rnr = goatsoup_rnd_number()
ubyte wordNr = (rnr >= $33) + (rnr >= $66) + (rnr >= $99) + (rnr >= $CC)
ubyte wordNr = ((rnr >= $33) as ubyte) + ((rnr >= $66) as ubyte) + ((rnr >= $99) as ubyte) + ((rnr >= $CC) as ubyte)
source_stack[stack_ptr] = source_ptr
stack_ptr++
source_ptr = getword(c, wordNr)
@ -853,7 +853,7 @@ planet {
sub display(bool compressed, ubyte distance) {
if compressed {
print_name_uppercase()
if distance {
if distance!=0 {
txt.print(" (")
util.print_10s(distance)
txt.print(" LY)")
@ -875,7 +875,7 @@ planet {
txt.spc()
txt.chrout('#')
txt.print_ub(number)
if distance {
if distance!=0 {
txt.print("\nDistance: ")
util.print_10s(distance)
txt.print(" LY")
@ -932,7 +932,7 @@ planet {
}
util {
sub prefix_matches(uword prefixptr, uword stringptr) -> ubyte {
sub prefix_matches(uword prefixptr, uword stringptr) -> bool {
repeat {
ubyte pc = @(prefixptr)
ubyte sc = @(stringptr)