Page 1 of 1

Wolfenstein 3D

Posted: Fri Jul 07, 2017 1:43 pm
by Phlamethrower
Seeing this in the ADFFS release notes...
Wolfenstein 3D, can't turn in-game music on when run on StrongArm or newer
...reminded me that I have a copy of the Wolf 3D source code (Powerslave released the source on their site sometime after iD released the original as GPL). IIRC I was able to use the source to build my own StrongARM/RISC OS 3.7-compatible version of the game, including removing the copy protection and fixing/disabling the CPU detection so that the in-game music would work. If you're interested I should be able to dig up the original sources plus the changes I made to get things working. And (from running Wolf 3D under ArcEm) I'm also reminded that there's a bug in the save game code where it uses OS_Find 0 to close all open files, with the side-effect that it doesn't work if you had the wrong filesystem selected when you started the game. So that might be a good one to squash for any future releases.

Re: Wolfenstein 3D

Posted: Fri Jul 07, 2017 2:29 pm
by Phlamethrower
Actually, it looks like I did most of my hacking directly on the executable (only using the source as reference). Hopefully I still have enough notes and intermediate versions to be able to track down what I changed.

http://www.iconbar.com/forums/viewthrea ... eadid=5457
http://www.iconbar.com/forums/viewthrea ... eadid=5466

Re: Wolfenstein 3D

Posted: Sun Jul 09, 2017 8:01 am
by JonAbbott
I may have the source, I'll check later and confirm. I thought it was a bug in the game, however your mention of the CPU check makes sense; ADFFS returns the ID for an ARM3. It may be a case of adding the option to specify the CPU type to emulate, or return an ARM610 when emulating RO3.5+. I'll give that a go and see if the music option becomes available, if not...
Phlamethrower wrote:Actually, it looks like I did most of my hacking directly on the executable (only using the source as reference).
Hacking the original is particularly useful, as I can add dynamic patching to the boot script. Feel free to post any notes/patch files here.

Re: Wolfenstein 3D

Posted: Sun Jul 09, 2017 9:48 am
by JonAbbott
Yes, I have the source and having looked at it I've realised the in-game music is missing due to a bug in ADFFS. MRC CP15,0,Rd,C2,_ wasn't returning the cache status when emulating RO3.11, now that's fixed its working correctly.

Thanks for the hint, wouldn't have spotted that issue if you'd not mentioned it.

Re: Wolfenstein 3D

Posted: Sun Jul 09, 2017 11:11 am
by Phlamethrower
FWIW, here's the method I used to patch my version.

* Expand the Wolf3D and WolfExe binaries (e.g. using xpand utility)
* Run the following BASIC program to decrypt wolfexe:

Code: Select all

ON ERROR PRINT REPORT$;" at ";ERL : END
DIM b% 512*1024
SYS "OS_File",16,"wolfexe1",b% TO ,,,,l%

REM Decrypt by reversing bytes in the binary
start%=b%+&44
len%=b%!&c
end%=start%+len%-1
len%=len%/2
REPEAT
SWAP ?start%,?end%
start%+=1
end%-=1
len%-=1
UNTIL len%=0

SYS "OS_File",10,"wolfexe2",&FF8,,b%,b%+l%
* Apply the following patches to the binary:

Code: Select all

Bypass decryption + checksum routine

 00008000 : EF000116 : ...ï : SWI     OS_WriteI+22
 00008004 : EF000100 : ...ï : SWI     OS_WriteI+0
-00008008 : EA000001 : ...ê : B       &00008014
+00008008 : EA00002F : /..ê : B       &000080CC
 0000800C : 00028674 : tŷ.. : ANDEQ   R8,R2,R4,ROR R6
 00008010 : 000286B8 : ¸ŷ.. : Undefined instruction
 00008014 : E24F101C : ..Oâ : ADR     R1,&00008000

Update computed checksum to be valid

 00008084 : E35300ED : í.Sã : CMP     R3,#&ED            ; ="í"
 00008088 : 1A000002 : .... : BNE     &00008098
 0000808C : EA00000E : ...ê : B       &000080CC
