This commit is contained in:
Irmen de Jong 2018-01-03 21:43:19 +01:00
parent 6511283bb8
commit 3c70790fbf
14 changed files with 839 additions and 52 deletions

289
il65/lexer.py Normal file
View File

@ -0,0 +1,289 @@
import sys
from .symbols import SourceRef
import ply.lex
# token names
tokens = (
"INTEGER",
"FLOATINGPOINT",
"DOTTEDNAME",
"NAME",
"DOT",
"IS",
"CLOBBEREDREGISTER",
"REGISTER",
"COMMENT",
"DIRECTIVE",
"AUGASSIGN",
"EQUAL",
"NOTEQUAL",
"RARROW",
"RETURN",
"TILDE",
"VARTYPE",
"KEYWORD",
"SUB",
"DATATYPE",
"CHARACTER",
"STRING",
"BOOLEAN",
"GOTO",
"INCR",
"DECR",
"NOT",
"LT",
"GT",
"LE",
"GE",
"LABEL",
"IF",
"ADDRESSOF",
"PRESERVEREGS",
"INLINEASM",
)
literals = ['+', '-', '*', '/', '(', ')', '[', ']', '{', '}', '.', ',', '!', '?', ':']
# regex rules for simple tokens
t_ADDRESSOF = r"\#"
t_IS = r"="
t_TILDE = r"~"
t_DIRECTIVE = r"%[a-z]+"
t_AUGASSIGN = r"\+=|-=|/=|\*=|<<=|>>=|&=|\|=|\^="
t_DECR = r"--"
t_INCR = r"\+\+"
t_EQUAL = r"=="
t_NOTEQUAL = r"!="
t_LT = r"<"
t_GT = r">"
t_LE = r"<="
t_GE = r">="
t_IF = "if(_[a-z]+)?"
t_RARROW = r"->"
# ignore inline whitespace
t_ignore = " \t"
t_inlineasm_ignore = " \t\r\n"
# states for allowing %asm inclusion of raw assembly
states = (
('inlineasm', 'exclusive'),
)
# reserved words
reserved = {
"sub": "SUB",
"var": "VARTYPE",
"memory": "VARTYPE",
"const": "VARTYPE",
"goto": "GOTO",
"return": "RETURN",
"true": "BOOLEAN",
"false": "BOOLEAN",
"not": "NOT",
"AX": "REGISTER",
"AY": "REGISTER",
"XY": "REGISTER",
"SC": "REGISTER",
"SI": "REGISTER",
"SZ": "REGISTER",
"A": "REGISTER",
"X": "REGISTER",
"Y": "REGISTER",
"if": "IF",
"if_true": "IF",
"if_not": "IF",
"if_ne": "IF",
"if_eq": "IF",
"if_cc": "IF",
"if_cs": "IF",
"if_vc": "IF",
"if_vs": "IF",
"if_gt": "IF",
"if_lt": "IF",
"if_pos": "IF",
"if_get": "IF",
}
# rules for tokens with some actions
def t_inlineasm(t):
r"%asm\s*\{\s*"
t.lexer.code_start = t.lexer.lexpos # Record start position
t.lexer.level = 1 # initial brace level
t.lexer.begin("inlineasm") # enter state 'inlineasm'
t.lexer.lineno += 1
def t_inlineasm_lbrace(t):
r"\{"
t.lexer.level += 1
def t_inlineasm_rbrace(t):
r"\}"
t.lexer.level -= 1
#if closing brace, return code fragment
if t.lexer.level == 0:
t.value = t.lexer.lexdata[t.lexer.code_start:t.lexer.lexpos-1]
t.type = "INLINEASM"
t.lexer.lineno += t.value.count("\n")
t.lexer.begin("INITIAL") # back to normal lexing rules
return t
def t_inlineasm_comment(t):
r";[^\n]*"
pass
def t_inlineasm_string(t):
r"""(?x) # verbose mode
(?<!\\) # not preceded by a backslash
" # a literal double-quote
.*? # 1-or-more characters
(?<!\\) # not preceded by a backslash
" # a literal double-quote
|
(?<!\\) # not preceded by a backslash
' # a literal single quote
.*? # 1-or-more characters
(?<!\\) # not preceded by a backslash
' # a literal double-quote
"""
pass
def t_inlineasm_nonspace(t):
r'[^\s\{\}\'\"]+'
pass
def t_inlineasm_error(t):
# For bad characters, we just skip over it
t.lexer.skip(1)
def t_CLOBBEREDREGISTER(t):
r"(AX|AY|XY|A|X|Y)\?"
t.value = t.value[:-1]
return t
def t_DATATYPE(t):
r"\.byte|\.wordarray|\.float|\.array|\.word|\.text|\.stext|\.ptext|\.pstext|\.matrix"
t.value = t.value[1:]
return t
def t_LABEL(t):
r"[a-zA-Z_]\w*\s*:"
t.value = t.value[:-1].strip()
return t
def t_DOTTEDNAME(t):
r"[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)+"
return t
def t_NAME(t):
r"[a-zA-Z_]\w*"
t.type = reserved.get(t.value, "NAME") # check for reserved words
return t
def t_STRING(t):
r"""(?x) # verbose mode
(?<!\\) # not preceded by a backslash
" # a literal double-quote
.*? # 1-or-more characters
(?<!\\) # not preceded by a backslash
" # a literal double-quote
|
(?<!\\) # not preceded by a backslash
' # a literal single quote
.*? # 1-or-more characters
(?<!\\) # not preceded by a backslash
' # a literal double-quote
"""
t.value = t.value[1:-1]
if len(t.value) == 1:
t.type = "CHARACTER"
if len(t.value) == 2 and t.value[0] == '\\':
t.type = "CHARACTER"
return t
def t_FLOATINGPOINT(t):
r"[-+]? (?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?"
try:
t.value = int(t.value)
t.type = "INTEGER"
except ValueError:
t.value = float(t.value)
return t
def t_INTEGER(t):
r"([-+]?\$?[a-fA-F\d]+ | [-+]?[\$%]?\d+ | [-+]?%?[01]+)(?!\.)"
sign = 1
if t.value[0] in "+-":
sign = -1 if t.value[0] == "-" else 1
t.value = t.value[1:]
if t.value[0] == '$':
t.value = int(t.value[1:], 16) * sign
elif t.value[0] == '%':
t.value = int(t.value[1:], 2) * sign
else:
t.value = int(t.value) * sign
return t
def t_COMMENT(t):
r";[^\n]*"
# don't include the \n at the end, that must be processed by t_newline
return None # ignore comments for now
def t_PRESERVEREGS(t):
r"!\s*[AXY]{0,3}\s*"
t.value = t.value[1:-1].strip()
return t
def t_newline(t):
r"\n+"
t.lexer.lineno += len(t.value)
return None # ignore white space tokens
def t_error(t):
line, col = t.lineno, find_tok_column(t)
sref = SourceRef("@todo-filename-f1", line, col)
t.lexer.error_function("{}: Illegal character '{:s}'", sref, t.value[0])
t.lexer.skip(1)
def find_tok_column(token):
""" Find the column of the token in its line."""
last_cr = lexer.lexdata.rfind('\n', 0, token.lexpos)
return token.lexpos - last_cr
def error_function(fmtstring, *args):
print("ERROR:", fmtstring.format(*args), file=sys.stderr)
lexer = ply.lex.lex()
lexer.error_function = error_function # can override this
if __name__ == "__main__":
ply.lex.runmain()
#lexer = ply.lex.Lexer()
#ply.lex.runmain(lexer=lexer)

