Remove invisible walls [jawa]
#1
Removes invisible walls.
WARNING! Halfpipes do not work as intended.

NTSC-U
C251508C 0000001C
7D2000A6 552C045E
7D800124 38210120
9421FF60 BDC10008
7E4802A6 2C030000
418200A4 48000011
636F7572 73652E6B
636C0000 7E2802A6
7F95E378 3A600000
7E138A14 89F00000
7E13AA14 89D00000
7E8F7214 2C140000
41820018 7C0F7000
41820008 48000060
3A730001 4BFFFFD4
7C701B78 82300008
82B0000C 7E318214
7EB58214 7E348B78
7C14A800 41800008
48000034 A274000E
39E0001F 7E737838
2C13001F 41810020
2C13000D 41820008
4800000C 39E00018
91F4000E 3A940010
4BFFFFC8 7E4803A6
B9C10008 382100A0
7D8000A6 512C0420
7D800124 00000000

PAL
C2519500 0000001C
7D2000A6 552C045E
7D800124 38210120
9421FF60 BDC10008
7E4802A6 2C030000
418200A4 48000011
636F7572 73652E6B
636C0000 7E2802A6
7F95E378 3A600000
7E138A14 89F00000
7E13AA14 89D00000
7E8F7214 2C140000
41820018 7C0F7000
41820008 48000060
3A730001 4BFFFFD4
7C701B78 82300008
82B0000C 7E318214
7EB58214 7E348B78
7C14A800 41800008
48000034 A274000E
39E0001F 7E737838
2C13001F 41810020
2C13000D 41820008
4800000C 39E00018
91F4000E 3A940010
4BFFFFC8 7E4803A6
B9C10008 382100A0
7D8000A6 512C0420
7D800124 00000000

NTSC-J
C2518E80 0000001C
7D2000A6 552C045E
7D800124 38210120
9421FF60 BDC10008
7E4802A6 2C030000
418200A4 48000011
636F7572 73652E6B
636C0000 7E2802A6
7F95E378 3A600000
7E138A14 89F00000
7E13AA14 89D00000
7E8F7214 2C140000
41820018 7C0F7000
41820008 48000060
3A730001 4BFFFFD4
7C701B78 82300008
82B0000C 7E318214
7EB58214 7E348B78
7C14A800 41800008
48000034 A274000E
39E0001F 7E737838
2C13001F 41810020
2C13000D 41820008
4800000C 39E00018
91F4000E 3A940010
4BFFFFC8 7E4803A6
B9C10008 382100A0
7D8000A6 512C0420
7D800124 00000000

NTSC-K
C2507520 0000001C
7D2000A6 552C045E
7D800124 38210120
9421FF60 BDC10008
7E4802A6 2C030000
418200A4 48000011
636F7572 73652E6B
636C0000 7E2802A6
7F95E378 3A600000
7E138A14 89F00000
7E13AA14 89D00000
7E8F7214 2C140000
41820018 7C0F7000
41820008 48000060
3A730001 4BFFFFD4
7C701B78 82300008
82B0000C 7E318214
7EB58214 7E348B78
7C14A800 41800008
48000034 A274000E
39E0001F 7E737838
2C13001F 41810020
2C13000D 41820008
4800000C 39E00018
91F4000E 3A940010
4BFFFFC8 7E4803A6
B9C10008 382100A0
7D8000A6 512C0420
7D800124 00000000


Code:
# System::DVDArchive::getFile([DVDArchive* d_arc], char const*, unsigned int*)
# returns file buffer (r3 = void* outbuf)
.set INVISIBLE_WALL, 0x0D
.set SOUND_TRIGGER, 0x18
.set STACK, 0xA0

.macro disable_interrupts
    mfmsr r9
    rlwinm r12, r9, 0, 17, 15
    mtmsr r12
.endm
.macro enable_interrupts
    mfmsr r12
    rlwimi r12, r9, 0, 16, 16
    mtmsr r12
    .endm
disable_interrupts

#default
addi sp, sp, 288
# push stack
stwu sp, -STACK (sp)
stmw r14, 0x8 (sp)

mflr r18
cmpwi r3, 0
beq end

check:

    bl course_kcl_string
        .string "course.kcl"
        .align 2
    course_kcl_string:
    mflr r17

    course_kcl:
        # r17 = &"course.kcl", string 1
        mr r21, r28 # r21 = filename, string 2
        # li r20, 0 # r21 = strings_are_equal
        li r19, 0 # r19 = strcmp counter
        loop:
            add r16, r19, r17
            lbz r15, 0 (r16) # str1 + off
            add r16, r19, r21
            lbz r14, 0 (r16) # str2 + off
            add r20, r15, r14
            cmpwi r20, 0 # if chr == \0
            beq success
            cmpw r15, r14 # (str1 + off) == (str2 + off)
            beq cont_add
            b end
        cont_add:
            addi r19, r19, 1
            b loop
        success:
            # course.kcl is loaded!
            # r3 = void* buf#
            mr r16, r3
            lwz r17, 0x08 (r16) # r17 = SEC3.start
            lwz r21, 0x0C (r16) # r21 = SEC4.start
            add r17, r17, r16 # SEC3* sec3 = file_start + SEC4.start
            add r21, r21, r16 # SEC4* sec4 = file_start + SEC3.start
            mr r20, r17 # r20 = i = SEC3.start
        loop2:
            cmpw r20, r21 # i, SEC4
            blt loop2_2
            b end
        loop2_2:
            lhz r19, 0xE (r20) # kcl flag
            li r15, 31 # and mask value
            and r19, r19, r15 # kcl_type = kcl_flag & mask [0x10] (isolate 5 LSB bits)
            cmpwi r19, 0x1F
            bgt- end
            cmpwi r19, INVISIBLE_WALL
            beq invis
            b inc
        invis:
            li r15, SOUND_TRIGGER
            stw r15, 0xE (r20) # *kcl_flag_ptr = SOUND_TRIGGER
        inc:
            addi r20, r20, 0x10 # i += 0x10
            b loop2

end:
    mtlr r18
    lmw r14, 0x8 (sp)
    # pop stack
    addi sp, sp, STACK
    enable_interrupts
Reply
#2
You can get weird bugs by manually disabling interrupts if a context switch happens after your mfmsr and before your mtmsr, and the msr is changed on another thread. OSLoadContext has special code to prevent this issue in OSDisableInterrupts (moves pc back to the start of the function if it was interrupted before the mtmsr), so really you should always call the actual function for this

Also, do you actually need interrupts disabled here?
Reply
#3
@Seeky Just to make sure I understand your post, does "Context Switch" refer to an external interrupt (of any sort) occurring on one of the first two instructions of his manual disable interrupts code? When I see Context Switch, I personally keep thinking of Context Synchronization (isync), lol.

Also, are you saying he should function call OSDisableInterrupts or any such task? Or are you saying to function call OSSave/Load Context which itself later on calls OSDisable/Restore Interrupts ?

Because if it's the former, then yes that would make sense. He would either need to call OSDisableInterrupts, or just execute the exact function manually (so r3 and r4 are used/filled accordingly if a external interrupt does indeed happen during this time).

At the end of his code, the method in which he restores interrupts shouldn't matter as long as he grabs the latest MSR and re-inserts the original MSR EE bit since interrupts are disabled at this moment in time. In essence, the Restore Interrupts function is "silly" for its need to check r3 (old EE bit) and branch. A simple bit re-insertion should work.

I just woke up, so apologies if I'm missing something obvious. Regardless, I share your same final thought, I'm not sure why Interrupts are being disabled at all?

---

@Jawa Nice work on learning some of the more advanced stuff on PPC Assembly. Was there a weird issues occurring in your code before you added in the Interrupt stuff?
Reply
#4
I'm saying that using a manual recreation of OSDisableInterrupts instead of calling the actual function isn't safe

Context switch being a change between threads (OSLoadContext)
Reply
#5
Looks like I'll have to update a couple of my tutorial threads due to now learning about this.
Reply
#6
(11-20-2022, 01:07 PM)Seeky Wrote: You can get weird bugs by manually disabling interrupts if a context switch happens after your mfmsr and before your mtmsr, and the msr is changed on another thread. OSLoadContext has special code to prevent this issue in OSDisableInterrupts (moves pc back to the start of the function if it was interrupted before the mtmsr), so really you should always call the actual function for this

Also, do you actually need interrupts disabled here?

Dolphin would sometimes crash. Maybe it's just an issue on my machine, but i included it just in case.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)