mirror of
https://github.com/irmen/prog8.git
synced 2024-06-26 07:29:32 +00:00
added read_flags() function, uword2bcd routine no longer enables irq again if it wasn't enabled before calling it.
This commit is contained in:
parent
ed43f7cd9b
commit
77dc35dc6a
|
@ -99,6 +99,10 @@ asmsub uword2bcd (uword value @ AY) -> clobbers(A,Y) -> () {
|
|||
%asm {{
|
||||
sta c64.SCRATCH_ZPB1
|
||||
sty c64.SCRATCH_ZPREG
|
||||
php
|
||||
pla ; read status register
|
||||
and #%00000100
|
||||
sta _had_irqd
|
||||
sei ; disable interrupts because of bcd math
|
||||
sed ; switch to decimal mode
|
||||
lda #0 ; ensure the result is clear
|
||||
|
@ -121,8 +125,11 @@ asmsub uword2bcd (uword value @ AY) -> clobbers(A,Y) -> () {
|
|||
dey ; and repeat for next bit
|
||||
bne -
|
||||
cld ; back to binary
|
||||
cli ; enable interrupts again @todo don't re-enable if it wasn't enabled before
|
||||
rts
|
||||
lda _had_irqd
|
||||
bne +
|
||||
cli ; enable interrupts again (only if they were enabled before)
|
||||
+ rts
|
||||
_had_irqd .byte 0
|
||||
}}
|
||||
}
|
||||
|
||||
|
@ -987,7 +994,7 @@ asmsub getchr (ubyte col @Y, ubyte row @A) -> clobbers(Y) -> (ubyte @ A) {
|
|||
bcc _mod
|
||||
inc _mod+2
|
||||
_mod lda $ffff ; modified
|
||||
rts
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1035,7 @@ asmsub getclr (ubyte col @Y, ubyte row @A) -> clobbers(Y) -> (ubyte @ A) {
|
|||
bcc _mod
|
||||
inc _mod+2
|
||||
_mod lda $ffff ; modified
|
||||
rts
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
|
|
|
@ -640,6 +640,15 @@ greatereq_w .proc
|
|||
bmi equal_b._equal_b_false
|
||||
.pend
|
||||
|
||||
func_read_flags .proc
|
||||
; -- put the processor status register on the stack
|
||||
php
|
||||
pla
|
||||
sta c64.ESTACK_LO,x
|
||||
dex
|
||||
rts
|
||||
.pend
|
||||
|
||||
|
||||
func_sin8 .proc
|
||||
ldy c64.ESTACK_LO+1,x
|
||||
|
|
|
@ -70,6 +70,7 @@ val BuiltinFunctions = mapOf(
|
|||
"clear_carry" to FunctionSignature(false, emptyList(), null),
|
||||
"set_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"clear_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"read_flags" to FunctionSignature(false, emptyList(), DataType.UBYTE),
|
||||
"swap" to FunctionSignature(false, listOf(BuiltinFunctionParam("first", NumericDatatypes), BuiltinFunctionParam("second", NumericDatatypes)), null),
|
||||
"memcopy" to FunctionSignature(false, listOf(
|
||||
BuiltinFunctionParam("from", IterableDatatypes + setOf(DataType.UWORD)),
|
||||
|
|
|
@ -80,7 +80,8 @@ enum class Syscall(val callNr: Short) {
|
|||
FUNC_SUM_F(134),
|
||||
FUNC_MEMCOPY(138),
|
||||
FUNC_MEMSET(139),
|
||||
FUNC_MEMSETW(140)
|
||||
FUNC_MEMSETW(140),
|
||||
FUNC_READ_FLAGS(141)
|
||||
|
||||
// note: not all builtin functions of the Prog8 language are present as functions:
|
||||
// some of them are straight opcodes (such as MSB, LSB, LSL, LSR, ROL_BYTE, ROR, ROL2, ROR2, and FLT)!
|
||||
|
@ -1613,6 +1614,14 @@ class StackVm(private var traceOutputFile: String?) {
|
|||
val text = heap.get(strPtr).str!!
|
||||
evalstack.push(Value(DataType.UBYTE, text.length))
|
||||
}
|
||||
Syscall.FUNC_READ_FLAGS -> {
|
||||
val carry = if(P_carry) 1 else 0
|
||||
val zero = if(P_zero) 2 else 0
|
||||
val irqd = if(P_irqd) 4 else 0
|
||||
val negative = if(P_negative) 128 else 0
|
||||
val flags = carry or zero or irqd or negative
|
||||
evalstack.push(Value(DataType.UBYTE, flags))
|
||||
}
|
||||
Syscall.FUNC_SIN -> evalstack.push(Value(DataType.FLOAT, sin(evalstack.pop().numericValue().toDouble())))
|
||||
Syscall.FUNC_COS -> evalstack.push(Value(DataType.FLOAT, cos(evalstack.pop().numericValue().toDouble())))
|
||||
Syscall.FUNC_SIN8 -> {
|
||||
|
|
|
@ -735,3 +735,6 @@ rsave()
|
|||
|
||||
rrestore()
|
||||
Restores the CPU registers and the status flags from previously saved values.
|
||||
|
||||
read_flags()
|
||||
Returns the current value of the CPU status register.
|
||||
|
|
|
@ -117,7 +117,8 @@ The following 6502 CPU hardware registers are directly usable in program code (a
|
|||
|
||||
- ``A``, ``X``, ``Y`` the three main cpu registers (8 bits)
|
||||
- the status register (P) carry flag and interrupt disable flag can be written via a couple of special
|
||||
builtin functions (``set_carry()``, ``clear_carry()``, ``set_irqd()``, ``clear_irqd()``)
|
||||
builtin functions (``set_carry()``, ``clear_carry()``, ``set_irqd()``, ``clear_irqd()``),
|
||||
and read via the ``read_flags()`` function.
|
||||
|
||||
However, you must assume that the 3 hardware registers ``A``, ``X`` and ``Y``
|
||||
are volatile. Their values cannot be depended upon, the compiler will use them as required.
|
||||
|
|
|
@ -9,11 +9,34 @@
|
|||
|
||||
sub start() {
|
||||
|
||||
for ubyte @zp fastindex in 10 to 20 {
|
||||
c64scr.print_ub(fastindex)
|
||||
uword w = 12345
|
||||
ubyte flags
|
||||
|
||||
c64.CHROUT('\n')
|
||||
|
||||
clear_irqd()
|
||||
c64utils.uword2bcd(w)
|
||||
flags=read_flags()
|
||||
c64scr.print_ubbin(1,flags)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
set_irqd()
|
||||
c64utils.uword2bcd(w)
|
||||
flags=read_flags()
|
||||
c64scr.print_ubbin(1,flags)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
clear_irqd()
|
||||
c64utils.uword2bcd(w)
|
||||
flags=read_flags()
|
||||
c64scr.print_ubbin(1,flags)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
set_irqd()
|
||||
c64utils.uword2bcd(w)
|
||||
flags=read_flags()
|
||||
c64scr.print_ubbin(1,flags)
|
||||
c64.CHROUT('\n')
|
||||
; do something
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user