486
il65/plyacc.py Normal file
View File

@ -0,0 +1,486 @@
from ply.yacc import yacc
from .symbols import SourceRef, AstNode
from .lexer import tokens, lexer, find_tok_column # get the lexer tokens. required.
start = "start"
class Module(AstNode):
def __init__(self, nodes, sourceref):
super().__init__(sourceref)
self.nodes = nodes or []
class Directive(AstNode):
def __init__(self, name, args, sourceref):
super().__init__(sourceref)
self.name = name
self.args = args or []
class Block(AstNode):
def __init__(self, name, address, scope, sourceref):
super().__init__(sourceref)
self.name = name
self.address = address
self.scope = scope
class Scope(AstNode):
def __init__(self, nodes, sourceref):
super().__init__(sourceref)
self.nodes = nodes
class Label(AstNode):
def __init__(self, name, sourceref):
super().__init__(sourceref)
self.name = name
class Register(AstNode):
def __init__(self, name, sourceref):
super().__init__(sourceref)
self.name = name
class PreserveRegs(AstNode):
def __init__(self, registers, sourceref):
super().__init__(sourceref)
self.registers = registers
class Assignment(AstNode):
def __init__(self, lhs, operator, rhs, sourceref):
super().__init__(sourceref)
self.lhs = lhs
self.operator = operator
self.rhs = rhs
class SubCall(AstNode):
def __init__(self, target, arguments, sourceref):
super().__init__(sourceref)
self.target = target
self.arguments = arguments
class InlineAssembly(AstNode):
def __init__(self, assembly, sourceref):
super().__init__(sourceref)
self.assembly = assembly
class VarDef(AstNode):
def __init__(self, name, vartype, datatype, value, sourceref):
super().__init__(sourceref)
self.name = name
self.vartype = vartype
self.datatype = datatype
self.value = value
class Datatype(AstNode):
def __init__(self, name, dimension, sourceref):
super().__init__(sourceref)
self.name = name
self.dimension = dimension
class Subroutine(AstNode):
def __init__(self, name, paramspec, resultspec, code, sourceref):
super().__init__(sourceref)
self.name = name
self.paramspec = paramspec
self.resultspec = resultspec
self.code = code
class Goto(AstNode):
def __init__(self, target, ifstmt, condition, sourceref):
super().__init__(sourceref)
self.target = target
self.ifstmt = ifstmt
self.condition = condition
class UnaryOp(AstNode):
def __init__(self, operator, operand, sourceref):
super().__init__(sourceref)
self.operator = operator
self.operand = operand
class BinaryOp(AstNode):
def __init__(self, operator, left, right, sourceref):
super().__init__(sourceref)
self.operator = operator
self.left = left
self.right = right
class Integer(AstNode):
def __init__(self, value, sourceref):
super().__init__(sourceref)
self.value = value
def p_start(p):
"""start : empty
| module_elements"""
if p[1]:
p[0] = Module(p[1], _token_sref(p, 1))
def p_module(p):
"""module_elements : module_elt
| module_elements module_elt"""
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_module_elt(p):
"""module_elt : directive
| block"""
p[0] = p[1]
def p_directive(p):
"""directive : DIRECTIVE
| DIRECTIVE directive_args
"""
if len(p) == 2:
p[0] = Directive(p[1], None, _token_sref(p, 1))
else:
p[0] = Directive(p[1], p[2], _token_sref(p, 1))
def p_directive_args(p):
"""directive_args : directive_arg
| directive_args ',' directive_arg
"""
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[3]]
def p_directive_arg(p):
"""directive_arg : NAME
| INTEGER
"""
p[0] = p[1]
def p_block(p):
"""block : TILDE NAME INTEGER scope
| TILDE NAME empty scope
| TILDE empty empty scope"""
p[0] = Block(p[2], p[3], p[4], _token_sref(p, 1))
def p_scope(p):
"""scope : '{' scope_elements_opt '}'"""
p[0] = Scope(p[2], _token_sref(p, 1))
def p_scope_elements_opt(p):
"""scope_elements_opt : empty
| scope_elements"""
p[0] = p[1]
def p_scope_elements(p):
"""scope_elements : scope_element
| scope_elements scope_element"""
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_scope_element(p):
"""scope_element : directive
| vardef
| subroutine
| label
| inlineasm
| statement"""
p[0] = p[1]
def p_label(p):
"""label : LABEL"""
p[0] = Label(p[1], _token_sref(p, 1))
def p_inlineasm(p):
"""inlineasm : INLINEASM"""
p[0] = InlineAssembly(p[1], _token_sref(p, 1))
def p_vardef(p):
"""vardef : VARTYPE type_opt NAME IS literal_value
| VARTYPE type_opt NAME"""
if len(p) == 4:
p[0] = VarDef(p[3], p[1], p[2], None, _token_sref(p, 1))
else:
p[0] = VarDef(p[3], p[1], p[2], p[5], _token_sref(p, 1))
def p_type_opt(p):
"""type_opt : DATATYPE
| DATATYPE '(' dimensions ')'
| empty"""
if len(p) == 4:
p[0] = Datatype(p[1], p[3], _token_sref(p, 1))
elif p:
p[0] = Datatype(p[1], None, _token_sref(p, 1))
def p_dimensions(p):
"""dimensions : INTEGER
| dimensions ',' INTEGER"""
if len(p)==2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[3]]
def p_literal_value(p):
"""literal_value : INTEGER
| FLOATINGPOINT
| STRING
| CHARACTER
| BOOLEAN"""
p[0] = p[1]
def p_subroutine(p):
"""subroutine : SUB NAME '(' sub_param_spec ')' RARROW '(' sub_result_spec ')' subroutine_body"""
p[0] = Subroutine(p[2], p[4], p[8], p[10], _token_sref(p, 1))
def p_sub_param_spec(p):
"""sub_param_spec : empty
| sub_param_list"""
p[0] = p[1]
def p_sub_param_list(p):
"""sub_param_list : sub_param
| sub_param_list ',' sub_param"""
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_sub_param(p):
"""sub_param : LABEL REGISTER
| empty REGISTER"""
p[0] = (p[1], p[2])
def p_param_name(p):
"""param_name : NAME ':'"""
p[0] = p[1]
def p_sub_result_spec(p):
"""sub_result_spec : empty
| '?'
| sub_result_list"""
if p[1] == '?':
p[0] = ['A', 'X', 'Y'] # '?' means: all registers clobbered
p[0] = p[1]
def p_sub_result_list(p):
"""sub_result_list : sub_result_reg
| sub_result_list ',' sub_result_reg"""
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[3]]
def p_sub_result_reg(p):
"""sub_result_reg : REGISTER
| CLOBBEREDREGISTER"""
p[0] = p[1]
def p_subroutine_body(p):
"""subroutine_body : scope
| IS INTEGER"""
if len(p) == 2:
p[0] = p[1]
else:
p[0] = p[2]
def p_statement(p):
"""statement : assignment
| subroutine_call
| goto
| conditional_goto
| incrdecr
| RETURN
"""
p[0] = p[1]
def p_incrdecr(p):
"""incrdecr : register INCR
| register DECR
| symbolname INCR
| symbolname DECR"""
p[0] = UnaryOp(p[2], p[1], _token_sref(p, 1))
def p_call_subroutine(p):
"""subroutine_call : symbolname preserveregs_opt '(' call_arguments_opt ')'"""
p[0] = SubCall(p[1], p[3], _token_sref(p, 1))
def p_preserveregs_opt(p):
"""preserveregs_opt : empty
| preserveregs"""
p[0] = p[1]
def p_preserveregs(p):
"""preserveregs : PRESERVEREGS"""
p[0] = PreserveRegs(p[1], _token_sref(p, 1))
def p_call_arguments_opt(p):
"""call_arguments_opt : empty
| call_arguments"""
p[0] = p[1]
def p_call_arguments(p):
"""call_arguments : call_argument
| call_arguments ',' call_argument"""
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[3]]
def p_call_argument(p):
"""call_argument : literal_value
| register"""
p[0] = p[1]
def p_register(p):
"""register : REGISTER"""
p[0] = Register(p[1], _token_sref(p, 1))
def p_goto(p):
"""goto : GOTO symbolname
| GOTO INTEGER"""
p[0] = Goto(p[2], None, None, _token_sref(p, 1))
def p_conditional_goto(p):
"""conditional_goto : IF GOTO symbolname"""
# @todo support conditional expression
p[0] = Goto(p[3], p[1], None, _token_sref(p, 1))
def p_symbolname(p):
"""symbolname : NAME
| DOTTEDNAME"""
p[0] = p[1]
def p_assignment(p):
"""assignment : assignment_lhs assignment_operator assignment_rhs"""
# @todo replace lhs/rhs by expressions
p[0] = Assignment(p[1], p[2], p[3], _token_sref(p, 1))
def p_assignment_operator(p):
"""assignment_operator : IS
| AUGASSIGN"""
p[0] = p[1]
def p_unary_operator(p):
"""unary_operator : '+'
| '-'
| NOT
| ADDRESSOF"""
p[0] = p[1]
def p_assignment_lhs(p):
"""assignment_lhs : register
| symbolname
| assignment_lhs ',' register
| assignment_lhs ',' symbolname"""
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_assignment_rhs(p):
"""assignment_rhs : literal_value
| symbolname
| register
| subroutine_call"""
p[0] = p[1]
def p_term(p):
"""term : register"""
p[0] = p[1]
def p_empty(p):
"""empty :"""
pass
def p_error(p):
if p:
sref = SourceRef("@todo-filename2", p.lineno, find_tok_column(p))
lexer.error_function("{}: before '{:.20s}' ({})", sref, str(p.value), repr(p))
else:
lexer.error_function("{}: at end of input", "@todo-filename3")
def _token_sref(p, token_idx):
""" Returns the coordinates for the YaccProduction object 'p' indexed
with 'token_idx'. The coordinate includes the 'lineno' and
'column'. Both follow the lex semantic, starting from 1.
"""
last_cr = p.lexer.lexdata.rfind('\n', 0, p.lexpos(token_idx))
if last_cr < 0:
last_cr = -1
column = (p.lexpos(token_idx) - last_cr)
return SourceRef("@todo-filename", p.lineno(token_idx), column)
precedence = (
('nonassoc', "COMMENT"),
)
parser = yacc()
if __name__ == "__main__":
import sys
file=sys.stdin # open(sys.argv[1], "rU")
result = parser.parse(input=file.read()) or Module(None, SourceRef("@todo-sfile", 1, 1))
print("RESULT")
print(result.nodes)

