mumble
One guy's collection of rants, babble, and 6502.

2012-05-03

BOOTD2.S
logo

NOTE: It took years for me to get (or emulate) hardware other than a disk][ Apple ][e, so it took years for me to realize that the following code works ONLY on ][ series that have a real disk][ controller (or equivalent). The //c and IIgs seem to have code that's much different in the $C600 slotspace.

Oh well, this ups the ante for me to make a version that works with ANY Apple or compatible!

Not that anyone else would care, but I've rewritten the evil "getting my Merlin-fu back" code so it makes more sense. I've also corrected some symbols, as I've disassembled and documented the ProDOS boot block since this stupid trick.

Furthermore, I apologize for the use of <pre>, but using nonbreaking spaces would suck more.

eslingc 20040803

********************************
*DISK][ STUPID TRICKS          *
*ESLINGC 20040803              *
*Merlin8 v2.57                 *
********************************
	 EXP	OFF
	 TR
	 TYP	$FF	;TSYS
*-------------------------------
BOOT	 = $801		;location of boot sector
PPATCH	 = $87A		;ProDOS patch addr
DPATCH	 = $84A		;DOS patch addr
BLKRDFE	 = $912		;ProDOS block reader frontend
UNIT	 = $43		;Unit (%DSSS0000) for ProDOS
RWTSLOAD = $8FE		;page byte of RWTS loader
DRV2PROM = $8636	;modify fake PROM drive byte (depends on controller!)
PROMBASE = $8600	;base for the PROM
C6PROM	 = $C600	;most everyone has slot 6
REALSLT  = $C006	;enable real slots
A1L	 = $3C		;from address for move
A2L	 = $3E		;length for MOVE
A4L	 = $42		;to address for MOVE
MOVE	 = $FE2C	;Monitor MOVE subr
*-------------------------------
* LDAD macro to reduce tedium for fixing adrs bytes
*-------------------------------
LDAD	 MAC		;load 16bit number in 2 locns
	 LDA	#<]1	;lob
	 STA	]2	;little-endian
	 LDA	#>]1	;hob
	 STA	]2+1
	 <<<		;not >>>
*-------------------------------
	 ORG	$2000	;TSYS requirement
*===============================
* relo program and setup
*===============================
	 STA	REALSLT		;ensure we're on real slots
	 LDAD	C6PROM;A1L	;from slot ROM
	 LDAD	PROMBASE;A4L	;to RAM "PROM"
	 LDAD	C6PROM+255;A2L	;len=$100
	 LDY	#0
	 JSR	MOVE		;go move it
	 LDAD	STUB;A1L	;move the stub
	 LDAD	PROMBASE+$F8;A4L ;to PROM base
	 LDAD	SEND-1;A2L	;amount of code to move
	 LDY	#0
	 JSR	MOVE	;getem
	 INC	DRV2PROM	;make PROM boot from drive 2
	 JMP	PROMBASE	;boot from drive2
