add SI register

This commit is contained in:
Irmen de Jong 2017-12-25 21:43:06 +01:00
parent a0a561cfb6
commit c78cbc4a33
8 changed files with 83 additions and 11 deletions

View File

@ -135,7 +135,7 @@ class EvaluatingTransformer(ast.NodeTransformer):
globals = {"__builtins__": {}} globals = {"__builtins__": {}}
locals = None locals = None
try: try:
result = eval(code, globals, locals) result = eval(code, globals, locals) # XXX unsafe...
except Exception as x: except Exception as x:
raise self.src.to_error(str(x)) from x raise self.src.to_error(str(x)) from x
else: else:

View File

@ -928,6 +928,12 @@ class CodeGenerator:
self.p("\t\tsec") self.p("\t\tsec")
else: else:
self.p("\t\tclc") self.p("\t\tclc")
elif l_register == "SI":
# interrupt disable bit
if rvalue.value:
self.p("\t\tsei")
else:
self.p("\t\tcli")
else: else:
raise CodeError("invalid register in immediate integer assignment", l_register, rvalue.value) raise CodeError("invalid register in immediate integer assignment", l_register, rvalue.value)

View File

@ -245,10 +245,10 @@ class ParseResult:
return True, "" return True, ""
return False, "(unsigned) byte required" return False, "(unsigned) byte required"
return False, "incompatible indirect value for register assignment" return False, "incompatible indirect value for register assignment"
if self.register == "SC": if self.register in ("SC", "SI"):
if isinstance(other, ParseResult.IntegerValue) and other.value in (0, 1): if isinstance(other, ParseResult.IntegerValue) and other.value in (0, 1):
return True, "" return True, ""
return False, "can only assign an integer constant value of 0 or 1 to SC" return False, "can only assign an integer constant value of 0 or 1 to SC and SI"
if self.constant: if self.constant:
return False, "cannot assign to a constant" return False, "cannot assign to a constant"
if isinstance(other, ParseResult.RegisterValue) and len(self.register) < len(other.register): if isinstance(other, ParseResult.RegisterValue) and len(self.register) < len(other.register):

View File

@ -16,9 +16,9 @@ from typing import Optional, Set, Union, Tuple, Dict, Iterable, Sequence, Any, L
PrimitiveType = Union[int, float, str] PrimitiveType = Union[int, float, str]
REGISTER_SYMBOLS = {"A", "X", "Y", "AX", "AY", "XY", "SC"} REGISTER_SYMBOLS = {"A", "X", "Y", "AX", "AY", "XY", "SC", "SI"}
REGISTER_SYMBOLS_RETURNVALUES = REGISTER_SYMBOLS | {"SZ"} REGISTER_SYMBOLS_RETURNVALUES = REGISTER_SYMBOLS | {"SZ"}
REGISTER_BYTES = {"A", "X", "Y", "SC"} REGISTER_BYTES = {"A", "X", "Y", "SC", "SI"}
REGISTER_WORDS = {"AX", "AY", "XY"} REGISTER_WORDS = {"AX", "AY", "XY"}
# 5-byte cbm MFLPT format limitations: # 5-byte cbm MFLPT format limitations:

View File

