added read_flags() function, uword2bcd routine no longer enables irq again if it wasn't enabled before calling it.

This commit is contained in:
Irmen de Jong 2019-03-05 23:10:00 +01:00
parent ed43f7cd9b
commit 77dc35dc6a
7 changed files with 63 additions and 10 deletions

View File

@ -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
}}
}

View File

@ -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

View File

@ -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)),

View File

@ -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 -> {

View File

@ -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.

View File

@ -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.

View File

@ -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
}
}
}