*===============================
* end of relo program
* the new end of the disk][ PROM follows
*===============================
STUB				;let edasm do the relo work
	 ORG	PROMBASE+$F8	;the stub assembles at $86f8, this is also controller-dependent
	 PHA			;save A register in case of ProDOS
	 LDA	BOOT
	 CMP	#$38		;ProDOS/SOS?
	 BEQ	:PRODOS		;yes
	 LDA	#$4C		;else, assume DOS and pray
	 STA	DPATCH
	 LDAD	DOS33ENT;DPATCH+1	;jump to DOS 3.3 stub
	 PLA			;restore A register
	 JMP	BOOT		;proceed to "boot"
:PRODOS	 LDAD	PENT;PPATCH	;program loader to JSR to our stub
	 PLA			;restore A reg
	 JMP	BOOT		;(re)enter into $0801 loader
PENT	 PHP			;save proc status jic
	 LDA	UNIT		;get slot/drive
	 ORA	#%10000000	;turn on drive 2
	 STA	UNIT		;make it so
	 PLP			;get original proc status
	 JMP	BLKRDFE		;carry on to block reader
DOS33ENT LDA	RWTSLOAD	;get RWTS loader page
	 STA	:DOSP+2		;self-modify to get relocating DOSes
	 LDA	#2		;drive 2
:DOSP	 STA	$C607		;into $x707 (make sure this is a 3byte)
	 JMP	(RWTSLOAD-1)	;jump to RWTS loader
	 ORG			;apparently will return to $20xx this way
SEND				;EOF(relo code)

( link )
Stupid Apple Tricks: Boot from drive 2
logo

NOTE: The following works only with a real disk][ controller. See the source for more details.

Have you ever owned an Apple ][ series computer? Ever do stupid, yet highly amusing stuff with it? I have, just to (re)learn my machine.

I. Booting from drive 2

Ok, I admit I hadn't had much sleep the previous night, but when I woke up, I thought, "Hrrrmm... what if I could boot from drive 2?" So the disassembling of PROMs and stuff began. Herein is a howto.

Altering the boot PROM

In order to boot drive 2, you must somehow activate drive 2. The following snippet is from the Cx00 PROM for the disk][ controller:

*C62FL

C62F-   BD 8E C0    LDA   $C08E,X
C632-   BD 8C C0    LDA   $C08C,X
C635-   BD 8A C0    LDA   $C08A,X    ;THIS IS THE DRIVE ACTIVATOR
C638-   BD 89 C0    LDA   $C089,X    ;MOTOR ON

The X register has the slot number*16 in it on entry to these instructions. The byte at $C636 needs to be changed to 8B in order to make drive 2 active, however. So, we move the entire $C6 page to another $x600 location. The location MUST be at $xs00, tho, where x will be "4" in my example, and s is the slot number ("6" in most apples), hence, we will "move" the PROM to $4600 with this command:

*4600<C600.C6FFM

There. We now have a writable "PROM." Let's make drive 2 be active:

*4636:8B

The "PROM" in RAM will now boot off of drive 2... for the FIRST sector.

The reason our fake PROM needs to be at $xs00 is because of this code:

*C621L

C621-   20 58 FF    JSR   $FF58     ;"GUARANTEED" RTS
C624-   BA          TSX             ;RETRIEVE PAGE WE'RE ON
C625-   BD 00 01    LDA   $0100,X   ;FROM THE STACK
C628-   4A          ASL             ;MULTIPLY PAGE BY 16
C629-   4A          ASL             ;TO GET SLOT*16
C62A-   4A          ASL
C62B-   4A          ASL
C62C-   85 2B       STA   $2B       ;SAVE OFF IN ZP

Woz pulled nifty "latent stack byte" tricks to get our slot number. Mmmmmm, hackery.

Making DOS use drive 2

If we were to try booting our fake PROM at this point, we'd succeed in loading track 0, sector 0 off of drive 2. We'd also get any sectors the boot sector loads until the loading routine for DOS 3.3 assumes we're on drive 1! for DOS 3.3, we get 9 sectors loaded at $B700 (this is all of RWTS, I believe) so that it can load the rest of DOS using the "read group of pages" routine found at $B793.

Our area of interest starts at $B700, where the $801 loader jumps, oddly enough:

*B700L

B700-   8E E9 B7    STX   $B7E9     ;SLOT*16 IN X, GOES INTO IOB
B703-   8E F7 B7    STX   $B7F7     ;"LAST ACCESSED" SLOT*16
B706-   A9 01       LDA   #$01      ;ASSUME DRIVE 1
B708-   8D F8 B7    STA   $B7F8     ;INTO IOB
B70B-   8D EA B7    STA   $B7EA

We need to change the byte at $B707 to $02 to make DOS use drive 2.

Making PROM stubs

Normally, this wouldn't be so involved. However, there exist diskettes on which there resides a relocatable DOS that loads in at $1600-$3FFF, getting relocated up to $9600 for your 64k apple. This makes for an interesting situation. Booting relocatable DOS without providing for it will result in an unspectacular crash. Therefore, we must find out where the DOS loaded up. This is rather easy, as the byte at $08FE contains the page location of our RWTS loader at $B700 for a 64k fixed DOS. This is constant, no matter what DOS 3.3 you're booting, so we can use that byte to modify our "PROM" stub detailed below.

Making the PROM modify things

The following original instructions must be modified:

46F8-   4C 01 08    JMP   $0801     ;JUMP TO 2ND STAGE LOADER
084A-   6C FD 08    JMP   ($08FD)   ;JUMP TO DOS RWTS LOADER

The code at $084A is simple. Our PROM will modify this line to be:

084A-   4C 0A 47    JMP   $470A     ;JUMP TO PROM STUB

The stub code that replaces the instruction at $46F8 and would otherwise run into the next slot is this:

46F8-   A9 4C       LDA   #$4C      ;JMP
46FA-   8D 4A 08    STA   $084A     ;MODIFY $0801 LOADER
46FD-   A9 0A       LDA   #$0A      ;$470A
46FF-   8D 4B 08    STA   $084B
4702-   A9 47       LDA   #$47
4704-   8D 4C 08    STA   $084C
4707-   4C 01 08    JMP   $0801     ;PROCEED TO $0801 LOADER NOW
470A-   AD FE 08    LDA   $08FE     ;PAGE BYTE OF LOADED RWTS
470D-   8D 14 47    STA   $4714     ;SELF-MODIFY DRIVE BYTE LOCATION
4710-   A9 02       LDA   #$02      ;DRIVE 2
4712-   8D 07 00    STA   $0007     ;STORE IN $XX07
4715-   6C FD 08    JMP   ($08FD)   ;JUMP TO RWTS LOADER

The stub above will modify the $0801 loader to jump back within the stub, then execute the $0801 loader. After loading RWTS, the stub will self-modify where to place the drive byte depending on the page byte of the loaded RWTS in $08FE. Once that info is filled in, the indirect jump to the RWTS loader fakes any normal DOS 3.3 into booting completeely and correctly from drive 2.

Assuming you booted DOS from drive 1 and typed this all in, you can save your work:

*BSAVE BOOTD2.DOS33,A$4600,L$118

This code can be BRUN safely because it never RTS's to anything.

Booting from drive 2 using ProDOS

As the source shows, booting from drive 2 using ProDOS is possible, but a tad trickier. For ProDOS, the boot block is actually 2 sectors long. We need a convenient place to jump to our stub and modify the UNIT byte at $43 before anything happens. There's a JSR at $0879 that will let us do our magic. We modify this to jump to our "stub":

0879-   20 12 09    JSR   $0912     ;READ A BLOCK

For ProDOS, indicating drive 2 is easier than for DOS 3.3 in that no code in the PRODOS image needs to be hacked. All we need to do is flip the high bit of the ProDOS temporary Unit number (stored at $43) on to indicate drive 2, and the boot loader and PRODOS take care of the rest:

PENT    PHP                 ;save proc status jic
        LDA     UNIT        ;get slot/drive
        ORA     #%10000000  ;turn on drive 2
        STA     UNIT        ;make it so
        PLP                 ;get original proc status
        JMP     BLKRDFE     ;carry on with block read

This, combined with the common task of making a fake "PROM" and hacking it, enables ProDOS to boot from drive 2.

The Source

The source takes care of booting either DOS 3.3 or ProDOS from a single binary. It's designed to assemble in the ProDOS version of Merlin, though you could conceivably assemble it in DOS 3.3 if you hack the TYP op out. Porting it to other assemblers could be tricky (it's not too hard to port to EDASM, though the "relocation" trick I (ab)use in Merlin may gum the works.).