@ -10,7 +10,8 @@ output raw
memory SCRATCH_ZP1 = $02 ; scratch register #1 in ZP memory SCRATCH_ZP1 = $02 ; scratch register #1 in ZP
memory SCRATCH_ZP2 = $03 ; scratch register #2 in ZP memory SCRATCH_ZP2 = $03 ; scratch register #2 in ZP
memory COLOR = $286 ; cursor color memory COLOR = $0286 ; cursor color
memory CINV = $0314 ; IRQ vector
; ---- VIC-II registers ---- ; ---- VIC-II registers ----
@ -163,6 +164,8 @@ sub HOMECRSR () -> (A?, X?, Y?) = $E566 ; cursor to top left of screen
; ---- C64 kernal routines ---- ; ---- C64 kernal routines ----
sub IRQDFRT () -> (A?, X?, Y?) = $EA31 ; default IRQ routine
sub IRQDFEND () -> (A?, X?, Y?) = $EA81 ; default IRQ end/cleanup
sub CINT () -> (A?, X?, Y?) = $FF81 ; (alias: SCINIT) initialize screen editor and video chip sub CINT () -> (A?, X?, Y?) = $FF81 ; (alias: SCINIT) initialize screen editor and video chip
sub IOINIT () -> (A?, X?) = $FF84 ; initialize I/O devices sub IOINIT () -> (A?, X?) = $FF84 ; initialize I/O devices
sub RAMTAS () -> (A?, X?, Y?) = $FF87 ; initialize RAM, tape buffer, screen sub RAMTAS () -> (A?, X?, Y?) = $FF87 ; initialize RAM, tape buffer, screen
@ -189,7 +192,7 @@ sub CLOSE (logical: A) -> (A?, X?, Y?) = $FFC3 ; (via 796 ($31C))
sub CHKIN (logical: X) -> (A?, X?) = $FFC6 ; (via 798 ($31E)) define an input channel sub CHKIN (logical: X) -> (A?, X?) = $FFC6 ; (via 798 ($31E)) define an input channel
sub CHKOUT (logical: X) -> (A?, X?) = $FFC9 ; (via 800 ($320)) define an output channel sub CHKOUT (logical: X) -> (A?, X?) = $FFC9 ; (via 800 ($320)) define an output channel
sub CLRCHN () -> (A?, X?) = $FFCC ; (via 802 ($322)) restore default devices sub CLRCHN () -> (A?, X?) = $FFCC ; (via 802 ($322)) restore default devices
sub CHRIN () -> (A, Y?) = $FFCF ; (via 804 ($324)) input a character sub CHRIN () -> (A, Y?) = $FFCF ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read.
sub CHROUT (char: A) -> () = $FFD2 ; (via 806 ($326)) output a character sub CHROUT (char: A) -> () = $FFD2 ; (via 806 ($326)) output a character
sub LOAD (verify: A, address: XY) -> (SC, A, X, Y) = $FFD5 ; (via 816 ($330)) load from device sub LOAD (verify: A, address: XY) -> (SC, A, X, Y) = $FFD5 ; (via 816 ($330)) load from device
sub SAVE (zp_startaddr: A, endaddr: XY) -> (SC, A) = $FFD8 ; (via 818 ($332)) save to a device sub SAVE (zp_startaddr: A, endaddr: XY) -> (SC, A) = $FFD8 ; (via 818 ($332)) save to a device
@ -205,9 +208,9 @@ sub IOBASE () -> (X, Y) = $FFF3 ; read base address
; ---- end of C64 kernal routines ---- ; ---- end of C64 kernal routines ----
memory .word NMI_VEC = $FFFA memory .word NMI_VEC = $FFFA ; nmi vector, set by the kernal if banked in
memory .word RESET_VEC = $FFFC memory .word RESET_VEC = $FFFC ; reset vector, set by the kernal if banked in
memory .word IRQ_VEC = $FFFE memory .word IRQ_VEC = $FFFE ; interrupt vector, set by the kernal if banked in
} }
@ -561,4 +564,26 @@ _pr_decimal
} }
} }
sub input_chars (buffer: AX) -> (A?, Y) {
; ---- Input a string (max. 80 chars) from the keyboard.
; It assumes the keyboard is selected as I/O channel!!
asm {
sta c64.SCRATCH_ZP1
stx c64.SCRATCH_ZP2
ldy #0 ; char counter = 0
- jsr c64.CHRIN
cmp #$0d ; return (ascii 13) pressed?
beq + ; yes, end.
sta (c64.SCRATCH_ZP1),y ; else store char in buffer
iny
bne -
+ lda #0
sta (c64.SCRATCH_ZP1),y ; finish string with 0 byte
rts
}
}
} }

View File

@ -73,6 +73,7 @@ The following 6502 hardware registers are directly accessible in your code (and
- ``A``, ``X``, ``Y`` - ``A``, ``X``, ``Y``
- ``AX``, ``AY``, ``XY`` (surrogate registers: 16-bit combined register pairs in LSB byte order lo/hi) - ``AX``, ``AY``, ``XY`` (surrogate registers: 16-bit combined register pairs in LSB byte order lo/hi)
- ``SC`` (status register's Carry flag) - ``SC`` (status register's Carry flag)
- ``SI`` (status register's Interrupt Disable flag)
### Zero Page ("ZP") ### Zero Page ("ZP")
@ -240,7 +241,10 @@ if this makes sense.
Subroutines are parts of the code that can be repeatedly invoked using a subroutine call from elsewhere. Subroutines are parts of the code that can be repeatedly invoked using a subroutine call from elsewhere.
Their definition, using the sub statement, includes the specification of the required input- and output parameters. Their definition, using the sub statement, includes the specification of the required input- and output parameters.
For now, only register based parameters are supported (A, X, Y and paired registers, and the carry status bit SC as a special). For now, only register based parameters are supported (A, X, Y and paired registers,
the carry status bit SC and the interrupt disable bit SI as specials).
For subroutine return values, the special SZ register is also available, it means the zero status bit.
The syntax is: The syntax is:
sub <identifier> ([proc_parameters]) -> ([proc_results]) { sub <identifier> ([proc_parameters]) -> ([proc_results]) {

View File

@ -223,6 +223,9 @@ start
SC = 0 SC = 0
SC = 1 SC = 1
SC = false SC = false
SI = 1
SI = 0
SI = false
uninitbyte1 = 99 uninitbyte1 = 99
uninitbyte1 = 1.234 uninitbyte1 = 1.234

34
testsource/input.ill Normal file
View File

@ -0,0 +1,34 @@
output prg,sys
import "c64lib"
~ main {
var .text name = "?"*80
start
SI = 1
[$0314.word] = #irq_handler
SI = 0
c64util.print_string("enter your name: ")
c64util.input_chars(name)
c64.CHROUT('\n')
; c64util.print_string("thank you, ") ; @todo fix param parsing /splitting
c64util.print_string("thank you ")
c64util.print_string(name)
c64.CHROUT('\n')
return
irq_handler
asm {
lda $cb
cmp #$40
beq +
inc c64.EXTCOL
+ jmp c64.IRQDFRT
}
}