Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native ARM Co Pro: OSBYTE SWI returns unexpected value in R1 #120

Closed
hoglet67 opened this issue Jun 24, 2021 · 9 comments
Closed

Native ARM Co Pro: OSBYTE SWI returns unexpected value in R1 #120

hoglet67 opened this issue Jun 24, 2021 · 9 comments

Comments

@hoglet67
Copy link
Owner

hoglet67 commented Jun 24, 2021

Result from PiTubeDirect is different to the ARM7TDMI Co Pro, likely due to this:

    reg[1] = x | (y << 8);      // JGH
    reg[2] = y;
@BigEd
Copy link
Collaborator

BigEd commented Jun 24, 2021

this change:
3abda3a
"JGH: tube-swi: Corrected R1 return from OSBYTE &80+"

@dudleysoft
Copy link

dudleysoft commented Jun 24, 2021

This seems to be at odds with the behaviour of the ARM7TDMI co-processor's OS_Byte return values, which simply returns the values of X and Y in R1 and R2.

This tripped me up when I tried to implement reading the mouse values in BQUAKE using OS_Byte 128 to read the ADVAL values from the host.

Reading the values in BeebEm in the ARM7TDMI co-processor was returning a different result to the PiNative co-processor.

@hoglet67 hoglet67 changed the title Native ARM Co Pro: OSBYTE SWI Mangles Return Parameters Native ARM Co Pro: OSBYTE SWI returns unexpected value in R1 Jun 25, 2021
@hoglet67
Copy link
Owner Author

I would suggest just anding the result with &FF in each case., i.e. treat the contents of bits 8-31 as undefined.

@jgharston would you care to explain what's going on here?

@dudleysoft
Copy link

I would suggest just anding the result with &FF in each case., i.e. treat the contents of bits 8-31 as undefined.

@jgharston would you care to explain what's going on here?

This is what I did in my code, I'd tested under BeebEm with the ARM7TDMI and was wondering why my mouse coordinates seemed wrong, which led me to looking at the code and spotting it was doing this. The funny thing is I was already doing this in my keyboard scanning code so I must have noticed it before, presumably at that point I didn't realise BeebEm was behaving differently.

I'm not sure which way is the correct way, if RISC OS does it this way then perhaps that's why the change was made.

@hoglet67
Copy link
Owner Author

Just to be clear, if you do AND with &FF, does the same code work on both platforms?

@jgharston
Copy link
Contributor

That's odd, I was sure RISC OS returned R1=x OR (y<<8) so that R1 returned the full value so the caller didn't need to do R1 OR (R2<<8), and I have a memory rattling around about "ADVAL returning full 32 bits" from somewhere.
But a quick test:

PRINT ~ADVAL7
3B6
SYS "OS_Byte",128,7,0 TO r0,r1,r2
PRINT ~r0,r1,r2
80 B6 3
*FX0
RISC OS 3.11

So, change it to reg[1] = x;
(I'll check some other ARM systems later)

"This tripped me up when I tried to implement reading the mouse values in BQUAKE using OS_Byte 128 to read the ADVAL values from the host."

How did it trip up? ORR R1,R1,R2,LSL#8 gives the same result regardless of whether R1 already has R2 in bit 8 upwards or not.

@dudleysoft
Copy link

Just to be clear, if you do AND with &FF, does the same code work on both platforms?

Yes it did.

"This tripped me up when I tried to implement reading the mouse values in BQUAKE using OS_Byte 128 to read the ADVAL values from the host."

I was writing in C, so I used x + (y<<8), because I tend to think in terms of regular maths rather than bitwise maths.

@jgharston
Copy link
Contributor

Yep, ARM CoPro, 1984ish:
BL L00000D24 ; Wait for returned byte
STMDB R13!,{R0} ; Save returned Carry
BL &03000D24 ; Wait for returned byte
MOV R2,R0 ; Return OSBYTE Y value
BL &03000D24 ; Wait for returned byte
MOV R1,R0 ; Return OSBYTE X value
LDMIA R13!,{R11} ; Restore saved Carry value to R11
LDMIA R13!,{R0,R14} ; Restore saved link,R0
BIC R14,R14,#&20000000 ; Clear link's carry flag
TST R11,#&80 ; Check carry value in R11
ORRNE R14,R14,#&20000000 ; Set link's carry flag if set
B L000000F8 ; Jump to exit

RISC OS Kernel (end of BUFFV called by OSBYTE &80), 1997ish:
TEQ R1, #0 ; don't stamp on carry
ADDMI R1, R1, R5 ; wrap number of chars if negative
SUBCS R1, R5, R1 ; C=1 => convert to spaces
SUBCS R1, R1, #1 ; one fewer spaces than BuffSizes
MOV R2, R1, LSR #8 ; make R2 = hi-byte
AND R1, R1, #&FF ; and R1 = lo-byte
Pull "R3-R5,PC"

...but I'm sure I've seen somewhere some OSBYTE calls returning larger values in R1. But BASIC does ORR dest,R1,R2,LSL #8 when reading a large OSBYTE (eg ADVAL and USR&FFF4) and AND dest,R1,#255 when reading a byte value (eg VPOS) anyway.

hoglet67 added a commit that referenced this issue Jun 25, 2021
Change-Id: Iafd3a9e32d9bbb94b03cfc91a760ee2c51151c89
@hoglet67
Copy link
Owner Author

Fixed in hognose-dev.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants