WIMP support

Discuss development specific to the Pi version of ADFFS
Post Reply
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

WIMP support

Post by JonAbbott »

Notes on providing WIMP support
  1. At all ADFFS entry points, check Wimp_ReadSysInfo 5 or OS_ReadSysInfo 6 DomainId to confirm the current task is one we're handling
  2. Spawn a new JIT area for child tasks (created via either Filer_Run or Wimp_StartTask)
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: WIMP support

Post by JonAbbott »

I've mostly implemented point 1 and have Eterna's KerBang! running as a WIMP task under RO3.71 SA emulation.

Ignoring the WIMP requirement, getting KerBang! working was a mission in itself. The first problem was the protection, which instead of using ADFS_DiscOp 3 to read track data, directly talks to the FDC via IOC. Running with that theme, for some bizarre reason the developers also decided to rewrite Event 11 (keypress) in it's entirety by reading/writing to the serial port directly via IOC, this also encompassed code to track the mouse. In the end I opted to correct the code instead of implement serial emulation, as I doubt there's many requirements for direct serial access via IOC.

Having solved these issues, I could see it still wouldn't work without WIMP support due to the way the protection worked, so decided to add basic WIMP support to ADFFS.

Restrictions with it are:
  1. Only one task is supported by the JIT
  2. 26bit Modules can't be entered whilst other tasks are active - it will crash the system, as there's no legal way to swap the JIT task back into memory
Although it's working under RO3.71 SA emulation, it's not working on the Pi yet. There are various other issues I need to resolve:
  1. After initialising the JIT various OS components complain about either a corrupt R13 or nested error handlers
  2. On the Pi, it forces the Pi to ARMv5 mode, which will probably break things if it's not already in ARMv5 mode
  3. As the JIT starts up it moves BASIC and patches it to be JIT aware - this will break all existing BASIC tasks
  4. Wimp_SlotSize needs ignoring at SWI handler level within the active JIT task
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: WIMP support

Post by JonAbbott »

I've been giving Wimp support some more thought of late, whilst considering how to code CPU Paravirtualization. The two are closely linked as entry/exit needs careful management for both to work.

The key issues are:
  1. At entry, the 26bit RMA isn't available as its stored within appspace
    • Option 1: TaskSwitch to the VM task (this isn't currently possible in RISCOS)
    • Option 2: Relocate the VM into a DA (offsetting address 0 to the base address of the DA)
    • Option 3: Relocate the JIT RMA to a DA
    • Option 4: Map the JIT RMA into memory within Module/Vector/IRQ entry points and move all Vector/IRQ entry points into a DA or the actual RMA
    Option 1 would be trivial, if RISCOS provided a means to forcibly TaskSwitch.

    Option 2 would require all LDR, LDM, LDF, LFM, STR, STM, STF, SFM to be replaced with Hypercalls, so the address can be offset. This would have a major impact on speed, but does allow for duplicated code blocks to be shared.

    Option 3 is similar to option 2, but would only relocate RMA based code. As RMA code has to be relative addressed, LDR, LDM, LDF, LFM, do not need to be Hypercalls but use of PC does pose a problem as the code address is going to go beyond the 26bit limit. Any instruction that is likely to rely on flags being in PC would need careful handling

    Option 4 might cause issues if the IRQ hardware vector is entered, whilst memory is remapped to the JIT RMA
  2. Exit has to be done via an address within the 26bit range
    • Solution: Use a magic address and rewrite everything that sets PC, to check for it
    As CPU Paravirtualization has to handle all instructions that alter PC, it's a trivial addition to check for the magic address and exit accordingly
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: WIMP support

Post by JonAbbott »

Some examples of possible Option 2 reencoding of some STR variations. Note these need to be used in USER with entry via a Hypercall which stores the return address in returnPC. The self-modifying code check doesn't account for Codelets being overwritten.

STR R0, [R1, #20]

Code: Select all

.tmp      DCD 0,0,0,0,0
.returnPC DCD <JIT instruction address + 4>
.VMbase   DCD <base address of VM memory>
.JITcode  DCD <JIT code base address>
.JITentry DCD <JIT entry instruction>

.codelet
STR   R12, tmp + 4*4
ADR   R12, tmp
STMIA R12!, {R1, R9-R11}
LDMIB R12, {R9-R11}
ADD   R1, R1, R9
STR   R0, [R1, #20]!	       ;original instruction with writeback
BIC   R1, R1, #%11            ;support self-modifiying code
STR   R11, [R10, R1]          ;overwrite JIT address with JIT entry instruction
LDMDB R12, {R1, R9-R12, PC}
STR R0, [R1, #20]!

Code: Select all

.tmp      DCD 0,0,0,0,0
.returnPC DCD <JIT instruction address + 4>
.VMbase   DCD <base address of VM memory>
.JITcode  DCD <JIT code base address>
.JITentry DCD <JIT entry instruction>

.codelet
STR   R12, tmp + 4*4
ADR   R12, tmp + 4
STMIA R12!, {R9-R11}
LDMIB R12, {R9-R11}
ADD   R1, R1, R9
STR   R0, [R1, #20]!	       ;original instruction
SUB   R1, R1, R9
BIC   R9, R1, #%11            ;support self-modifiying code
STR   R11, [R10, R9]          ;overwrite JIT code with JIT entry instruction
LDMDB R12, {R9-R12, PC}
STR R0, [R1], #20

Code: Select all

.tmp      DCD 0,0,0,0,0
.returnPC DCD <JIT instruction address + 4>
.VMbase   DCD <base address of VM memory>
.JITcode  DCD <JIT code base address>
.JITentry DCD <JIT entry instruction>

.codelet
STR   R12, tmp + 4*4
ADR   R12, tmp + 4
STMIA R12!, {R9-R11}
LDMIB R12, {R9-R11}
ADD   R1, R1, R9
STR   R0, [R1], #20	       ;original instruction
SUB   R1, R1, R9
SUB   R9, R1, #20            ;remove the post increment
BIC   R9, R9, #%11           ;support self-modifiying code
STR   R11, [R10, R9]         ;overwrite JIT code with JIT entry instruction
LDMDB R12, {R9-R12, PC}
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: WIMP support

Post by JonAbbott »

Hypercall methods suitable for codelet calls:

Code: Select all

SWI:
<condition>1111[23..20][19..0]
Where:
[23..20] = Hypercall OS
[19..0] = Codelet number (0..1048576)
Pros: Can be quickly detected and decoded off the SWI vector
Cons: Requires CPU Mode Paravirtualization

Code: Select all

Co-Pro LDC/STC:
<condition>110[24..12]<CP#>[7..0]
Where:
[7..0] = [7..0] of the Codelet number
[24..12] = [20..8] of the Codelet number (0..2097151)
Pros: Will work without CPU Mode Paravirtualization
Cons: Takes over a complete Co-Processor
Post Reply