-00008090 : C35D5F94 : “_]Ã : Undefined instruction
-00008094 : 00000000 : .... : ANDEQ   R0,R0,R0
+00008090 : 631010C3 : Ã..c : Undefined instruction
+00008094 : 000000ED : í... : ANDEQ   R0,R0,R13,ROR #1
 00008098 : E28F0000 : ..•â : ADR     R0,&000080A0
 0000809C : EF00002B : +..ï : SWI     OS_GenerateError
 000080A0 : ABAD1DEA : ê.­« : BLGE    &FEB4F850          ; *** Unpredictable

Don't stiff the machine on serious errors, just quit (WolfLib.HeapManage wolf_error)

 00008AD4 : EF000006 : ...ï : SWI     OS_Byte
 00008AD8 : E59F0018 : ..flå : LDR     R0,&00008AF8
 00008ADC : E3500000 : ..Pã : CMP     R0,#0
-00008AE0 : 0AFFFDB1 : ±ýÿ. : BEQ     &000081AC
+00008AE0 : EAFFFDB1 : ±ýÿê : B       &000081AC
 00008AE4 : E8BD5FFF : ÿ_½è : LDMIA   R13!,{R0-R12,R14}
 00008AE8 : E3A0F000 : .ð ã : MOV     PC,#0
 00008AEC : E3A01001 : .. ã : MOV     R1,#1

Use OS_Exit if load_level_song fails (WolfLib.SndBlaster load_level_song)

 00013684 : E28F1014 : ..•â : ADR     R1,&000136A0
 00013688 : E2400001 : ..@â : SUB     R0,R0,#1
 0001368C : E350003B : ;.Pã : CMP     R0,#&3B            ; =";"
