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 {{ %asm {{
sta c64.SCRATCH_ZPB1 sta c64.SCRATCH_ZPB1
sty c64.SCRATCH_ZPREG sty c64.SCRATCH_ZPREG
php
pla ; read status register
and #%00000100
sta _had_irqd
sei ; disable interrupts because of bcd math sei ; disable interrupts because of bcd math
sed ; switch to decimal mode sed ; switch to decimal mode
lda #0 ; ensure the result is clear 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 dey ; and repeat for next bit
bne - bne -
cld ; back to binary cld ; back to binary
cli ; enable interrupts again @todo don't re-enable if it wasn't enabled before lda _had_irqd
rts 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 bcc _mod
inc _mod+2 inc _mod+2
_mod lda $ffff ; modified _mod lda $ffff ; modified
rts rts
}} }}
} }
@@ -1028,7 +1035,7 @@ asmsub getclr (ubyte col @Y, ubyte row @A) -> clobbers(Y) -> (ubyte @ A) {
bcc _mod bcc _mod
inc _mod+2 inc _mod+2
_mod lda $ffff ; modified _mod lda $ffff ; modified
rts rts
}} }}
} }

View File

@@ -640,6 +640,15 @@ greatereq_w .proc
bmi equal_b._equal_b_false bmi equal_b._equal_b_false
.pend .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 func_sin8 .proc
ldy c64.ESTACK_LO+1,x ldy c64.ESTACK_LO+1,x

View File

@@ -70,6 +70,7 @@ val BuiltinFunctions = mapOf(
"clear_carry" to FunctionSignature(false, emptyList(), null), "clear_carry" to FunctionSignature(false, emptyList(), null),
"set_irqd" to FunctionSignature(false, emptyList(), null), "set_irqd" to FunctionSignature(false, emptyList(), null),
"clear_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), "swap" to FunctionSignature(false, listOf(BuiltinFunctionParam("first", NumericDatatypes), BuiltinFunctionParam("second", NumericDatatypes)), null),
"memcopy" to FunctionSignature(false, listOf( "memcopy" to FunctionSignature(false, listOf(
BuiltinFunctionParam("from", IterableDatatypes + setOf(DataType.UWORD)), BuiltinFunctionParam("from", IterableDatatypes + setOf(DataType.UWORD)),

View File

@@ -80,7 +80,8 @@ enum class Syscall(val callNr: Short) {
FUNC_SUM_F(134), FUNC_SUM_F(134),
FUNC_MEMCOPY(138), FUNC_MEMCOPY(138),
FUNC_MEMSET(139), 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: // 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)! // 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!! val text = heap.get(strPtr).str!!
evalstack.push(Value(DataType.UBYTE, text.length)) 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_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_COS -> evalstack.push(Value(DataType.FLOAT, cos(evalstack.pop().numericValue().toDouble())))
Syscall.FUNC_SIN8 -> { Syscall.FUNC_SIN8 -> {

View File

@@ -735,3 +735,6 @@ rsave()
rrestore() rrestore()
Restores the CPU registers and the status flags from previously saved values. 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) - ``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 - 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`` 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. are volatile. Their values cannot be depended upon, the compiler will use them as required.

View File

@@ -9,11 +9,34 @@
sub start() { sub start() {
for ubyte @zp fastindex in 10 to 20 { uword w = 12345
c64scr.print_ub(fastindex) 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') c64.CHROUT('\n')
; do something
}
} }
} }