View File

@ -974,7 +974,7 @@ sub print_word_decimal0 (word: XY) -> (?) {
} }
sub print_word_decimal (word: XY) -> (A?, X? Y?) { sub print_word_decimal (word: XY) -> (A?, X?, Y?) {
; ---- print the word in X/Y in decimal form, without left padding 0s ; ---- print the word in X/Y in decimal form, without left padding 0s
%asm { %asm {
jsr word2decimal jsr word2decimal

View File

@ -21,7 +21,7 @@
sub sub4 (string: XY, other : A) -> (Y?) = $dd22 sub sub4 (string: XY, other : A) -> (Y?) = $dd22
bar bar:
goto $c000 goto $c000
goto [$c000.word] goto [$c000.word]
@ -134,7 +134,7 @@ bar
~ main { ~ main {
start start:
foo.bar() foo.bar()
return return

View File

@ -1,13 +1,14 @@
%output prg,basic %output prg,basic
%import "c64lib" %import c64lib
~ main { ~ main {
var .word value var .word value
memory .word memvalue = $8000 memory .word memvalue = $8000
start start:
A = 100 A = 100
@ -29,7 +30,7 @@ start
;if_cc goto $c000 ;if_cc goto $c000
;if_cc goto [$c000.word] ;if_cc goto [$c000.word]
label label:
; conditional if with a single 'truth' value (register) ; conditional if with a single 'truth' value (register)
if_true A goto label2 if_true A goto label2
if_not A goto label2 if_not A goto label2
@ -48,7 +49,7 @@ label
if_zero XY goto label2 if_zero XY goto label2
if XY goto label2 if XY goto label2
label2 label2:
; conditional if with a single 'truth' value (variable) ; conditional if with a single 'truth' value (variable)
if_true value goto label3 if_true value goto label3
if_not value goto label3 if_not value goto label3
@ -59,7 +60,7 @@ label2
if_zero memvalue goto label3 if_zero memvalue goto label3
if memvalue goto label3 if memvalue goto label3
label3 label3:
; conditional if with a single 'truth' value (indirect address) ; conditional if with a single 'truth' value (indirect address)
if_true [$c000] goto label4 if_true [$c000] goto label4
if_not [$c000] goto label4 if_not [$c000] goto label4
@ -72,7 +73,7 @@ label3
if_true [A] goto label4 if_true [A] goto label4
if_true [Y] goto label4 if_true [Y] goto label4
label4 label4:
return return
} }
@ -87,18 +88,18 @@ label4
var .word wordvar = 22345 var .word wordvar = 22345
start start:
c64.init_system() c64.init_system()
A = 0 A = 0
printloop printloop:
c64scr.print_byte_decimal(A) c64scr.print_byte_decimal(A)
c64.CHROUT('\n') c64.CHROUT('\n')
A++ A++
if A <20 goto printloop if A <20 goto printloop
return return
label1 label1:
if_true A==123 goto label1 if_true A==123 goto label1
if_true A == 123 goto label1 if_true A == 123 goto label1
if_true A!=0 goto label1 if_true A!=0 goto label1
@ -138,6 +139,6 @@ label1
if_true wordvar goto label2 if_true wordvar goto label2
label2 label2:
return return
} }

View File

@ -4,7 +4,7 @@
%zp clobber %zp clobber
%import "c64lib" %import c64lib
~ ZP { ~ ZP {
; ZeroPage block definition: ; ZeroPage block definition:
@ -72,7 +72,7 @@
var .wordarray(10) init_wordarray = $1234 var .wordarray(10) init_wordarray = $1234
var .wordarray(10) init_wordarrayb = true var .wordarray(10) init_wordarrayb = true
var .text text = "hello"+"-null" var .text text = "hello-null"
var .ptext ptext = 'hello-pascal' var .ptext ptext = 'hello-pascal'
var .stext stext = 'screencodes-null' var .stext stext = 'screencodes-null'
var .pstext pstext = "screencodes-pascal" var .pstext pstext = "screencodes-pascal"

View File

@ -2,10 +2,10 @@
%output prg, basic %output prg, basic
%import "c64lib" %import c64lib
~ main_testing { ~ main_testing {
start start:
var .float myfloat1 = 1234.56789 var .float myfloat1 = 1234.56789
var .float myfloat2 = 9876.54321 var .float myfloat2 = 9876.54321
var .float myfloatneg1 = -555.666 var .float myfloatneg1 = -555.666
@ -52,7 +52,7 @@ sub printflt (float: AY) -> (?) {
} }
start start:
; assign some float values to the memory ; assign some float values to the memory
AY = #flt_pi AY = #flt_pi
some_address = # flt_pi some_address = # flt_pi
@ -112,7 +112,7 @@ start
printflt(# flt_point25) printflt(# flt_point25)
printflt(#c64.FL_FR4) printflt(#c64.FL_FR4)
reg_to_float reg_to_float:
c64.CHROUT!('\n') c64.CHROUT!('\n')
A=33 A=33

View File

@ -1,12 +1,12 @@
%output prg,basic %output prg,basic
%import "c64lib" %import c64lib
~ main { ~ main {
var .text name = "?"*80 var .text name = "????????????????????????????????????????????????????????????????????????????????" ; 80
var .word orig_irq var .word orig_irq
start start:
c64.init_system() c64.init_system()
orig_irq = c64.CINV orig_irq = c64.CINV
@ -19,7 +19,7 @@ start
c64scr.input_chars(name) c64scr.input_chars(name)
c64.CHROUT('\n') c64.CHROUT('\n')
blop blop:
%breakpoint ; yeah! %breakpoint ; yeah!
c64scr.print_string("thank you, mr or mrs: ") c64scr.print_string("thank you, mr or mrs: ")
@ -33,7 +33,7 @@ blop
return return
irq_handler irq_handler:
%asm { %asm {
lda c64.SFDX lda c64.SFDX
cmp #$40 ; nothing pressed? cmp #$40 ; nothing pressed?

View File

@ -1,6 +1,6 @@
%output prg,basic %output prg,basic
%import "c64lib" %import c64lib
%import "mathlib" %import mathlib
~ main { ~ main {
var .text name = '?' * 80 var .text name = '?' * 80
@ -9,7 +9,7 @@
var attempts_left = 10 var attempts_left = 10
start start:
c64.init_system() c64.init_system()
A = c64.VMCSB A = c64.VMCSB
@ -41,7 +41,7 @@ start
c64scr.print_string("I am thinking of a number from 1 to 100!You'll have to guess it!\n") c64scr.print_string("I am thinking of a number from 1 to 100!You'll have to guess it!\n")
printloop printloop:
c64scr.print_string("\nYou have ") c64scr.print_string("\nYou have ")
c64scr.print_byte_decimal(attempts_left) c64scr.print_byte_decimal(attempts_left)
c64scr.print_string(" guess") c64scr.print_string(" guess")
@ -51,7 +51,7 @@ printloop
A-- A--
if_zero A goto ask_guess if_zero A goto ask_guess
c64scr.print_string("es") c64scr.print_string("es")
ask_guess ask_guess:
c64scr.print_string(" left.\nWhat is your next guess? ") c64scr.print_string(" left.\nWhat is your next guess? ")
Y = c64scr.input_chars(guess) Y = c64scr.input_chars(guess)
c64.CHROUT('\n') c64.CHROUT('\n')
@ -65,21 +65,21 @@ ask_guess
c64scr.print_string("low!\n") c64scr.print_string("low!\n")
goto continue goto continue
correct_guess correct_guess:
c64scr.print_string("\nThat's my number, impressive!\n") c64scr.print_string("\nThat's my number, impressive!\n")
goodbye() goodbye()
return return
too_high too_high:
c64scr.print_string("That is too ") c64scr.print_string("That is too ")
c64scr.print_string("high!\n") c64scr.print_string("high!\n")
continue continue:
attempts_left-- attempts_left--
if_zero attempts_left goto game_over if_zero attempts_left goto game_over
goto printloop goto printloop
game_over game_over:
c64scr.print_string("\nToo bad! It was: ") c64scr.print_string("\nToo bad! It was: ")
c64scr.print_byte_decimal(secretnumber) c64scr.print_byte_decimal(secretnumber)
c64.CHROUT('\n') c64.CHROUT('\n')

View File

@ -26,7 +26,7 @@
var .wordarray(10) words2 = $bbcc var .wordarray(10) words2 = $bbcc
start ;foo start: ;foo
X = 55 X = 55
Y = $77 Y = $77
Y = X Y = X
@ -63,7 +63,7 @@ start ;foo
; [646,Y] = [$d020,X] ; [646,Y] = [$d020,X]
_loop block2.zpw1 ++ _loop: block2.zpw1 ++
A ++ A ++
X ++ X ++
Y ++ Y ++
@ -103,7 +103,7 @@ sub customsub (Y)->() {
} }
somelabel1222 somelabel1222:
customsub(2) customsub(2)
return return
@ -119,7 +119,7 @@ somelabel1222
} }
~ block3 { ~ block3 {
somelabel1 somelabel1:
%asm { %asm {
nop nop
nop nop
@ -180,7 +180,8 @@ somelabel1
~ fidget $1000 ~ fidget $1000
{ {
subroutine subroutine:
; subroutine (A, X, Y) ; subroutine (A, X, Y)
;[border2] = red ;[border2] = red
;[screen2] = white ;[screen2] = white

View File

@ -7,7 +7,7 @@
} }
~ main { ~ main {
start start:
A=0 A=0
[$d020]=A [$d020]=A
X=false X=false

View File

@ -2,7 +2,7 @@
%output prg,basic ; create a c-64 program with basic SYS call to launch it %output prg,basic ; create a c-64 program with basic SYS call to launch it
%import "c64lib" ; searched in several locations and with .ill file extension added %import c64lib ; searched in several locations and with .ill file extension added
~ main ~ main
{ {
@ -24,7 +24,7 @@
var .text hello2 = "@@\f\b\n\r\t@@" var .text hello2 = "@@\f\b\n\r\t@@"
start start:
global2.make_screen_black() global2.make_screen_black()
A='?' A='?'
@ -66,7 +66,7 @@ start
~ global2 { ~ global2 {
make_screen_black make_screen_black:
c64.EXTCOL = c64.BGCOL0 = 0 c64.EXTCOL = c64.BGCOL0 = 0
c64.COLOR = 3 c64.COLOR = 3
Y = true Y = true

View File

@ -1,6 +1,6 @@
%output prg,basic ; create a c-64 program with basic SYS to() launch it %output prg,basic ; create a c-64 program with basic SYS to() launch it
%import "c64lib.ill" %import c64lib.ill
~ main ~ main
{ {
@ -8,7 +8,7 @@
var .ptext p_greeting = "hello world!\r12345678 is a big number.\r" var .ptext p_greeting = "hello world!\r12345678 is a big number.\r"
const .word BORDER = $d020 const .word BORDER = $d020
start start:
c64scr.print_pimmediate() ; this prints the pstring immediately following it c64scr.print_pimmediate() ; this prints the pstring immediately following it
%asm { %asm {
.ptext "hello-pimmediate!{cr}" .ptext "hello-pimmediate!{cr}"
@ -26,7 +26,7 @@ start
c64.CHROUT (13) c64.CHROUT (13)
return return
start2 start2:
global2.make_screen_black() global2.make_screen_black()
c64.CLEARSCR() c64.CLEARSCR()
c64scr.print_string(greeting) c64scr.print_string(greeting)
@ -52,7 +52,7 @@ start2
~ global2 { ~ global2 {
make_screen_black make_screen_black:
c64.EXTCOL = c64.BGCOL0 = 0 c64.EXTCOL = c64.BGCOL0 = 0
c64.COLOR = 3 c64.COLOR = 3
return return

View File

@ -1,6 +1,6 @@
%output prg,basic %output prg,basic
%import "c64lib" %import c64lib
%import "mathlib" %import mathlib
~ main { ~ main {
@ -9,9 +9,9 @@
var var1 =2 var var1 =2
var .word wvar1 = 2 var .word wvar1 = 2
start start:
A=math.randbyte() A=math.randbyte()
A+=c64.RASTER A += c64.RASTER
A-=c64.TIME_LO A-=c64.TIME_LO
X,A=math.divmod_bytes(A, 99) X,A=math.divmod_bytes(A, 99)
c64scr.print_byte_decimal(A) c64scr.print_byte_decimal(A)
@ -19,7 +19,7 @@ start
return return
rndloop rndloop:
XY = math.randword() XY = math.randword()
%asm { %asm {
txa txa
@ -76,6 +76,10 @@ rndloop
X >>= 7 X >>= 7
X >>= 8 X >>= 8
X >>= 22 X >>= 22
XY = 1
AX = 2
SC =2
QW =3
;XY <<= 0 ;XY <<= 0
;XY <<= 1 ;XY <<= 1
;XY <<= 2 ;XY <<= 2
@ -114,7 +118,7 @@ rndloop
bne - bne -
} }
loop loop :
A=c64.GETIN() A=c64.GETIN()
if_not goto loop if_not goto loop
c64scr.scroll_right_full(1) c64scr.scroll_right_full(1)
@ -133,6 +137,12 @@ loop
Y = $33 Y = $33
c64scr.clear_screen (81, 5) c64scr.clear_screen (81, 5)
c64scr.clear_screen (81, 5)
c64scr.clear_screen (81, 5)
c64scr.clear_screen (81, 5)
c64scr.clear_screen ! (81, 5)
c64scr.clear_screen ! (81, 5)
c64scr.clear_screen !(81, 5)
c64scr.clear_screen !(81, 5) c64scr.clear_screen !(81, 5)
c64scr.clear_screen !A (81, 5) c64scr.clear_screen !A (81, 5)
c64scr.clear_screen !X (81, 5) c64scr.clear_screen !X (81, 5)