-00013690 : 83A0F000 : .𠃠: MOVHI   PC,#0
+00013690 : 8F000011 : ...• : SWIHI   OS_Exit
 00013694 : E7910100 : ..’ç : LDR     R0,[R1,R0,LSL #2]
 00013698 : EBFFFFB4 : ´ÿÿë : BL      &00013570
 0001369C : E8BD8003 : .€½è : LDMIA   R13!,{R0,R1,PC}

Replace checksum calculation with hardcoded value (WolfLib.SndBlaster PPcheck_sum)

 000137B4 : 000E0065 : e... : ANDEQ   R0,R14,R5,RRX
 000137B8 : 00011FEC : ì... : ANDEQ   R1,R1,R12,ROR #31
 000137BC : 00012238 : 8".. : ANDEQ   R2,R1,R8,LSR R2
-000137C0 : E92D4002 : .@-é : STMDB   R13!,{R1,R14}
-000137C4 : E51F0014 : ...å : LDR     R0,&000137B8
+000137C0 : E3A00026 : &. ã : MOV     R0,#&26            ; ="&"
+000137C4 : E1A0F00E : .ð á : MOV     PC,R14
 000137C8 : E51F1014 : ...å : LDR     R1,&000137BC
 000137CC : E0411000 : ..Aà : SUB     R1,R1,R0
 000137D0 : E090E001 : .à‘à : ADDS    R14,R0,R1

Disable CPU detection (WolfLib.Processor interrogate_processor)

 00019E3C : 00000000 : .... : ANDEQ   R0,R0,R0
 00019E40 : 00000000 : .... : ANDEQ   R0,R0,R0
 00019E44 : 00000000 : .... : ANDEQ   R0,R0,R0
-00019E48 : E58FE090 : ‘à•å : STR     R14,&00019EE0
+00019E48 : E1A0F00E : .ð á : MOV     PC,R14
 00019E4C : EF000016 : ...ï : SWI     OS_EnterOS
 00019E50 : F1A00000 : .. ñ : Undefined instruction
 00019E54 : E3A00001 : .. ã : MOV     R0,#1

Hardcode processor type to '3' (i.e. ARM3) (WolfLib.Processor processor_type / real_processor_type)

 00019EDC : E1B0F00E : .ð°á : MOVS    PC,R14
 00019EE0 : 00000000 : .... : ANDEQ   R0,R0,R0
 00019EE4 : E1A0F002 : .ð á : MOV     PC,R2
-00019EE8 : 00000000 : .... : ANDEQ   R0,R0,R0
-00019EEC : 00000000 : .... : ANDEQ   R0,R0,R0
+00019EE8 : 00000003 : .... : ANDEQ   R0,R0,R3
+00019EEC : 00000003 : .... : ANDEQ   R0,R0,R3
 00019EF0 : 33323130 : 0123 : Undefined instruction
 00019EF4 : 37363534 : 4567 : Undefined instruction
 00019EF8 : 42413938 : 89AB : SUBMI   R3,R1,#&000E0000

Disable more copy protection (WolfLib.Processor get_game_id)

 00019FE4 : E51F0104 : ...å : LDR     R0,&00019EE8
 00019FE8 : E1A0F00E : .ð á : MOV     PC,R14
 00019FEC : E92D5FFE : þ_-é : STMDB   R13!,{R1-R12,R14}
-00019FF0 : E3A00CFF : ÿ. ã : MOV     R0,#&FF00
-00019FF4 : E3A01000 : .. ã : MOV     R1,#0
-00019FF8 : EB000065 : e..ë : BL      &0001A194
-00019FFC : E1A0A002 : .  á : MOV     R10,R2
-0001A000 : E28F0FC2 : Â.•â : ADR     R0,&0001A310
-0001A004 : E2801080 : €.€â : ADD     R1,R0,#&80         ; ="€"
+00019FF0 : E59F0008 : ..flå : LDR     R0,&0001A000
+00019FF4 : E59F1008 : ..flå : LDR     R1,&0001A004
+00019FF8 : E5810000 : ..Ŵå : STR     R0,[R1,#0]
+00019FFC : E8BD9FFE : þfl½è : LDMIA   R13!,{R1-R12,PC}
+0001A000 : 0000029A : Œ... : MULEQ   R0,R10,R2
+0001A004 : 00023A80 : €:.. : ANDEQ   R3,R2,R0,LSL #21
 0001A008 : E3A02000 : .  ã : MOV     R2,#0
 0001A00C : E5C02000 : . Àå : STRB    R2,[R0,#0]
 0001A010 : E2800001 : ..ۉ : ADD     R0,R0,#1

Disable disc swap code (WolfLib.Floppy ensure_disc)
Not sure why I did this, doesn't seem directly related to copy protection. Perhaps just for use under non-ADFS filesystems?

 0001A470 : E3A08001 : .€ ã : MOV     R8,#1
 0001A474 : EA000003 : ...ê : B       &0001A488
 0001A478 : E92D4000 : .@-é : STMDB   R13!,{R14}
-0001A47C : EB0001B4 : ´..ë : BL      &0001AB54
-0001A480 : E3500000 : ..Pã : CMP     R0,#0
-0001A484 : 08BD8000 : .€½. : LDMEQIA R13!,{PC}
-0001A488 : EBFFFFD1 : Ñÿÿë : BL      &0001A3D4
-0001A48C : E1580000 : ..Xá : CMP     R8,R0
+0001A47C : E1A00000 : .. á : MOV     R0,R0
+0001A480 : E3A00000 : .. ã : MOV     R0,#0
+0001A484 : E8BD8000 : .€½è : LDMIA   R13!,{PC}
+0001A488 : E3A00000 : .. ã : MOV     R0,#0
+0001A48C : E8BD8000 : .€½è : LDMIA   R13!,{PC}
 0001A490 : 08BD8000 : .€½. : LDMEQIA R13!,{PC}
 0001A494 : E1A00008 : .. á : MOV     R0,R8
 0001A498 : EB000019 : ...ë : BL      &0001A504

Use OS_Exit if SightPlayer fails (WolfLib.IdActor SightPlayer)

 0001EA3C : E5C04032 : 2@Àå : STRB    R4,[R0,#50]
 0001EA40 : E5D01032 : 2.Ðå : LDRB    R1,[R0,#50]
 0001EA44 : E3510000 : ..Qã : CMP     R1,#0
-0001EA48 : 03A0F000 : .ð . : MOVEQ   PC,#0
+0001EA48 : 0F000011 : .... : SWIEQ   OS_Exit
 0001EA4C : E8BD901E : .‘½è : LDMIA   R13!,{R1-R4,R12,PC}
 0001EA50 : E92D503C : <P-é : STMDB   R13!,{R2-R5,R12,R14}
 0001EA54 : EBFFD8F0 : ðØÿë : BL      &00014E1C