mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
add SI register
This commit is contained in:
parent
a0a561cfb6
commit
c78cbc4a33
@ -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:
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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]) {
|
||||||
|
@ -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
34
testsource/input.ill
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user