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.