|
Post by Ian Colquhoun on Feb 7, 2007 22:32:34 GMT -5
I was wondering whether anyone here might have a pointer to some documentation on how programs that autostart work? By autostart I mean something that you LOAD"PROG",8,1 and it automatically starts running some code whether it be to continue loading or playing music or what have you. The reason I ask is that I'm trying to examine a program that uses a custom load routine and I figure that trying to have a look at the autostart stuff would be a place to start.
|
|
|
Post by MadModder on Feb 8, 2007 13:06:14 GMT -5
I remember having a piece of code written off of a magazine. The programs only purpose was to autoload a user selected file. I'll try to find it. I'm not going to look for the magazine. It's well burried under all junk in the basement togehter with some hundreds of other magazines... [Edit] Here it is madmodders.se/temp/C64/AUTOSTART.PRGIt's in swedish, and it defaults to disk device 8. VÄNTA = WAIT VILL DU ANVÄNDA BAND ELLER DISK = DO YOU WANT TO USE TAPE OR DISK VAD HETER FILEN SOM DU VILL LÄGGA AUTOSTART PÅ = WHAT IS THE NAME OF THE FILE YOU WANT TO AUTOSTART BASIC ELLER MASKINKOD = BASIC OR MACHINE CODE. ie. if you want to RUN the file, or SYS it. SYSADRESS = SYS ADDRESS Then it saves a 1 block file named boot. It's a good thing to edit the directory and put it first.
|
|
|
Post by gmoon on Feb 8, 2007 14:49:54 GMT -5
I think the basic technique is to load a small ML prg (load"whatever"8,1) into the unused space @ $02A7, which spills over into the BASIC indirect vector table @ $0300. The prg overwrites the BASIC IMAIN vector ($0302-303), and replaces that with the start addr ($02A7.)
Once the system starts the code @$02A7, it uses the kernal FS routines to load the main file, into which it jumps once the load is complete.
|
|
|
Post by gmoon on Feb 8, 2007 17:13:51 GMT -5
A really 'stupid' demo of the concept-- *=$02a7 start lda $a1 sta $d020 jmp start
*=$0300 .word $e38b ; error vector-- it's 'in the way', so must also be changed .word $02a7 ; IMAIN vector, set to prg start
Assemble the src to something like 'arun.prg'. Just LOAD"ARUN",8,1. It will automatically run. Works fine in VICE. This doesn't load a file, it just changes the BG color ~ 3 seconds. You need to insert the usual SETLFS, SETNAM & LOAD kernal calls here to load a file (remove the code @ 'start', there isn't much mem here to work with.) You can't run/stop--restore this one, it doesn't reset the IMAIN vector afterwards....
|
|
|
Post by tlr on Feb 8, 2007 17:58:12 GMT -5
I think the basic technique is to load a small ML prg (load"whatever"8,1) into the unused space @ $02A7, which spills over into the BASIC indirect vector table @ $0300. The prg overwrites the BASIC IMAIN vector ($0302-303), and replaces that with the start addr ($02A7.) Once the system starts the code @$02A7, it uses the kernal FS routines to load the main file, into which it jumps once the load is complete. There are many ways to autostart. - Overloading the vectors at $0300 and up. For example $0302 like you wrote, but also $0314, or others.
- Overloading the stack ($0100 and up) with all $01. Upon doing the next RTS the address will be pop:ed from stack as PC=$0101+1=$0102.
- Overloading the memory under kernal and then wrapping around to $0000-$0001.
This is particulary cool. you can load code at $e000-$fffe, set the IRQ vector at $fffe to your start address and make sure that memory under the load routine is padded with 00's. Then let the loader wrap around to $0000 and load $2f,$35 which will in effect map out the kernal triggering a break through the $fffe vector.
You can use the wrap around technique in combination with the other two aswell. For tape there are even more variants. Ian Colquhoun: maybe you could post the loader for us to examine?
|
|
|
Post by expertsetup on Feb 8, 2007 19:18:26 GMT -5
[/li][li]Overloading the memory under kernal and then wrapping around to $0000-$0001. This is particulary cool. you can load code at $e000-$fffe, set the IRQ vector at $fffe to your start address and make sure that memory under the load routine is padded with 00's. Then let the loader wrap around to $0000 and load $2f,$35 which will in effect map out the kernal triggering a break through the $fffe vector.[/list] You can use the wrap around technique in combination with the other two aswell.[/quote] tlr this sounds quite intriguing, I'm wondering if you can provide a simple example?
|
|
|
Post by gmoon on Feb 8, 2007 22:26:46 GMT -5
This is particulary cool. you can load code at $e000-$fffe, set the IRQ vector at $fffe to your start address and make sure that memory under the load routine is padded with 00's. Then let the loader wrap around to $0000 and load $2f,$35 which will in effect map out the kernal triggering a break through the $fffe vector. Well....that's just so cool. I had no idea that the kernal LOAD routines wouldn't range-check at $FFFF. And the zeros under the LOAD routine ensure that a break occurs the instant ROM switches to RAM. To use that to map out the ROM and simultaneously trigger the break--very cool indeed.
|
|
|
Post by tlr on Feb 9, 2007 5:55:42 GMT -5
Ok, I wrote one just now: autowrap_simple.prgIt has the limitation that the load routine must execute in the range $f505-$f540 when kernal gets switched out. This is true for the stock kernal but probably not for a turbo loader. The wrap technique can be used in several (more complex) ways that does not have this limitation though.
|
|
|
Post by expertsetup on Feb 9, 2007 6:47:11 GMT -5
This is particulary cool. you can load code at $e000-$fffe, set the IRQ vector at $fffe to your start address and make sure that memory under the load routine is padded with 00's. Then let the loader wrap around to $0000 and load $2f,$35 which will in effect map out the kernal triggering a break through the $fffe vector. Well....that's just so cool. I had no idea that the kernal LOAD routines wouldn't range-check at $FFFF. And the zeros under the LOAD routine ensure that a break occurs the instant ROM switches to RAM. To use that to map out the ROM and simultaneously trigger the break--very cool indeed. I see, I missed the obvious that the zeros under load would cause the break to the $fffe vector. Thanks for the example tlr I am going to take a look right now...
|
|
|
Post by Ian Colquhoun on Feb 9, 2007 10:20:54 GMT -5
There are many ways to autostart. - Overloading the vectors at $0300 and up. For example $0302 like you wrote, but also $0314, or others.
- Overloading the stack ($0100 and up) with all $01. Upon doing the next RTS the address will be pop:ed from stack as PC=$0101+1=$0102.
- Overloading the memory under kernal and then wrapping around to $0000-$0001.
This is particulary cool. you can load code at $e000-$fffe, set the IRQ vector at $fffe to your start address and make sure that memory under the load routine is padded with 00's. Then let the loader wrap around to $0000 and load $2f,$35 which will in effect map out the kernal triggering a break through the $fffe vector.
You can use the wrap around technique in combination with the other two aswell. For tape there are even more variants. Ian Colquhoun: maybe you could post the loader for us to examine? Phew... thanks folks, this gives me lots to ponder! tlr: I'd love to be able to get the loader and rest of the program itself off the disk but that's part of the problem. The directory of the disk is phony. The loader is a 0 block file and proceeds to load files that aren't listed at all. The disk is riddled with copy protection that I haven't been able to copy successfully with any method - including mnib/nibtools. I just figured this might give me a starting point to figure out how this beast actually works.
|
|
|
Post by tlr on Feb 9, 2007 10:29:00 GMT -5
tlr: I'd love to be able to get the loader and rest of the program itself off the disk but that's part of the problem. The directory of the disk is phony. The loader is a 0 block file and proceeds to load files that aren't listed at all. The disk is riddled with copy protection that I haven't been able to copy successfully with any method - including mnib/nibtools. I just figured this might give me a starting point to figure out how this beast actually works. Ahh, interesting! Let's see if we can guide you to get the loader of the disk? Do you have some way to transfer files from the C64 to a PC? If you have an XM1541 cable you can probably just copy the 0 block file to the pc. (or you can copy it with any normal c64 file copier to a different disk) What happens if you just whole-disk copy it? Will it totally fail (i.e lock up the drive during copy), or does it just produce a non-working image? If it doesn't lock up the drive, could you post a (non-working) .d64 of the disk? What tools are you using for the analysis BTW? ML-monitor?
|
|
|
Post by Ian Colquhoun on Feb 9, 2007 16:38:44 GMT -5
Ok... help is good! I've been trying to get a backup of this disk since I first acquired it in 1989! Golan, if you're reading - this is Darkstar 3.1. I do have XM1541 capability - hence the mnib reference above. So, here are 2 images. A D64 and a G64 from the latest NIB I took with mnib. Neither of them work properly. www-acad.sheridanc.on.ca/~ian/c64/ds31bbs.d64www-acad.sheridanc.on.ca/~ian/c64/ds31bbs.g64The file "(C) 1987 D.S.S." autostarts, flashes the border red/black while it reads and should come up to a screen where you select either the ASCII or Colour version of the BBS. It then should continue loading until it prompts you for Disk 2 which contains a bunch of configuration. I've never been able to get a copy to get anywhere near that close. Anyhow - the other files that actually show in the directory are for Darkterm - the accompanying terminal program. They all should work fine - no protection on them. My ultimate goal of course is to get the copy protection off this stuff so it can be preserved. The disk I have as far as I know is the only copy that has surfaced in recent memory - maybe the only one left anywhere. I use the monitor in the Super Snapshot cart for examining this stuff. Which brings me to another annoying part of this software. I've snapshotted it up to the point it wants the config disk which is all well and good, however, after it reads all the config stuff, it re-asks for the master disk and does another copy protection check. I hope all this peaks the interest of those of you that are far more skilled than I! Thanks guys.
|
|
|
Post by tlr on Feb 10, 2007 5:23:20 GMT -5
Thanks. Could you post images of the other disks aswell? (or PM/mail them) The file "(C) 1987 D.S.S." autostarts, flashes the border red/black while it reads and should come up to a screen where you select either the ASCII or Colour version of the BBS. It then should continue loading until it prompts you for Disk 2 which contains a bunch of configuration. I've never been able to get a copy to get anywhere near that close. How for how long does it flash, or rather how long between each "red"? Is this the same for the original and the copy? My ultimate goal of course is to get the copy protection off this stuff so it can be preserved. The disk I have as far as I know is the only copy that has surfaced in recent memory - maybe the only one left anywhere. One way is the remove the protection. For preservation it is even cooler to understand the protection enough to be able to replicate it exactly in a .g64 (which probably is even harder). I use the monitor in the Super Snapshot cart for examining this stuff. Which brings me to another annoying part of this software. I've snapshotted it up to the point it wants the config disk which is all well and good, however, after it reads all the config stuff, it re-asks for the master disk and does another copy protection check. Freezed copies are never safe enough anyway. Clean unstarted cracks are the way to go. This ensures that you fully understand the protection mechanism. I'm not sure I will have time to do this fully, but here's an analysis of the initial loader: +-----------------------+ | Autostart loader | | | | File: | | "(C) 1987 D.S.S." | | $0100-$0256 | +-----------------------+
Basic lines if loaded with LOAD"*",8:
>C:0100 0e 08 00 00 41 b2 c2 28 ....A..( 0 A=PEEK(186) >C:0108 31 38 36 29 00 20 08 00 186). .. 0 LOAD"0:(C)*",A,1 >C:0110 00 93 22 30 3a 28 43 29 .."0:(C) >C:0118 2a 22 2c 41 2c 31 00 00 *",A,1.. >C:0120 00 .
Encrypted loader code:
>C:0121 2c d1 84 a0 95 1b aa ab ,....... >C:0129 8f 94 1a aa 29 0d 07 88 ....)... >C:0131 5a f1 a8 a9 06 2e 88 28 Z......( >C:0139 9a 45 56 a6 ad db d9 a1 .EV..... >C:0141 21 9d 42 56 a9 20 f5 2a !.BV. .* >C:0149 4f 4e de 71 50 4d 4c cf ON.qPML. >C:0151 6d a2 bd bd cf 87 61 d9 m.....a. >C:0159 75 81 b9 3d 4f 87 61 26 u..=O.a& >C:0161 0a 01 99 9d cf a7 41 d9 ......A. >C:0169 75 81 6c 41 26 0a 01 99 u.lA&... >C:0171 1d 4f 27 08 60 50 0b bb .O'.`P.. >C:0179 50 0a 75 19 13 17 1e 05 P.u..... >C:0181 07 05 6b 6d 02 0b 01 45 ..km...E >C:0189 00 00 00 00 00 00 00 00 ........ >C:0191 00 00 00 00 00 00 00 00 ........ >C:0199 00 00 00 00 00 00 00 00 ........ >C:01a1 00 00 00 00 00 00 00 00 ........ >C:01a9 00 00 00 00 00 00 00 00 ........ >C:01b1 00 00 00 00 00 00 00 00 ........ >C:01b9 00 00 00 00 00 00 00 00 ........ >C:01c1 00 00 00 00 00 00 00 00 ........ >C:01c9 00 00 00 00 00 00 00 00 ........ >C:01d1 00 00 00 00 00 00 00 00 ........ >C:01d9 00 00 00 00 00 00 00 00 ........ >C:01e1 00 00 00 00 00 00 00 00 ........ >C:01e9 00 00 00 00 00 00 00 .......
>C:01f0 02 02 02 02 02 02 02 02 ........ ;overloaded return addresses >C:01f8 02 02 02 02 02 02 02 02 ........
Unused code: .C:0200 EA NOP .C:0201 EA NOP .C:0202 EA NOP
;Stack entry point: ; $ae=$56, $af=$02 (end address after load) .C:0203 A2 FE LDX #$FE .C:0205 9A TXS ;reset stack .C:0206 A9 36 LDA #$36 .C:0208 85 01 STA $01 ;switch out basic .C:020a A5 BA LDA $BA .C:020c 80 08 STA $0880 ;current device # -> $0880 .C:020f A5 AE LDA $AE ;=$56 .C:0211 45 AF EOR $AF ;=$02 -> Acc=$54 .C:0213 A0 21 LDY #$21 .C:0215 84 9D STY $9D ; Disable kernal messages .C:0217 59 00 01 EOR $0100,Y .C:021a 99 00 01 STA $0100,Y ; Decrypt $0121-$01ef .C:021d C8 INY .C:021e C0 F0 CPY #$F0 .C:0220 D0 F5 BNE $0217 .C:0222 A9 00 LDA #$00 ;Black border + bg .C:0224 20 D0 STA $D020 .C:0227 21 D0 STA $D021 .C:022a 4C 21 01 JMP $0121 ;start decrypted loader. .C:022d 40 RTI
>C:022e 2a 2a 20 53 54 41 47 47 ** STAGG >C:0236 45 52 20 54 52 41 58 20 ER TRAX >C:023e 2a 2a 2a 2a 20 28 43 29 **** (C) >C:0246 20 31 39 38 37 20 44 2e 1987 D. >C:024e 53 2e 53 2e 20 2a 2a 2a S.S. ***
After running: .C:0121 78 SEI .C:0122 A9 2D LDA #$2D ;point NMI to $022d (=RTI) .C:0124 18 03 STA $0318 .C:0127 A9 02 LDA #$02 .C:0129 19 03 STA $0319 .C:012c A9 80 LDA #$80 .C:012e 8A 02 STA $028A ;key repeat on all keys .C:0131 58 CLI .C:0132 A9 01 LDA #$01 .C:0134 A8 TAY .C:0135 AE 80 08 LDX $0880 .C:0138 20 BA FF JSR $FFBA ; <dev>,1,1 .C:013b A9 0F LDA #$0F .C:013d A2 79 LDX #$79 .C:013f A0 01 LDY #$01 .C:0141 20 BD FF JSR $FFBD ; Filename at $0179 = "OVERLINK MODE" .C:0144 A9 00 LDA #$00 .C:0146 20 D5 FF JSR $FFD5 ; Load it! ($cf00-$d000) .C:0149 B0 FE BCS $0149 ; If fail, lock up. .C:014b 20 51 01 JSR $0151 ; Decrypt .C:014e 4C 00 CF JMP $CF00 ; start it.
.C:0151 A2 00 LDX #$00 ; Decrypt code at $cf00-$d000 .C:0153 BD 00 CF LDA $CF00,X .C:0156 48 PHA .C:0157 29 F0 AND #$F0 .C:0159 85 04 STA $04 .C:015b BD 80 CF LDA $CF80,X .C:015e 48 PHA .C:015f 29 0F AND #$0F .C:0161 05 04 ORA $04 .C:0163 9D 00 CF STA $CF00,X .C:0166 68 PLA .C:0167 29 F0 AND #$F0 .C:0169 85 04 STA $04 .C:016b 68 PLA .C:016c 29 0F AND #$0F .C:016e 05 04 ORA $04 .C:0170 9D 80 CF STA $CF80,X .C:0173 E8 INX .C:0174 E0 80 CPX #$80 .C:0176 D0 DB BNE $0153 .C:0178 60 RTS
>C:0179 30 3a 4f 56 45 52 4c 49 0:OVERLI >C:0181 4e 4b 20 4d 4f 44 45 00 NK MODE. >C:0189 00 00 00 00 00 00 00 00 ........ >C:0191 00 00 00 00 00 00 00 00 ........ >C:0199 00 00 00 00 00 00 00 00 ........ >C:01a1 00 00 00 00 00 00 00 00 ........ >C:01a9 00 00 00 00 00 00 00 00 ........ >C:01b1 00 00 00 00 00 00 00 00 ........ >C:01b9 00 00 00 00 00 00 00 00 ........ >C:01c1 00 00 00 00 00 00 00 00 ........ >C:01c9 00 00 00 00 00 00 00 00 ........ >C:01d1 00 00 00 00 00 00 00 00 ........ >C:01d9 00 00 00 00 00 00 00 00 ........ >C:01e1 00 00 00 00 00 00 00 00 ........ >C:01e9 00 00 00 00 00 00 00 ....... The code at $cf00-$d000 will then execute Track=18/Sector=14 in drive ram at $0500. This code loads up a bunch of stuff in drive ram at $0300-$0500 + $0600-$0700. The $0300-$0400 stuff is read back by the $cf00-$d000 code to $a000-$a0f7, and is there used to read 32 encrypted sectors from Track=13/Sector=0 and up to addresses $0900-$2900. This code is then entered at $0900, decrypts it self, and runs some interrupt code which detects that something is wrong and wipes the memory. I'll post back when I have detailed more.
|
|
|
Post by tlr on Feb 10, 2007 9:11:50 GMT -5
+-----------------------+ | Stage 2 loader | | | | File: | | "OVERLINK MODE" | | $CF00-$D000 | +-----------------------+
Original file: >C:cf00 aa 0f 80 19 00 af cf 81 ........ >C:cf08 1e 08 20 49 a0 36 00 cc .. I.6.. >C:cf10 ef 9c f7 af 0d ad a2 80 ........ >C:cf18 03 20 b6 fb a4 0c 22 bf . ....". >C:cf20 f0 29 cf f0 a0 01 ab a0 .)...... >C:cf28 82 0f 28 b0 f6 a0 06 a0 ..(..... >C:cf30 dc af c2 2f bc f6 2f c9 .../../. >C:cf38 f0 ad 00 20 cd f1 a0 06 ... .... >C:cf40 b1 e4 c2 29 df f8 c9 ce ...).... >C:cf48 08 d5 f0 2c ce f0 aa 09 ...,.... >C:cf50 20 cd f0 a0 9d a1 c0 29 ......) >C:cf58 9b cd a1 00 2c c3 f0 93 ....,... >C:cf60 32 02 cd c5 0a d2 fc a0 2....... >C:cf68 0c 21 c8 fc 91 34 ca ca .!...4.. >C:cf70 7a da fa 2a ca fa aa 8a z..*.... >C:cf78 8a 9a ca aa 9a aa ca 2a .......* >C:cf80 99 cb ad 78 23 c9 ff 9d ...x#... >C:cf88 39 c3 c4 f0 dd f1 23 c9 9.....#. >C:cf90 f0 40 be c9 4f 28 5e 00 .@..O(^. >C:cf98 08 80 8a ff 89 f0 a0 0d ........ >C:cfa0 2f c0 f0 af 09 b2 f8 2e /....... >C:cfa8 d0 f8 c0 ca 0f d9 f2 22 ......." >C:cfb0 cf f0 af 00 4d cf f0 a0 ....M... >C:cfb8 0f 82 2f d0 89 2f d0 a0 ../../.. >C:cfc0 49 a1 4f a0 c2 4f a8 c0 I.O..O.. >C:cfc8 4d a0 45 60 3c 0f e9 a2 M.E`<... >C:cfd0 00 83 2f d2 84 20 df a0 ../.. .. >C:cfd8 0a 8f 10 d0 60 4f 0f 29 ....`O.) >C:cfe0 3e 40 28 40 37 30 25 30 >@(@70%0 >C:cfe8 20 30 3f 2f 31 3e e8 e0 0?/1>.. >C:cff0 e9 e0 e6 e0 ec ef e9 e0 ........ >C:cff8 ed e7 ef e2 e4 e0 ef e0 ........
Decrypted loader: .C:cf00 A9 0B LDA #$0B ;Entry point .C:cf02 8D 18 03 STA $0318 .C:cf05 A9 CF LDA #$CF .C:cf07 8D 19 03 STA $0319 ; NNI = $cf0b (=RTI) .C:cf0a 24 40 BIT $40 ; hidden RTI. .C:cf0c AD 31 03 LDA $0331 ; is patched load routine? .C:cf0f C9 E0 CMP #$E0 .C:cf11 90 FE BCC $CF11 ; yes, lock up! .C:cf13 A9 0F LDA #$0F .C:cf15 A8 TAY .C:cf16 AE 80 08 LDX $0880 ;device number .C:cf19 20 BA FF JSR $FFBA ;15,<dev>,15 .C:cf1c A9 00 LDA #$00 .C:cf1e 20 BD FF JSR $FFBD .C:cf21 20 C0 FF JSR $FFC0 ;open 15,<dev>,15 .C:cf24 A9 02 LDA #$02 .C:cf26 A8 TAY .C:cf27 AE 80 08 LDX $0880 .C:cf2a 20 BA FF JSR $FFBA ;2,<dev>,2 .C:cf2d A9 02 LDA #$02 .C:cf2f A2 DF LDX #$DF .C:cf31 A0 CF LDY #$CF .C:cf33 20 BD FF JSR $FFBD ;"#2" .C:cf36 20 C0 FF JSR $FFC0 ;set buffer #2 as current .C:cf39 A2 0F LDX #$0F .C:cf3b 20 C9 FF JSR $FFC9 ;Output on file 15 .C:cf3e A0 00 LDY #$00 .C:cf40 B9 E1 CF LDA $CFE1,Y .C:cf43 20 D2 FF JSR $FFD2 ;"B-E:2,0,18,14" .C:cf46 C8 INY .C:cf47 C0 0D CPY #$0D .C:cf49 D0 F5 BNE $CF40 .C:cf4b 20 CC FF JSR $FFCC ;CLALL .C:cf4e A9 02 LDA #$02 .C:cf50 20 C3 FF JSR $FFC3 ;Input on file 2. .C:cf53 A2 94 LDX #$94 ;$cf94 = "M-R..." (128 bytes at $0300) .C:cf55 A0 CF LDY #$CF .C:cf57 20 9A CF JSR $CF9A ;do read .C:cf5a A0 00 LDY #$00 .C:cf5c 20 CF FF JSR $FFCF ;Get 7 bytes from $0300 -> $003e .C:cf5f 99 3E 00 STA $003E,Y .C:cf62 C8 INY .C:cf63 C0 07 CPY #$07 .C:cf65 D0 F5 BNE $CF5C .C:cf67 A0 00 LDY #$00 .C:cf69 20 CF FF JSR $FFCF ;Get $79 bytes from $0307 -> ($3e) (=$a000) .C:cf6c 91 3E STA ($3E),Y .C:cf6e C8 INY .C:cf6f C0 79 CPY #$79 .C:cf71 D0 F6 BNE $CF69 .C:cf73 20 CC FF JSR $FFCC ;CLALL .C:cf76 A9 80 LDA #$80 ;change "M-R..." to: 128 bytes at $0380 .C:cf78 8D 97 CF STA $CF97 .C:cf7b A2 94 LDX #$94 .C:cf7d A0 CF LDY #$CF .C:cf7f 20 9A CF JSR $CF9A ;do read .C:cf82 A0 79 LDY #$79 .C:cf84 20 CF FF JSR $FFCF ;Get $80 bytes from $0380 -> $a079 .C:cf87 91 3E STA ($3E),Y .C:cf89 C8 INY .C:cf8a C0 F9 CPY #$F9 .C:cf8c D0 F6 BNE $CF84 .C:cf8e 20 CC FF JSR $FFCC ;CLALL .C:cf91 4C B7 CF JMP $CFB7 ;start the code
>C:cf94 4d 2d 52 00 03 80 M-R.....
.C:cf9a 86 FB STX $FB .C:cf9c 84 FC STY $FC .C:cf9e A2 0F LDX #$0F .C:cfa0 20 C9 FF JSR $FFC9 ;output on file 15 .C:cfa3 A0 00 LDY #$00 .C:cfa5 B1 FB LDA ($FB),Y .C:cfa7 20 D2 FF JSR $FFD2 ;"M-R..." .C:cfaa C8 INY .C:cfab C0 06 CPY #$06 .C:cfad D0 F6 BNE $CFA5 .C:cfaf 20 CC FF JSR $FFCC ;CLALL .C:cfb2 A2 0F LDX #$0F .C:cfb4 4C C6 FF JMP $FFC6 ;Input from file 15
.C:cfb7 A9 00 LDA #$00 ;Start code .C:cfb9 8D 20 D0 STA $D020 .C:cfbc 8D 21 D0 STA $D021 .C:cfbf A6 41 LDX $41 ;=$0d .C:cfc1 A4 42 LDY $42 ;=$09 .C:cfc3 A9 CF LDA #$CF .C:cfc5 48 PHA .C:cfc6 A9 CE LDA #$CE .C:cfc8 48 PHA .C:cfc9 A5 40 LDA $40 ;=$20 .C:cfcb 6C 3E 00 JMP ($003E) ;=JSR $a000 .C:cfce EA NOP .C:cfcf A9 00 LDA #$00 .C:cfd1 8D 20 D0 STA $D020 .C:cfd4 8D 21 D0 STA $D021 .C:cfd7 A9 0B LDA #$0B .C:cfd9 8D 11 D0 STA $D011 .C:cfdc 6C 43 00 JMP ($0043) ;=JMP $0900
>C:cfdf 23 32 #2 >C:cfe1 42 2d 45 3a 32 2c 30 2c B-E:2,0, >C:cfe9 31 38 2c 31 34 18,14 >C:cfee ea ea ea ea ea ea ea ea ........ >C:cff6 ea ea ea ea ea ea ea ea ........ >C:cffe ea ea ..
+-----------------------+ | Stage 2 drive code | | | | File: | | Track=18,Sector=14 | | $0500-$0600 | +-----------------------+
.C:0500 A9 0F LDA #$0F .C:0502 20 25 05 JSR $0525 ; Read 18,15 .C:0505 20 51 05 JSR $0551 ; Decrypt to $0400 .C:0508 A9 10 LDA #$10 .C:050a 20 25 05 JSR $0525 ; Read 18,16 .C:050d 20 51 05 JSR $0551 ; Decrypt to $0600 .C:0510 A9 11 LDA #$11 .C:0512 20 25 05 JSR $0525 ; Read 18,17 .C:0515 20 51 05 JSR $0551 ; Decrypt to $0300 .C:0518 A9 07 LDA #$07 .C:051a 85 47 STA $47 ; Set data block ID char = 7 ; (which is the default) .C:051c A9 B0 LDA #$B0 ; Seek .C:051e A2 12 LDX #$12 .C:0520 A0 00 LDY #$00 .C:0522 4C 44 05 JMP $0544 ; Seek 18,00 and exit
.C:0525 A8 TAY ; Perform read. Y=Sector .C:0526 38 SEC .C:0527 E9 0F SBC #$0F .C:0529 AA TAX .C:052a BD 61 05 LDA $0561,X ; Get High address from table .C:052d 85 3C STA $3C .C:052f A9 00 LDA #$00 .C:0531 85 3B STA $3B .C:0533 A9 B0 LDA #$B0 ; Seek .C:0535 A2 12 LDX #$12 .C:0537 20 44 05 JSR $0544 .C:053a D0 FE BNE $053A .C:053c A9 80 LDA #$80 ; Read .C:053e 20 44 05 JSR $0544 .C:0541 D0 FE BNE $0541 .C:0543 60 RTS .C:0544 86 06 STX $06 ; Peform job, X=Track, Y=Sector, A=JobCode .C:0546 84 07 STY $07 .C:0548 85 00 STA $00 ; go .C:054a A5 00 LDA $00 ; wait for completion .C:054c 30 FC BMI $054A .C:054e C9 01 CMP #$01 ; Z=1 if ok. .C:0550 60 RTS .C:0551 A0 00 LDY #$00 ; Decrypt Sector to target pointed by $3b/$3c .C:0553 B9 00 05 LDA $0500,Y .C:0556 59 00 03 EOR $0300,Y .C:0559 91 3B STA ($3B),Y .C:055b C8 INY .C:055c D0 F5 BNE $0553 .C:055e 60 RTS >C:055f ea ea 04 06 03 ea ea 2a .......* >C:0567 2a 53 54 41 47 47 45 52 *STAGGER >C:056f 20 36 34 21 2a 2a 00 ea 64!**.. >C:0577 ea ea ea ea ea ea ea ea ........ >C:057f ea ea ea ea ea ea ea ea ........ >C:0587 ea ea ea ea ea ea ea ea ........ >C:058f ea ea ea ea ea ea ea ea ........ >C:0597 ea ea ea ea ea ea ea ea ........ >C:059f ea ea ea ea ea ea ea ea ........ >C:05a7 ea ea ea ea ea ea ea ea ........ >C:05af ea ea ea ea ea ea ea ea ........ >C:05b7 ea ea ea ea ea ea ea ea ........ >C:05bf ea ea ea ea ea ea ea ea ........ >C:05c7 ea ea ea ea ea ea ea ea ........ >C:05cf ea ea ea ea ea ea ea ea ........ >C:05d7 ea ea ea ea ea ea ea ea ........ >C:05df ea ea ea ea ea ea ea ea ........ >C:05e7 ea ea ea ea ea ea ea ea ........ >C:05ef ea ea ea ea ea ea ea ea ........ >C:05f7 ea ea ea ea ea ea ea ea ........
After the block at $0500-$0600 has been executed by the B-E command:
>C:0300 00 a0 20 0d 09 00 09 85 .. ..... >C:0308 04 8e 9a a0 84 af a9 00 ........ >C:0310 8d 9b a0 8d 56 a0 85 ae ....V... >C:0318 a9 f4 8d 18 03 a9 a0 8d ........ >C:0320 19 03 a9 b0 20 a8 a0 a9 .... ... >C:0328 80 20 a8 a0 20 57 a0 ad . .. W.. >C:0330 56 a0 49 02 8d 56 a0 8d V.I..V.. >C:0338 20 d0 a0 00 b9 00 a1 91 ....... >C:0340 ae c8 d0 f8 e6 af ee 9b ........ >C:0348 a0 ad 9b a0 c9 15 d0 08 ........ >C:0350 a9 00 8d 9b a0 ee 9a a0 ........ >C:0358 c6 04 d0 c6 60 ea a9 05 ....`... >C:0360 a2 8f a0 a0 20 da a0 a9 .... ... >C:0368 00 20 67 a0 a9 80 8d 8c . g..... >C:0370 a0 8d 81 a0 a9 06 a2 89 ........ >C:0378 a0 a0 20 da a0 a2 0f 20 .. .... >C:0380 c6 ff a0 00 20 cf ff 99 .... ... >C:0388 00 a1 c8 10 f7 4c cc ff .....L.. >C:0390 4d 2d 52 00 03 80 4d 2d M-R...M- >C:0398 45 00 06 4d 2d 57 06 00 E..M-W.. >C:03a0 02 00 00 4d 2d 57 00 00 ...M-W.. >C:03a8 01 00 4d 2d 52 00 00 8d ..M-R... >C:03b0 a2 a0 a9 08 a2 94 a0 a0 ........ >C:03b8 20 da a0 a9 07 a2 9c a0 ....... >C:03c0 a0 20 da a0 a9 05 a2 a3 . ...... >C:03c8 a0 a0 20 da a0 a2 0f 20 .. .... >C:03d0 c6 ff 20 e4 ff 48 20 cc .. ..H . >C:03d8 ff 68 30 e8 c9 01 d0 d2 .h0..... >C:03e0 60 86 02 84 03 48 a2 0f `....H.. >C:03e8 20 c9 ff 68 aa a0 00 b1 ..h.... >C:03f0 02 20 d2 ff c8 ca d0 f7 . ...... >C:03f8 4c cc ff 40 ea ea ea ea L..@....
.C:0400 A9 00 LDA #$00 .C:0402 AA TAX .C:0403 9D 00 06 STA $0600,X .C:0406 E8 INX .C:0407 D0 FA BNE $0403 .C:0409 8D 8D 04 STA $048D .C:040c AD 8D 04 LDA $048D .C:040f 4A LSR A .C:0410 90 22 BCC $0434 .C:0412 20 5C 04 JSR $045C .C:0415 A9 B0 LDA #$B0 .C:0417 20 4A 04 JSR $044A .C:041a D0 28 BNE $0444 .C:041c A9 80 LDA #$80 .C:041e 20 4A 04 JSR $044A .C:0421 D0 21 BNE $0444 .C:0423 20 74 04 JSR $0474 .C:0426 20 8E 04 JSR $048E .C:0429 EE 8D 04 INC $048D .C:042c AD 8D 04 LDA $048D .C:042f C9 10 CMP #$10 .C:0431 D0 D9 BNE $040C .C:0433 60 RTS .C:0434 A9 B0 LDA #$B0 .C:0436 20 4A 04 JSR $044A .C:0439 D0 D1 BNE $040C .C:043b A9 80 LDA #$80 .C:043d 20 4A 04 JSR $044A .C:0440 D0 CA BNE $040C .C:0442 F0 E2 BEQ $0426 .C:0444 20 74 04 JSR $0474 .C:0447 4C 0C 04 JMP $040C .C:044a A2 20 LDX #$20 .C:044c AC 8D 04 LDY $048D .C:044f 86 06 STX $06 .C:0451 84 07 STY $07 .C:0453 85 00 STA $00 .C:0455 A5 00 LDA $00 .C:0457 30 FC BMI $0455 .C:0459 C9 01 CMP #$01 .C:045b 60 RTS .C:045c AD 00 1C LDA $1C00 .C:045f 48 PHA .C:0460 29 FC AND #$FC .C:0462 8D 8C 04 STA $048C .C:0465 68 PLA .C:0466 29 03 AND #$03 .C:0468 18 CLC .C:0469 69 01 ADC #$01 .C:046b 29 03 AND #$03 .C:046d 0D 8C 04 ORA $048C .C:0470 8D 00 1C STA $1C00 .C:0473 60 RTS .C:0474 AD 00 1C LDA $1C00 .C:0477 48 PHA .C:0478 29 FC AND #$FC .C:047a 8D 8C 04 STA $048C .C:047d 68 PLA .C:047e 29 03 AND #$03 .C:0480 38 SEC .C:0481 E9 01 SBC #$01 .C:0483 29 03 AND #$03 .C:0485 0D 8C 04 ORA $048C .C:0488 8D 00 1C STA $1C00 .C:048b 60 RTS .C:048c 00 BRK .C:048d 00 BRK .C:048e AD 8D 04 LDA $048D .C:0491 C9 0A CMP #$0A .C:0493 B0 0E BCS $04A3 .C:0495 A0 00 LDY #$00 .C:0497 B9 00 06 LDA $0600,Y .C:049a 59 00 03 EOR $0300,Y .C:049d 99 00 06 STA $0600,Y .C:04a0 C8 INY .C:04a1 D0 F4 BNE $0497 .C:04a3 60 RTS >C:04a4 ea ea ea ea ea ea ea ea ........ >C:04ac ea ea ea ea ea ea ea ea ........ >C:04b4 ea ea ea ea ea ea ea ea ........ >C:04bc ea ea ea ea ea ea ea ea ........ >C:04c4 ea ea ea ea ea ea ea ea ........ >C:04cc ea ea ea ea ea ea ea ea ........ >C:04d4 ea ea ea ea ea ea ea ea ........ >C:04dc ea ea ea ea ea ea ea ea ........ >C:04e4 ea ea ea ea ea ea ea ea ........ >C:04ec ea ea ea ea ea ea ea ea ........ >C:04f4 ea ea ea ea ea ea ea ea ........ >C:04fc ea ea ea ea ....
.C:0600 A0 00 LDY #$00 ;Block decryptor for stage 3 loader .C:0602 B9 00 03 LDA $0300,Y .C:0605 AA TAX .C:0606 6A ROR A .C:0607 6A ROR A .C:0608 29 80 AND #$80 .C:060a 8D 62 06 STA $0662 .C:060d 8A TXA .C:060e 2A ROL A .C:060f 2A ROL A .C:0610 29 01 AND #$01 .C:0612 0D 62 06 ORA $0662 .C:0615 8D 62 06 STA $0662 .C:0618 8A TXA .C:0619 6A ROR A .C:061a 6A ROR A .C:061b 6A ROR A .C:061c 6A ROR A .C:061d 29 40 AND #$40 .C:061f 0D 62 06 ORA $0662 .C:0622 8D 62 06 STA $0662 .C:0625 8A TXA .C:0626 2A ROL A .C:0627 2A ROL A .C:0628 2A ROL A .C:0629 2A ROL A .C:062a 29 02 AND #$02 .C:062c 0D 62 06 ORA $0662 .C:062f 8D 62 06 STA $0662 .C:0632 8A TXA .C:0633 2A ROL A .C:0634 2A ROL A .C:0635 2A ROL A .C:0636 29 20 AND #$20 .C:0638 0D 62 06 ORA $0662 .C:063b 8D 62 06 STA $0662 .C:063e 8A TXA .C:063f 6A ROR A .C:0640 6A ROR A .C:0641 6A ROR A .C:0642 29 04 AND #$04 .C:0644 0D 62 06 ORA $0662 .C:0647 8D 62 06 STA $0662 .C:064a 8A TXA .C:064b 2A ROL A .C:064c 29 10 AND #$10 .C:064e 0D 62 06 ORA $0662 .C:0651 8D 62 06 STA $0662 .C:0654 8A TXA .C:0655 6A ROR A .C:0656 29 08 AND #$08 .C:0658 0D 62 06 ORA $0662 .C:065b 99 00 03 STA $0300,Y .C:065e C8 INY .C:065f D0 A1 BNE $0602 .C:0661 60 RTS
;Decryption state >C:0662 00 .
>C:0663 ea ea ea ea ea ea ea ea ........ >C:066b ea ea ea ea ea ea ea ea ........ >C:0673 ea ea ea ea ea ea ea ea ........ >C:067b ea ea ea ea ea ea ea ea ........ >C:0683 ea ea ea ea ea ea ea ea ........ >C:068b ea ea ea ea ea ea ea ea ........ >C:0693 ea ea ea ea ea ea ea ea ........ >C:069b ea ea ea ea ea ea ea ea ........ >C:06a3 ea ea ea ea ea ea ea ea ........ >C:06ab ea ea ea ea ea ea ea ea ........ >C:06b3 ea ea ea ea ea ea ea ea ........ >C:06bb ea ea ea ea ea ea ea ea ........ >C:06c3 ea ea ea ea ea ea ea ea ........ >C:06cb ea ea ea ea ea ea ea ea ........ >C:06d3 ea ea ea ea ea ea ea ea ........ >C:06db ea ea ea ea ea ea ea ea ........ >C:06e3 ea ea ea ea ea ea ea ea ........ >C:06eb ea ea ea ea ea ea ea ea ........ >C:06f3 ea ea ea ea ea ea ea ea ........ >C:06fb ea ea ea ea ea .....
|
|
|
Post by tlr on Feb 10, 2007 9:19:55 GMT -5
+-------------------------------------------------+ | Stage 3 loader | | | | File: | | Track=18,Sector=17 | | $a000-$a0f8 | | | | Depends: | | Drive code at $0600-$0700 from Stage 2 loader | +-------------------------------------------------+
The stage 3 loader is loaded by the stage 2 loader by reading $0300-$0400 from the drive memory. When loaded it results in:
The stage 3 loader loads the stage 4 loader/menu to $0900-$2900. The stage 3 loader is reused later by the stage 4 loader/menu to load the selected program version (ascii or color) to $2900-$9700.
>C:003e 00 a0 >C:0040 20 0d 09 >C:0043 00 09
From $CFBF and up X=$0d, Y=$09, Acc=$20 jsr $a000 jmp ($0043)
.C:a000 85 04 STA $04 ;Number of sectors. .C:a002 8E 9A A0 STX $A09A ;Track .C:a005 84 AF STY $AF .C:a007 A9 00 LDA #$00 .C:a009 8D 9B A0 STA $A09B ;Sector .C:a00c 8D 56 A0 STA $A056 ;Color .C:a00f 85 AE STA $AE .C:a011 A9 F4 LDA #$F4 .C:a013 8D 18 03 STA $0318 .C:a016 A9 A0 LDA #$A0 .C:a018 8D 19 03 STA $0319 .C:a01b A9 B0 LDA #$B0 .C:a01d 20 A8 A0 JSR $A0A8 ;Seek .C:a020 A9 80 LDA #$80 .C:a022 20 A8 A0 JSR $A0A8 ;Read T/S to drive at $0300 .C:a025 20 57 A0 JSR $A057 ;Decrypt $0300 by executing the ;$0600 code. .C:a028 AD 56 A0 LDA $A056 .C:a02b 49 02 EOR #$02 ;Toggle between black and red. .C:a02d 8D 56 A0 STA $A056 .C:a030 8D 20 D0 STA $D020 .C:a033 A0 00 LDY #$00 .C:a035 B9 00 A1 LDA $A100,Y ;Copy block to target .C:a038 91 AE STA ($AE),Y .C:a03a C8 INY .C:a03b D0 F8 BNE $A035 .C:a03d E6 AF INC $AF .C:a03f EE 9B A0 INC $A09B ;Sector .C:a042 AD 9B A0 LDA $A09B ;Sector .C:a045 C9 15 CMP #$15 ;21 .C:a047 D0 08 BNE $A051 .C:a049 A9 00 LDA #$00 .C:a04b 8D 9B A0 STA $A09B ;Sector=0 .C:a04e EE 9A A0 INC $A09A ;Track .C:a051 C6 04 DEC $04 .C:a053 D0 C6 BNE $A01B .C:a055 60 RTS .C:a056 EA NOP
.C:a057 A9 05 LDA #$05 ;Decrypt and load $0300 -> $a100 .C:a059 A2 8F LDX #$8F .C:a05b A0 A0 LDY #$A0 .C:a05d 20 DA A0 JSR $A0DA ; Send "M-E" $0600 .C:a060 A9 00 LDA #$00 .C:a062 20 67 A0 JSR $A067 .C:a065 A9 80 LDA #$80 .C:a067 8D 8C A0 STA $A08C .C:a06a 8D 81 A0 STA $A081 .C:a06d A9 06 LDA #$06 .C:a06f A2 89 LDX #$89 .C:a071 A0 A0 LDY #$A0 .C:a073 20 DA A0 JSR $A0DA ;Send "M-R" $0300 (128 bytes) .C:a076 A2 0F LDX #$0F .C:a078 20 C6 FF JSR $FFC6 .C:a07b A0 00 LDY #$00 .C:a07d 20 CF FF JSR $FFCF .C:a080 99 00 A1 STA $A100,Y .C:a083 C8 INY .C:a084 10 F7 BPL $A07D .C:a086 4C CC FF JMP $FFCC
>C:a089 4d 2d 52 00 03 80 M-R... >C:a08f 4d 2d 45 00 06 M-E.. >C:a094 4d 2d 57 06 00 02 00 00 M-W..... >C:a09c 4d 2d 57 00 00 01 00 M-W.... >C:a0a3 4d 2d 52 00 00 M-R..
Execute job: .C:a0a8 8D A2 A0 STA $A0A2 ; Store job code .C:a0ab A9 08 LDA #$08 .C:a0ad A2 94 LDX #$94 .C:a0af A0 A0 LDY #$A0 .C:a0b1 20 DA A0 JSR $A0DA ; Write T/S ($0a/$0b) .C:a0b4 A9 07 LDA #$07 .C:a0b6 A2 9C LDX #$9C .C:a0b8 A0 A0 LDY #$A0 .C:a0ba 20 DA A0 JSR $A0DA ; Write $00 with job .C:a0bd A9 05 LDA #$05 .C:a0bf A2 A3 LDX #$A3 .C:a0c1 A0 A0 LDY #$A0 .C:a0c3 20 DA A0 JSR $A0DA ; initiate read of job status .C:a0c6 A2 0F LDX #$0F .C:a0c8 20 C6 FF JSR $FFC6 .C:a0cb 20 E4 FF JSR $FFE4 .C:a0ce 48 PHA .C:a0cf 20 CC FF JSR $FFCC .C:a0d2 68 PLA .C:a0d3 30 E8 BMI $A0BD ; not done, loop .C:a0d5 C9 01 CMP #$01 .C:a0d7 D0 D2 BNE $A0AB ; not ok, loop forever. .C:a0d9 60 RTS
.C:a0da 86 02 STX $02 ;Send Disk command x/y=addr, Acc=len .C:a0dc 84 03 STY $03 .C:a0de 48 PHA .C:a0df A2 0F LDX #$0F .C:a0e1 20 C9 FF JSR $FFC9 .C:a0e4 68 PLA .C:a0e5 AA TAX .C:a0e6 A0 00 LDY #$00 .C:a0e8 B1 02 LDA ($02),Y .C:a0ea 20 D2 FF JSR $FFD2 .C:a0ed C8 INY .C:a0ee CA DEX .C:a0ef D0 F7 BNE $A0E8 .C:a0f1 4C CC FF JMP $FFCC .C:a0f4 40 RTI .C:a0f5 EA NOP .C:a0f6 EA NOP .C:a0f7 EA NOP .C:a0f8 EA NOP
|
|