Page 19 of 26
Re: Q_Liberator malaise
Posted: Tue Feb 11, 2025 8:41 am
by RalfR
Derek_Stewart wrote: Wed Feb 05, 2025 11:00 pmIs it possible to alter the Qliberator compiler to produce the code the patch does?
Unfortunately, there seems to be a problem: If an unpatched (MC) program is started from a patched Q-Dock, i.e. Q-Dock only runs in the writethrough cache, then the started program also only runs in writethrough mode, so it seems to have "inherited" something. And no, the started program is not a Q-Dock daughter job.
Why and how is not yet known, but Wolfgang is informed.
Re: Q_Liberator malaise
Posted: Mon Feb 17, 2025 5:40 pm
by RalfR
An idea that occurred to me, which of course could be completely wrong:
Basically, QLib programs with Copyback cache enabled already run on the Q60. Programs that don't run (e.g. Q-Dock and Qtrans [this is just an example, as they are regurlarly used]) contain code from easyPTR. So it could be that the problem lies there. Possibly also in connection with the address registers abused by QLib. Or when QLib programs access the PE.
This is just an idea for now, it must be checked.
Re: Q_Liberator malaise
Posted: Mon Feb 17, 2025 6:10 pm
by dilwyn
This is indeed true for my QLibbed programs. All mine contain toolkits of one form or another, usually DJToolkit, Display_cde, Basconfig, Easyptr and the QLiberator extensions files (Qerr, Qpipe, QLib_ext)
Display_cde is a prime suspect in this case. It has a small data area within its code used to get the results of an iop.flim call, which I'd forgotten about. Does not modify any of its own instructions, but does modify those 4 words. I suppose that doesn't help matters.
Don't know if DJToolkit modifies itself in any way - Norman?
Re: Q_Liberator malaise
Posted: Mon Feb 17, 2025 6:37 pm
by RalfR
Regarding the misuse of the address registers: QLiberator misuses 3 bits of address registers (according to Wolfgang Lenerz).
This may interfere with other extensions.
Example:
Imagine you have a command, let's say:
move.l d0,(a0)
where A0 is $10000, i.e. you write the contents of register d0 to address $10000
If Qlib has now set the upper 3 bits, then the address becomes
$e0010000, and you write there.
If this value is now read out again, but without the 3 bits being set, it is possible that you will get some wrong value back...
Re: Q_Liberator malaise
Posted: Mon Feb 17, 2025 9:26 pm
by Artificer
RalfR wrote :
Basically, QLib programs with Copyback cache enabled already run on the Q60. Programs that don't run (e.g. Q-Dock and Qtrans [this is just an example, as they are regurlarly used]) contain code from easyPTR. So it could be that the problem lies there. Possibly also in connection with the address registers abused by QLib. Or when QLib programs access the PE.
EasyPTR is not the key problem. Qliberated programs using QPTR suffer similar problems as easyPTR programs with copyback enabled. Your point about abuse of address registers might be a cause of the problem as QLIb error messages when programs crash do sometimes suggest the code has lost the place.
Dilwyn wrote :
Display_cde is a prime suspect in this case.
I doubt that Display_cde is the explanation as my own Qlib/QPTR compiled programs suffer the same problems with copyback and I do not use Display_cde.
Cheers
Re: Q_Liberator malaise
Posted: Mon Feb 17, 2025 10:13 pm
by tofro
dilwyn wrote: Mon Feb 17, 2025 6:10 pm
Display_cde is a prime suspect in this case. It has a small data area within its code used to get the results of an iop.flim call, which I'd forgotten about. Does not modify any of its own instructions, but does modify those 4 words. I suppose that doesn't help matters.
That's not particularly nice, but also not particularly dangerous. As long as what you write in the program area is data and never executed as code, the data in the data cache and in memory is identical and are read back correctly.
If you make the CPU read something back as an instruction that you've just written as data, what's in the instruction cache might not be identical to what's in memory (CPU thinks "He's just written data to x. I'll put that in the data cache for later use. Then "he wants to execute code at x, I happen to have that in instruction cache and save myself a read".
These cases need a cache flush. The data and instruction caches on 680x0 are completely separate and have no automatic interaction whatsoever.
Re: Q_Liberator malaise
Posted: Tue Feb 18, 2025 6:18 am
by NormanDunbar
dilwyn wrote: Mon Feb 17, 2025 6:10 pm
Don't know if DJToolkit modifies itself in any way - Norman?
There is no code that modifies itself in DJToolkit. My brain isn't good enough to keep track of what's going on in that sort of thing!
Cheers,
Norm.
Re: Q_Liberator malaise
Posted: Tue Feb 18, 2025 2:27 pm
by Peter
Lets always keep in mind that generating new code without cache flush would be just as wrong as modifying existing code without cache flush.
Anyway, my gut feeling goes more toward the abuse of the upper three address bits by now.
Re: Q_Liberator malaise
Posted: Thu Mar 27, 2025 6:29 pm
by techfury
I've been doing a bit of digging into this, mainly out of curiosity since I recently received a QXL...
There are some "interesting" sequences of code in qlib_run_asm:
Here we seem to be testing bit 30 of a pointer in A3 (I apologize for not understanding the context of this in the least, but that btst sure is sticking out to me, even though my 68k assembly is rusty):
Code: Select all
L1888 move.w (a4)+,d2
movea.l $04(a2,d2.w),a3
move.l a3,d0
btst #$1E,d0
beq.s L18A0
clr.w $0012(a3)
clr.l $0014(a3)
rts
*
L18A0 moveq #$26,d6
bra L05E8
In another place, we seem to be seeing setting bit 30 of a pointer, then testing another condition, then setting bit 29?
Code: Select all
L0400 move.w d1,-$0002(a0)
addq.l #$02,a0
move.l (a0),d1
add.l d0,d1
bset #$1E,d1
tst.b $0051(a5)
beq.s L0418
bset #$1D,d1
L0418 move.l d1,(a0)+
bra.s L03EA
L041C move.l a4,-$0008(a2)
rts
*
Curiously, I am only able to locate instances of bset and btst that modify bits 29 and 30 of pointers- perhaps bit 31 isn't actually used by Qlib? But messing around with bit 29/30 (and expecting them to not be decoded by the hardware) would certainly be congruent with writeback cache problems.
Edit: found another:
Code: Select all
L18A6 movea.w (a4)+,a0
adda.l a2,a0
move.l $0004(a0),d0
movea.l d0,a3
addq.w #$04,$0012(a3)
btst #$1D,d0
beq.s L18CE
move.w -(a5),d0
add.w -(a5),d0
add.w -(a5),d0
addq.w #$06,a5
subi.b #$09,d0
bne.s L18F8
move.w #$0203,(a0)
bra.s L18D4
L18CE move.w (a0),d0
subq.b #$02,d0
beq.s L18FC
This time, checking bit 29 and doing something if it's set...
Re: Q_Liberator malaise
Posted: Fri Mar 28, 2025 11:42 am
by Martin_Head
I am currently going through QLib_run_asm trying to add comments
This is what I have for these areas
Involves FOR loops.
A2 is a pointer to the start of variables
A4 is the compiled programs position pointer
Code: Select all
; code 9E - get FOR control variable
L1888 move.w (a4)+,d2 ;get FOR variable reference
movea.l $04(a2,d2.w),a3
move.l a3,d0
btst #$1E,d0
beq.s L18A0
clr.w $0012(a3)
clr.l $0014(a3)
rts
*
L18A0 moveq #$26,d6
bra L05E8 ;reset basic user stack pointer
In the next bit, This is during setting up the new jobs data area before actually running the compiled program
A5 points at the start of the job.
I may be coming up to this bit of code soon. I am working on the sub routine at L02A4 at the moment.
I am around L02E6, where it looks like it's about to create a name table.
Code: Select all
L0400 move.w d1,-$0002(a0)
addq.l #$02,a0
move.l (a0),d1
add.l d0,d1
bset #$1E,d1
tst.b jh_base+jh_autof(a5) ;test AUTOF
beq.s L0418 ;off
; AUTOF is on
bset #$1D,d1
L0418 move.l d1,(a0)+
bra.s L03EA
L041C move.l a4,-$0008(a2)
rts
This also to do with FOR handling
Code: Select all
; code A4 - Start the FOR
L18A6 movea.w (a4)+,a0 ;get the FOR variable reference
adda.l a2,a0
move.l $0004(a0),d0
movea.l d0,a3
addq.w #$04,$0012(a3)
btst #$1D,d0
beq.s L18CE
move.w -(a5),d0
add.w -(a5),d0
add.w -(a5),d0
addq.w #$06,a5
subi.b #$09,d0
bne.s L18F8
move.w #$0203,(a0)
bra.s L18D4
L18CE move.w (a0),d0
subq.b #$02,d0
beq.s L18FC
L18D4 bsr L103E ;make sure there is an integer on the stack
move.w (a1)+,$0002(a3)
bsr L103E ;make sure there is an integer on the stack
move.w (a1)+,$0004(a3)
bsr L103E ;make sure there is an integer on the stack
move.w (a1)+,d0
move.w d0,(a3)
lea $0004(a3),a0
tst.w $0002(a3)
bpl.s L1948
bra.s L1958
L18F8 move.w #$0202,(a0)
L18FC bsr L0FE6 ;convert TOS to float
move.w (a1)+,$000A(a3)
move.l (a1)+,$0006(a3)
bsr L0FE6 ;convert TOS to float
move.w (a1)+,$000C(a3)
move.l (a1)+,$000E(a3)
bsr L0FE6 ;convert TOS to float
move.w (a1)+,d4
move.w d4,(a3)
move.l (a1)+,d5
move.l d5,$0002(a3)
move.l $000E(a3),d1
move.w $000C(a3),d0
bra.s L1974
I am mostly working on the initialisation stuff at the moment. Not really looked into the actual running of the compiled program yet.