Happy Hacking.

( link )
Why I chose the Apple][
logo

When I first saw a computer, it was an Apple][(+?) ... Also, the first computer I'd ever programmed for was an Apple][(+/e). Those reasons alone aren't why I stuck with it, however. Set your watch to October of 1986.

I'd been in my first computer class in HS which I was truly interested in. This evening, we went to the public library to get an orientation on their computers, which happened to be a ][e and a ][+. To prove that I was green about computers in general, I'd brought my TRSDOS-formatted floppies in and asked the caretaker to try booting one. Naturally, it failed.

I took the simple test and got my orange dot on my library card anyway. This was the beginning of loads of tube time on these two machines.

I started out by running a few of the BASIC programs off the System Master, then LISTing them to see how they worked. I had no clue (back then) how a "CALL 2080" made the Apple do all that nifty shit (in this case, it did a CATALOG, then let you select what actions to perform on the file). I had no clue about anything Apple. What I DID have, however, was access to loads of documentation on these machines!

Thanks to having the docs, I taught myself FPBASIC, a bit of INTBASIC, and most importantly, 6502 assembly language. I'd also gotten proficient in doing things with the disk -- sector editing, CopyII+ parm file hacks, hacking DOS with nothing more than a well-worn copy of _Beneath Apple DOS_, getting into ProDOS, etc... There wasn't as much documentation as I needed, but I got good results with what I had and what I reverse-engineered on my own, so that made me stick with it.

Contrast this to the TRS-80 Model III I'd been working on that first year. Sure, I had a GWBASIC-like reference available, and used it... but by the end of the year, I'd had a taste of assembly language, and there was no TRS-80 memory map, no Z80 instruction set (hell, I didn't even KNOW what CPU was used in the TRS-80 back then), no docs of which locations were special for TRSDOS or the TRS-80 in general... none of that! All of this was available to me for the Apple, or I could find out if I really needed it.

Many years later -- and despite the fact that I'd thrown most of my best docs in the rubbish bin right after I'd drank an excess of Stupid -- I can still find out what I need to know about the Apples I have. Yes, I still use the Apple today.

I'm currently working on some ROM enhancements to the Apple][e... it's going pretty good, but I find that enhancing one piece breake another...

Did I mention that, even though I'd been using an Apple in some way since 1984, I still learn new things about it today?

( link )

2011-09-27

The Apple Section will be back
logo

In an act of simplification, I've decommissioned the old content manager that drove the mumble, and with that, the old posts in the Apple II section disappeared. They will appear here momentarily.

( link )

2011-09-23

This is a test of subdirs
logo

More filler and testing stuff. Wonder how this will present itself.

( link )

I got yer can Home