Galaforce 2 - a Kevin Edwards self-decrypting loader which loads in the main game files, decrypts the main game file and executes an RTS - to an execute address purposely pushed onto the stack beforehand.
0400 LDA #15 0402 LDX #0 \*FX15,0 0404 JSR OSbyte \Clear keyboard 0407 SEI \disable interrupts 0408 LDA #0 040A LDX #15 040C STA &02A1,X 040F DEX \Ensure no foreign ROMs 0410 BPL &040C \are present 0412 LDY &FFB6 \and no foreign vectors 0415 DEY \by copying default address 0416 LDA &FFB7 \vectors from OS ROM. 0419 STA &70 041B LDA &FFB8 041E STA &71 0420 LDA (&70),Y 0422 STA &0200,Y 0425 DEY 0426 BPL &0420 0428 JMP &04E2 \continue execution at 4E2 \Kevin advertises himself in this next bit 0428 ** ** ** 50 72 6F 74 65 Prote 0430 63 74 69 6F 6E 20 64 65 ction de 0438 73 69 67 6E 20 26 20 63 sign & C 0440 6F 64 69 6E 67 20 28 63 oding (c 0448 29 20 4B 65 76 69 6E 20 ) Kevin 0450 45 64 77 61 72 64 73 20 Edwards 0458 31 39 38 38 2D 2D 2D 2D 1988---- 0460 2D 2D 2D 2D 2D 2D 2D 2D -------- 0468 2D 2D 2D 2D 2D 2D 2D 2D -------- 0470 2D 2D 2D 2D 2D 2D 2D 2D -------- 0478 2D 2D 2D 2D 2D 2D 2D 2D -------- 0480 2D 2D 2D 2D 2D 2D 2D 2D -------- 0488 2D 2D 2D 2D 2D 2D 2D 2D -------- 0490 2D 2D 2D 2D 2D 2D 2D 2D -------- 0498 2D 2D 2D 2D 2D 2D 2D 2D -------- 04A0 2D 2D 2D 2D 2D 2D 2D 2D -------- 04A8 2D 2D 2D 2D 2D 2D 2D 2D -------- 04B0 2D 2D 2D 2D 2D 2D 2D 2D -------- 04B8 2D 2D 2D 2D 2D 2D 2D 2D -------- 04C0 2D 2D 2D 2D 2D 2D 2D 2D -------- 04C8 2D 2D 2D 2D 2D 2D 2D 2D -------- 04D0 2D 2D 2D 2D 2D 2D 2D 2D -------- 04D8 2D 2D 2D 2D 2D 2D 2D 2D -------- 04E0 2D 2D ** ** ** ** ** ** -- 04E2 SEI \disable interrupts 04E3 LDX #255 04E5 TXS \reset stack pointer 04E6 INX \X=0 04E7 LDA #3 04E9 STA &0258 \*FX200,3 04EC LDA #75 04EE STA &70 04F0 LDA #69 04F2 STA &71 04F4 LDA #86 04F6 STA &72 04F8 LDA #73 04FA STA &73 04FC LDA #78 \Store values used in 04FE STA &74 \decryption 0500 LDA &0500 0503 EOR &70 0505 INC &0511 0508 EOR &72 050A INC &71 050C INC &71 050E EOR &71 0510 EOR #237 0512 EOR &0600,X 0515 LDY &74 0517 STY &051B 051A EOR #236 051C EOR &0601,X 051F EOR &73 0521 STA &0600,X 0524 LDA &73 0526 EOR &74 0528 STA &73 052A CLC 052B ADC #244 052D STA &74 052F EOR &0511 0532 STA &72 0534 LSR A 0535 EOR &74 0537 STA &70 0539 INX 053A BNE &0500 053C LDY #3 \*FX200,3 053E STY &0258 0541 LDA #&4C \&4C is code for JMP 0543 STA &0287 \When break is pressed, if ?&287=&4C 0546 LDA #&87 \we JMP to the address in &288/9 0548 STA &0288 \which is 054B DEY \Y=2 054C STY &0289 \&24C 054F LDA #64 0551 STA &0D00 0554 LDA &FFFA 0557 BNE &05B4 0559 LDA &FFFB 055C CMP #13 055E BNE &05B4 0560 INC &0501 0563 BNE &0500 0565 LDA #0 0567 STA &70 0569 STA &71 056B TAY 056C LDA &71 056E EOR &0600,Y 0571 STA &71 0573 LDX #8 0575 LDA &71 0577 ROL A 0578 BCC &0586 057A LDA &71 057C EOR #8 057E STA &71 0580 LDA &70 0582 EOR #16 0584 STA &70 0586 ROL &70 0588 ROL &71 058A DEX 058B BNE &0575 058D INY 058E CPY #20 0590 BNE &056C 0592 LDA &70 \Checksum, match 0594 CMP &06FE \contents of &70/71 0597 BNE &05AD \against &6FE/6FF 0599 LDA &71 059B CMP &06FF 059E BEQ &0600 \If matched, continue at &600 05A0 BNE &05AD \Otherwise loop forever \Kevin says hello 05A0 ** ** 48 69 20 42 54 57 Hi BTW 05A8 20 2E 2E 2E 2E ** ** ** ... \Come to this bit if checksums don't match 05AD LDA #200 05AF LDX #3 05B1 JSR OSbyte \*FX200,3 05B4 STA &0600,Y \Clear memory 05B7 INY 05B8 JMP &05B4 \Loop forever \Next bit is padding, as you can see from the \repeated PAD word 05B8 ** ** ** 20 28 63 29 20 (c) 05C0 4B 65 76 69 6E 20 45 64 Kevin Ed 05C8 77 61 72 64 73 20 31 39 wards 19 05D0 38 38 20 20 20 20 20 50 88 P 05D8 41 44 50 41 44 50 41 44 ADPADPAD 05E0 50 41 44 50 41 44 50 41 PADPADPA 05E8 44 50 41 44 50 41 44 50 DPADPADP 05F0 41 44 50 41 44 50 41 44 ADPADPAD 05F8 50 41 44 50 41 44 50 41 PADPADPA 0600 LDX #239 \Set stack pointer 0602 TXS \to 239 0603 LDA #&57 \execution point 0605 PHA \of game minus 1 0606 LDA #&FF \ie &5800 0608 PHA 0609 LDA #209 060B PHA 060C LDA #99 060E PHA 060F LDX #53 \Check that there are no foreign 0611 LDA &0200,X \vectors by loading their hi bytes. 0614 BPL &05B4 \If they are <&80 (+ve) then 0616 DEX \user has fiddled so jump to 0617 DEX \loop-forever routine. 0618 BPL &0611 061A LDA #0 061C TAY 061D STA &0600,Y \Clear memory up to current point 0620 INY \&600-628 0621 CPY #29 0623 BNE &061D 0625 CLI 0626 LDA #140 \*TAPE 0628 LDX #12 062A JSR OSbyte 062D LDX #&BC \*command at &6BC 062F LDY #&06 \*L.GAME? 900 0631 JSR OScli 0634 LDX #&CC \*command at &6CC 0636 LDY #&06 \*L.GAME2?? E00 0638 JSR OScli 063B LDA #15 063D LDX #0 \*FX15,0 063F JSR OSbyte \clear kbd 0642 SEI \disable interrupts 0643 LDA #3 0645 STA &0258 \*FX200,3 0648 LDA &0287 064B CMP #76 \If contents of &287 064D BEQ &0652 \are <> 76 jump to 064F JMP &05B4 \loop-forever routine 0652 LDY #0 0654 LDX #78 0656 PLA \Value put on stack at &60C 0657 STA &70 \?&70=99 0659 STA &71 \?&71=99 065B PLA 065C STA &72 \?&72=209 065E LDA &0E00,Y \Decode game code 0661 EOR &70 0663 DEC &71 0665 EOR &71 0667 EOR &72 0669 STA &0E00,Y 066C INC &72 066E LDA &72 0670 SEC 0671 SBC #95 0673 EOR &71 0675 STA &72 0677 EOR &70 0679 STA &70 067B EOR #228 067D STA &71 067F EOR &72 0681 INY 0682 BNE &065E 0684 INC &0660 0687 INC &066B 068A DEX 068B BNE &065E 068D STX &0287 0690 CLI \reneable interrupts 0691 RTS \return to address on stack ie &5800. \More PADding 0690 ** ** 50 84 44 50 41 81 PADPAD 0698 50 41 44 95 41 44 50 84 PADPADPA 06A0 44 50 41 44 50 41 44 50 DPADPADP 06A8 41 44 50 41 44 50 41 44 ADPADPAD 06B0 50 41 44 95 41 44 50 84 PADPADPA 06B8 44 50 41 81 4C 4F 41 81 DPADLOAD 06C0 20 47 61 6D 65 83 7F 20 Game.. 06C8 39 30 30 0D 4C 4F 41 44 900.LOAD 06D0 20 47 61 A8 65 32 84 BA Game2.. 06D8 20 45 30 F5 0D 50 72 AA E0..Pro 06E0 74 65 63 74 69 6F 6E 20 tection 06E8 28 63 29 20 4B 65 76 69 (c) Kevi 06F0 6E 20 45 A1 77 61 72 A1 n Edward 06F8 73 20 31 FC 38 38 34 74 s 19884t
Mr Spock 1 Feb 2005