Files
FireBee_SVN/usb/store/bios.S

1379 lines
32 KiB
ArmAsm

/* TOS 4.04 Xbios dispatcher for the CT60/CTPCI boards
* and USB-disk / Ram-Disk utility
* Didier Mequignon 2005-2009, e-mail: aniplay@wanadoo.fr
*
* Modified to be used as an application by David Gálvez 2010.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "vars.h"
#define old_pun_ptr 0x516
#undef pun_ptr
#define pun_ptr pun_ptr_usb
.global _max_logical_drive
#define MAX_LOGICAL_DRIVE _max_logical_drive
.chip 68040
.global ___mint
#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) || \
defined(CONFIG_USB_ISP116X_HCD) || defined(CONFIG_USB_ARANYM_HCD)
#ifdef CONFIG_USB_STORAGE
.global _install_usb_stor,_usb_stor_read,_usb_stor_write,_usb_1st_disk_drive,_SuperFromUser, _SuperTouser
#endif /* CONFIG_USB_STORAGE */
#endif /* CONFIG_USB_UHCI || CONFIG_USB_OHCI || CONFIG_USB_EHCI || CONFIG_USB_ISP116X_HCD */
#if defined(CONFIG_USB_KEYBOARD) || (CONFIG_USB_MOUSE)
.global _asm_set_ipl
.global _call_ikbdvec,_call_mousevec
#endif
#ifdef DEBUG_BIOS_LAYER
.global display_string,hex_long,hex_word,hex_byte,display_char,wait_key,_debug
#endif
.data
/* XHDI */
#define XH_DL_SECSIZ 0 // maximal sector size (BIOS level)
#define XH_DL_MINFAT 1 // minimal number of FATs
#define XH_DL_MAXFAT 2 // maximal number of FATs
#define XH_DL_MINSPC 3 // sectors per cluster minimal
#define XH_DL_MAXSPC 4 // sectors per cluster maximal
#define XH_DL_CLUSTS 5 // maximal number of clusters of a 16 bit FAT
#define XH_DL_MAXSEC 6 // maximal number of sectors
#define XH_DL_DRIVES 7 // maximal number of BIOS drives supported by the DOS
/* AHDI */
#define PUN_DEV 0x1F /* device number of HD */
#define PUN_UNIT 0x07 /* Unit number */
#define PUN_SCSI 0x08 /* 1=SCSI 0=ACSI */
#define PUN_IDE 0x10 /* Falcon IDE */
#define PUN_USB 0x20 /* USB */
#define PUN_REMOVABLE 0x40 /* Removable media */
#define PUN_VALID 0x80 /* zero if valid */
#define pinfo_puns 0 // 2 bytes
#define pinfo_pun 2 // 32 bytes
#define pinfo_pstart 34 // 32 x 4 bytes
#define pinfo_cookie 162 // 4 bytes
#define pinfo_cookptr 166 // 4 bytes
#define pinfo_vernum 170 // 2 bytes
#define pinfo_maxsiz 172 // 2 bytes
#define pinfo_ptype 174 // 32 x 4 bytes
#define pinfo_psize 302 // 32 x 4 bytes
#define pinfo_flags 430 // 32 x 2 bytes, internal use: B15:swap, B7:change, B0:bootable
#define pinfo_bpb 494 // 32 x 32 bytes
#define pinfo_devnum 1518 // 32 bytes
#define pinfo_size 1550
#if 1//#ifdef DEBUG_BIOS_LAYER
//debug1: .asciz "XBIOS #0x"
//debug2: .asciz "Setscreen 0x"
debug3: .asciz "hdv_rw 0x"
debug4: .ascii "hdv_bpb"
.byte 13,10,0
debug5: .ascii "hdv_mediach"
.byte 13,10,0
//debug6: .asciz "Vsetmode 0x"
//debug7: .asciz "ValidMode 0x"
//debug8: .asciz "Gettime 0x
debug132: .asciz "XHDI XHReadWrite 0x"
debug133: .ascii "XHDI XHInqTarget2"
.byte 13,10,0
debug134: .ascii "XHDI XHInqDev"
.byte 13,10,0
debug135: .ascii "XHDI XHInqDriver"
.byte 13,10,0
debug136: .ascii "XHDI XHInqDev2"
.byte 13,10,0
debug137: .ascii "XHDI XHDOSLimits"
.byte 13,10,0
debug138: .ascii "GALVEZ DEBUG" /* Galvez: DEBUG */
.byte 13,10,0
debug139: .ascii "XHDI XHReadWrite" /* Galvez: DEBUG */
.byte 13,10,0
.align 2
#endif
// dc.l 0x58425241 // XBRA
// dc.l 0x5F504349 // _PCI
// dc.l 0 // cannot store here because we are in flash
text_color:
moveq #0,D0
move.w 0x3E86,D0 // number of planes
cmp.l #2,D0
bls.s .black_and_white
pea (A0)
move.w #9,-(SP)
trap #1 // Cconws
addq.l #6,SP
.black_and_white:
rts
#if defined(CONFIG_USB_KEYBOARD) || (CONFIG_USB_MOUSE)
_asm_set_ipl:
link A6,#-8
movem.l D6-D7,(SP)
move.w SR,D7 // current SR
move.l D7,D0 // prepare return value
and.l #0x0700,D0 // mask out IPL
lsr.l #8,D0 // IPL
move.l 8(A6),D6 // get argument
and.l #7,D6 // least significant three bits
lsl.l #8,D6 // move over to make mask
and.l #0x0000F8FF,D7 // zero out current IPL
or.l D6,D7 // place new IPL in SR
move.w D7,SR
movem.l (SP),D6-D7
lea 8(SP),SP
unlk A6
rts
_call_ikbdvec:
lea -24(SP),SP
movem.l D0-D2/A0-A2,(SP)
move.l 28(SP),D0 // ikbd code
move.l 32(SP),A0 // iorec
and.l #0xFF,D0
move.l 0x1132,A2 // ikbdvec
jsr (A2)
movem.l (SP),D0-D2/A0-A2
lea 24(SP),SP
rts
_call_mousevec:
lea -24(SP),SP
movem.l D0-D2/A0-A2,(SP)
move.l 28(SP),A0 // data
move.l 32(SP),A2
move.l (A2),A2 // mousevec
jsr (A2)
movem.l (SP),D0-D2/A0-A2
lea 24(SP),SP
rts
#endif
install_xbra: // A0: handler, D0: vector, D1: ID
lea -28(SP),SP
movem.l D1-D3/A0-A3,(SP)
moveq #0,D3
move.w D0,D3 // vector
move.l A0,A3 // handler
move.l D1,-(SP)
move.w #3,-(SP) // TT ram if possible
move.l #18,-(SP) // size
move.w #0x44,-(SP) // Mxalloc
trap #1
addq.l #8,SP
move.l (SP)+,D1
tst.l D0
beq.s .error_xbra
move.l D0,A0
move.l #0x58425241,(A0)+ // XBRA
move.l D1,(A0)+
clr.l (A0)+
move.w #0x4EF9,(A0)+ // JMP
move.l A3,(A0)+ // handler
lea -10(A0),A0
cpusha BC
move.l D3,A1
move.l (A1),D0
move.l D0,(A0)+ // old vector
move.l A0,(A1) // JMP, new vector
.error_xbra:
tst.l D0
movem.l (SP),D1-D3/A0-A3
lea 28(SP),SP
rts
#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) || \
defined(CONFIG_USB_ISP116X_HCD) || defined(CONFIG_USB_ARANYM_HCD)
#ifdef CONFIG_USB_STORAGE
_install_usb_stor:
lea -32(SP),SP
movem.l D1-D4/A0-A3,(SP)
move.l 36(SP),D0 // dev_num
cmp.l #PUN_DEV,D0
bhi .no_pinfo // error
move.l 40(SP),D2 // part_type
move.l D2,D1
and.l #0xFFFFFF,D1 // ID
// GEMDOS
cmp.l #0x47454D,D1 // GEM up to 16M
beq.s .partition_ok
cmp.l #0x42474D,D1 // BGM over 16M
beq.s .partition_ok
cmp.l #0x524157,D1 // RAW
beq.s .partition_ok
// DOS 1:FAT12, 0xB/0xC:FAT32
cmp.l #0x4,D2 // FAT16 up to 32M
beq.s .partition_ok
cmp.l #0x6,D2 // FAT16 over 32M
beq.s .partition_ok
tst.l ___mint // Galvez: NOT MiNT? then go out
beq .invalid_partition_type
cmp.l #0xE,D2 // WIN95 FAT16
beq .partition_ok
cmp.l #0xB,D2 // FAT32
beq.s .partition_ok
cmp.l #0xC,D2 // FAT32
bne .partition_ok
cmp.l #0x81,D2 // MINIX
bne .partition_ok
cmp.l #0x83,D2 // EXT2/LNX
bne .partition_ok
.partition_ok:
move.l old_pun_ptr,A2 // Galvez: we need it to update hd driver pun struct
move.l pun_ptr,D0
bne.s .pinfo_ok
move.w #3,-(SP) // TT ram if possible
move.l #pinfo_size,-(SP)
move.w #0x44,-(SP) // Mxalloc
trap #1
addq.l #8,SP
move.l D0,pun_ptr
beq.s .no_pinfo
move.l D0,A3
clr.w pinfo_puns(A3)
move.w #0x0300,D0
move.w D0,pinfo_vernum(A3)
move.w #0x4000,D0
move.w D0,pinfo_maxsiz(A3)
lea pinfo_pun(A3),A0
moveq #-1,D0
move.w D0,(A0)+ // drives A/B
move.l D0,(A0)+
move.l D0,(A0)+
move.l D0,(A0)+
move.l D0,(A0)+
move.l D0,(A0)+
move.l D0,(A0)+
move.l D0,(A0)+
move.w D0,(A0)
lea pinfo_pstart(A3),A0
lea pinfo_size(A3),A1
.clrpun:
clr.w -(A1)
cmp.l A0,A1
bgt.s .clrpun
move.l A3,D0 // pun_ptr
.pinfo_ok:
move.l D0,A3 // pun_ptr
moveq #2,D4 // drive C
move.l _drvbits,D0
.search_empty_drive_usb:
btst D4,D0
beq.s .drive_not_exist_usb
addq.l #1,D4
cmp.l #MAX_LOGICAL_DRIVE,D4
bcs.s .search_empty_drive_usb
bra .drive_full_usb // all drives already used
.no_pinfo:
moveq #0,D0 // not installed
bra .end_usb_disk
.drive_not_exist_usb:
move.w pinfo_puns(A3),D0
addq.l #1,D0
move.w D0,pinfo_puns(A3)
moveq #0,D0
bset #7,D0 // changed
lea pinfo_flags(A3),A0
move.l D0,(A0,D4.l*4) // B15:swap, B7:change, B0:bootable
lea pinfo_psize(A3),A0
move.l 48(SP),D3 // part_size
move.l 44(SP),D1 // part_offset
move.l 40(SP),D2 // part_type
move.l 36(SP),D0 // dev_num
move.b D0,pinfo_devnum(A3,D4.l)
move.l D2,pinfo_ptype(A3,D4.l*4)
move.l D4,D2
or.l #PUN_USB,D2
move.b D2,pinfo_pun(A3,D4.l)
cmp.l #15,D4 // Galvez: update AHDI pun struct:
bgt .ahdi_part_num_limit // Galvez: if logical part. > 16
move.b D2,pinfo_pun(A2,D4.l) // Galvez: don't update pun struct,
move.w D0,-(SP) // Galvez: to avoid corruption.
move.w pinfo_puns(A2),D0 // Galvez: update hd driver pun stuct
addq.l #1,D0 // Galvez: othewise MiNT only handles 16MB
move.w D0,pinfo_puns(A2) // Galvez: when not using XHDI
move.w (SP)+,D0 // Galvez: see BLOCK_IO.c (MiNT sources)
.ahdi_part_num_limit:
move.l D3,(A0,D4.l*4) // size
move.l D1,pinfo_pstart(A3,D4.l*4)
move.l _dskbufp,A0
move.l A0,-(SP) // buffer
move.l #1,-(SP) // blkcnt
move.l D1,-(SP) // blknr
move.l D0,-(SP) // devnum
jsr _usb_stor_read
lea 16(SP),SP
tst.l D0
beq .end_usb_disk // read error
tst.l _usb_1st_disk_drive
bne .usb_1st_drive_ok // hdv vectors installed
move.l D4,_usb_1st_disk_drive
move.w SR,D0
move.w D0,-(SP)
or.l #0x700,D0 // mask interrupts
move.w D0,SR
move.l #0x5F555342,D1 // _USB
lea det_hdv_bpb_usb(PC),A0
move.w #hdv_bpb,D0
bsr install_xbra
move.l D0,old_hdv_bpb_usb
lea det_hdv_rw_usb(PC),A0
move.w #hdv_rw,D0
bsr install_xbra
move.l D0,old_hdv_rw_usb
lea det_hdv_mediach_usb(PC),A0
move.w #hdv_mediach,D0
bsr install_xbra
move.l D0,old_hdv_mediach_usb
move.l cookie,D0
beq.s .no_cookie_jar
move.l D0,A0
move.l #0x58484449,D1 // XHDI
.find_cookie_jar:
tst.l (A0)
beq.s .cookie_slot_free
cmp.l (A0),D1
beq.s .cookie_found
addq.l #8,A0
bra.s .find_cookie_jar
.cookie_found:
move.l 4(A0),D0
move.l D0,old_xhdi
lea xhdi(PC),A1
clr.l -(SP) // XHGetVersion
move.l D0,A0
jsr (A0)
addq.l #4,SP
move.l D0,old_xhdi_version
move.l A1,-(SP)
move.w #9,-(SP) // Galvez: XHNewCookie
jsr (A0)
add.l #6,SP
tst.l D0
beq.s .no_cookie_jar
move.l A1,4(A0) // Galvez: Replace cookie "by-hand"
bra.s .no_cookie_jar
.cookie_slot_free:
move.l 4(A0),12(A0) // copy size
lea xhdi(PC),A1
move.l A1,(A0)+
clr.l (A0)
clr.l old_xhdi
move.l #0x120,D0 // protocol version
move.l D0,old_xhdi_version
.no_cookie_jar:
move.w (SP)+,D0
move.w D0,SR // restore interrupts
.usb_1st_drive_ok:
move.l _dskbufp,A0 // boot sector
lea pinfo_bpb(A3),A1
move.l D4,D2 // logical drive
asl.l #5,D2 // * 32
add.l D2,A1
moveq #0,D2
move.b 0xC(A0),D2
asl.l #8,D2
move.b 0xB(A0),D2 // BPS
move.w D2,(A1) // sector size
moveq #0,D1
move.b 0xD(A0),D1 // SPC
move.w D1,2(A1) // cluster size in sectors
move.w D1,D0
mulu D2,D0
move.w D0,4(A1) // cluster size in bytes
moveq #0,D0
move.b 0x12(A0),D0
asl.l #8,D0
move.b 0x11(A0),D0 // NDIRS
asl.l #5,D0 // * 32
divu D2,D0 // / sector size
move.w D0,6(A1) // size directory in sectors
moveq #0,D2
move.b 0x17(A0),D2
asl.l #8,D2
move.b 0x16(A0),D2 // SPF
move.w D2,8(A1) // FAT size
moveq #0,D0
move.b 0xF(A0),D0
asl.l #8,D0
move.b 0xE(A0),D0 // RES
move.l D0,D3
add.l D2,D3 // + FAT size
move.w D3,10(A1) // 1st sector of FAT2
moveq #0,D3
move.b 0x10(A0),D3 // NFATS
mulu D2,D3 // * FAT size
add.l D0,D3 // + RES
moveq #0,D0
move.w 6(A1),D0 // size directory in sectors
add.l D3,D0
move.w D0,12(A1) // 1st data sector
moveq #0,D2
move.b 0x14(A0),D2
asl.l #8,D2
move.b 0x13(A0),D2 // NSECTS
bne.s .nsects_ok_usb
lea pinfo_psize(A3),A2
move.l (A2,D4.w*4),D2 // partition size in sectors
sub.l D0,D2 // - 1st data sector
.nsects_ok_usb:
divu D1,D2
move.w D2,14(A1) // total clusters
moveq #1,D0
move.w D0,16(A1) // FAT 16
clr.w 18(A1)
clr.l 20(A1)
clr.l 24(A1)
clr.l 28(A1)
move.l _drvbits,D0
bset D4,D0
move.l D0,_drvbits
moveq #2,D0 // drive C
cmp.l D4,D0
bne.s .no_set_drive_usb
move.w D0,_bootdev
move.w D0,-(SP)
move.w #0xE,-(SP) // Dsetdrv
trap #1
addq.l #4,SP
.no_set_drive_usb:
move.l 36(SP),D0 // devnum
movem.l 52(SP),A1/A2/A3 // vendor / revision / product
move.l product_name,A0 // save product name pointer for XHDI
#if DEBUG_BIOS_LAYER
move.l D0, -(SP)
move.b D4,D0
jsr hex_byte /* Galvez: DEBUG device */
move.l (SP)+,D0
#endif
move.l A3,(A0,D4.l*4)
bsr display_drive_usb
pea message2b(PC)
move.w #9,-(SP)
trap #1 // Cconws
addq.l #6,SP
moveq #0x41,D0 // A
add.l D4,D0
move.w D0,-(SP)
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
pea crlf(PC)
move.w #9,-(SP)
trap #1 // Cconws
addq.l #6,SP
move.l D4,D0 // OK
bra.s .end_usb_disk
.invalid_partition_type:
pea error4(PC)
bra.s .display_error_usb
.drive_full_usb:
pea error2(PC)
.display_error_usb:
move.l 36+4(SP),D0 // devnum
movem.l 52+4(SP),A1/A2/A3 // vendor / revision / product
bsr display_drive_usb
move.w #0x2C,-(SP)
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
move.w #0x20,-(SP)
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
move.w #9,-(SP)
trap #1 // Cconws
addq.l #6,SP
moveq #0,D0 // not installed
.end_usb_disk:
movem.l (SP),D1-D4/A0-A3
lea 32(SP),SP
rts
display_drive_usb:
move.l A1,-(SP)
moveq #0x30,D1
add.l D1,D0 // dev_num
move.w D0,-(SP)
lea blue(PC),A0
bsr text_color
pea message2(PC) // USB-disk installed
move.w #9,-(SP)
trap #1 // Cconws
addq.l #6,SP
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
move.w #0x2E,-(SP)
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
move.w #0x30,-(SP)
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
lea black(PC),A0
bsr text_color
move.w #0x20,-(SP)
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
move.w #9,-(SP)
trap #1 // Cconws
addq.l #6,SP
move.w #0x20,-(SP)
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
move.l A2,-(SP)
move.w #9,-(SP)
trap #1 // Cconws
addq.l #6,SP
move.w #0x20,-(SP)
move.w #2,-(SP)
trap #1 // Cconout
addq.l #4,SP
move.l A3,-(SP)
move.w #9,-(SP)
trap #1 // Cconws
addq.l #6,SP
rts
det_hdv_bpb_usb:
move.l A0,-(SP)
move.l pun_ptr,A0
moveq #0,D0
move.w 4+4(SP),D0 // drive
cmp.l _usb_1st_disk_drive,D0
bcs.s .dhbu2
cmp.l #MAX_LOGICAL_DRIVE,D0
bcc.s .dhbu2
tst.b pinfo_pun(A0,D0.l)
bpl.s .dhbu1
.dhbu2:
move.l (SP)+,A0
moveq #0,D0
move.l old_hdv_bpb_usb,-(SP)
rts
.dhbu1:
move.l D1,-(SP)
move.l pinfo_ptype(A0,D0.l*4),D1
and.l #0xFFFFFF,D1
cmp.l #0x524157,D1 // RAW
beq.s .dhbu4
cmp.l #0x81,D1 // MINIX
beq.s .dhbu4
cmp.l #0x83,D1 // EXT2/LNX
bne.s .dhbu3
.dhbu4:
move.l (SP)+,D1
move.l (SP)+,A0
moveq #0,D0
rts
.dhbu3:
lea pinfo_bpb(A0),A0
asl.l #5,D0 // * 32
add.l A0,D0
#if DEBUG_BIOS_LAYER
move.l D0,-(SP)
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.l (SP),D0
jsr hex_long
moveq #0x20,D0
jsr display_char
lea debug4(PC),A0
jsr display_string
move.l (SP)+,D0
#endif
move.l (SP)+,D1
move.l (SP)+,A0
rts
det_hdv_rw_usb:
lea -28(SP),SP
movem.l D1-D4/A0-A2,(SP)
#if DEBUG_BIOS_LAYER
lea debug3(PC),A0
jsr display_string
move.w 4+28(SP),D0 // rwflag
jsr hex_word
moveq #0x20,D0
jsr display_char
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.l 6+28(SP),D0 // buffer
jsr hex_long
moveq #0x20,D0
jsr display_char
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.w 10+28(SP),D0 // num sectors
jsr hex_word
moveq #0x20,D0
jsr display_char
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.w 12+28(SP),D0 // logical sector
jsr hex_word
moveq #0x20,D0
jsr display_char
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.w 16+28(SP),D0 // Galvez: logical sector (lrecno)
jsr hex_long
moveq #0x20,D0
jsr display_char
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.w 14+28(SP),D0 // drive
jsr hex_word
moveq #13,D0
jsr display_char
moveq #10,D0
jsr display_char
#endif
btst #3,5+28(SP) // rwflag
bne.s .dhru8 // physical
move.l pun_ptr,A0
moveq #0,D0
move.w 14+28(SP),D0 // drive
cmp.l _usb_1st_disk_drive,D0
bcs.s .dhru8
cmp.l #MAX_LOGICAL_DRIVE,D0
bcc.s .dhru8
moveq #0,D4
move.b pinfo_pun(A0,D0.l),D4
bpl.s .dhru1 // valid
.dhru8:
movem.l (SP),D1-D4/A0-A2
lea 28(SP),SP
moveq #0,D0
move.l old_hdv_rw_usb,-(SP)
rts
.dhru1:
move.l D4,D2
and.l #PUN_USB,D2
beq.s .dhru8 // not USB
and.l #PUN_DEV,D4
moveq #0,D2
move.w 12+28(SP),D2 // logical sector
cmp.w #0xffff,D2 // Galvez: check recno <> -1
bne.s .dhru6
move.l 16+28(SP),D2 // logical sector
.dhru6:
tst.l D2
bmi .dhru2 // negative logical sector
move.l 6+28(SP),D1 // buffer
beq .dhru4 // no buffer
move.l pinfo_pstart(A0,D0.l*4),D3
move.l pinfo_devnum(A0,D0.l),D4 // devnum in the USB bus
lea pinfo_bpb(A0),A0
asl.l #5,D0 // * 32
add.l D0,A0
move.w 14(A0),D0 // total clusters
mulu.w 2(A0),D0 // cluster size in sectors
cmp.l D0,D2 // logical sector to hight
bcc .dhru2
moveq #0,D0
move.w (A0),D0 // sector size
lsr.l #8,D0
lsr.l #1,D0 // / 512
move.l D1,A0 // buffer
move.w 10+28(SP),D1 // num sectors
beq .dhru4 // no sectors
mulu D0,D1
mulu.l D0,D2
add.l D3,D2 // start sector
move.l D1,D3 // count
btst #0,5+28(SP) // rwflag
beq.s .dhru7 // read
// write
tst.l D2 // logical sector
beq.s .dhru2 // root sector
move.l A0,-(SP) // buffer
move.l D3,-(SP) // blkcnt
move.l D2,-(SP) // blknr
move.l D4,-(SP) // USB devnum
jsr _usb_stor_write
bra.s .dhru5
.dhru2:
moveq #-1,D0 // error
bra.s .dhru3
.dhru4:
moveq #0,D0 // OK
bra.s .dhru3
.dhru7:
move.l A0,-(SP) // buffer
move.l D3,-(SP) // blkcnt
move.l D2,-(SP) // blknr
move.l D4,-(SP) // USB devnum
jsr _usb_stor_read
.dhru5:
lea 16(SP),SP
tst.l D0
seq.b D0
ext.w D0
ext.l D0
bclr #0,D0 // OK or device not responding -2
.dhru3:
movem.l (SP),D1-D4/A0-A2
lea 28(SP),SP
rts
det_hdv_mediach_usb:
move.l A0,-(SP)
move.l pun_ptr,A0
moveq #0,D0
move.w 4+4(SP),D0 // drive
cmp.l _usb_1st_disk_drive,D0
bcs.s .dhmu2
cmp.l #MAX_LOGICAL_DRIVE,D0
bcc.s .dhmu2
tst.b pinfo_pun(A0,D0.l)
bpl.s .dhmu1
.dhmu2:
move.l (SP)+,A0
moveq #0,D0
move.l old_hdv_mediach_usb,-(SP)
rts
.dhmu1:
#if 0 // #if DEBUG_BIOS_LAYER
move.l A0,-(SP)
lea debug5(PC),A0
jsr display_string
move.l (SP)+,A0
#endif
lea pinfo_flags(A0),A0
add.l D0,A0
add.l D0,A0
bclr #7,1(A0)
sne.b D0
and.l #2,D0
move.l (SP)+,A0
rts
// XHDI
dc.l 0x27011992
xhdi:
link A6,#0
movem.l D1-A5,-(SP)
moveq #0,D1
move.w 8(A6),D1
move.w D1,D0
#if DEBUG_BIOS_LAYER
move.w D0, -(SP)
jsr hex_word /* Galvez: DEBUG. XHDI function */
move.w (SP)+,D0
#endif
moveq #-32,D0 // invalid function
cmp.l #18,d1
bcc.s .bad_xhdi
move.w SR,D0 // supervisor only
moveq #-1,d0 // error
move.w tab_xhdi(PC,D1.l*2),D1
jsr tab_xhdi(PC,D1.W)
.bad_xhdi:
movem.l (SP)+,D1-A5
unlk A6
rts
#if DEBUG_BIOS_LAYER
debug:
lea debug138(PC),A0
jsr display_string
rts
#endif
tab_xhdi:
dc.w XHGetVersion-tab_xhdi // 0
dc.w XHInqTarget-tab_xhdi // 1
dc.w XHReserve-tab_xhdi // 2
dc.w XHLock-tab_xhdi // 3
dc.w XHStop-tab_xhdi // 4
dc.w XHEject-tab_xhdi // 5
dc.w XHDrvMap-tab_xhdi // 6
dc.w XHInqDev-tab_xhdi // 7
dc.w XHInqDriver-tab_xhdi // 8
dc.w XHNewCookie-tab_xhdi // 9
dc.w XHReadWrite-tab_xhdi // 10
dc.w XHInqTarget2-tab_xhdi // 11
dc.w XHInqDev2-tab_xhdi // 12
dc.w XHDriverSpecial-tab_xhdi // 13
dc.w XHGetCapacity-tab_xhdi // 14
dc.w XHMediumChanged-tab_xhdi // 15
dc.w XHMiNTInfo-tab_xhdi // 16
dc.w XHDOSLimits-tab_xhdi // 17
XHGetVersion:
#if DEBUG_BIOS_LAYER
move.l A0,-(SP)
lea debug138(PC),A0
jsr display_string
move.l (SP)+,A0
#endif
move.l #0x120,D0 // protocol version
move.l old_xhdi_version,D1
cmp.l D1,D0
bcs.s .xv1
move.l D1,D0 // minimum version
.xv1:
rts
XHInqTarget:
moveq #32,D2 // stringlen
bra.s .xi1
XHInqTarget2:
#if DEBUG_BIOS_LAYER
move.l A0,-(SP)
lea debug133(PC),A0
jsr display_string
move.l (SP)+,A0
#endif
move.w 26(A6),D2 // stringlen
.xi1:
tst.w 12(A6) // minor
bne.s .xi2
moveq #0,D0
move.w 10(A6),D0 // major
cmp.w #PUN_USB,D0
bcs.s .xi2
cmp.w #PUN_USB+PUN_DEV,D0
bls.s .xi3
.xi2:
tst.l old_xhdi
beq.s .xi7
moveq #-15,D0 // unknown device
rts
.xi7:
move.l old_xhdi,-(SP)
rts
.xi3:
tst.l 14(A6)
beq.s .xi8
move.l 14(A6),A0
move.l #512,(A0)
.xi8:
tst.l 18(A6)
beq.s .xi9
move.l 18(A6),A0 // flags
move.l #0x00000002,(A0) // removable
.xi9:
move.l 22(A6),D1 // product_name
beq.s .xi6 // no pointer
move.l D1,A0
and.b #PUN_DEV,D0
move.l product_name,A1
move.l (A1,D0.l*4),D0 // Galvez: D0 should be the bios drive number
beq.s .xi6 // no pointer
move.l D0,A1
.xi5:
move.b (A1)+,(A0)+
beq.s .xi4
subq.w #1,D2
bpl.s .xi5 // Galvez: test
.xi4:
clr.b -1(A0)
.xi6:
moveq #0,D0
rts
XHReserve:
XHLock:
XHStop:
XHEject:
tst.l old_xhdi
beq.s .xnu1
moveq #0,D0
rts
.xnu1:
move.l old_xhdi,-(SP)
rts
XHDrvMap:
move.l _drvbits,D0
rts
XHInqDev:
#if DEBUG_BIOS_LAYER
lea debug134(PC),A0
jsr display_string
#endif
move.l pun_ptr,A0
moveq #0,D0
move.w 10(A6),D0 // bios_device
cmp.l _usb_1st_disk_drive,D0
bcs.s .xd2
cmp.l #MAX_LOGICAL_DRIVE,D0
bcc.s .xd2
moveq #0,D1
move.b pinfo_pun(A0,D0.l),D1
bpl.s .xd1
.xd2:
tst.l old_xhdi
beq.s .xd3
moveq #-46,D0 // invalid drive number
rts
.xd3:
move.l old_xhdi,-(SP)
rts
.xd1:
move.l D1,D2
and.l #PUN_USB+PUN_DEV,D2
beq.s .xd2
tst.l 12(A6)
beq.s .xd4
move.l 12(A6),A1 // major
move.w D1,(A1)
.xd4:
tst.l 16(A6)
beq.s .xd5
move.l 16(A6),A1 // minor
clr.w (A1)
.xd5:
tst.l 20(A6)
beq.s .xd6
move.l pinfo_pstart(A0,D0.l*4),D1
move.l 20(A6),A1 // start_sector
move.l D1,(A1)
.xd6:
lea pinfo_bpb(A0),A0
asl.l #5,D0 // * 32
add.l A0,D0
tst.l 24(A6)
beq.s .xd7
move.l 24(A6),A1 // bpb
move.l D0,(A1)
.xd7:
moveq #0,D0
rts
XHInqDriver:
#if DEBUG_BIOS_LAYER
lea debug135(PC),A0
jsr display_string
#endif
move.l pun_ptr,A0
moveq #0,D0
move.w 10(A6),D0 // bios_device
cmp.l _usb_1st_disk_drive,D0
bcs.s .xdr2
cmp.l #MAX_LOGICAL_DRIVE,D0
bcc.s .xdr2
moveq #0,D1
move.b pinfo_pun(A0,D0.l),D1
bpl.s .xdr1
.xdr2:
tst.l old_xhdi
beq.s .xdr8
moveq #-46,D0 // invalid drive number
rts
.xdr8:
move.l old_xhdi,-(SP)
rts
.xdr1:
move.l D1,D0
and.l #PUN_USB,D0
beq.s .xdr2
move.l 12(A6),D0 // name, 17 characters
beq.s .xdr3
move.l D0,A1
lea message1(PC),A0
moveq #17,D1
.xdr6:
move.b (A0)+,D0
beq.s .xdr7
move.b D0,(A1)+
subq.l #1,D1
bpl.s .xdr6
.xdr7:
clr.b (A1)
.xdr3:
move.l 16(A6),D0 // version, 7 characters
beq.s .xdr4
move.l D0,A1
move.b #0x34,(A1)+ // ??? TOS 4.04
move.b #0x2E,(A1)+
move.b #0x30,(A1)+
move.b #0x34,(A1)+
clr.b (A1)
.xdr4:
move.l 20(A6),D0 // company, 17 characters
beq.s .xdr5
move.l D0,A1
clr.b (A1)
.xdr5:
move.l 24(A6),A1 // ahdi_version
move.w pinfo_vernum(A0),(A1)
move.l 28(A6),A1 // maxIPL
moveq #5,D0
move.w D0,(A1)
moveq #0,D0
rts
XHReadWrite: // read / write physical sectors
#if DEBUG_BIOS_LAYER
lea debug139(PC),A0
jsr display_string
#endif
tst.w 12(A6) // minor
bne.s .xr4
moveq #0,D4
move.w 10(A6),D4 // major
cmp.l #PUN_USB,D4
bcs.s .xr4
cmp.l #PUN_USB+PUN_DEV,D4
bls.s .xr1
.xr4:
tst.l old_xhdi
beq.s .xr6
moveq #-15,D0 // unknown device
rts
.xr6:
move.l old_xhdi,-(SP)
rts
.xr1:
#if DEBUG_BIOS_LAYER
lea debug132(PC),A0
jsr display_string
move.w 14(A6),D0 // rwflag
jsr hex_word
moveq #0x20,D0
jsr display_char
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.l 24(A6),D0 // buffer
jsr hex_long
moveq #0x20,D0
jsr display_char
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.w 20(A6),D0 // num sectors
jsr hex_word
moveq #0x20,D0
jsr display_char
moveq #0x30,D0
jsr display_char
moveq #0x78,D0
jsr display_char
move.l 16(A6),D0 // logical sector
jsr hex_long
moveq #13,D0
jsr display_char
moveq #10,D0
jsr display_char
#endif
move.l 22(A6),A0 // buffer
moveq #0,D3
move.w 20(A6),D3 // count
beq .xr2 // no sectors
move.l 16(A6),D2 // start sector
btst #0,15(A6) // rwflag
beq.s .xr7 // read
// write
move.l A0,-(SP) // buffer
move.l D3,-(SP) // blkcnt
move.l D2,-(SP) // blknr
move.l D4,D0 // major
and.l #PUN_DEV,D0
move.l pun_ptr,A0
move.b pinfo_devnum(A0,D0.l),D0 // devnum in the USB bus
move.l D0,-(SP) // USB devnum
jsr _usb_stor_write
bra.s .xr5
.xr2:
moveq #-1,D0 // error
bra.s .xr3
.xr7:
move.l A0,-(SP) // buffer
move.l D3,-(SP) // blkcnt
move.l D2,-(SP) // blknr
move.l D4,D0 // major
and.l #PUN_DEV,D0
move.l pun_ptr,A0
move.b pinfo_devnum(A0,D0.l),D0 // devnum in the USB bus
move.l D0,-(SP) // USB devnum
jsr _usb_stor_read
.xr5:
lea 16(SP),SP
tst.l D0
seq.b D0
ext.w D0
ext.l D0
bclr #0,D0 // OK or device not responding -2
.xr3:
rts
XHInqDev2:
#if DEBUG_BIOS_LAYER
lea debug136(PC),A0
jsr display_string // Galvez: changed bsr by jsr to avoid linker error
#endif
move.l pun_ptr,A0
moveq #0,D0
move.w 10(A6),D0 // bios_device
cmp.l _usb_1st_disk_drive,D0
bcs.s .xdd2
cmp.l #MAX_LOGICAL_DRIVE,D0
bcc.s .xdd2
moveq #0,D1
move.b pinfo_pun(A0,D0.l),D1
bpl.s .xdd1
.xdd2:
tst.l old_xhdi
beq.s .xdd4
moveq #-46,D0 // invalid drive number
rts
.xdd4:
move.l old_xhdi,-(SP)
rts
.xdd1:
move.w D1,D2
and.b #PUN_USB+PUN_DEV,D2
beq.s .xdd2
tst.l 12(A6)
beq.s .xdd5
move.l 12(A6),A1 // major
move.w D2,(A1)
.xdd5:
tst.l 16(A6)
beq.s .xdd6
move.l 16(A6),A1 // minor
clr.w (A1)
.xdd6:
tst.l 20(A6)
beq.s .xdd7
move.l pinfo_pstart(A0,D0.l*4),D1
move.l 20(A6),A1 // start_sector
move.l D1,(A1)
.xdd7:
tst.l 24(A6)
beq.s .xdd8
lea pinfo_bpb(A0),A2
move.l D0,D1
asl.l #5,D1 // * 32
add.l A2,D1
move.l 24(A6),A1 // bpb
move.l D1,(A1)
.xdd8:
tst.l 28(A6)
beq.s .xdd9
move.l 28(A6),A1 // blocks
lea pinfo_psize(A0),A2
move.l (A2,D0.l*4),(A1)
.xdd9:
tst.l 32(A6)
beq.s .xdd10
move.l 32(A6),A1 // partid
clr.l (A1)
move.b pinfo_ptype+3(A0,D0.l*4),D1
move.w #0x0044,(A1) // NULL+ 'D'
move.b D1,2(A1)
.xdd10:
moveq #0,D0
rts
XHDriverSpecial:
XHGetCapacity:
XHMediumChanged:
XHMiNTInfo:
XHNewCookie:
tst.l old_xhdi
beq.s .xn1
moveq #-32,D0 // invalid function number
rts
.xn1:
move.l old_xhdi,-(SP)
rts
XHDOSLimits:
tst.l old_xhdi
bne.s .xn1
#if DEBUG_BIOS_LAYER
lea debug137(PC),A0
jsr display_string
#endif
moveq #0,D0
move.w 10(A6),D0 // which
cmp.l #XH_DL_SECSIZ,D0 // maximal sector size (BIOS level)
bne.s .xl1
move.l #0x4000,D0
rts
.xl1:
cmp.l #XH_DL_MINFAT,D0 // minimal number of FATs
bne.s .xl2
moveq #1,D0
rts
.xl2:
cmp.l #XH_DL_MAXFAT,D0 // maximal number of FATs
bne.s .xl3
moveq #2,D0
rts
.xl3:
cmp.l #XH_DL_MINSPC,D0 // sectors per cluster minimal
bne.s .xl4
moveq #2,D0
rts
.xl4:
cmp.l #XH_DL_MAXSPC,D0 // sectors per cluster maximal
bne.s .xl5
#ifdef COLDFIRE
moveq #64,D0 // for this Coldfire version of BDOS, else 2
#else
moveq #2,D0
#endif
rts
.xl5:
cmp.l #XH_DL_CLUSTS,D0 // maximal number of clusters of a 16 bit FAT
bne.s .xl6
move.l #0x8000,D0
rts
.xl6:
cmp.l #XH_DL_MAXSEC,D0 // maximal number of sectors
bne.S .xl7
#ifdef COLDFIRE
move.l #0x200000,D0 // for this Coldfire version of BDOS, else 0x10000
#else
move.l #0x10000,D0
#endif
rts
.xl7:
cmp.l #XH_DL_DRIVES,D0 // maximal number of BIOS drives supported by the DOS
bne.s .xl8
moveq #16,D0
rts
.xl8:
moveq #-32,D0 // invalid function number
rts
#endif /* CONFIG_USB_STORAGE */
#endif /* CONFIG_USB_UHCI || CONFIG_USB_OHCI || CONFIG_USB_EHCI || CONFIG_USB_ISP116X_HCD */
#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) || \
defined(CONFIG_USB_ISP116X_HCD) || defined(CONFIG_USB_ARANYM_HCD)
#ifdef CONFIG_USB_STORAGE
message1: .ascii "TOS4.04 "
message2: .asciz "USB "
message2b: .asciz ", disk installed in "
#endif
#endif
crlf: .byte 13,10,0
error: .asciz "No ram-disk installed, "
error1: .ascii "no enough radeon memory"
.byte 13,10,0
error2: .ascii "all drives already used"
.byte 13,10,0
error3: .ascii "error disk name"
.byte 13,10,0
error4: .ascii "partition type not supported"
.byte 13,10,0
blue: .byte 0x1B,0x62,0x34,0
black: .byte 0x1B,0x62,0x3F,0
.align 2
#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) \
|| defined(CONFIG_USB_ISP116X_HCD) || defined(CONFIG_USB_ARANYM_HCD)
#ifdef CONFIG_USB_STORAGE
.lcomm pun_ptr_usb,4
.lcomm user_sp,4
.lcomm _usb_1st_disk_drive,4
.lcomm old_hdv_bpb_usb,4
.lcomm old_hdv_rw_usb,4
.lcomm old_hdv_mediach_usb,4
.lcomm old_xhdi,4
.lcomm old_xhdi_version,4
.lcomm product_name,4*(PUN_DEV+1)
#endif /* CONFIG_USB_STORAGE */
#endif /* CONFIG_USB_UHCI || CONFIG_USB_OHCI || CONFIG_USB_EHCI || CONFIG_USB_ISP116X_HCD */