*************************************************************************** * / * * _____.__ _ .___. * * / /_____________. _________.__________.________ | |________ * * ___/____ / ____|_/ | /| \\| ._ / * * \\ \\/ \\ \\ \\ / | :___/?| \\ \\ |/ / * * \\_____________\\___/_____/___/_____|____| |____|\\_____________/ * * -========================/===========|______\\================- * * * * .---.----(*( HARDWARE TRACKLOADER )*)---.---. * * `-./ \\.-' * * (c)oded by StingRay * * -------------------- * * August 2007 * * * * SPECIAL "PLEASE NEW ZEALAND'S BEST" RELEASE * * * *************************************************************************** ; trackloader coded by stingray for www.flashtro.com ; 10/11/12-Aug-2007 ; ; thanks to Cr?xshadows, :Wumpscut:, Das Ich, Funker Vogt, [:SITD:], ; God Module, Suicide Commando, etc. for music while coding this :) *************************************************** *** HISTORY *** *************************************************** ; 16-Aug-2007 - special "please New Zealand's best" release ; - checksum checks added, increases loadersize to 530 ; bytes, it's off by default, enable it by setting ; LD_CHECKSUM to 1 ; - according to New Zealand's best, this loader is ; "extremely limited and buggy". So better use ; a loader coded by New Zealand's best. Good luck ; finding one. ;) If you should find one, better check ; the size of the mfm buffer in that very loader then ; as New Zealand's best has quite a complicated and ; very special approach to calculate mfm buffer ; sizes. At least it's too complicated for me because ; I can't see that my MFM buffer size is too small but ; if New Zealand's best says it is, then it is! ; 13-Aug-2007 - due to a bug the fast "step to next track" routine ; is gone (happened when the loader was called multiple ; times), using LD_StepToTrack again, loader is 30 ; bytes smaller now and works reliable as added bonus :) ; - optimized the size a bit more, LD_CURRENTRACK is now ; d5, loadersize is 494 bytes now :) ; - boundary check in the mfm decoder improved, if ; end is reached, it simply exits, no need to decode ; another sector then :) ; - current loadersize (safety off): 494 bytes ; - quick and dirty bugfix, loader didn't work correctly ; if # of bytes to skip was >512bytes, for now this ; quickfix should do (uses 512*11 bytes memory, guess why), ; might do a better fix later ; 12-Aug-2007 - missing cia timers implemented ; - rasterline timing removed as it's not easy ; to implement without a lot of changes due to the ; way current cia timing is implemented, doesn't ; matter anway as there are 4 selectable CIA timers, ; should be more than adequate ; - instead of using LD_StepToTrack a much simpler ; and faster routine is used to step to the next ; track now, increases loadersize but also the speed :) ; - forgot to set error code in LD_DriveReady, wrong ; error returned if the drive actually DID clear the ; DSKRDY bit :) ; - fixed timeout in LD_LoadTrack, apparently 5ms was ; way too short, timeout value is now 20*50=1000 ms=1sec ; - added LD_SAFETY, if enabled some error checks are ; performed ; - doesn't trash any bytes (max. 3) at the end of the buffer ; anymore ; - offset logic fixed, everything seems to work fine now ; - size optimized LD_DriveOn and LD_StepToTrack ; - some hours later: should work with start offsets ; that are not a multiple of 4 now, slows down mfm decoding ; quite a bit because of the needed checks and writing ; bytes only instead of longs, could be made faster ; with special case code but that would enlarge the loader ; and it's big enough already (558 bytes), at least ; there should be no memory trashing at all anymore and ; it should work with all offsets/lengths ; - some minutes later: 'FUCK IT' I say! :) Got sick of that ; fucked up innerloop, I now use the MFM buffer as ; temporary buffer and copy it afterwards to the real ; address, a lot faster, a lot shorter and only uses ; 512 bytes more memory :) ; 11-Aug-2007 - added the loader part ; - some bugfixes and size optimizing ; - first working version ; - offset logic wrong, trashes 2 bytes ; - drive check improved, split into 2 different ; routines now (LD_DriveOn, LD_DriveReady) ; after the 500ms timer is expired, a read attempt ; is performed to check if the drive is available/ready ; - added timeout check in LD_LoadTrack, if no IRQ signal ; is received within 5ms an error is returned, according ; to the HW manual, max. time needed to get to the ; next track is 3ms so 5ms is more than enough time ; - split the timer routines in LD_StartTimer, ; LD_CheckTimer and LD_WaitTimer ; 10-Aug-2007 - started coding ; - cia timers, step to track, selectable drives, ; no actual loading/mfm decoding yet IF 0 ; example code, change 0 to 1 to assemble it SECTION CODE,CODE_c TEST move.w #$4000,$dff09a lea BUFFER,a0 ; destination lea MFM,a1 ; mfm buffer moveq #0,d0 ; start offset in bytes move.l #100000,d1 ; length in bytes moveq #1,d2 ; drive to use jsr LOADER lea BUFFER,a0 ; destination ;lea MFM,a1 ; mfm buffer move.l #80*11*512,d0 ; start offset in bytes move.l #200000,d1 ; length in bytes moveq #1,d2 ; drive to use jsr LOADER lea BUFFER,a0 ; destination ;lea MFM,a1 ; mfm buffer move.l #40*11*512,d0 ; start offset in bytes move.l #200000,d1 ; length in bytes moveq #1,d2 ; drive to use jsr LOADER move.w #$c000,$dff09a rts BUFFER dcb.l 200000/4,"STR!" dcb.l 1024/4,"STR!" MFM dcb.l $2400/2,"MFM!" MFMEND dcb.l $2400/2,"END!" ENDC ; internal constants, don't touch LD_TIME3MS = 2148 ; 3000/1.3968255 LD_TIME5MS = 3580 ; 5000/1.3968255, LD_TIME18MS = 12886 ; 18000/1.3968255, after reversing dir LD_NODRIVE = 1 ; drive not accessible LD_READERROR = 2 ; timeout while reading track LD_OUTOFBOUNDS = 3 ; requested offset/length out of bounds LD_CRCERROR = 4 ; checksum error LD_CIAA_A = 1 ; cia a, timer a LD_CIAA_B = 2 ; cia a, timer b LD_CIAB_A = 3 ; cia b, timer a LD_CIAB_B = 4 ; cia b, timer b ; these are the ONLY user changeable settings LD_USECIA = LD_CIAB_A ; which timer to use, look above LD_SAFETY = 0 ; set to 1 for more safety, e.g boundary ; checking, increases loadersize LD_CHECKSUM = 0 ; set to 1 to enable checksum check ******************************************* *** TRACKLOADER *** ******************************************* ; a0.l: load address ; a1.l: mfm buffer (only once, $2400 words) ; d0.l: offset (bytes, 0-160*11*512) ; d1.l: size (bytes, 0-160*11*512) ; d2.w: drive (0-3) ;------ ; d0.l: error code (0 = no error) LOADER movem.l d1-a6,-(a7) lea $dff000,a6 lea $bfd100,a5 lea LD_VARS(pc),a4 tst.l LD_MFM(a4) ; mfm buffer already set? bne.b .mfmok move.l a1,LD_MFM(a4) .mfmok IFNE LD_SAFETY move.l d1,d4 sub.l d0,d4 cmp.l #160*11*512,d4 ble.b .ok moveq #LD_OUTOFBOUNDS,d0 bra.b .error ENDC .ok lea (a0,d1.l),a3 ; end of buffer move.l d0,d4 divu.w #512*11,d4 move.w d4,d5 ; LD_CURRENTTRACK(a4) swap d4 ; number of bytes to skip addq.b #3,d2 bsr.b LD_DriveOn ; select drive bsr.b LD_DriveReady ; selected drive ready? tst.l d0 beq.b .driveok moveq #LD_NODRIVE,d0 ; return correct errorcode :) bra.b .exit .driveok .loop bsr.b LD_StepToTrack ; move stepper motor to start track bsr.w LD_LoadTrack ; load and decode track tst.l d0 ; error? bne.b .exit bsr.w LD_DecodeTrack IFNE LD_CHECKSUM tst.l d0 bne.b .exit ENDC addq.w #1,d5 cmp.l a0,a3 bhi.b .loop moveq #0,d0 ; no error .exit bsr.b LD_DriveOff ; switch off drive .error movem.l (a7)+,d1-a6 rts ******************************************* *** DRIVE HANDLING ROUTINES *** ******************************************* ; d2.b: drive LD_DriveOn moveq #$7d,d1 ; deselect all drives bra.b LD_DriveSet ; d2.b: drive LD_DriveOff moveq #-3,d1 ; move.b #$fd,d1 LD_DriveSet move.b d1,(a5) bclr d2,d1 move.b d1,(a5) rts ; waits for DSKRDY bit to go low or a 500ms timer to expire ; after that, a read attempt is performed to check if the ; drive is available ; ; required because there are drives (f.e. some external drives, ; hello Mr.Spiv :D or the crappy drives in the Escom Amigas ; without the floppy fix (which btw is also a shitload of ; crap because it never switches off the drive motor!)) ; that don't ever clear the DSKREADY bit LD_DriveReady moveq #10-1,d7 .loop move.w #LD_TIME5MS*10,d0 ; 50 ms bsr.b LD_StartTimer .check btst #5,$bfe001-$bfd100(a5) beq.b .motorok bsr.b LD_CheckTimer beq.b .check dbf d7,.loop ; 10*50ms ; no DSKREADY signal within 500ms, try to read a track ; to check if drive is ready bra.w LD_LoadTrack .motorok moveq #0,d0 ; no error rts ******************************************* *** TIMER ROUTINES *** ******************************************* IFEQ LD_USECIA-1 ; CIA A, TIMER A ; d0.w: time in ms LD_StartTimer move.b #1<<3,$bfee01-$bfd100(a5) ; set one-shot mode move.b d0,$bfe401-$bfd100(a5) ; set timerA low byte lsr.w #8,d0 move.b d0,$bfe501-$bfd100(a5) ; set timerA high byte and start timer rts ; returns timer status (z-flag set: timer still running) LD_CheckTimer btst #0,$bfed01-$bfd100(a5) ; wait for timerA interrupt rts ELSE IFEQ LD_USECIA-2 ; CIA A, TIMER B ; d0.w: time in ms LD_StartTimer move.b #1<<3,$bfef01-$bfd100(a5) ; set one-shot mode move.b d0,$bfe601-$bfd100(a5) ; set timerB low byte lsr.w #8,d0 move.b d0,$bfe701-$bfd100(a5) ; set timerB high byte and start timer rts ; returns timer status (z-flag set: timer still running) LD_CheckTimer btst #1,$bfed01-$bfd100(a5) ; wait for timerB interrupt rts ELSE IFEQ LD_USECIA-3 ; CIA B, TIMER A ; d0.w: time in ms LD_StartTimer move.b #1<<3,$e00-$100(a5) ; set one-shot mode move.b d0,$400-$100(a5) ; set timerA low byte lsr.w #8,d0 move.b d0,$500-$100(a5) ; set timerA high byte and start timer rts ; returns timer status (z-flag set: timer still running) LD_CheckTimer btst #0,$d00-$100(a5) ; wait for timerA interrupt rts ELSE IFEQ LD_USECIA-4 ; CIA B, TIMER B ; d0.w: time in ms LD_StartTimer move.b #1<<3,$f00-$100(a5) ; set one-shot mode move.b d0,$600-$100(a5) ; set timerB low byte lsr.w #8,d0 move.b d0,$700-$100(a5) ; set timerB high byte and start timer rts ; returns timer status (z-flag set: timer still running) LD_CheckTimer btst #1,$d00-$100(a5) ; wait for timerB interrupt rts ENDC ENDC ENDC ENDC ; simply waits for the timer to expire LD_WaitTimer .wait bsr.b LD_CheckTimer beq.b .wait rts LD_Wait18ms move.w #LD_TIME18MS,d0 LD_Timer bsr.b LD_StartTimer bra.b LD_WaitTimer ******************************************* *** STEP TO ACTUAL TRACK *** ******************************************* LD_StepToTrack tst.b LD_INITFLAG(a4) bne.b .noinit bsr.b LD_MoveToTrack0 ; move to track 0 for orientation st LD_INITFLAG(a4) .noinit bclr #1,(a5) ; default direction = inwards bset #2,(a5) ; default side: 0 move.w LD_LASTTRACK(a4),d0 move.w d5,d1 lsr.w #1,d0 ; /2 because we have 2 sides/track lsr.w #1,d1 bcc.b .sideok bclr #2,(a5) ; odd track, side is 1 .sideok sub.w d0,d1 beq.b .exit ; already at correct track bgt.b .step neg.w d1 ; we need positive loopcounter bset #1,(a5) ; direction = outwards .step bsr.b LD_Step subq.w #1,d1 bne.b .step move.w d5,LD_LASTTRACK(a4) .exit rts LD_MoveToTrack0 .loop btst #4,$e001-$d100(a5) ; already on track0? beq.b .ok ; yes, nothing to do bset #1,(a5) ; direction = outwards bsr.b LD_Step ; step one track bra.b .loop .ok clr.w LD_LASTTRACK(a4) rts LD_Step bclr #0,(a5) ; set step signal bset #0,(a5) ; clear step signal bra.b LD_Wait18ms ; wait for steppermotor to finish ******************************************* *** LOAD AND DECODE ONE TRACK *** ******************************************* ; a0: destination ; a3: end of buffer ; d4: offset ;---- ; d0: error code (0: no error) ; split into 2 parts because of the drive check LD_LoadTrack move.w #1<<15|1<<4,$96(a6) ; enable disk dma move.w #~(1<<15)&$ff00,$9e(a6) ; clear adkcon (just to be sure) ; set fastmode (mfm), wordsync, mfmprec, no precomp move.w #1<<8|1<<10|1<<12|1<<15,$9e(a6) move.w #$4000,$24(a6) move.w #$4489,$7e(a6) move.w #1<<1,$9c(a6) ; clear disk irq move.l LD_MFM(a4),a1 move.l a1,$20(a6) move.w #1<<15+$1900,$24(a6) move.w #1<<15+$1900,$24(a6) bsr.b .timer moveq #20,d3 ; 1s, should be more than enough .waitDMA move.w $1e(a6),d1 btst #1,d1 bne.b .done bsr.w LD_CheckTimer beq.b .waitDMA bsr.b .timer ; reload timer subq.w #1,d3 bne.b .waitDMA moveq #LD_READERROR,d0 ; timeout! bra.b .error .done moveq #0,d0 ; no error .error move.w #$4000,$24(a6) move.w #1<<4,$96(a6) ; disable disk dma rts .timer move.w #LD_TIME5MS*10,d0 ; 50ms bra.w LD_StartTimer ; decode mfm ; a0: destination ; a1: mfm buffer ; a3: end of buffer ; d4: offset LD_DecodeTrack IFNE LD_CHECKSUM movem.l d2/d5/a5,-(a7) ; save ELSE move.l a5,-(a7) ENDC lea $1900*2(a1),a5 ; temp move.l #$55555555,d3 moveq #0,d7 .secloop move.l a1,a2 .getsync cmp.w #$4489,(a2)+ bne.b .getsync cmp.w #$4489,(a2) beq.b .getsync ; get info data movem.l (a2),d0/d1 bsr.b .decode lsr.w #8,d0 ; d0: sector number cmp.w d0,d7 ; are we on the correct sector? beq.b .sectorok lea $440-8(a2),a2 bra.b .getsync .sectorok ; calc checksum IFNE LD_CHECKSUM movem.l $38-8(a2),d0/d1 bsr.b .decode move.l d0,d5 ; save moveq #0,d2 ; checksum for this sector ENDC lea $40-8(a2),a2 ; point to data moveq #512/4-1,d6 .loop move.l 512(a2),d1 ; data (even) move.l (a2)+,d0 ; data (odd) IFNE LD_CHECKSUM eor.l d0,d2 eor.l d1,d2 ENDC bsr.b .decode move.l d0,(a5)+ dbf d6,.loop IFNE LD_CHECKSUM moveq #LD_CRCERROR,d0 and.l d3,d2 cmp.l d2,d5 bne.b .crcerror ENDC addq.w #1,d7 cmp.w #11,d7 blt.b .secloop lea $1900*2(a1),a5 add.w d4,a5 move.w #512*11,d0 sub.w d4,d0 ; # of bytes to copy .copy cmp.l a3,a0 bge.b .exit move.b (a5)+,(a0)+ subq.w #1,d0 bne.b .copy moveq #0,d4 ; next track starts at the beginning .exit IFNE LD_CHECKSUM moveq #0,d0 ; no errors ENDC .crcerror IFNE LD_CHECKSUM movem.l (a7)+,d2/d5/a5 ELSE move.l (a7)+,a5 ENDC rts .decode and.l d3,d0 and.l d3,d1 add.l d0,d0 ; <<1 or.l d1,d0 rts LD_VARS RSRESET LD_MFM rs.l 1 ; ptr to mfmbuffer LD_LASTTRACK rs.w 1 ; last track LD_INITFLAG rs.b 1 ; $ff: init done rs.b 1 ; padding LD_VARS_SIZEOF rs.b 0 dcb.b LD_VARS_SIZEOF PRINTT PRINTT "LOADERSIZE:" PRINTV *-LOADER PRINTT
Bad Brothers – Music Line Editor
Publication author offline 12 hours mus@shi9 0 Comments: 1166Publics: 2810Registration: 06-03-2017
very entertaining indeed 🙂
thanks for sharing your work StingRay
codetapper please criticize in a more constructive way
Having one just now.. cheers!
-sigh- I tried! 🙂
soo whos up for a beer ? heh
StingRay: Do you think the 300 odd installs I have released installed themselves? No skills, my arse. I declined your offer because you made it into a pointless exercise. You wanted to rewrite WHDLoad and make a cracktro. You have probably made 50 cracktros in advance and I admit I haven’t made any, so that’s a ridiculous thing to add to a challenge. As for writing a HD installer without WHDLoad, I told you that was also an exercise in stupidity as there is an amazing tool out there that does all the annoying stuff for you and lets you… Read more »
Thank you TCB, I already offered such a challenge to Codetapper. 😉 But as he is just someone with a big mouth and absolutely no skills he declined the offer. Make of that what you will. I won’t offer such challenge again because I don’t need any more proof that it would be wasted time. And it’s not me who has issues here, if you check this thread you’ll see who of us desperately wants to find something to blame on me even if it’s something as ridiculous as an icon. 😉 But I agree, it is indeed entertaining, I… Read more »
Guys – as much as this is amusing to read, but you both have some serious issues 🙂 Here are 2 adults debating about performing the art of cracking 20-year old software. If you want a real competition, make it measurable. E.g. you both make some time available (say 48hrs) and at a set time, a jury of your peers will give you an original that you need to: – Crack & fix future-proof – Train with as many options you can come up with – Make a hd-version Along with the original, your jury shall outline the rules &… Read more »
Haha you are so ridiculous dear Codetapper, complaining about an icon which was not even done by me. Oh dear.. So, dear Codetapper, how many of your installs could you have done without Mr.Larmer’s Copylock decoder? And about this "I know what I am doing", you don’t know ANYTHING except for how to talk BS, sad but true. Remember my Jonathan install? You slagged it off even though you didn’t have any clue at all what you were talking about. And the best proof that you don’t know anything is this thread, may I remind you a bit? 1. "From… Read more »
Well 300 odd WHDLoad installs shows I know what I’m doing, you’ve still only released a single fix so it’s a bit of a joke to say I don’t know what I’m doing.
Nice icon in the Pango install btw. Quality. Must have spent hours on that default JPEG icon.
I second TCB and Galahad -YAWN- 🙂 Just one last note to Codetapper, don’t twist the facts, YOU started this crap with your utterly unqualified comments on EAB. Everyone can check that and see your utterly clueless posts there as well. Like you blamed me for a workaround I had to code for a slave because of a limitation in WHDLoad and you also had nothing better to do than to boast how "it’s a quality fix" I made even though you didn’t have ANY clue what you were talking about. You are just someone with an ?berego, too bad… Read more »
-yawn…-
It is pointless to reinvent the wheel. There is a perfectly good loader out there by Rob, used in over 500 games so why not use it? Spend your time doing something useful, like writing a game rather than another loader! You also wanted to rewrite the equivalent of WHDLoad, again I don’t see the point.
And just remember it was you that started all this crap with your stupid comments in that tutorial about checksums.
Oh btw, what’s it with your secret love affair with Rob Northen? (Sorry Rob ;D) Apparently you believe the only one in the world who is/was able to code a good loader was Mr.Northen. It is a good loader, no doubt, but if that means in your world there can’t be any better you again show how much of a newbie you are. But then again, you seem to like to be dependent on others so nothing new here. I don’t claim my loader is any better than Rob Northen’s but it works (for me, if others have problems with… Read more »
Ok Codetapper, as usual you don’t comment about YOUR faults in any way, instead you keep going on boasting and I still find it utterly amusing. First of all, who said this is a tutorial? Me? So again, one totally useless comment from you. Next one, sector decoding, I really don’t know what you are going on about. I check on which sector I am and decode that one then. As Mr.Spiv said, it’s not the most efficient way and I am well aware of that. And that someone who is not even able to calculate MFM buffer sizes and… Read more »
ahhh… codetapper, if your a kiwi, then be cool, cuz we all know the aussies are wankers, but im a kiwi, so please represent New Zealand highly, or state that your really Australian.
Nothing wrong with the sector and track decoding.. the code just scans the MFM buffer 11 times and decodes sectors in correct order into the temp buffer. Might not be the most efficient way but works.
I personally would rather load a track of data, perform the checksum, find that it’s incorrect, and reload the track, bailing out with an error. StingRay seems to prefer load the track, the data is corrupt, the user will know it’s corrupt because the program crashes. Great attitude! Or was that last listing more beta software that you release, and because it’s beta, it’s allowed to crash? Have you ever heard of graceful degradation? A famous person once said the most elegant piece of code can be ruined by error trapping. As for the other major problem, do you actually… Read more »
Updated the loader to a "please New Zealand’s best" version. You can have checksum checks now if you want. Doesn’t matter that the game/demo won’t work correctly if checksums are wrong anyway and that the checksum checks increased the loadersize to 530 bytes I suppose, I do all to please New Zealand’s best. 🙂
No problem for me, I never started this in the first place anyway. 🙂
Can you just shake hands and make up?
Now now boys – be nice to eachother! 🙂
And thanks for your "1" rating.:) That makes me smile even more.:) All I can say is "The MFM buffer is too small". That really shows how much you know about coding. You just scored world’s best own goal and made the "old son who’s too lazy to get back to the drawing board" burst out in laughter. Thank you, you really made my day.:) Oh, and could you elaborate a bit on this "it won’t work in many cases where the first valid data is quite far into the MFM buffer." nonsense? And as you have coded so many… Read more »
Haha, thanks for your nice words, I knew if someone would have something to say it would be you, worlds best cracker, coder and hd fixer who can nothing but complain about utterly useless things like missing version checks in BETA slaves and stuff like that. 🙂 Then again, it’s hilarious. 🙂 I might tell you that I left out checksum checks on purpose, that I don’t know why you are saying the mfm buffer is too small and furthermore, I DID crack more than just one game in my time so I don’t understand that comment either. Then again,… Read more »
You have outdone yourself StingRay – this loader is even worse than those buggy patches you uploaded on EAB! If you had cracked a few games in your time, you might have picked up on some of the faults. This loader is extremely limited and buggy. From the parameters it looks like you can load data from any offset, but in fact you’re forced to load on track boundaries. There are no checksums at all (hopeless!), the MFM buffer is too small, it won’t work in many cases where the first valid data is quite far into the MFM buffer.… Read more »
Thanks. 🙂 I really hope you do, hopefully this loader motivates you a bit. =)
Nice one Sting, I’ll be sure to use it if I ever finish a crack 🙂
uploaded an updated version, fixed a bug in the mfm decoder.
Yup, I was bored. 😀 It should even work on your drives, Spivster. 😛 At least it shouldn’t lock up. 🙂
"August 2007".. new skool :sly
Kudos for the 500ms driveon delays 😀
good work sting!