ORIC Jasmin disk controller ROM disassembly by Peter Gordon (pete@petergordon.org.uk) *************************************** F800 to FD00 = $FF padding *************************************** jsEntryPoint FD00 78 SEI ; Disable interrupts FD01 A9 00 LDA #$00 ; Turn off overlay RAM (although if it was on FD03 8D FA 03 STA $03FA ; I don't know how this could be expected to run :-) FD06 A9 7F LDA #$7F ; Disable VIA interrupts FD08 8D 0E 03 STA $030E FD0B EA NOP ; ... FD0C EA NOP FD0D EA NOP FD0E EA NOP FD0F EA NOP FD10 A9 7F LDA #$7F ; Disable VIA interrupts again. FD12 8D 0E 03 STA $030E FD15 A9 00 LDA #$00 ; Turn off overlay RAM again FD17 8D FA 03 STA $03FA FD1A A0 20 LDY #$20 ; Copy hw reset routine from $fd51 to $0401 FD1C 88 DEY ; (31 bytes) FD1D F0 10 BEQ $FD2F FD1F B9 50 FD LDA $FD50,Y FD22 99 00 04 STA $0400,Y FD25 B9 00 04 LDA $0400,Y ; The copy is verified... FD28 D9 50 FD CMP $FD50,Y FD2B D0 F2 BNE $FD1F FD2D F0 ED BEQ $FD1C FD2F 4C 01 04 JMP $0401 *************************************** FD32 to FD50 is padded with NOPs *************************************** jsReset(0401) FD51 A9 7F LDA #$7F ; Disable VIA interrupts (0403) FD53 8D 0E 03 STA $030E (0406) FD56 A9 00 LDA #$00 ; Write $00 to $3ff - $3f8, which: (0408) FD58 A0 08 LDY #$08 ; * Selects drive 3, then 2, then 1, then 0 (040A) FD5A 99 F7 03 STA $03F7,Y ; * Enables BASIC ROM, disables RAM overlay (040D) FD5D 88 DEY ; * Resets the disk drive, and (040E) FD5E D0 FA BNE $FD5A ; * Selects side 0 (0410) FD60 A9 01 LDA #$01 ; Disable BASIC rom again (0412) FD62 8D FB 03 STA $03FB (0415) FD65 78 SEI ; Disable interrupts (0416) FD66 4C 00 FE JMP $FE00 ; Jump back to the jasmin ROM (0419) FD69 EA NOP (041A) FD6A EA NOP (041B) FD6B EA NOP (041C) FD6C EA NOP (041D) FD6D EA NOP (041E) FD6E EA NOP (041F) FD6F EA NOP *************************************** FD70 to FDFF is padded with NOPs *************************************** FE00 78 SEI ; Disable interrupts FE01 A9 7F LDA #$7F ; Disable VIA interrupts FE03 8D 0E 03 STA $030E FE06 EA NOP FE07 EA NOP FE08 EA NOP FE09 EA NOP FE0A EA NOP FE0B A0 0E LDY #$0E ; Copy 14 byte routine from $FE63 to $0400 FE0D 88 DEY FE0E C0 FF CPY #$FF FE10 F0 09 BEQ $FE1B FE12 B9 63 FE LDA $FE63,Y FE15 99 00 04 STA $0400,Y FE18 18 CLC FE19 90 F2 BCC $FE0D FE1B A9 01 LDA #$01 ; Select drive 0 FE1D 8D FC 03 STA $03FC FE20 8D F9 03 STA $03F9 ; Reset the drive FE23 A9 00 LDA #$00 FE25 8D F4 03 STA $03F4 ; Issue a restore command FE28 A9 FF LDA #$FF ; Delay for 1964796 cycles (=almost 2 seconds) FE2A 8D E0 BF STA $BFE0 FE2D 8D E1 BF STA $BFE1 FE30 A9 02 LDA #$02 FE32 8D E2 BF STA $BFE2 FE35 CE E0 BF DEC $BFE0 FE38 D0 0A BNE $FE44 FE3A CE E1 BF DEC $BFE1 FE3D D0 05 BNE $FE44 FE3F CE E2 BF DEC $BFE2 FE42 F0 05 BEQ $FE49 FE44 EA NOP FE45 EA NOP FE46 EA NOP FE47 D0 EC BNE $FE35 FE49 AD F4 03 LDA $03F4 ; Read the status register FE4C 29 20 AND #$20 ; Get the head loaded status FE4E D0 08 BNE $FE58 ; If the head is loaded (disk in drive test?) go to $FE58 FE50 A2 D2 LDX #$D2 ; ROM offset for "BOOTING FAILED!" message FE52 20 71 FE JSR $FE71 ; Print the message FE55 4C 00 04 JMP $0400 FE58 A2 E1 LDX #$E1 ; ROM offset for "BOOTING... TDOS" message FE5A 20 71 FE JSR $FE71 ; Print the message FE5D 20 F0 FE JSR $FEF0 ; Read sector 1 to $400 FE60 4C 00 04 JMP $0400 ; Jump to it! *************************************** (0400) FE63 A9 00 LDA #$00 (0402) FE65 8D FB 03 STA $03FB (0405) FE68 8D F9 03 STA $03F9 (0408) FE6B 8D FC 03 STA $03FC (040B) FE6E 6C FC FF JMP ($FFFC) *************************************** jsPrintMsg FE71 A0 FF LDY #$FF ; Copy from $FE00 + X + 1 to $bb82 (top of the screen) FE73 E8 INX ; End of string is marked by bit 7 being set FE74 C8 INY FE75 BD 00 FE LDA $FE00,X FE78 30 05 BMI $FE7F FE7A 99 82 BB STA $BB82,Y FE7D 10 F4 BPL $FE73 FE7F 29 7F AND #$7F FE81 99 82 BB STA $BB82,Y FE84 60 RTS *************************************** FE85 AD F4 03 LDA $03F4 ; Get drive status FE88 4A LSR ; Busy bit into C FE89 B0 FA BCS $FE85 ; Loop until the drive is not busy FE8B A9 01 LDA #$01 ; Put 1 into the sector register FE8D 8D F6 03 STA $03F6 FE90 A9 8C LDA #$8C ; Read sector (single record, 15ms delay) FE92 8D F4 03 STA $03F4 FE95 A0 00 LDY #$00 ; Reset counter FE97 58 CLI ; Enable interrupts FE98 EA NOP FE99 EA NOP FE9A EA NOP FE9B EA NOP FE9C EA NOP FE9D 58 CLI FE9E AD F4 03 LDA $03F4 ; Loop while the drive is busy FEA1 29 01 AND #$01 ; (IRQ reads data from disk to $400) FEA3 D0 F9 BNE $FE9E FEA5 60 RTS *************************************** FEA6 EA NOP FEA7 EA NOP FEA8 EA NOP FEA9 EA NOP FEAA EA NOP FEAB EA NOP FEAC EA NOP FEAD EA NOP FEAE EA NOP FEAF EA NOP FEB0 EA NOP FEB1 EA NOP FEB2 EA NOP FEB3 EA NOP FEB4 EA NOP FEB5 00 BRK FEB6 05 04 ORA $04 FEB8 0B ??? FEB9 02 ??? FEBA 0C ??? FEBB 08 PHP FEBC 0E 40 00 ASL $0040 FEBF D0 C0 BNE $FE81 FEC1 FF ??? FEC2 10 F4 BPL $FEB8 FEC4 7F ??? FEC5 EA NOP FEC6 EA NOP *************************************** jsIrq FEC7 AA TAX ; Preserve A FEC8 AD F7 03 LDA $03F7 ; Read data byte FECB 99 00 04 STA $0400,Y ; Store at $400+Y FECE C8 INY ; Increment read counter FECF 8A TXA ; Restore A FED0 40 RTI ; Return *************************************** FED1 55 55 'UU' FED3 'BOOTING FAILED' FEE1 A1 '!'+128 FEE2 'BOOTING.. TDO' FEEF D3 'S'+128 *************************************** FEF0 A9 20 LDA #$20 ; Try up to 32 times FEF2 8D E0 BF STA $BFE0 FEF5 CE E0 BF DEC $BFE0 ; Decrement retries FEF8 F0 0A BEQ $FF04 ; Give up? FEFA 20 85 FE JSR $FE85 ; Read sector 1 to $400 FEFD A9 00 LDA #$00 ; Clear intrq FEFF 2D F4 03 AND $03F4 FF02 F0 03 BEQ $FF07 ; Skip fail message FF04 4C 50 FE JMP $FE50 ; Print "BOOTING FAILED!" and die FF07 A9 1C LDA #$1C ; Any lost data or errors? FF09 2D F4 03 AND $03F4 FF0C D0 E7 BNE $FEF5 ; If so, try again FF0E 60 RTS ; Done! *************************************** FF0F FF ??? FF10 A9 35 LDA #$35 FF12 8D 83 BB STA $BB83 FF15 4C 00 04 JMP $0400 FF18 EA NOP *************************************** FF19 to FFFB = $FF padding *************************************** FFFC 00 FD Start vector = $FD00 FFFD C7 FE Interrupt vector = $FEC7