; conv.dis - disassembly of Convergent Technologies Miniframe Boot ROM's ; ; This is the "B" rom set (there is another set called "A" - newer ?) ; ; Annotation begun 8/14/89 T. Trebisky ; ttrebisky@as.arizona.edu ; 0x800000: 00005f00 ; Stack pointer 0x800004: 00800024 ; PC 0x800008: 008003f0 ; Initialize disk 0x80000c: 008006a2 ; Read 0x800010: 0080068a ; Write 0x800014: 00800696 ; Format 0x800018: 00800398 ; Find superblock pointer 0x80001c: 008003e4 ; Recalibrate and initialize disk 0x800020: 0 ; OK here we go, first write to the GCR (0x450000), turning off all 4 LED's, ; disable bus-errors, and turn off the ROM bit to allow access to RAM ; ; GCR is just the high 8 bits: EPER4310-------- ; E = 1 enables NMI and BERR interrupts ; P = 1 enables Parity error interrupts ; E = 0 is even parity ( 1 = odd is normal ) ; R = 0 forces ROM access (hides RAM), system boots up this way ; 4310 = set low to turn on corresponding LED (0 is bottom, near connectors) 0x800024: movw #0x3f00,0x450000:l ; Now initialize the "system" 8253, The idea is to keep track of lost time ; in the boot ROM so as to keep system clock up to date. ; Notice that the 8253 is slow and cannot be accessed on successive cycles, ; this is the reason for the "nop" instructions between accesses. ; ; 0x74 = CW for counter 1 - lsb then msb, Mode 2 binary ; 0xb6 = CW for counter 2 - lsb then msb, Mode 3 binary ; ; The 8253 has 3 counter/timers, Timer 0 is not used here (but can be ; programmed to interrupt as "fast timer" on 8259 priority 4). ; Timer 0 and 1 are fed a 76,800 Hz clock (REFCLK), having Timer 1 divide ; it by 500 hex (1280) yields a 60 Hz output which can be enabled to be ; a level 6 autovector. This output is fed to Counter 2, which just counts ; the ticks and can be read by software, it's output is not connected anywhere. 0x80002c: movw #0x74,0xc00006:l 0x800034: nop 0x800036: movw #0xb6,0xc00006:l 0x80003e: nop ; Load 8253 counter 2 with zeros 0x800040: clrw 0xc00004:l 0x800046: nop 0x800048: clrw 0xc00004:l 0x80004e: nop ; Load 8253 counter 1 with 0x0500 0x800050: movw #0,0xc00002:l 0x800058: nop 0x80005a: movw #5,0xc00002:l ; Initialize the first 6 Map registers, each one maps a 4K page (0-fff) ; so this establishes a transparent mapping for 0-5fff (including the stack). 0x800062: movw #0x2000,0x400000:l 0x80006a: movw #0x2001,0x400002:l 0x800072: movw #0x2002,0x400004:l 0x80007a: movw #0x2003,0x400006:l 0x800082: movw #0x2004,0x400008:l 0x80008a: movw #0x2005,0x40000a:l ; Save the processor registers (to 0-03f) 0x800092: moveml d0-d7/a0-a7,0:l ; Save GSR to 40-41 ; Save BSR0 to 42-43 ; Save BSR1 to 44-45 0x80009a: movl #0x40,a0 0x8000a0: movw 0x410000:l,a0@+ 0x8000a6: movw 0x430000:l,a0@+ 0x8000ac: movw 0x440000:l,a0@+ ; Save Map registers, 000 (0x400000) to 46-47 ; 3FF (0x4007fe) to 844-845 0x8000b2: movl #0x400000,a1 0x8000b8: movl #0x3ff,d0 0x8000be: movw a1@+,a0@+ 0x8000c0: dbra d0,0x8000be ; copy CDT (Crash Data Table) to 846-8c5 ; Odd, it looks like 3f8 is a location in the page table just copied, ; but why is it used as a long pointer, that would grab two successive ; table entries and use them as a pointer (??!) ; At any rate, 0x20 long entries (0x80 = 128 bytes) get moved to 846-8C5. 0x8000c4: clrw 0x420000:l ; clear CSR 0x8000ca: movl 0x3f8:l,d0 0x8000d0: bclr #0,d0 0x8000d4: movl d0,a1 0x8000d6: movl #0x1f,d0 0x8000dc: movl a1@+,a0@+ 0x8000de: dbra d0,0x8000dc ; check CDT for proper CDT signature ( 'EPJR' ) ; if signature is wrong, assume power-up reset boot 0x8000e2: clrw 0x420000:l ; clear CSR 0x8000e8: movl #0x846,a0 ; first long in CDT 0x8000ee: cmpl #0x45504a52,a0@+ 0x8000f4: bnes 0x800124 ; power up will jump ; from here, must be software requested (or erroneous) reset 0x8000f6: tstb 0x854:l ; was this a panic? 0x8000fc: beqs 0x80010c 0x8000fe: movb #0,0x852:l ; 0x852 = 0 0x800106: jmp 0x800148:l 0x80010c: addl #8,a0 0x800112: movb #1,a0@+ ; 0x852 = 1 0x800116: movb #0,a0@+ ; 0x853 = 0 0x80011a: movb #0,a0@ ; 0x854 = 0 0x80011e: jmp 0x800148:l ; Set up the CDT area (this must be a power-up reset) 0x800124: movl #0x846,a0 0x80012a: movl #0x45504a52,a0@+ 0x800130: movl #0,a0@+ ; 0x84a = 0 0x800136: movl #0,a0@+ ; 0x84e = 0 0x80013c: movb #2,a0@+ ; 0x852 = 2 *** flags power up 0x800140: movb #0,a0@+ ; 0x853 = 0 0x800144: movb #0,a0@ ; 0x854 = 0 ; Initialize the Page Map, transparent, first 2Mb present, not accessed 0x800148: movw #0x2000,d3 0x80014c: movl #0x400000,a4 0x800152: movl #0x1ff,d0 0x800158: movw d3,a4@+ 0x80015a: addqw #1,d3 0x80015c: dbra d0,0x800158 ; Second 2Mb mapped as transparent, not present 0x800160: bclr #0xd,d3 ; turn off page present bit 0x800164: movl #0x1ff,d0 0x80016a: movw d3,a4@+ 0x80016c: addqw #1,d3 0x80016e: dbra d0,0x80016a ; Turn on all LEDS (via GCR) 0x800172: movw #0x3000,0x450000:l ; set up the 8259 ; 0x13 = ICW1 -- Edge triggered, 4 byte calls, single 8259 ; 0x00 = ICW2 -- Vector base (T7-T3) = 00 ; 0x01 = ICW4 -- Non-buffered 8086 mode ; 0xff = OCW1 -- all interrupt sources masked off 0x80017a: movw #0x13,0xc90000:l 0x800182: movw #0,0xc90002:l 0x80018a: movw #1,0xc90002:l 0x800192: movw #0xff,0xc90002:l ; same treatment for 8259 on the expansion board (non-existant for us) 0x80019a: movw #0x13,0xc70100:l 0x8001a2: movw #0,0xc70102:l 0x8001aa: movw #1,0xc70102:l 0x8001b2: movw #0xff,0xc70102:l ; ************************************************ ; loop to recalibrate disks - ; stays here forever, until some disk recalibrates ; ; d0 = 2 (FD), 1 (HD1), 0 (HD0) ; ************************************************ 0x8001ba: movw #0x3700,0x450000:l ; set LED pattern 0x8001c2: clrl d3 ; flag if any disk worked 0x8001c4: movl #2,d0 ; loop counter ( 2, 1, 0 ) 0x8001ca: movl #0x2000,d1 ; BASE address for control area 0x8001d0: movl #0x3000,d2 ; buffer address for i/o 0x8001d6: jsr 0x8003e4:l 0x8001dc: cmpl #4,d7 ; 4 is error status 0x8001e2: beqs 0x8001e6 ; anything else is fine 0x8001e4: addql #1,d3 ; One worked ! 0x8001e6: subql #1,d0 ; done ? 0x8001e8: bges 0x8001d6 ; keep going, do them all 0x8001ea: tstl d3 ; loop till someone works 0x8001ec: beqs 0x8001ba ; LED pattern "searching for dump area" (4 and 1 on) ; This is not pertinent for power-up boot 0x8001ee: movw #0x3500,0x450000:l 0x8001f6: cmpb #2,0x852:l ; power up boot ? 0x8001fe: beqs 0x80027a ; Yes ! ; looking for dump area on disk (bypassed on power-up boot) 0x800200: movl #0x66,a0 ; offset for dump area pointer 0x800206: movl #0x2000,d1 ; BASE of control area pool 0x80020c: movl #0x3000,d2 ; buffer address 0x800212: jsr 0x800398:l ; get pointer to dump area 0x800218: tstl d7 ; find one ? 0x80021a: bnes 0x80027a ; no ; found a dump area, ; d4 = pointer to dump area on disk (in 1K block units) ; d5 = number of blocks in dump area (in 1K block units) ; d6 = device which had it ; now see how much memory we have to dump 0x80021c: clrl d2 ; start counter 0x80021e: movl d2,a6 ; first 128K block base = 0 0x800220: clrw 0x420000:l ; clear CSR 0x800226: movl a6,a5 0x800228: addl #0x1fffe,a5 ; check last word in 128K block 0x80022e: movw a5@+,d0 ; read from it (data irrelevant) 0x800230: movw 0x410000:l,d0 ; check GSR 0x800236: andw #0xffff8000,d0 ; Memory not present bit 0x80023a: beqs 0x80024e ; Zero means not present 0x80023c: cmpl #0x10,d2 ; End search at 2MB boundary 0x800242: beqs 0x80024e 0x800244: addql #1,d2 ; click counter 0x800246: addl #0x20000,a6 ; next 128K block 0x80024c: bras 0x800220 ; OK - found end of memory, now work with number of 512 byte sectors 0x80024e: lsll #8,d2 ; Size of memory to dump 0x800250: lsll #1,d5 ; Size of dump area 0x800252: cmpl d2,d5 ; compare 0x800254: blts 0x800258 0x800256: movl d2,d5 ; dump area is bigger 0x800258: tstl d5 ; are we dumping anything 0x80025a: beqs 0x80027a ; no (dump area size = 0 ?) ; d5 = number of blocks to dump ; d6 = device to dump to 0x80025c: movl d6,d7 ; LED's get device code 0x80025e: orl #0x3000,d7 ; LED's (won't work in LSB) 0x800264: movw d7,0x450000:l ; LED's 0x80026a: movl #0,d3 ; start with this address 0x800270: lsll #1,d4 ; to this address on disk 0x800272: clrl d7 0x800274: jsr 0x80068a:l ; Call write routine ; Regular sequence for power-up boot is here ; Doing address test of memory 0x80027a: movl #0x3000,d0 ; start address test here 0x800280: movl d0,a0 0x800282: movl #0x80000,a6 ; end test before here 0x800288: movl d0,a0 0x80028a: movw #0x3800,d4 ; Bogus LED status 0x80028e: movw d4,0x450000:l ; "Mem Addr Test Fail" 0x800294: movw a0,a0@ ; Write addr at addr 0x800296: movl a0,d7 0x800298: cmpw a0@+,d7 ; Read it back 0x80029a: beqs 0x8002b0 ; Better be equal 0x80029c: orl #0x3800,d4 ; Address Test Failed !! 0x8002a2: movl d4,d7 0x8002a4: movw d7,0x450000:l ; Post status to LED 0x8002aa: stop #0x2700 ; Stop Dead 0x8002ae: bras 0x8002aa ; Really Dead! 0x8002b0: cmpl a0,a6 0x8002b2: bgts 0x800294 ; Loop thru range ; Second phase of address test, scan the range specified once again ; make sure data written is still there, unmangled. 0x8002b4: movl d0,a0 ; start address from above 0x8002b6: movw #0x3000,d4 ; LED status -- 0x8002ba: movw d4,0x450000:l ; Address Test occurring 0x8002c0: movl a0,d7 0x8002c2: cmpw a0@+,d7 0x8002c4: bnes 0x80029c ; OOPS 0x8002c6: cmpl a0,a6 0x8002c8: bgts 0x8002c0 ; Address Test done and successful ; Move 128 byte CDT area to 0x6ff80 - 0x6ffff 0x8002ca: movl #0x6ff80,a1 ; move it to here 0x8002d0: movl #0x846,a0 ; from here 0x8002d6: movl #0x7f,d0 ; this many (N-1) 0x8002dc: movb a0@+,a1@+ ; byte by byte 0x8002de: dbra d0,0x8002dc ; more ; LED status "searching for loader" 0x8002e2: movw #0x3600,0x450000:l 0x8002ea: movl #0x5a,a0 ; offset for loader pointer 0x8002f0: movl #0x2000,d1 ; BASE of control area pool 0x8002f6: movl #0x3000,d2 ; buffer address 0x8002fc: jsr 0x800398:l ; get pointer 0x800302: tstl d7 ; find one ? 0x800304: beqs 0x800310 ; YES !! ; LED status: FAIL3 - cannot find loader ; keep trying forever (maybe someone will put a disk in) 0x800306: movw #0x3a00,0x450000:l ; LED's 0x80030e: bras 0x8002ea ; keep trying ; LED status: Loading loader (4 and 3 on) 0x800310: movw #0x3300,0x450000:l ; Bravo! we have found a loadable image ; d4 = pointer to image on disk (in 1K block units) ; d5 = number of blocks in image (in 1K block units) ; d6 = device which had it 0x800318: movl #0x70000,d3 ; read image to here 0x80031e: lsll #1,d4 ; convert to 512 byte blocks 0x800320: lsll #1,d5 ; ditto - this many of them 0x800322: clrl d7 0x800324: jsr 0x8006a2:l ; Read the loader 0x80032a: tstl d7 ; Did it work ? 0x80032c: bnes 0x8002e2 ; NO ; LED status: Entering loader (4, 1 and 0 on) 0x80032e: movw #0x3400,0x450000:l 0x800336: clrw 0xc6002a:l ; Turn off floppy motor 0x80033c: jmp 0x70000:l ; <<< **** GO **** !! 0x800342: 0x4028 @( ; ?junk 0x800344: 0x2329 #) ; ?junk 0x800346: 0x7072 pr ; ?junk 0x800348: 0x6f6d om ; ?junk 0x80034a: 0x3232 22 ; ?junk 0x80034c: 0x0 0x80034e: 0x0 ; ********************************************************* ; Routine to read a disk "superblock" (first 1024 bytes on device) ; Validates what it reads (magic "UQVQ" in first word, and checksum) ; call with d6 = device (2=FD, 1=HD1, 0=HD0) ; returns with d7=0 if valid ; returns with d7=1 if anything goes wrong ; called from 8003ac, 8005ac ; ********************************************************* 0x800350: movl #2,d5 ; Read this many 512 blocks 0x800356: movl 0x2004:l,d3 ; To this buffer address 0x80035c: clrl d4 ; From this disk address ( 0 ) 0x80035e: movl #1,d7 0x800364: jsr 0x8006a2:l ; Read Em! 0x80036a: tstl d7 ; Did it work ??? 0x80036c: bnes 0x800390 ; NO! Argh! 0x80036e: movl 0x2004:l,a1 ; Buffer address 0x800374: cmpl #0x55515651,a1@ ; 'UQVQ' must be first longword 0x80037a: bnes 0x800390 ; It isn't -- Argh! 0x80037c: jsr 0x8003d4:l ; calculate checksum 0x800382: movl #0,d7 ; valid return if we have: 0x800388: cmpl #-1,d5 ; valid checksum ? 0x80038e: beqs 0x800396 ; YES! 0x800390: movl #1,d7 ; error return 0x800396: rts ; ********************************************************* ; Routine to search for pointer in a "superblock" ; Call with: ; a0 = offset to pointer info in superblock ; d1 = control area base (0x2000) ; d2 = buffer to use (0x3000) ; Returns: ; d4 = pointer to dump area on disk (in 1K block units) ; d5 = number of blocks in dump area (in 1K block units) ; ; called from 800212 -- to find dump area (with a0 = 0x66) ; called from 8002fc -- to find loader (with a0 = 0x5a) ; also external entry point ; ; BLOCK +0x5a - 0x5d = first block (1K) on disk for loader ; BLOCK +0x5e - 0x5f = number of blocks (1K) on disk for loader ; ; BLOCK +0x60 - 0x63 = first block (1K) on disk for block list ; BLOCK +0x64 - 0x65 = number of blocks (1K) on disk for block list ; ( but see some strangeness, 80060a ) ; ; BLOCK +0x66 - 0x69 = first block (1K) on disk for dump area ; BLOCK +0x70 - 0x71 = number of blocks (1K) on disk for dump area ; ********************************************************* 0x800398: movl #2,d0 ; begin loop with FD 0x80039e: addl d2,a0 ; point to item of interest 0x8003a0: jsr 0x8003f0:l ; initialize device info 0x8003a6: tstl d7 ; did it work ? 0x8003a8: bnes 0x8003c8 ; NO 0x8003aa: movl d0,d6 ; set device number 0x8003ac: jsr 0x800350:l ; read "superblock" 0x8003b2: tstl d7 ; did it work ? 0x8003b4: bnes 0x8003c8 ; NO 0x8003b6: movl a0@,d4 ; start pointer on disk 0x8003b8: movw a0@(4),d5 0x8003bc: andl #0xffff,d5 ; size of area on disk 0x8003c2: beqs 0x8003c8 ; forget it if size==0 0x8003c4: clrl d7 ; Got one! 0x8003c6: rts ; Done 0x8003c8: subql #1,d0 ; loop on (FD=2, HD1=1, HD0=0) 0x8003ca: bges 0x8003a0 0x8003cc: movl #2,d7 ; Noone had desired pointer 0x8003d2: rts ; Give up ; ********************************************************* ; Calculate checksum on 1024 byte block ; called from 80037c and 800d2e ; Call with: a1 pointing to the buffer ; d5 returns the checksum ; ********************************************************* 0x8003d4: clrl d5 ; initialize checksum 0x8003d6: movl #0x100,d4 ; this many 4 byte longwords 0x8003dc: addl a1@+,d5 ; add one 0x8003de: subql #1,d4 ; reduce count 0x8003e0: bnes 0x8003dc ; more 0x8003e2: rts ; done ! ; ********************************************************* ; This routine is called to recalibrate and initialize a disk ; Called from 8001d6 (initial recalibration loop), ; also external entry point ; ********************************************************* 0x8003e4: moveml d0-d6/a0-a7,sp@- 0x8003e8: movl #1,d5 0x8003ee: bras 0x8003f6 ; ********************************************************* ; This routine is called to just initialize a disk ; Called from 8003a0 (superblock pointer finding routine), ; also external entry point ; ********************************************************* 0x8003f0: moveml d0-d6/a0-a7,sp@- 0x8003f4: clrl d5 ; common code for both entry points above ; ; 0x2000-3 holds base address (4 bytes) for IO control area allocation ; 0x2004-7 holds base address (4 bytes) for other gyrations ; 0x2008-9 holds DMA word count on completion (noone ever uses it) ; 0x200a-b holds error status on operation completion ; 0x200c-d holds HD error flags (from WD1010) ; 0x200e-11 holds count of errors (never initialized) 0x8003f6: clrw 0xc60036:l ; reset disk BIU 0x8003fc: movl d0,d6 0x8003fe: movl d1,0x2000:l ; only place this is set 0x800404: movl d2,0x2004:l ; only place this is set 0x80040a: jsr 0x800438:l ; set a0 (according to d6) 0x800410: cmpl #0,d0 0x800416: beq 0x800508 ; HD 0 0x80041a: cmpl #1,d0 0x800420: beq 0x80052a ; HD 1 0x800424: cmpl #2,d0 0x80042a: beqs 0x800494 ; floppy 0x80042c: movl #3,d7 ; Error - no such d0 allowed 0x800432: moveml sp@+,d0-d6/a0-a7 ; lots of people return here 0x800436: rts ; ********************************************************* ; allocate an IO control area, based on the value in d6 ; 0x426 is 0x26 byte prefix, then 0x400 buffer (1k byte) ; The base is fetched (long) from 0x2000 ; BASE to BASE+0x0013 are used for other things (see above) ; ; d6 = 0 a0 = BASE + 0x0014 d7 = 0 ; d6 = 1 a0 = BASE + 0x043A d7 = 0 ; d6 = 2 a0 = BASE + 0x0860 d7 = 0 ; d6 = any other value --- d7 = 3 ; ********************************************************* 0x800438: clrl d7 ; valid return (d7=0) 0x80043a: movl 0x2000:l,a0 ; get base address for alloc 0x800440: addl #0x14,a0 ; ( +0x14 ) 0x800446: cmpl #0,d6 0x80044c: beqs 0x800470 0x80044e: addl #0x426,a0 ; ( +0x43A ) 0x800454: cmpl #1,d6 0x80045a: beqs 0x800470 0x80045c: addl #0x426,a0 ; floppy ( +0x860 ) 0x800462: cmpl #2,d6 0x800468: beqs 0x800470 0x80046a: movl #3,d7 ; Error (d7=3) 0x800470: rts ; Set up the 8259 ; 0x13 = ICW1 -- Edge triggered, 4 byte calls, single 8259, need ICW4 ; 0x58 = ICW2 -- Vector base (T7-T3) = 58 - 5F (Why?) ; 0x03 = ICW4 -- Auto EOI, Non-buffered 8086 mode ; 0xff = OCW1 -- all interrupt sources masked off 0x800472: movw #0x13,0xc90000:l 0x80047a: movw #0x58,0xc90002:l 0x800482: movw #3,0xc90002:l 0x80048a: movw #0xff,0xc90002:l 0x800492: rts ; ********************************************************* ; Entry point for Floppy Disk ; only call is from 80042a above ; ********************************************************* 0x800494: clrw 0xc60022:l ; FD reset off 0x80049a: movw 0xc60010:l,d0 ; read FD status (silly) 0x8004a0: clrw 0xc60028:l ; FD motor on 0x8004a6: jsr 0x800472:l ; setup 8259 (all disabled) 0x8004ac: movb #1,a0@(0x20) ; 0 = HD, 1 = FD 0x8004b2: movb #2,a0@(0x21) ; 0 = HD0, 1 = HD1, 2 = FD ; Sneaky place to hide a bit -- the following test looks at bit 0 in the ; "slow comm port status register" -- When that bit is zero, a floppy ; drive is connected to the floppy port (the hardware exists) 0x8004b8: movw 0xc30008:l,d7 ; SCOMM status port 0x8004be: andw #1,d7 ; FD present bit 0x8004c2: bne 0x800560 ; none there, return w/ d7=4 ; Aha - a floppy is out there 0x8004c6: tstl d5 ; d5=1 on recalibrate 0x8004c8: beq 0x80056a ; not a recal, bypass ; Wait for floppy drive to come up ready 0x8004cc: movl #0x29810,d1 ; 170,000 decimal (timeout) 0x8004d2: movw 0xc60010:l,d0 ; floppy status 0x8004d8: btst #7,d0 ; check Not-Ready bit 0x8004dc: beqs 0x8004e2 ; Zero means Ready 0x8004de: subql #1,d1 ; count down (timeout) 0x8004e0: bgts 0x8004d2 ; check status again ; OK - the floppy is there and ready! (or the above loop timed out) ; Recalibrate the thing. 0x8004e2: jsr 0x800b0c:l ; set density 0x8004e8: movw #0,0xc60010:l ; Restore > floppy command 0x8004f0: jsr 0x800abe:l ; Wait for completion 0x8004f6: clrw 0xc60012:l ; write 0 to track register 0x8004fc: movl d0,d7 ; d0 holds status 0x8004fe: andl #4,d7 ; check TRACK0 bit 0x800504: beqs 0x800560 ; error (TRACK0 should be 1) 0x800506: bras 0x80056a ; good - at Track 0 ; ********************************************************* ; Entry point for Hard Disk 0 ; The SDH value of 0x20 = 512 byte sectors, drive 0, head 0 ; only call is from 800416 above ; ********************************************************* 0x800508: clrw 0xc60026:l ; HD reset off 0x80050e: jsr 0x800472:l ; setup 8259 (all disabled) 0x800514: tstl d5 0x800516: beqs 0x80056a 0x800518: movw #0x20,0xc60002:l ; write precomp cyl 0x800520: movw #0x20,0xc6000c:l ; SDH (1/4) 0x800528: bras 0x800542 ; ********************************************************* ; Entry point for Hard Disk 1 ; The SDH value of 0x28 = 512 byte sectors, drive 1, head 0 ; only call is from 800420 above ; ********************************************************* 0x80052a: clrw 0xc60026:l ; HD reset off 0x800530: jsr 0x800472:l ; setup 8259 (all disabled) 0x800536: tstl d5 0x800538: beqs 0x80056a 0x80053a: movw #0x28,0xc6000c:l ; SDH (2/4) ; common code for both Hard Disks 0x800542: movb d0,a0@(0x21) ; 0 = HD0, 1 - HD1 0x800546: movw #0x10,0xc6000e:l ; HD restore cmd 0x80054e: movb #0,a0@(0x20) ; HD = 0, FD = 1 0x800554: jsr 0x800a1a:l ; wait for completion 0x80055a: btst #0,d0 ; HD error bit 0x80055e: beqs 0x80056a ; OK if zero 0x800560: movl #4,d7 ; set error status 0x800566: bra 0x800432 ; return ; common code for everyone (FD and HD) ; recalibrate ends up here if everything went well 0x80056a: movw #4,a0@(0) 0x800570: movw #4,a0@(2) 0x800576: movw #4,a0@(4) 0x80057c: movw #4,a0@(6) 0x800582: movw #1,a0@(8) ; never used 0x800588: movw #1,a0@(0xa) 0x80058e: movb #1,a0@(0xe) ; flags (density...) 0x800594: clrw a0@(0xc) 0x800598: cmpb #1,a0@(0x20) ; 1 = FD 0x80059e: bnes 0x8005a6 0x8005a0: clrb a0@(0xf) ; 0 for a floppy 0x8005a4: bras 0x8005ac 0x8005a6: movb #2,a0@(0xf) ; 2 for a hard disk 0x8005ac: jsr 0x800350:l ; read "superblock" 0x8005b2: tstl d7 ; did it work ? 0x8005b4: bne 0x800432 ; NO 0x8005b8: movl 0x2004:l,a1 0x8005be: addl #0xe,a1 0x8005c4: movw a1@+,a0@(8) ; ( 0x300e ) never used 0x8005c8: movw a1@+,a0@(0xa) ; ( 0x3010 ) 0x8005cc: movw a1@+,d0 ; ( 0x3012 ) 0x8005ce: movw d0,d1 0x8005d0: movw d0,a0@(2) ; sectors/track 0x8005d4: andw #-2,d0 ; force even 0x8005d8: movw d0,a0@(0) ; sectors/track - even 0x8005dc: movw a1@+,d2 ; ( 0x3014 ) 0x8005de: movw d2,a0@(6) ; sectors/cyl 0x8005e2: andl #0xffff,d2 0x8005e8: divu d1,d2 0x8005ea: mulu d0,d2 0x8005ec: movw d2,a0@(4) ; sectors/cyl - fiddled 0x8005f0: movb a1@+,a0@(0xe) ; ( 0x3016 ) flags (density...) 0x8005f4: movb a1@+,a0@(0xf) ; ( 0x3017 ) HD seek/restore 0x8005f8: movw a1@+,a0@(0x10) ; ( 0x3018 ) never used 0x8005fc: movl 0x2004:l,a1 0x800602: addl #0x60,a1 0x800608: movl a1@+,d4 ; ( 0x3060 ) 0x80060a: movl a1@,d2 ; ( 0x3064 ) ??? long ??? 0x80060c: beqs 0x800680 ; note above that the test on 0x3064 is done long, but this surely was meant ; to be word. Look at the notes before the 800398 routine, this will work ; since the entry at 0x3066 is the pointer the the dump area, and will most ; likely have the upper 2 bytes zero (unless the dump area is at the end of ; a really big hard disk). Notice that this "entry" is only tested, never used. ; special code follows - should only find this stuff if this is a hard disk ; the entry on floppys should always be zero. 0x80060e: lsll #1,d4 ; start sector 0x800610: movl #2,d5 ; this many 512 byte sectors 0x800616: movl 0x2004:l,d3 ; read to this address 0x80061c: clrl d7 0x80061e: jsr 0x8006a2:l ; Read Em! 0x800624: tstl d7 ; Did it work 0x800626: bnes 0x800676 ; no - trouble 0x800628: movl 0x2004:l,a1 ; address of buffer 0x80062e: jsr 0x8003d4:l ; calculate checksum 0x800634: cmpl #-1,d5 ; better be (-1) 0x80063a: bnes 0x800676 ; no - trouble 0x80063c: movl #0x7f,d4 ; no more than this many 0x800642: movl 0x2004:l,a1 ; start here 0x800648: addl #8,a1 ; skip the first 8 bytes 0x80064e: lea a0@(0x26),a2 ; use this as a buffer 0x800652: movw a1@+,d3 ; Loop 0x800654: movw d3,a2@+ ; copy 2 bytes 0x800656: clrl d0 0x800658: movw a1@+,d0 ; or this on.... 0x80065a: orw d0,d3 ; just to check for zero. 0x80065c: tstw d3 ; if it is..... 0x80065e: beqs 0x800680 ; Exit loop. 0x800660: divu a0@(2),d0 ; divide by sectors/track 0x800664: movw d0,a2@+ 0x800666: swap d0 0x800668: movw d0,a2@+ 0x80066a: movw a1@+,a2@+ 0x80066c: addql #2,a1 0x80066e: addqw #1,a0@(0xc) ; count these 0x800672: subql #1,d4 0x800674: bgts 0x800652 ; get more 0x800676: movl #5,d7 ; return with d7=5 0x80067c: bra 0x800432 0x800680: movl #0,d7 ; return with d7=0 0x800686: bra 0x800432 ; ************************************************ ; ** General IO routines -- Write/Format/Read *** ; ** ; ** d3 = memory address for i/o ; ** d4 = disk address (in # of 512 byte sectors) ; ** d5 = # of 512 byte sectors to move ; ** d6 = device (2=FD, 1=HD1, 0=HD0) ; ** d7 = 0 or 1 ; ************************************************ ; ; Write - Called from 800274 (for memory dump) ; also External entry 0x80068a: moveml d0-d6/a0-a7,sp@- 0x80068e: movl #1,d2 ; 1 = Write 0x800694: bras 0x8006ac ; Format - External calls only 0x800696: moveml d0-d6/a0-a7,sp@- 0x80069a: movl #2,d2 ; 2 = Format 0x8006a0: bras 0x8006ac ; Read - Called from 800324 (to read loader), ; Called from 800364 (to read "superblock" for loader/dump pointers), ; Called from 80061e (to read "superblock" for disk params) ; also External entry 0x8006a2: moveml d0-d6/a0-a7,sp@- 0x8006a6: movl #0,d2 ; 0 = Read ; common code for the 3 entry points above 0x8006ac: movl d7,d0 ; copy d7 to d0 (to save it) 0x8006ae: jsr 0x800438:l ; get a0 pointer (based on d6) 0x8006b4: tstl d7 ; only non-zero if d6 invalid 0x8006b6: bne 0x80042c ; invalid d6 (return w/d7=3) 0x8006ba: clrw 0xc60030:l ; disable disk DMA 0x8006c0: clrw 0xc60036:l ; reset disk BIU 0x8006c6: movb d0,a0@(0x25) ; low byte of d7 (0 or 1) 0x8006ca: movb d2,a0@(0x24) ; 0=Read, 1=Write, 2=Format 0x8006ce: movw #0xa,a0@(0x22) ; 10 retries 0x8006d4: lsrl #1,d3 ; convert to word address 0x8006d6: movl d3,a0@(0x12) ; save word address 0x8006da: movw a0@(4),d0 0x8006de: movw a0@(0),d3 0x8006e2: tstb a0@(0x25) 0x8006e6: beqs 0x8006f0 0x8006e8: movw a0@(6),d0 0x8006ec: movw a0@(2),d3 ; now: d0 = sectors/cyl ; d3 = sectors/track 0x8006f0: divu d0,d4 0x8006f2: movw d4,a0@(0x16) ; desired cylinder 0x8006f6: swap d4 ; get remainder 0x8006f8: andl #0xffff,d4 0x8006fe: divu d3,d4 0x800700: movw d4,a0@(0x18) ; desired head 0x800704: swap d4 ; get remainder 0x800706: movw d4,a0@(0x1a) ; desired sector 0x80070a: movw d5,a0@(0x1c) ; # of blocks (512 byte) 0x80070e: movw d5,a0@(0x1e) ; # of blocks (512 byte) ; entered from 8008c2, 800a16, 800c24 0x800712: tstw a0@(0x1c) ; need any more 0x800716: ble 0x800680 ; NO - all done !!!! 0x80071a: cmpb #1,a0@(0x20) ; 1 = FD 0x800720: bnes 0x800736 0x800722: cmpb #2,a0@(0x24) ; 2 = Format (Floppy) 0x800728: beq 0x8007d6 0x80072c: movw #1,a0@(0x1e) ; Floppy R/W 1 sector at a time 0x800732: bra 0x8007d6 0x800736: cmpb #2,a0@(0x24) ; 2 = Format (Hard disk) 0x80073c: bge 0x8007d6 ; HD format bypasses ; Hard Disk read/write tangles with what follows... 0x800740: lea a0@(0x26),a1 ; use this as a buffer 0x800744: movw a0@(0xc),d0 ; count of entries 0x800748: andl #0xffff,d0 0x80074e: movw a0@(0x1a),d1 ; sector number 0x800752: andl #0xffff,d1 0x800758: addw a0@(0x1c),d1 ; sector count 0x80075c: bras 0x800764 0x80075e: addql #2,a1 0x800760: addql #2,a1 0x800762: addql #2,a1 0x800764: subql #1,d0 0x800766: blts 0x8007ac 0x800768: movw a1@+,d2 0x80076a: cmpw a0@(0x16),d2 ; cylinder 0x80076e: bnes 0x80075e 0x800770: movw a1@+,d2 0x800772: cmpw a0@(0x18),d2 ; head 0x800776: bnes 0x800760 0x800778: movw a1@+,d2 0x80077a: cmpw a0@(0x1a),d2 ; sector 0x80077e: blts 0x800762 0x800780: cmpw d1,d2 0x800782: bges 0x800762 0x800784: subw a0@(0x1a),d2 ; sector 0x800788: bnes 0x8007d2 0x80078a: movw #1,a0@(0x1e) ; sector count 0x800790: clrl d3 0x800792: movw a1@,d3 0x800794: divu a0@(0xa),d3 0x800798: clrl d4 0x80079a: movw d3,d4 0x80079c: swap d3 0x80079e: andl #0xffff,d3 0x8007a4: clrl d5 0x8007a6: movw a0@(0),d5 0x8007aa: bras 0x8007e8 0x8007ac: movw a0@(0x1a),d0 ; sector number 0x8007b0: andl #0xffff,d0 0x8007b6: addw a0@(0x1c),d0 ; sector count 0x8007ba: movw a0@(0),d5 ; set d5 to sectors/track 0x8007be: tstb a0@(0x25) 0x8007c2: beqs 0x8007c8 0x8007c4: movw a0@(2),d5 0x8007c8: cmpw d5,d0 0x8007ca: bles 0x8007d6 0x8007cc: movw d5,d2 0x8007ce: subw a0@(0x1a),d2 ; sector number 0x8007d2: movw d2,a0@(0x1e) ; sector count 0x8007d6: clrl d5 0x8007d8: clrl d4 0x8007da: clrl d3 0x8007dc: movw a0@(0x16),d4 ; cylinder 0x8007e0: movw a0@(0x18),d3 ; head 0x8007e4: movw a0@(0x1a),d5 ; sector 0x8007e8: movl a0@(0x12),d1 ; word address 0x8007ec: movw a0@(0x1e),d0 ; sector count 0x8007f0: andl #0xffff,d0 0x8007f6: cmpb #2,a0@(0x24) ; 2 = Format 0x8007fc: bnes 0x80080c 0x8007fe: lsrl #1,d0 ; Formatting - adjust count 0x800800: cmpb #0,a0@(0x20) ; 0 = HD 0x800806: bnes 0x80080e 0x800808: addql #2,d1 ; HD format skips 2 items 0x80080a: bras 0x80080e 0x80080c: lsll #8,d0 ; convert to word count 0x80080e: negl d0 ; fix for DMA count ; set up for disk DMA, both floppy and hard disk share the same channel 0x800810: movw d0,0xc80000:l ; DMA 16 bit word count 0x800816: movw d1,0xc80002:l ; DMA low 16 addr bits 0x80081c: swap d1 ; 16 bit <= => 0x80081e: cmpb #0,a0@(0x24) ; 0=Read 0x800824: bnes 0x80082e ; 1=Write 2 = Format 0x800826: movw d1,0xc80008:l ; DMA high addr - Read 0x80082c: bras 0x800834 0x80082e: movw d1,0xc80006:l ; DMA high addr - Write 0x800834: cmpb #1,a0@(0x20) ; 1 = FD 0x80083a: beq 0x800b3a ; go to FD routine 0x80083e: clrw 0xc6002c:l ; HD reset off 0x800844: jsr 0x8008ee:l ; setup HD transfer 0x80084a: cmpb #0,a0@(0x24) ; 0 = Read 0x800850: bnes 0x80085c 0x800852: movw #0x2c,0xc6000e:l ; HD read multi-sectors 0x80085a: bras 0x800876 0x80085c: cmpb #2,a0@(0x24) ; 2 = Format 0x800862: bnes 0x80086e ; 1 = Write 0x800864: movw #0x50,0xc6000e:l ; HD write format 0x80086c: bras 0x800876 0x80086e: movw #0x34,0xc6000e:l ; HD write multi-sectors 0x800876: jsr 0x800a1a:l ; wait for completion 0x80087c: movl d0,d7 ; check status 0x80087e: andl #0xa3,d7 0x800884: beq 0x8009c8 ; good! ; here on hard disk IO error 0x800888: tstb a0@(0x25) ; are we allowing retries 0x80088c: bnes 0x8008c6 ; No 0x80088e: cmpw #5,a0@(0x22) ; retry count ( 10 initially ) 0x800894: bnes 0x8008b6 0x800896: clrw 0xc60026:l ; HD reset off 0x80089c: clrl d3 0x80089e: clrl d4 0x8008a0: clrl d5 0x8008a2: jsr 0x80097a:l 0x8008a8: jsr 0x8009a4:l 0x8008ae: btst #0,d0 ; any error in HD status 0x8008b2: bne 0x800560 ; trouble 0x8008b6: addql #1,0x200e:l ; count the retries 0x8008bc: subw #1,a0@(0x22) ; --retry 0x8008c2: bgt 0x800712 ; Do it again ; too many retries - return with error status ; FD and HD use this, but some bits only make sense for HD 0x8008c6: movl #6,d7 ; start building a status 0x8008cc: addb a0@(0x24),d7 ; 0=Read, 1=Write, 2=Format 0x8008d0: andl #0xff,d0 ; mask completion status 0x8008d6: swap d0 ; swap 16 bit halves 0x8008d8: orl d0,d7 ; add that on 0x8008da: movw 0x200c:l,d0 ; error flags from WD1010 0x8008e0: andl #0xff,d0 ; just a byte 0x8008e6: rorl #8,d0 ; move left 8 bits 0x8008e8: orl d0,d7 ; and tack it on 0x8008ea: bra 0x800432 ; return with fancy code in d7 ; called from 800844, 80097a, 8009aa ; HD1 needs write precomp set, HD0 doesn't (but will inherit HD1 settings) 0x8008ee: cmpb #1,a0@(0x21) ; 0 = HD0, 1 = HD1 0x8008f4: beqs 0x8008fe 0x8008f6: movw #0x20,0xc60002:l ; HD Write precomp cyl 0x8008fe: movw a0@(0x1e),d0 0x800902: cmpb #2,a0@(0x24) ; 2 = format 0x800908: bnes 0x800914 0x80090a: movl a0@(0x12),d0 ; Formatting 0x80090e: lsll #1,d0 0x800910: movl d0,a1 0x800912: movw a1@+,d0 0x800914: movw d0,0xc60004:l ; HD sector count 0x80091a: clrl d1 0x80091c: movb a0@(0xe),d0 ; density flags (and this) 0x800920: andl #4,d0 0x800926: beqs 0x80093a 0x800928: bset #5,d1 ; tweak cylinder number 0x80092c: cmpw #7,d3 ; tweak sector number 0x800930: bles 0x80093a 0x800932: bset #6,d1 ; tweak cylinder number 0x800936: addw #0x20,d5 ; tweak sector number 0x80093a: cmpb #2,a0@(0x24) ; 2 = Format 0x800940: bnes 0x800944 0x800942: movw a1@,d5 0x800944: movw d5,0xc60006:l ; HD sector number 0x80094a: movw d4,0xc60008:l ; HD cyl number (low) 0x800950: lsrl #8,d4 0x800952: andl #0xff,d4 0x800958: orw d4,d1 0x80095a: movw d1,0xc6000a:l ; HD cyl number (high) 0x800960: andl #7,d3 ; 3 bits 0x800966: movl d6,d0 0x800968: lsll #3,d0 ; drive (0 or 1) 0x80096a: orl d0,d3 0x80096c: orl #0x20,d3 ; 512 byte sectors always 0x800972: movw d3,0xc6000c:l ; SDH (3/4) 0x800978: rts 0x80097a: jsr 0x8008ee:l 0x800980: clrl d0 0x800982: movb a0@(0xf),d0 0x800986: addw #0x70,d0 ; HD seek command 0x80098a: movw d0,0xc6000e:l 0x800990: jsr 0x800a1a:l ; wait for completion 0x800996: movw 0xc6000e:l,d0 ; HD status 0x80099c: btst #1,d0 ; Cmd in Progress 0x8009a0: bnes 0x800996 ; Poll till done 0x8009a2: rts 0x8009a4: clrl d3 0x8009a6: clrl d4 0x8009a8: clrl d5 0x8009aa: jsr 0x8008ee:l 0x8009b0: clrl d0 0x8009b2: movb a0@(0xf),d0 0x8009b6: addw #0x10,d0 ; HD restore command 0x8009ba: movw d0,0xc6000e:l 0x8009c0: jsr 0x800a1a:l ; wait for completion 0x8009c6: rts ; successful hard disk AND floppy disk IO comes here: ; from 800bda (floppy) and 800884 (hard) 0x8009c8: movw a0@(0x1e),d0 0x8009cc: subw d0,a0@(0x1c) 0x8009d0: movw d0,d1 0x8009d2: addw a0@(0x1a),d1 0x8009d6: clrl d2 0x8009d8: movw a0@(0),d3 0x8009dc: tstb a0@(0x25) 0x8009e0: beqs 0x8009e6 0x8009e2: movw a0@(2),d3 0x8009e6: cmpw d3,d1 0x8009e8: blts 0x8009f2 0x8009ea: movl #1,d2 0x8009f0: clrl d1 0x8009f2: movw d1,a0@(0x1a) 0x8009f6: addw a0@(0x18),d2 0x8009fa: cmpw a0@(0xa),d2 0x8009fe: blts 0x800a06 0x800a00: clrl d2 0x800a02: addqw #1,a0@(0x16) 0x800a06: movw d2,a0@(0x18) 0x800a0a: lsll #8,d0 0x800a0c: addl d0,a0@(0x12) 0x800a10: movw a0@(0x1c),a0@(0x1e) 0x800a16: bra 0x800712 ; ************************************************ ; ** Routine to wait for HD command completion. ** ; ************************************************ ; ; Activate 8259 for HD interrupts ; 0x9f = OCW1 -- Unmask level 6 and 5 (Disk error, and HD EOXfer) ; 0x0e = OCW3 -- Poll IR register on next read 0x800a1a: movw #0x9f,0xc90002:l 0x800a22: movl #0x927c0,d1 ; 600,000 decimal (timeout) 0x800a28: movw #0xe,0xc90000:l 0x800a30: subql #1,d1 0x800a32: bnes 0x800a50 0x800a34: movw 0xc6000e:l,d0 ; timeout 0x800a3a: movw #-0x1111,0x200a:l ; set status 0x800a42: clrw 0xc60030:l ; disable disk DMA 0x800a48: clrw 0xc60036:l ; reset disk BIU 0x800a4e: bras 0x800a96 ; read 8259 IR register, 0x85 = interrupt at level 05 (overflow or underrun) ; 0x86 = interrupt at level 06 (HD end of Xfer) 0x800a50: movw 0xc90000:l,d0 0x800a56: cmpb #0x85,d0 0x800a5a: bnes 0x800a76 ; here with overflow/underrun 0x800a5c: clrw 0xc60024:l ; HD reset on 0x800a62: rorl #8,d1 0x800a64: roll #8,d1 0x800a66: clrw 0xc60026:l 0x800a6c: movw #-0x1101,0x200a:l ; set status (home-made) 0x800a74: bras 0x800a42 0x800a76: cmpb #0x86,d0 0x800a7a: bnes 0x800a28 ; keep on going ; here with successful End of transfer 0x800a7c: clrw 0xc60030:l ; disable disk DMA 0x800a82: movw 0xc6000e:l,0x200a:l ; save status (WD1010) 0x800a8c: movw 0xc60002:l,0x200c:l ; save err flags (1010) ; Reset 8259 ; 0xff = OCW1 -- Mask all interrupt levels ; HD_SDH = 0x18 sets 256 byte sectors, drive 4, head 0 (Impossible drive) 0x800a96: movw #0xff,0xc90002:l 0x800a9e: clrw 0xc60036:l ; reset disk BIU 0x800aa4: movw #0x18,0xc6000c:l ; SDH (4/4) ; The DMA word count here is stored, never referenced anywhere 0x800aac: movw 0xc80000:l,0x2008:l ; DMA word count (disk) 0x800ab6: movw 0x200a:l,d0 ; fetch status 0x800abc: rts ; ************************************************ ; ** Routine to wait for FD command completion. ** ; ************************************************ ; ; Activate 8259 for FD interrupts ; 0x7f = OCW1 -- Unmask level 7 (FD EOXfer) ; 0x0e = OCW3 -- Poll IR register on next read 0x800abe: movw #0x7f,0xc90002:l 0x800ac6: movl #0x61a80,d1 ; 400,000 decimal (timeout) 0x800acc: movw #0xe,0xc90000:l 0x800ad4: subql #1,d1 0x800ad6: bnes 0x800aee 0x800ad8: movw #-0x1107,0x200a:l ; timed out! set status 0x800ae0: clrw 0xc60030:l ; disable disk DMA 0x800ae6: clrw 0xc60036:l ; reset disk BIU 0x800aec: bras 0x800a96 ; remask interrupts, return ; read 8259 IR register, 0x87 = interrupt at level 07 0x800aee: movw 0xc90000:l,d0 ; poll the 8259 0x800af4: cmpb #0x87,d0 ; are we done? 0x800af8: bnes 0x800acc ; no, poll some more 0x800afa: clrw 0xc60030:l ; Done! disable disk DMA 0x800b00: movw 0xc60010:l,0x200a:l ; save status (2797) 0x800b0a: bras 0x800a96 ; remask interrupts, return ; ************************************************ ; ** Routine to set floppy density ; ** a0@(0x16) is current cyliner number ; ** a0@(0xe) are density flags as follows: ; ------00 -- single density ; ------01 -- double density ; ------1x and cyl==0 -- single density ; ------1x and cyl!=0 -- double density ; ************************************************ 0x800b0c: movb a0@(0xe),d0 ; check flags 0x800b10: andl #2,d0 ; cylinder number stuff ? 0x800b16: beqs 0x800b26 ; NO 0x800b18: tstw a0@(0x16) ; cyliner zero 0x800b1c: bnes 0x800b32 ; NO 0x800b1e: clrw 0xc60032:l ; set single density 0x800b24: rts 0x800b26: movb a0@(0xe),d0 ; check flags 0x800b2a: andl #1,d0 ; always double density ? 0x800b30: beqs 0x800b1e ; NO - then always single 0x800b32: clrw 0xc60034:l ; set double density 0x800b38: rts ; ************************************************ ; ** common routine for floppy disk IO ********** ; ************************************************ ; ; first thing is to seek to the correct track 0x800b3a: movw d4,0xc60016:l ; write track # to data reg. 0x800b40: cmpb 0xc60013:l,d4 ; compare with track reg. 0x800b46: beqs 0x800b90 ; same - no need to seek 0x800b48: jsr 0x800b0c:l ; set density 0x800b4e: cmpb #2,a0@(0x24) ; 2 = Format 0x800b54: bnes 0x800b60 ; not formatting 0x800b56: movw #0x10,0xc60010:l ; Formatting - just seek 0x800b5e: bras 0x800b68 ; otherwise: 0x800b60: movw #0x14,0xc60010:l ; seek with verify 0x800b68: jsr 0x800abe:l ; wait for command complete 0x800b6e: movl d0,d7 ; get status 0x800b70: andl #0x98,d7 ; Not Rdy | Seek Err | CRC 0x800b76: beqs 0x800b90 ; Good! none of these bits set ; FD seek error 0x800b78: tstb a0@(0x25) ; allowing retries 0x800b7c: bnes 0x800b8c ; No 0x800b7e: addql #1,0x200e:l ; count the retries 0x800b84: subw #1,a0@(0x22) ; --retry 0x800b8a: bgts 0x800b3a ; try again 0x800b8c: bra 0x8008c6 ; build error status, return ; Here after successful seek to desired track ; set up and start the desired command. 0x800b90: clrw 0xc6002e:l ; enable floppy DMA 0x800b96: addqw #1,d5 ; add 1 to sector number 0x800b98: movw d5,0xc60014:l ; write it to sector reg 0x800b9e: jsr 0x800b0c:l ; set density 0x800ba4: lslw #1,d3 ; side select bit 0x800ba6: cmpb #0,a0@(0x24) ; 0 = Read 0x800bac: bnes 0x800bb4 0x800bae: addw #0x88,d3 ; read single sector 0x800bb2: bras 0x800bc6 0x800bb4: cmpb #2,a0@(0x24) ; 2 = Format ( 1 = Write ) 0x800bba: bnes 0x800bc2 0x800bbc: addw #0xf0,d3 ; format (write track) 0x800bc0: bras 0x800bc6 0x800bc2: addw #0xa8,d3 ; write single sector 0x800bc6: movw d3,0xc60010:l ; start the command ! 0x800bcc: jsr 0x800abe:l ; wait for completion 0x800bd2: movl d0,d7 ; get status 0x800bd4: andl #0xdc,d7 ; mask for error bit (2797FDC) 0x800bda: beq 0x8009c8 ; good! none of these set ; Floppy disk IO error 0x800bde: tstb a0@(0x25) ; allowing retries 0x800be2: bnes 0x800c28 ; No 0x800be4: cmpw #5,a0@(0x22) ; check retry count 0x800bea: bnes 0x800c18 ; do it again 0x800bec: clrw 0xc60022:l ; FD reset off 0x800bf2: jsr 0x800b0c:l ; set density 0x800bf8: movw #0,0xc60010:l ; restore command ;; Some funny business here, I believe the ROM just lost a bit -- ;; The following 3 words: ;; 0x800c00: 4eb1 0080 0abe ;; Disassemble as this junk: (and grab a fourth word) ;; 0x800c00: jsr a1@(-0x80,d0:w) ; (8 bytes, nonsense) ;; If we set just one bit: ;; 0x800c00: 4eb9 0080 0abe ;; This disassembles as: ;; 0x800c00: jsr 0x800abe:l ;; And the following instruction as: ;; 0x800c06: 4279 00c6 0012 ;; 0x800c06: clrw 0xc60012:l ;; Which makes sense, so I reproduce this code below: 0x800c00: jsr 0x800abe:l ; wait for command completion 0x800c06: clrw 0xc60012:l ; write 0 to track register 0x800c0c: movl d0,d7 ; look at status 0x800c0e: andl #4,d7 ; Expect 1 here (Track 0) 0x800c14: beq 0x800560 ; trouble 0x800c18: addql #1,0x200e:l ; count the retries 0x800c1e: subw #1,a0@(0x22) ; --retry 0x800c24: bgt 0x800712 ; do it again 0x800c28: bra 0x8008c6 ; build error status, return /* The End */