Module Name:    src
Committed By:   isaki
Date:           Sun Aug 16 06:43:44 UTC 2020

Modified Files:
        src/sys/arch/x68k/stand/libiocs: iocscall.h
        src/sys/arch/x68k/stand/xxboot: Makefile.xxboot boot.S bootmain.c
            consio1.c version xx.c xxboot.h xxboot.ldscript
        src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1: Makefile
        src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2: Makefile
        src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1: Makefile
        src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2: Makefile
Added Files:
        src/sys/arch/x68k/stand/xxboot: ashldi3.S ashrdi3.S memcmp.S memcpy.S
            memset.S
        src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs: Makefile

Log Message:
Overhaul xxboot.  And merge floppy boot, taken from boot_ustar.
- Rewrite boot.S completely.
  boot.S now supports boot from SCSI HD/CD and floppy.
- Use IOCS call to identify the floppy format, instead of chkfmt.s which
  accesses hardware directly.
- Import print_hex() debug function from boot_ufs.
- Import a feature that displays initial registers (for debug) from boot_ufs,
  and restore it (this in boot_ufs has been broken).
- Add size optimized alternatives for some libkern routines.
- Stop linking libsa to prevent to link unexpected objects.
- Bump version to 2.0.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/x68k/stand/libiocs/iocscall.h
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/x68k/stand/xxboot/Makefile.xxboot
cvs rdiff -u -r0 -r1.1 src/sys/arch/x68k/stand/xxboot/ashldi3.S \
    src/sys/arch/x68k/stand/xxboot/ashrdi3.S \
    src/sys/arch/x68k/stand/xxboot/memcmp.S \
    src/sys/arch/x68k/stand/xxboot/memcpy.S \
    src/sys/arch/x68k/stand/xxboot/memset.S
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/x68k/stand/xxboot/boot.S
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/x68k/stand/xxboot/bootmain.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/x68k/stand/xxboot/consio1.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/x68k/stand/xxboot/version \
    src/sys/arch/x68k/stand/xxboot/xx.c \
    src/sys/arch/x68k/stand/xxboot/xxboot.h
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/x68k/stand/xxboot/xxboot.ldscript
cvs rdiff -u -r0 -r1.1 src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x68k/stand/libiocs/iocscall.h
diff -u src/sys/arch/x68k/stand/libiocs/iocscall.h:1.2 src/sys/arch/x68k/stand/libiocs/iocscall.h:1.3
--- src/sys/arch/x68k/stand/libiocs/iocscall.h:1.2	Sat Jan 18 05:07:34 2020
+++ src/sys/arch/x68k/stand/libiocs/iocscall.h	Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: iocscall.h,v 1.2 2020/01/18 05:07:34 isaki Exp $	*/
+/*	$NetBSD: iocscall.h,v 1.3 2020/08/16 06:43:43 isaki Exp $	*/
 
 /*
  *	IOCS call macros for X680x0
@@ -30,6 +30,7 @@
 #define __B_CLR_ST	0x2A
 #define __B_READ	0x46
 #define __B_RECALI	0x47
+#define __B_READID	0x4A
 #define __B_DRVCHK	0x4E
 #define __BOOTINF	0xFFFFFF8E
 #define __JISSFT	0xFFFFFFA1

Index: src/sys/arch/x68k/stand/xxboot/Makefile.xxboot
diff -u src/sys/arch/x68k/stand/xxboot/Makefile.xxboot:1.17 src/sys/arch/x68k/stand/xxboot/Makefile.xxboot:1.18
--- src/sys/arch/x68k/stand/xxboot/Makefile.xxboot:1.17	Fri Aug 14 03:54:46 2020
+++ src/sys/arch/x68k/stand/xxboot/Makefile.xxboot	Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.xxboot,v 1.17 2020/08/14 03:54:46 isaki Exp $
+#	$NetBSD: Makefile.xxboot,v 1.18 2020/08/16 06:43:43 isaki Exp $
 
 NOMAN=		# defined
 
@@ -25,7 +25,12 @@ BINMODE=	444
 S=		${.CURDIR}/../../../../..
 M=		$S/arch/x68k
 .PATH:		${.CURDIR}/..
-SRCS=	boot.S bootmain.c conf.c consio1.c xx.c
+SRCS=	boot.S bootmain.c conf.c xx.c
+SRCS+=	ashrdi3.S
+SRCS+=	ashldi3.S
+SRCS+=	memcpy.S
+SRCS+=	memset.S
+SRCS+=	memcmp.S
 
 .include "${S}/conf/newvers_stand.mk"
 
@@ -47,7 +52,7 @@ LINKFLAGS+=  --defsym=BOOT_TEXTADDR=$(BO
 LINKFLAGS+=  --defsym=TEXTDATASIZE=$(TEXTDATASIZE)
 LIBIOCS!= cd $M/stand/libiocs && ${PRINTOBJDIR}
 LIBSA!=	  cd $M/stand/libsa && ${PRINTOBJDIR}
-LDLIBS=	  -L${LIBSA}/lib/sa -lsa -L ${LIBSA}/lib/kern -lkern
+LDLIBS=	  -L ${LIBSA}/lib/kern -lkern
 LDLIBS+=  -L${LIBIOCS} -liocs
 
 .PATH: $S/lib/libsa
@@ -57,8 +62,11 @@ CPPFLAGS+= -DLIBSA_NO_FD_CHECKING
 CPPFLAGS+= -DLIBSA_NO_FS_WRITE
 CPPFLAGS+= -DLIBSA_NO_RAW_ACCESS
 CPPFLAGS+= -DLIBSA_NO_TWIDDLE
+CPPFLAGS+= -DUSTAR_SECT_PER_CYL=30
 SRCS+=	open.c close.c read.c lseek.c loadfile.c loadfile_aout.c alloc.c
+SRCS+=	errno.c globals.c
 SRCS+=  $(FS).c
+SRCS+=	${BOOTSRCS}
 
 .PATH: $M/stand/common
 SRCS+=	exec_image.S

Index: src/sys/arch/x68k/stand/xxboot/boot.S
diff -u src/sys/arch/x68k/stand/xxboot/boot.S:1.12 src/sys/arch/x68k/stand/xxboot/boot.S:1.13
--- src/sys/arch/x68k/stand/xxboot/boot.S:1.12	Tue Jan 28 12:02:02 2020
+++ src/sys/arch/x68k/stand/xxboot/boot.S	Sun Aug 16 06:43:43 2020
@@ -1,8 +1,4 @@
-| file: boot.S
-| author: chapuni([email protected])
-|         ITOH Yasufumi
-|
-| $NetBSD: boot.S,v 1.12 2020/01/28 12:02:02 isaki Exp $
+| $NetBSD: boot.S,v 1.13 2020/08/16 06:43:43 isaki Exp $
 
 |
 | (1) IPL (or previous stage loader) loads first 1KB of this primary
@@ -14,9 +10,6 @@
 | (3) The full primary bootloader loads the secondary bootloader known as
 |     /boot from its filesystem to 0x6000.  And jump to there.
 |
-| Therefore, The first 1KB must be relocatable.
-| The first 1KB must be smaller than or equal to 1024 bytes.
-|
 |       (1)         ->        (2)         ->        (3)
 |  +------------+        +------------+        +------------+    0x000000
 |  :            :        :            :        :            :
@@ -29,6 +22,7 @@
 |  :            :        |boot loader |        |boot loader |
 |  :            :        |(text+data) |        |(text+data) |
 |  :            :        +------------+        +------------+    0x005000
+|  :            :        |(startregs) |        |(startregs) |
 |  :            :        |(bss)       |        |(bss)       |
 |  :            :        +------------+        +------------+    0x006000
 |  :            :        :            :        | /boot      |
@@ -40,310 +34,357 @@
 |  :            :        :(heap)      :        :(heap)      :
 |  :            :        :            :        :            :
 |
+| The program code before first_kbyte
+| - must not access any text/data labels after first_kbyte
+|   (because it may not be loaded yet).
+| - must access any labels before first_kbyte by PC relative addressing
+|   (because this loader is assembled as starting from 0x3000 but is loaded
+|   at 0x2000 or 0x2400).
+| - must use RELOC() macro to access bss section (and first_kbyte as a jump
+|   destination address).
+|
+| The program code after first_kbyte can access any labels in all sections
+| directly.
 
 #include <machine/asm.h>
 #include "iocscall.h"
 
-#define SCSI_ADHOC_BOOTPART
-
-#define SRAM		0x00ED0000	/* SRAM stat addr */
-#define SRAM_MEMSZ	(SRAM + 8)	/* (L) size of main memory */
-#define MINMEM		0x00400000	/* at least 4MB required */
+#define RELOC(var)	%a5@(((var)-top):W)
 
 #define BOOT_ERROR(s)	jbsr boot_error; .asciz s; .even
 
-	.globl	_C_LABEL(bootmain)
-	.text
+#define minN	(0)
+#define minC	(1)
+#define minH	(2)
+#define minR	(3)
+#define maxN	(4)
+#define maxC	(5)
+#define maxH	(6)
+#define maxR	(7)
+
+		.globl	_C_LABEL(bootmain)
+		.globl	_C_LABEL(startregs)
+		.text
+
 ASENTRY_NOPROFILE(start)
 ASENTRY_NOPROFILE(top)
-		bras	_ASM_LABEL(entry0)
+		bras	entry
 		.ascii	"SHARP/"
 		.ascii	"X680x0"
 		.word	0x8199,0x94e6,0x82ea,0x82bd
 		.word	0x8e9e,0x82c9,0x82cd,0x8cbb
 		.word	0x8ec0,0x93a6,0x94f0,0x8149
-		.word	0
-| d4 �ˤϤ��Ǥ� SCSI ID �����äƤ���
-ASENTRY_NOPROFILE(entry0)
-		moveml	%d0-%d7/%a0-%a7,_C_LABEL(startregs)
-		lea	TEXTADDR:W,%a5	| set base ptr
-#define _RELOC(adr)	%a5@(((adr)-top):W)
-#define ASRELOC(var)	_RELOC(_ASM_LABEL(var))
-#define RELOC(var)	_RELOC(_C_LABEL(var))
-
-		lea	RELOC(__bss_start),%a1
-		bra	_ASM_LABEL(entry)
-
-|	Disklabel= 404bytes
-|	Since LABELOFFSET in <machine/disklabel.h> is 0x40,
-|	entry must be after 0x000001d4 (0x000f01d4)
+msg_progname:
+		| This will be printed on boot_error.  And it also roles
+		| a signature in binary dump.
+		| Max length of PROG(without \0) is 14 ("fdboot_ustarfs").
+		.ascii	"\r\n\n"		| 3
+		.ascii	PROG			| 14
+		.asciz	": "			| 2+1
+		.org	msg_progname + 20
+entry:
+		jbra	disklabel_end
+
+		| Disklabel must be placed at 0x40 and the size is 404 bytes.
+		| (See LABELOFFSET in <machine/disklabel.h>)
 		.org	0x40
 disklabel:
 		.space	404
+disklabel_end:
+		| At first save all initial registers for observing traces
+		| of the IPL (or the previous bootloader).  At this point
+		| we cannot use RELOC() yet so that use absolute addressing.
+		| To prevent startregs from being cleared by subsequent bss
+		| initialization, we place it out of bss area.
+		moveml	%d0-%d7/%a0-%a7,startregs:W
+
+		| Initialize the screen.  Some IPL (060turbo ROM or genuine
+		| boot selector) don't initialize the screen.  It should be
+		| done as early as possible.
+		moveql	#0x10,%d1
+		IOCS(__CRTMOD)
 
-ASENTRY_NOPROFILE(entry)
-		movew	#_end-1,%d0	| bss end (low word only)
-
-		| clear out bss  (must be <= 64KB)
-		subw	%a1,%d0
-clrbss:		clrb	%a1@+
+		| Set system stack
+		swap	%d1			| %d1 = 0x0010_0000
+		moveal	%d1,%sp
+
+		| Set base pointer.  Now we can use RELOC() macro.
+		leal	TEXTADDR:W,%a5
+
+		| Initialize bss.
+		| This code limits bss less than 64KB but it's no matter.
+		| The bss cannot grow more than 4KB.  See xxboot.ldscript.
+		leal	RELOC(__bss_start),%a1
+		movew	#_end - 1,%d0		| bss end
+
+		subw	%a1,%d0			| don't change this op!!
+clrbss:						|  see chkmpu below
+		clrb	%a1@+
 		dbra	%d0,clrbss
 
-		movel	%d4,RELOC(ID)	| SCSI ID (if booted from SCSI)
-
-		lea	0x00100000,%sp	| set system stack
-		lea	%a5@,%a1	| set load address
-					| a1 will be used later for IOCS calls
+		| If it boots from SCSI, %d4 has SCSI ID.
+		movel	%d4,RELOC(SCSI_ID)
 
-		| we use 68020 instructions, and check MPU beforehand
+chkmpu:
+		| Check MPU beforehand since we want to use 68020 instructions.
+		| Here the above "subw %a1,%d0" = 0x9049 and %d0.w = -1 at this
+		| point, so that subsequent moveb loads
+		|   0x49 if MPU <= 010 (clrbss + %d0.w)
+		|   0x90 if MPU >= 020 (clrbss + %d0.w*2).
+		| This is a MOVE op, not a TST op because TST with pc-relative
+		| is not available on 000/010.
+		moveb	%pc@(clrbss-chkmpu-2:B,%d0:W:2),%d0
+		jmi	mpuok
+		BOOT_ERROR("MPU 68000?");
+mpuok:
+		|
+		| Check where did I boot from.
 		|
-		| here d0.w = -1, and the above "subw a1,d0" = 0x9049, and
-		|	if MPU <= 010	loads 0x49,
-		|	if MPU >= 020	loads 0x90.
-		| This is a move, not a tst instruction
-		| because pc-relative tsts are not available on 000/010.
-chkmpu:		moveb	%pc@(clrbss-chkmpu-2:B,%d0:W:2),%d0	| 103B 02xx
-		jmi	mpuok		| MC68020 or later
-		BOOT_ERROR("MPU 68000?")
-mpuok:		| XXX check for MMU?
-
 		IOCS(__BOOTINF)
-		lsll	#8,%d0		| clear MSByte
-		lsrl	#8,%d0		|
-		movel	%d0,RELOC(BOOT_INFO)
+		movel	%d0,RELOC(BOOT_INFO)	| save whole result
 
+		| %d0 = 0xHHWWWWWW
 		|
-		| 0x80...0x8F		SASI
-		| 0x90...0x93		Floppy
-		| 0xED0000...0xED3FFE	SRAM
-		| others		ROM (SCSI?)
-		|
-		movel	%d0,%d1
-		clrb	%d1
-		tstl	%d1
-		jne	boot_ram_rom
-		|
-		| SASI or Floppy
-		|
-		movel	%d0,%d2
-		andib	#0xFC,%d0
-		cmpib	#0x90,%d0
-		jne	boot_dev_unsupported	| boot from SASI?
-		|
-		| Floppy
-		|
-		moveb	%d2,%d0
-		andib	#0x03,%d0		| drive # (head=0)
-		jbsr	check_fd_format
-		moveml	%d0-%d1,RELOC(FDSECMINMAX) | min and max sec #
-		lslw	#8,%d2
-		moveq	#0x70,%d1
-		orw	%d2,%d1		| PDA*256 + MODE
+		| HH:     how did I boot (powersw or alarm etc)
+		| WWWWWW: where did I boot from
+		|  0x80...0x8f		SASI
+		|  0x90...0x93		Floppy
+		|  0xed0000...0xed3ffe	SRAM
+		|  others		ROM (maybe SCSI)
+
+		bfextu	%d0{#8:#8},%d1
+		jne	boot_rom_ram		| ROM or SRAM
+		| FALLTHROUGH			| SASI or Floppy
+
+boot_sasi_floppy:
+		| Floppy or SASI
+		cmpiw	#0x90,%d0
+		jlt	boot_dev_not_supp	| SASI
+
+		|
+		| Boot from floppy
+		|
+boot_floppy:
+		| Make PDA+MODE
+		lslw	#8,%d0			| %d0=$00009X00 (X is unit#)
+		moveql	#0x70,%d1
+		orw	%d0,%d1			| %d1=$00009X70 = (PDA<<8)+MODE
 		movel	%d1,RELOC(FDMODE)
-		movel	%d0,%d2		| read position (first sector)
-		movel	#8192,%d3	| read bytes
+check_fd_format:
+		| Check fd format.
+		| Obtain min & max sector # of track(cylinder) 0.
+		| On x68k, we can consider only double-sided floppy.
+		moveql	#0,%d2
+init_loop:
+		| On 1st time, clear %d3-%d5 with zero.
+		| On 2nd time, initialize %d3-%d5 with first %d2.
+		movel	%d2,%d3			| %d3: initial NCHR
+		movel	%d2,%d4			| %d4: minimum NCHR
+		movel	%d2,%d5			| %d5: maximum NCHR
+loop:
+		| B_READID with MSB of %d2 set obtains detected CHRN to %d2.
+		moveql	#1,%d2			| %d2 = 0x00000001
+		rorl	#1,%d2			| %d2 = 0x80000000
+		IOCS(__B_READID)
+						| %d2 = 0xCCHHRRNN
+		rorl	#8,%d2			| %d2 = 0xNNCCHHRR
+
+		| On 1st time, goto init_loop with %d2 (%d2 is not zero).
+		| On 2nd time, fall through because %d3 is not zero.
+		tstl	%d3
+		jeq	init_loop
+
+		cmpl	%d4,%d2			| if (%d2 < %d4)
+		jge	1f			|
+		movel	%d2,%d4			|  min = %d2
+1:
+		cmpl	%d5,%d2			| if (%d2 > %d5)
+		jle	1f			|
+		movel	%d2,%d5			|  max = %d2
+1:
+		cmpl	%d3,%d2			| if (%d2 == %d3) break
+		jne	loop
+
+		| Assume 2HD
+		oriw	#0x0100,%d5		| FDSEC.maxsec.H = 1
+		moveml	%d4-%d5,RELOC(FDSEC)	| Store
+		| end of check_fd_format
+
+		| read 8KB myself from floppy
+						| %d1: (PDA<<8)+MODE already
+		movel	%d4,%d2			| %d2: read pos = first sector
+		moveql	#0x20,%d3		| %d3: read bytes = (0x20 << 8)
+		lsll	#8,%d3			|  = 0x2000 = 8192
+		leal	%a5@,%a1		| %a1: dest buffer
 		IOCS(__B_READ)
-		jra	boot_read_done
-
-#include "chkfmt.s"
-
-boot_ram_rom:
-		movel	%d0,%d1
-		swap	%d1
-		cmpiw	#0x00ED,%d1
-		jne	boot_SCSI
-		| boot from SRAM?
-
-boot_dev_unsupported:
-		BOOT_ERROR("unsupported boot device")
-
-|
-| volatile void BOOT_ERROR(const char *msg);
-|	print error message, wait for key press and reboot
-|
-booterr_msg:	.asciz	"\r\n\n"
-reboot_msg:	.asciz	"\r\n[Hit key to reboot]"
-		.even
-
-ENTRY_NOPROFILE(BOOT_ERROR)
-		addql	#4,%sp
 
-boot_error:	lea	%pc@(booterr_msg),%a1
-		IOCS(__B_PRINT)
-		moveal	%sp@+,%a1
-		IOCS(__B_PRINT)
-ENTRY_NOPROFILE(exit)
-ENTRY_NOPROFILE(_rtt)
-		lea	%pc@(reboot_msg),%a1
-		IOCS(__B_PRINT)
-
-		| wait for a key press (or release of a modifier)
-		IOCS(__B_KEYINP)
-
-		| issue software reset
-		trap	#10
-		| NOTREACHED
+		| Jump to full parimary loader
+		jmp	RELOC(first_kbyte)
 
+boot_rom_ram:
+		| ROM(SCSI) or SRAM
+		cmpib	#0xed,%d1
+		jeq	boot_dev_not_supp	| SRAM
 
 		|
-		| ROM boot ... probably from SCSI
+		| Boot from SCSI
 		|
-boot_SCSI:
-#ifdef SCSI_ADHOC_BOOTPART
-		|
-		| Find out boot partition in an ad hoc manner.
-		|
-
+boot_scsi:
 		| get block length of the SCSI disk
-		SCSIIOCS(__S_READCAP)	| using buffer at a1
+		leal	RELOC(SCSI_CAP),%a1
+		SCSIIOCS(__S_READCAP)
 		tstl	%d0
-		jeq	1f
+		jeq	boot_scsi1
 		BOOT_ERROR("READCAP failed")
-1:		moveq	#0,%d5
-		moveb	%a1@(6),%d5	| 1: 256, 2: 512, 4: 1024, 8: 2048
-		lsrb	#1,%d5		| 0: 256, 1: 512, 2: 1024, 4: 2048
-		movel	%d5,RELOC(SCSI_BLKLEN)
-
-		| find out the start position of the boot partition
-		| XXX VERY AD HOC
+boot_scsi1:
+		movel	RELOC(SCSI_CAP+4),%d0	| %d0 = blocksize in bytes
+		lsrl	#2,%d0			| %d0 = blocksize in longword
+		moveql	#25,%d5
+		bfffo	%d0{#0:#32},%d1		| 25:256 24:512 23:1024 22:2048
+		subl	%d1,%d5			|  0:256  1:512  2:1024  3:2048
+		movel	%d5,RELOC(SCSI_BLKLEN)	| %d5 = sector length index
+
+		| Find out the start position of the boot partition.
+		| There seems to be no interface or consensus about this and
+		| so that we would have to do it heuristicly.
 		|
 		| ROM firmware:
-		|	pass read pos (in block #) in d2
-		|	Human68k-style partition table does not exist
-		|	d2 is 4 at the maximum
+		|	pass read pos (in block #, aka sector #) in %d2.
+		|	Human68k-style partition table does not exist.
+		|	%d2 is 4 at the maximum.
 		| SCSI IPLs (genuine and SxSI):
-		|	pass read pos (in kilobytes) in d2
-		|	d2 is bigger than 0x20
-		|	partition table on the memory is destroyed
+		|	pass read pos (in kilobytes) in %d2.
+		|	%d2 is bigger than 0x20.
+		|	partition table on the memory is destroyed.
 		| BOOT MENU Ver.2.22:
-		|	passes partition table entry address in a0
-		|	d2 is cleared to zero
-		| No other IPL is supported.  XXX FIXME
+		|	passes partition table entry address in %a0.
+		|	%d2 is cleared to zero
+		| No other IPLs are supported.
+
 		tstl	%d2
-		jne	sc1
-		| no information in d2 -- probably from BOOT MENU
-		| a0 points the partiion table entry
-		movel	%a0@(0x0008),%d2 | in KByte
-sc1:		cmpl	#0x20,%d2
-		jcs	sc2
-		lsll	#8,%d2		| clear MSByte
-		lsrl	#7,%d2		| in 512 byte block
-		divul	%d5,%d2		| in sector
-sc2:
-		| read entire boot
-		moveq	#TDSIZE/512,%d3	| size is TDSIZE byte
-		divul	%d5,%d3		| in sector
-		jbsr	scsiread	| read at  %a1
-
-		cmpil	#5,%d2
-		bcc	sc3
-		movql	#0,%d2
-sc3:		movel	%d2,RELOC(SCSI_PARTTOP)
-#else
-		moveq	#1,%d5		| 512bytes/sec
-		movel	%d5,%sp@-
-		moveq	#8192/512,%d3	| �ɤ߹������祵����
-		moveq	#0x40,%d2	| ���������Ǥ�(sd*a �Τ�)
-		SCSIIOCS(__S_READ)
-#endif
+		jne	1f
+		| If no information in %d2, probably from BOOT MENU.
+		| %a0 points the on-memory partition table entry.
+		movel	%a0@(0x0008),%d2	| %d2 = pos in kbyte
+1:
+		moveql	#0x20,%d3
+		cmpl	%d3,%d2
+		jcs	1f			| jump if %d2 > 0x20
+		| SCSI IPL or BOOT MENU.
+		| At this point, %d2 is pos in kbyte in all cases.
+		lsll	#8,%d2			| %d2 = pos in longword
+		divul	%d0,%d2			| %d2 = pos in sector
+1:
+		| At this point, %d2 is pos in sector in all cases.
+		| TDSIZE = 8192, TDSIZE / 4 = 0x800 = (0x20 << 6).
+		lsll	#6,%d3			| %d3 = TDSIZE in longword
+		divul	%d0,%d3			| %d0 = TDSIZE in sector
+		| Read full primary bootloader
+		moveal	%a5,%a1			| %a1 = dest buffer
+		jbsr	scsiread
 
-boot_read_done:
-		jmp	first_kbyte
+		| Selected start sector should not <= 4.  There should be
+		| partition table.  If so, repoints to zero(?).
+		moveql	#5,%d0
+		cmpl	%d0,%d2
+		bcc	1f
+		moveql	#0,%d2
+1:
+		movel	%d2,RELOC(SCSI_PARTTOP)
+
+		| Jump to full parimary loader
+		jmp	RELOC(first_kbyte)
+
+|
+| scsiread
+|	Read SCSI disk using __S_READ as possible.  If __S_READ cannot be
+|	used (due to read length or offset), use __S_READEXT instead.
+| input:
+|	%d2.l: pos in sector
+|	%d3.l: len in sector (must be < 65536)
+|	%d4.l: target SCSI ID
+|	%d5.l: sector length index (0:256, 1:512, 2:1024, 3:2048, ...)
+|	%a1.l: buffer address
+| destroy:
+|	%d0,%d1
+scsiread:
+		| if (len >= 256 || pos + len >= 0x200000)
+		|   use READEXT
+		| else
+		|   use READ
 
-read_error:	BOOT_ERROR("read error")
+		moveql	#__S_READEXT,%d1
 
-#undef RELOC	/* base register  a5  is no longer available */
-#undef ASRELOC
-#undef _RELOC
+		cmpiw	#256,%d3
+		jge	scsiread_core		| if (d3 >= 256) use READEXT
 
-|
-|	read SCSI
-|
-|	input:	d2.l: pos in sector
-|		d3.l: len in sector
-|		d4: target SCSI ID
-|		d5: sector length (1: 512, 2: 1024, 4: 2048)
-|		a1: buffer address
-|	destroy:
-|		d0, d1, a1
-|
-scsiread:
-		moveml	%d2-%d3/%d6-%d7/%a2,%sp@-
-		| if (pos >= 0x200000 || (len > 255 && pos + len >= 0x200000))
-		|	use READEXT
-		| else
-		|	use READ
-		moveq	#0x20,%d0
-		swap	%d0		| d0.l = 0x00200000
-		moveq	#0,%d6
-		subqb	#1,%d6		| d6.l = 255
-		movel	%d5,%d7
-		lsll	#8,%d7
-		lsll	#1,%d7		| d7 = sector length (byte)
-		cmpl	%d0,%d2
-		jcc	scsiread_ext
-		moveq	#__S_READ,%d1
-		cmpl	%d3,%d6
-		jcc	scsiread_noext
-		subl	%d2,%d0		| d0.0 = 0x200000 - pos
-		cmpl	%d0,%d3		|	<= len
-		jcs	scsiread_noext	| no
-
-scsiread_ext:	| use READEXT
-		extw	%d6		| d6.l = 65535
-		moveq	#__S_READEXT,%d1
-
-scsiread_noext:	| use READ
-loop_scsiread:
-		| d1: SCSI IOCS call #
-		| d6: max sector count at a time
-		movel	%d3,%a2		| save original len in a2
-		cmpl	%d3,%d6
-		jcc	1f
-		movel	%d6,%d3
-1:		IOCS(__SCSIDRV)		| SCSIIOCS(d1)
-		tstl	%d0
-		jne	read_error
-		movel	%d3,%d0
-		mulul	%d7,%d0
-		addl	%d0,%a1
-		exg	%d3,%a2		| restore original len to d3
-		addl	%a2,%d2		| pos += read count
-		subl	%a2,%d3		| len -= read count
-		jne	loop_scsiread
-		moveml	%sp@+,%d2-%d3/%d6-%d7/%a2
+		movel	%d2,%d0
+		addl	%d3,%d0			| %d0 = pos + len
+		jcs	scsiread_core		| if overflow, use READEXT
+		bftst	%d0{#0:#11}		| if (pos + len >= 0x200000)
+		jne	scsiread_core		|  use REAEXT
+
+		moveql	#__S_READ,%d1		| else use READ
+scsiread_core:
+		IOCS(__SCSIDRV)
 		rts
 
+boot_dev_not_supp:
+		BOOT_ERROR("not supported device");
+
 |
-|	The former part must reside in the first 1KB.
+| void __dead BOOT_ERROR(const char *msg);
+|	Print an error message, wait for key press, and reboot.
+|	Called from C.
+ENTRY_NOPROFILE(BOOT_ERROR)
+		addql	#4,%sp			| throw away return address
+		| FALLTHROUGH
 |
+| BOOT_ERROR(msg)
+|	Print an error message, wait for key press, and reboot.
+|	Called from asm.
+boot_error:
+		leal	%pc@(msg_progname),%a1
+		IOCS(__B_PRINT)
+		moveal	%sp@+,%a1
+		IOCS(__B_PRINT)
+ENTRY_NOPROFILE(exit)
+ENTRY_NOPROFILE(_rtt)
+		leal	%pc@(msg_reboot),%a1
+		IOCS(__B_PRINT)
+
+		| wait for a key press (or release of a modifier)
+		IOCS(__B_KEYINP)
+
+		| issue software reset
+		trap	#10
+		| NOTREACHED
+msg_reboot:
+		.asciz	"\r\n[Hit key to reboot]"
+		.even
+
 		.globl	first_kbyte
 first_kbyte:
 |--------------------------------------------------------------------------
 |
-|	The latter text+data part is not accessible at the first boot time.
-|	PC-relative can be used from here.
-|
-		| Initialize the screen here.  Some IPL (060turbo ROM or
-		| genuine boot selector) don't initialize the screen.
-		| Such initialization should be done as early as possible
-		| but it's too severe to place it in first_kbyte area.
-		| Therefore do it here.
-		moveq	#0x10,%d1
-		IOCS(__CRTMOD)
-
-		jmp	_C_LABEL(bootmain)	| 0x0Fxxxx ������Ǥ椯
-
-		.word	0
+#if defined(SELFTEST)
+		jbsr	selftest_ashldi3
+		jbsr	selftest_ashrdi3
+		jbsr	selftest_memcmp
+		jbsr	selftest_memmove
+		jbsr	selftest_memset
+#endif
 
-| int badbaddr __P((void *adr));
-|	check if the given address is valid for byte read
-|	return: 0: valid, 1: not valid
+		jmp	_C_LABEL(bootmain)
+		| NOTREACHED
 
+|
+| uint32_t badbadd(void *addr)
+|	returns 1 if reading addr occurs bus error.  Otherwise it returns 0.
 ENTRY_NOPROFILE(badbaddr)
-		lea	0x0008:W,%a1		| MPU Bus Error vector
-		moveq	#1,%d0
-		lea	%pc@(badr1),%a0
+		leal	0x0008:W,%a1		| bus error vector
+		moveql	#1,%d0
+		leal	%pc@(badbaddr1),%a0
 		movew	%sr,%sp@-
 		oriw	#0x0700,%sr		| keep out interrupts
 		movel	%a1@,%sp@-
@@ -351,163 +392,118 @@ ENTRY_NOPROFILE(badbaddr)
 		movel	%sp,%d1			| save sp
 		moveal	%sp@(10),%a0
 		tstb	%a0@			| try read...
-		moveq	#0,%d0			| this is skipped on bus error
-badr1:		moveal	%d1,%sp			| restore sp
+		moveql	#0,%d0			| this is skipped on bus error
+badbaddr1:
+		moveal	%d1,%sp			| restore sp
 		movel	%sp@+,%a1@
 		movew	%sp@+,%sr
 		rts
 
-| void RAW_READ __P((void *buf, u_int32_t blkpos, size_t bytelen));
-| inputs:
-|	buf:	 input buffer address
-|	blkpos:	 read start position in the partition in 512byte-blocks
-|	bytelen: read length in bytes
-
-Lraw_read_buf=4+(4*11)
-Lraw_read_pos_=Lraw_read_buf+4
-Lraw_read_len=Lraw_read_buf+8
-
-#ifdef SCSI_ADHOC_BOOTPART
-|	RAW_READ of physical disk
-ENTRY_NOPROFILE(RAW_READ0)
-		moveq	#0,%d0
-		jra	raw_read1
-#endif
-
-ENTRY_NOPROFILE(RAW_READ)
-#ifdef SCSI_ADHOC_BOOTPART
-		movel	_C_LABEL(SCSI_PARTTOP),%d0
-raw_read1:
-#endif
+|
+| int raw_read(uint32_t blkpos, uint32_t bytelen, void *buf)
+|	blkpos:  read start position in 512 byte block unit (always?).
+|	bytelen: read length in bytes.
+|	         caller already avoids bytelen == 0 so that no checks here.
+|	         must be a multiple of sector size on scsi.
+|	buf:     destination buffer address
+|
+ENTRY_NOPROFILE(raw_read)
+		moveal	%sp,%a1
 		moveml	%d2-%d7/%a2-%a6,%sp@-
-		moveml	%sp@(Lraw_read_buf),%d1-%d3
-		movel	%d1,%a1
-		| d2.l:		pos in 512byte-blocks
-		| d3.l:		length in bytes
-		| a1 (=d1):	buffer address
-
-		lea	TEXTADDR:W,%a5	| set base ptr
-#define _RELOC(adr)	%a5@(((adr)-top):W)
-#define ASRELOC(var)	_RELOC(_ASM_LABEL(var))
-#define RELOC(var)	_RELOC(_C_LABEL(var))
-
-		tstb	_RELOC(_C_LABEL(BOOT_INFO)+1) | simple check.  may be incorrect!
-		beqs	raw_read_floppy
+		moveml	%a1@,%d0/%d2-%d3/%a1	| %d0 (return address)
+						| %d2 blkpos
+						| %d3 bytelen
+						| %a1 buf
+		| At this point boot device is either floppy or SCSI.
+		tstb	%pc@(BOOT_INFO+1)
+		jeq	raw_read_floppy
+		| FALLTHROUGH
 
 raw_read_scsi:
-		movel	RELOC(ID),%d4	| SCSI ID
-#ifdef SCSI_ADHOC_BOOTPART
-		movel	RELOC(SCSI_BLKLEN),%d5 | sector size: 0-2
-		| XXX length must be sector aligned
-		lsrl	#8,%d3		| size in 256byte-blocks
-		lsrl	#1,%d3
-		divul	%d5,%d3		| size in sector
-		beqs	read_half	| minimal error check
-		divul	%d5,%d2		| pos in sector
-		addl	%d0,%d2		| physical pos in sector
-#else
-		moveq	#1,%d5		| 512bytes/sec
-		moveq	#9,%d0		| shift count
-		addl	#511,%d3
-		lsrl	%d0,%d3
-		bcss	read_half	| minimal error check
+						| %d2 = pos from device top
+						|  in 512 bytes/block
+		lsll	#1,%d2			| %d2 = in 256 bytes/block
+		movel	%pc@(SCSI_BLKLEN),%d5	| %d5 = sector length index
+		lsrl	%d5,%d2			| %d2 = pos from device top
+						|  in media sector size
 
-		addl	#0x40,%d2	| 'a' partition starts here
-#endif
-|		jcc	1f
-|		BOOT_ERROR("out of seek")	| pos exceeds 32bit
-|1:
+		divull	%pc@(SCSI_CAP+4),%d0:%d3| %d3 = bytelen / sectsize
+						| %d0 = bytelen % sectsize
+		tstl	%d0
+		jeq	.Lraw1
+		BOOT_ERROR("Err1")		| ASSERT(bytelen%sectsize==0)
+.Lraw1:
+		movel	%pc@(SCSI_ID),%d4	| %d4 = SCSI ID
 		jbsr	scsiread
-		bras	raw_read_end
 
-raw_read_floppy:
-		|
-		| Floppy read routine
-		|
-
-		| convert to seek position
-
-		asll	#2,%d2		| size in 128byte-blocks
-
-		| sec = raw_read_pos	(d2)
-		| sec >>= 7 + (sector length: 0-3)
-
-		lea	RELOC(FDSECMINMAX),%a0
-		moveq	#0,%d1
-		moveb	%a0@,%d1	| d1: sector length (0-3)
-		lsrl	%d1,%d2		| d2: pos in sector
-		bcss	read_half	| error check
-
-		| trk = sec / (# sectors)
-		| sec = sec % (# sectors)
-
-		moveb	%a0@(7),%d1	| d1: max sector #
-		subb	%a0@(3),%d1	|   - min sector #
-		addqb	#1,%d1		| d1: # sectors
-		divu	%d1,%d2		| d2: (sec << 16) | track
-
-		| position = (sec length << 24) | (track/2 << 16)
-		|		| (track%2 << 8) | (min sec # + sec)
-
-		movel	%a0@,%d0	| d0: (sec len << 24) | min sec #
-		lsrw	#1,%d2		| d2: (sec << 16) | (track / 2)
-		jcc	1f
-		bset	#8,%d0		| |= (track % 2) << 8
-1:		swap	%d2		| d2: ((track / 2) << 16) | sec
-		addl	%d0,%d2		| d2: position
-
-		| read
-		movel	RELOC(FDMODE),%d1	| PDA*256 + MODE
-
-		| B_READ (for floppy)
-		|  d1.w: PDA x 256 + MODE
-		|	PDA: 0x90 (drive 0) ... 0x93 (drive 3)
-		|	MODE:	bit6: MFM
-		|		bit5: retry
-		|		bit4: seek
-		|  d2.l: position
-		|	bit31-24: sector length (0: 128, 1: 256, 2: 512, 3: 1K)
-		|	bit23-16: track # (0-79)
-		|	bit15-08: side (0 or 1)
-		|	bit07-00: sector # (1-)
-		|  d3.l: read bytes
-		|  a1:   read address
-		| return:
-		|  d0:	bit 31-24	ST0
-		|	bit 23-16	ST1
-		|	bit 15- 8	ST2
-		|	bit  7- 0	C
-		|	-1 on parameter error
-		| destroy: d0, d2, d3, a1
-		IOCS(__B_READ)
-		andil	#0xf8ffff00,%d0		| check status (must be zero)
-		jne	read_error
-
-raw_read_end:
-		moveml	%sp@+,%a2-%a6/%d2-%d7
+raw_read_exit:
+		moveml	%sp@+,%d2-%d7/%a2-%a6
 		rts
-#undef _RELOC	/* base register  a5  is no longer available */
-#undef ASRELOC
-#undef RELOC
-
-read_half:	BOOT_ERROR("read half of block")
 
+raw_read_floppy:
+		| nhead = FDSEC.maxsec.H - FDSEC.minsec.H + 1
+		|       = 2;
+		| nsect = FDSEC.maxsec.R - FDSEC.minsec.R + 1;
+		|
+		| sect = (blkpos % nsect) + FDSEC.minsec.R;
+		| head = ((blkpos / nsect) % nhead) + FDSEC.minsec.H;
+		| cyl  = ((blkpos / nsect) / nhead) + FDSEC.minsec.C;
+		|
+		| NCHR = (FDSEC.minsec.N << 24) |
+		|      (cyl << 16) |
+		|      (head << 8) |
+		|      sect;
+
+		| calc nsect.
+		moveql	#1,%d0			| %d0 = 1
+		addb	%pc@(FDSEC+maxR),%d0	| %d0 = 1 + maxsec.R
+		subb	%pc@(FDSEC+minR),%d0	| %d0 = 1 + maxsec.R - minsec.R
+						|     = nsect
+
+		| Convert blkpos to N/C/H/R.
+		divuw	%d0,%d2			| %d2.hw = blkpos % nsect
+						| %d2.lw = blkpos / nsect
+		| Here, %d2.hw becomes sector number and .lw becomes cyl+head.
+		| %d2.lw = %0000_0000_CCCC_CCCH in binary form.  LSB of
+		| (blkpos / nsect) is head number because we support only
+		| double-sided floppy here.
+						| %d2.w = %0000_0000_CCCC_CCCH
+		lslw	#7,%d2			| %d2.w = %0CCC_CCCC_H000_0000
+		lsrb	#7,%d2			| %d2.w = %0CCC_CCCC_0000_000H
+						| i.e,
+						| %d2 = $00rrCCHH
+		swap	%d2			| %d2 = $CCHH00rr
+		lslw	#8,%d2			| %d2 = $CCHHrr00
+		| two bytes from odd FDSEC+minR is (minR << 8 | maxN) and
+		| minN == maxN always.
+		addw	%pc@(FDSEC+minR),%d2	| %d2 = $CCHHRRNN
+		rorl	#8,%d2			| %d2 = $NNCCHHRR
 
-|
-|	global variables
-|
-	BSS(ID, 4)			| SCSI ID
-	BSS(BOOT_INFO, 4)		| result of IOCS(__BOOTINF)
-	BSS(FDMODE, 4)			| Floppy access mode: PDA x 256 + MODE
-	BSS(FDSECMINMAX, 8)		| +0: (min sector) sector length
-					| +1: (min sector) track #
-					| +2: (min sector) side
-					| +3: (min sector) sector #
-					| +4: (max sector) sector length
-					| +5: (max sector) track #
-					| +6: (max sector) side
-					| +7: (max sector) sector #
-#ifdef SCSI_ADHOC_BOOTPART
-	BSS(SCSI_PARTTOP, 4)		| start sector of boot partition
-	BSS(SCSI_BLKLEN ,4)		| sector len 0: 256, 1: 512, 2: 1024
-#endif
+		movel	%pc@(FDMODE),%d1	| %d1 = PDA+MODE
+		IOCS(__B_READ)
+		andil	#0xf8ffff00,%d0		| Check status (must be zero)
+		jeq	raw_read_exit
+		BOOT_ERROR("B_READ failed");
+
+|
+| BSS
+|
+		BSS(BOOT_INFO, 4)	| whole result of IOCS BOOTINF
+
+		BSS(FDMODE, 4)
+		BSS(FDSEC, 8)		| +0: (minN) sector length
+					| +1: (minC) track number
+					| +2: (minH) head
+					| +3: (minR) sector number
+					| +4: (maxN) sector length
+					| +5: (maxC) track number
+					| +6: (maxH) head
+					| +7: (maxR) sector number
+
+		BSS(SCSI_ID, 4)		| SCSI ID, if booted from SCSI
+		BSS(SCSI_CAP, 8)	| result of SCSI READCAP
+					|  +0.L: total number of logical blocks
+					|  +4.L: block length in bytes
+		BSS(SCSI_PARTTOP, 4)	| top sector # of this partition
+		BSS(SCSI_BLKLEN ,4)	| sector length index
+					|  0:256, 1:512, 2:1024, 3:2048, ..

Index: src/sys/arch/x68k/stand/xxboot/bootmain.c
diff -u src/sys/arch/x68k/stand/xxboot/bootmain.c:1.7 src/sys/arch/x68k/stand/xxboot/bootmain.c:1.8
--- src/sys/arch/x68k/stand/xxboot/bootmain.c:1.7	Fri Aug 14 03:43:28 2020
+++ src/sys/arch/x68k/stand/xxboot/bootmain.c	Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: bootmain.c,v 1.7 2020/08/14 03:43:28 isaki Exp $	*/
+/*	$NetBSD: bootmain.c,v 1.8 2020/08/16 06:43:43 isaki Exp $	*/
 
 /*-
  * Copyright (c) 1993, 1994 Takumi Nakamura.
@@ -36,6 +36,7 @@
 #include <sys/param.h>
 #include <sys/types.h>
 #include <machine/bootinfo.h>
+#include <machine/disklabel.h>
 #include <lib/libsa/stand.h>
 #include <lib/libsa/loadfile.h>
 
@@ -46,12 +47,26 @@
 
 #define EXSCSI_BDID	((void *)0x00ea0001)
 
-/* for debug */
-unsigned int startregs[16];
-
 static int get_scsi_host_adapter(char *);
+int get_scsi_part(void);
 void bootmain(void) __attribute__ ((__noreturn__));
 
+#if defined(XXBOOT_DEBUG)
+/* Print 'x' as 'width' digit hex number */
+void
+print_hex(unsigned int x, int width)
+{
+
+	if (width > 0) {
+		print_hex(x >> 4, width - 1);
+		x &= 0x0F;
+		if (x > 9)
+			x += 7;
+		IOCS_B_PUTC((unsigned int) '0' + x);
+	}
+}
+#endif
+
 /*
  * Check the type of SCSI interface
  */
@@ -82,7 +97,8 @@ get_scsi_host_adapter(char *devstr)
 	} else if (badbaddr(EXSCSI_BDID)) {
 		ha = (X68K_BOOT_SCSIIF_MHA << 4) | 0;
 #ifdef XXBOOT_DEBUG
-		*(uint32_t *)devstr = '/' << 24 | 'm' << 16 | 'h' << 8 | 'a';
+		*(uint32_t *)devstr =
+		    ('/' << 24) | ('m' << 16) | ('h' << 8) | 'a';
 #endif
 	} else {
 		ha = (X68K_BOOT_SCSIIF_SPC << 4) | 1;
@@ -94,10 +110,63 @@ get_scsi_host_adapter(char *devstr)
 	return ha;
 }
 
+#define PARTTBL_TOP	(4)	/* sector pos of part info in 512byte/sector */
+#define NPART		(15)	/* total number of Human68k partitions */
+#define MAXPART		(6)
+int
+get_scsi_part(void)
+{
+	union {
+		char pad[1024];
+		struct {
+			uint32_t magic;		/* 0x5836384b ("X68k") */
+			uint32_t parttotal;	/* total block# -1 */
+			uint32_t diskblocks;
+			uint32_t diskblocks2;	/* backup? */
+			struct dos_partition parttbl[NPART];
+		} __packed;
+	} partbuf;
+	int i;
+	int part_top;
+
+	/*
+	 * Read partition table.
+	 * The actual partition table size we want to read is 256 bytes but
+	 * raw_read() for SCSI requires bytelen a multiple of sector size
+	 * (SCSI_CAP.blocksize).  Human68k supports sector size only 256,
+	 * 512 and 1024 so that we always use 1024 bytes fixed length buffer.
+	 */
+	raw_read(PARTTBL_TOP, SCSI_CAP.blocksize, &partbuf);
+
+	if (partbuf.magic != 0x5836384b/*"X68k"*/) {
+		BOOT_ERROR("Bad Human68k partition table");
+		/* NOTREACHED */
+	}
+
+	/*
+	 * SCSI_PARTTOP is top sector # of this partition in sector size
+	 * of this device (normally 512 bytes/sector).
+	 * part_top is top block # of this partition in 1024 bytes/block.
+	 * Human68k partition table uses 1024 bytes/block unit.
+	 */
+	part_top = SCSI_PARTTOP >> (2 - SCSI_BLKLEN);
+	for (i = 0; i < MAXPART; i++) {
+		if ((uint32_t)partbuf.parttbl[i].dp_start == part_top)
+			goto found;
+	}
+	BOOT_ERROR("Can't find this partition?");
+	/* NOTREACHED */
+found:
+	/* bsd disklabel's c: means whole disk.  Skip it */
+	if (i >= 2)
+		i++;
+	return i;
+}
+
 void
 bootmain(void)
 {
-	int bootdev, ha, fd;
+	int bootdev, fd;
 	char bootdevstr[16];
 	u_long marks[MARK_MAX];
 
@@ -106,35 +175,50 @@ bootmain(void)
 	IOCS_B_PRINT(bootprog_rev);
 	IOCS_B_PRINT("\r\n");
 
-	ha = get_scsi_host_adapter(bootdevstr);
-#ifdef XXBOOT_DEBUG
-	bootdevstr[10] = '0' + (ID & 7);
-	bootdevstr[14] = 'a';
+#if defined(XXBOOT_DEBUG)
+	/* Print the initial registers */
+	int i;
+	for (i = 0; i < __arraycount(startregs); i++) {
+		print_hex(startregs[i], 8);
+		IOCS_B_PRINT((i & 7) == 7 ? "\r\n" : " ");
+	}
+	IOCS_B_PRINT("BOOT_INFO ");
+	print_hex(BOOT_INFO, 8);
+	IOCS_B_PRINT("\r\n");
 #endif
 
-#if defined(CDBOOT)
-	bootdev = X68K_MAKESCSIBOOTDEV(X68K_MAJOR_CD, ha >> 4, ha & 15,
-				       ID & 7, 0, 0);
-#elif defined(FDBOOT) || defined(SDBOOT)
 	if (BINF_ISFD(&BOOT_INFO)) {
 		/* floppy */
+		int minor;
+		/* fdNa for 1024 bytes/sector, fdNc for 512 bytes/sector */
+		minor = (FDSEC.minsec.N == 3) ? 0 : 2;
+		bootdev = X68K_MAKEBOOTDEV(X68K_MAJOR_FD, BOOT_INFO & 3, minor);
 #ifdef XXBOOT_DEBUG
 		*(uint32_t *)bootdevstr =
 		    ('f' << 24) | ('d' << 16) | ('@' << 8) |
 		    ('0' + (BOOT_INFO & 3));
-		bootdevstr[4] = '\0';
+		bootdevstr[4] = 'a' + minor;
+		bootdevstr[5] = '\0';
 #endif
-		/* fdNa for 1024 bytes/sector, fdNc for 512 bytes/sector */
-		bootdev = X68K_MAKEBOOTDEV(X68K_MAJOR_FD, BOOT_INFO & 3,
-		    (FDSECMINMAX.minsec.N == 3) ? 0 : 2);
 	} else {
 		/* SCSI */
-		bootdev = X68K_MAKESCSIBOOTDEV(X68K_MAJOR_SD, ha >> 4, ha & 15,
-		    ID & 7, 0, 0 /* XXX: assume partition a */);
-	}
+		int major, ha, part;
+		ha = get_scsi_host_adapter(bootdevstr);
+		part = 0;
+#if defined(CDBOOT)
+		major = X68K_MAJOR_CD;
 #else
-	bootdev = 0;
+		major = X68K_MAJOR_SD;
+		if (SCSI_PARTTOP != 0)
+			part = get_scsi_part();
+#endif
+		bootdev = X68K_MAKESCSIBOOTDEV(major, ha >> 4, ha & 15,
+		    SCSI_ID & 7, 0, part);
+#ifdef XXBOOT_DEBUG
+		bootdevstr[10] = '0' + (SCSI_ID & 7);
+		bootdevstr[14] = 'a' + part;
 #endif
+	}
 
 #ifdef XXBOOT_DEBUG
 	IOCS_B_PRINT("boot device: ");
@@ -143,9 +227,17 @@ bootmain(void)
 	IOCS_B_PRINT("\r\n");
 
 	marks[MARK_START] = BOOT_TEXTADDR;
+
+#if defined(XXBOOT_USTARFS)
+	/* ustarfs requires mangled filename... */
+	fd = loadfile("USTAR.volsize.4540", marks,
+	    LOAD_TEXT|LOAD_DATA|LOAD_BSS);
+#else
+	/* XXX what is x68k/boot? */
 	fd = loadfile("x68k/boot", marks, LOAD_TEXT|LOAD_DATA|LOAD_BSS);
 	if (fd < 0)
 		fd = loadfile("boot", marks, LOAD_TEXT|LOAD_DATA|LOAD_BSS);
+#endif
 	if (fd >= 0) {
 		close(fd);
 		exec_image(BOOT_TEXTADDR, /* image loaded at */

Index: src/sys/arch/x68k/stand/xxboot/consio1.c
diff -u src/sys/arch/x68k/stand/xxboot/consio1.c:1.1 src/sys/arch/x68k/stand/xxboot/consio1.c:1.2
--- src/sys/arch/x68k/stand/xxboot/consio1.c:1.1	Tue Mar 20 13:01:32 2012
+++ src/sys/arch/x68k/stand/xxboot/consio1.c	Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: consio1.c,v 1.1 2012/03/20 13:01:32 minoura Exp $	*/
+/*	$NetBSD: consio1.c,v 1.2 2020/08/16 06:43:43 isaki Exp $	*/
 
 /*
  * Copyright (c) 2001,2010 MINOURA Makoto.
@@ -29,10 +29,8 @@
 #include <lib/libkern/libkern.h>
 #include <lib/libsa/stand.h>
 
-#include "libx68k.h"
-
+#include "xxboot.h"
 #include "iocs.h"
-#include "consio.h"
 
 int
 getchar(void)

Index: src/sys/arch/x68k/stand/xxboot/version
diff -u src/sys/arch/x68k/stand/xxboot/version:1.3 src/sys/arch/x68k/stand/xxboot/version:1.4
--- src/sys/arch/x68k/stand/xxboot/version:1.3	Sat Jan 18 05:07:34 2020
+++ src/sys/arch/x68k/stand/xxboot/version	Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.3 2020/01/18 05:07:34 isaki Exp $
+$NetBSD: version,v 1.4 2020/08/16 06:43:43 isaki Exp $
 
 NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
 file is important - make sure the entries are appended on end, last item
@@ -7,3 +7,4 @@ is taken as the current.
 1.0:	Initial revision.
 1.1:	Fix FFS and LFS boot from SCSI HD and floppies.  Always print version.
 1.2:	Initialize the screen.
+2.0:	Rewrite mostly.  Support xxboot_ustarfs.
Index: src/sys/arch/x68k/stand/xxboot/xx.c
diff -u src/sys/arch/x68k/stand/xxboot/xx.c:1.3 src/sys/arch/x68k/stand/xxboot/xx.c:1.4
--- src/sys/arch/x68k/stand/xxboot/xx.c:1.3	Fri Aug 14 03:34:22 2020
+++ src/sys/arch/x68k/stand/xxboot/xx.c	Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xx.c,v 1.3 2020/08/14 03:34:22 isaki Exp $	*/
+/*	$NetBSD: xx.c,v 1.4 2020/08/16 06:43:43 isaki Exp $	*/
 
 /*
  * Copyright (c) 2010 MINOURA Makoto.
@@ -29,6 +29,7 @@
 #include <lib/libsa/stand.h>
 
 #include "xxboot.h"
+#include "iocs.h"
 
 int
 xxopen(struct open_file *f, ...)
@@ -49,7 +50,24 @@ xxstrategy(void *arg, int rw, daddr_t db
            void *buf, size_t *rsize)
 {
 
-	RAW_READ(buf, (uint32_t)dblk, size);
+	/*
+	 * dblk is (always?) in 512 bytes unit, even if CD (2048 byte/sect).
+	 * size is in byte.
+	 *
+	 * On SCSI HD, the position specified in raw_read() (1st argument)
+	 * counts from the beginning of the disk, not the beginning of the
+	 * partition.  On SCSI CD and floppy, SCSI_PARTTOP is zero.
+	 */
+#if defined(XXBOOT_DEBUG)
+	IOCS_B_PRINT("xxstrategy ");
+	print_hex(dblk, 8);
+	IOCS_B_PRINT(" len=");
+	print_hex(size, 8);
+	IOCS_B_PRINT("\r\n");
+#endif
+	if (size != 0) {
+		raw_read((uint32_t)(SCSI_PARTTOP + dblk), (uint32_t)size, buf);
+	}
 	if (rsize)
 		*rsize = size;
 	return 0;
Index: src/sys/arch/x68k/stand/xxboot/xxboot.h
diff -u src/sys/arch/x68k/stand/xxboot/xxboot.h:1.3 src/sys/arch/x68k/stand/xxboot/xxboot.h:1.4
--- src/sys/arch/x68k/stand/xxboot/xxboot.h:1.3	Fri Aug 14 03:34:22 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot.h	Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xxboot.h,v 1.3 2020/08/14 03:34:22 isaki Exp $	*/
+/*	$NetBSD: xxboot.h,v 1.4 2020/08/16 06:43:43 isaki Exp $	*/
 
 /*
  * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
@@ -28,24 +28,41 @@
 #define BINF_ISFD(pbinf)	(*((uint8_t *)(pbinf) + 1) == 0)
 
 /* boot.S */
-extern void RAW_READ(void *, uint32_t, size_t);
+extern int raw_read(uint32_t, uint32_t, void *);
 extern int badbaddr(volatile void *);
-extern unsigned int BOOT_INFO;	/* result of IOCS(__BOOTINF) */
-extern unsigned int ID;		/* target SCSI ID */
+extern void BOOT_ERROR(const char *) __dead;
+extern uint32_t BOOT_INFO;	/* result of IOCS(__BOOTINF) */
+extern uint32_t SCSI_ID;	/* target SCSI ID */
+extern uint32_t SCSI_PARTTOP;	/* top sector # of this partition */
+extern uint32_t SCSI_BLKLEN;	/* sector length index */
+extern struct {
+	uint32_t total_blocks;
+	uint32_t blocksize;
+} SCSI_CAP;
 extern struct {
 	struct fdfmt{
-		uint8_t	N;	/* sector length 0: 128, ..., 3: 1K */
+		uint8_t	N;	/* sector length 1:256, 2:512, 3:1024 */
 		uint8_t	C;	/* cylinder # */
 		uint8_t	H;	/* head # */
 		uint8_t	R;	/* sector # */
 	} minsec, maxsec;
-} FDSECMINMAX;			/* FD format type of the first track */
+} FDSEC;			/* FD format type of the first track */
+
+/* bootmain.c */
+extern void print_hex(u_int, int);
+
+/* consio1.c */
+extern int getchar(void);
+extern void putchar(int);
 
 /* xx.c */
 extern int xxopen(struct open_file *, ...);
 extern int xxclose(struct open_file *);
 extern int xxstrategy(void *, int, daddr_t, size_t, void *, size_t *);
 
+/* xxboot.ldscript */
+extern uint32_t startregs[16];
+
 /* vers.c */
 extern const char bootprog_name[];
 extern const char bootprog_rev[];

Index: src/sys/arch/x68k/stand/xxboot/xxboot.ldscript
diff -u src/sys/arch/x68k/stand/xxboot/xxboot.ldscript:1.9 src/sys/arch/x68k/stand/xxboot/xxboot.ldscript:1.10
--- src/sys/arch/x68k/stand/xxboot/xxboot.ldscript:1.9	Fri Aug 14 03:54:46 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot.ldscript	Sun Aug 16 06:43:43 2020
@@ -40,6 +40,11 @@ SECTIONS
     _edata  =  .;
   }
   . = TEXTADDR + TEXTDATASIZE;
+
+  /* Place uint32_t startregs[16] out of bss */
+  PROVIDE(startregs = .);
+  . += 0x40/* sizeof(startregs) */;
+
   .bss :
   {
     __bss_start = .;

Index: src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile
diff -u src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile:1.5 src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile:1.6
--- src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile:1.5	Fri Aug 14 03:40:47 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile	Sun Aug 16 06:43:44 2020
@@ -1,7 +1,6 @@
-#	$NetBSD: Makefile,v 1.5 2020/08/14 03:40:47 isaki Exp $
+#	$NetBSD: Makefile,v 1.6 2020/08/16 06:43:44 isaki Exp $
 
 FS=		ffsv1
-BOOTCPPFLAGS=	-DSDBOOT -DFDBOOT
 
 TOUCHPROG=	@true
 

Index: src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile
diff -u src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile:1.5 src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile:1.6
--- src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile:1.5	Fri Aug 14 03:40:47 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile	Sun Aug 16 06:43:44 2020
@@ -1,7 +1,6 @@
-#	$NetBSD: Makefile,v 1.5 2020/08/14 03:40:47 isaki Exp $
+#	$NetBSD: Makefile,v 1.6 2020/08/16 06:43:44 isaki Exp $
 
 FS=		ffsv2
-BOOTCPPFLAGS=	-DSDBOOT -DFDBOOT
 
 TOUCHPROG=	@true
 

Index: src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile
diff -u src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile:1.5 src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile:1.6
--- src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile:1.5	Fri Aug 14 03:40:47 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile	Sun Aug 16 06:43:44 2020
@@ -1,7 +1,6 @@
-#	$NetBSD: Makefile,v 1.5 2020/08/14 03:40:47 isaki Exp $
+#	$NetBSD: Makefile,v 1.6 2020/08/16 06:43:44 isaki Exp $
 
 FS=		lfsv1
-BOOTCPPFLAGS=	-DSDBOOT -DFDBOOT
 
 TOUCHPROG=	@true
 

Index: src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile
diff -u src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile:1.5 src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile:1.6
--- src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile:1.5	Fri Aug 14 03:40:47 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile	Sun Aug 16 06:43:44 2020
@@ -1,7 +1,6 @@
-#	$NetBSD: Makefile,v 1.5 2020/08/14 03:40:47 isaki Exp $
+#	$NetBSD: Makefile,v 1.6 2020/08/16 06:43:44 isaki Exp $
 
 FS=		lfsv2
-BOOTCPPFLAGS=	-DSDBOOT -DFDBOOT
 
 TOUCHPROG=	@true
 

Added files:

Index: src/sys/arch/x68k/stand/xxboot/ashldi3.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/ashldi3.S:1.1
--- /dev/null	Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/ashldi3.S	Sun Aug 16 06:43:43 2020
@@ -0,0 +1,121 @@
+/*	$NetBSD: ashldi3.S,v 1.1 2020/08/16 06:43:43 isaki Exp $	*/
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+ASENTRY_NOPROFILE(__ashldi3)
+		moveml	%sp@(4),%d0-%d1/%a0	| %d0:%d1 = quad value
+						| %a0     = shift count
+		jbra	start
+loop:
+		lsll	#1,%d1			| X:%d1 =<< 1
+		roxll	#1,%d0			| %d0:X =<< 1
+start:
+		subql	#1,%a0			| sub %a0 doesn't affect ccr,
+		tstl	%a0			|  but this extra TST op is
+						|  smaller than push/pop %d2.
+		jpl	loop
+		rts
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+		.macro	PRINT	msg
+		leal	\msg,%a1
+		IOCS(__B_PRINT)
+		.endm
+
+		.macro	TEST	name
+		leal	\name,%a2
+		jbsr	test
+		.endm
+
+ASENTRY_NOPROFILE(selftest_ashldi3)
+		moveml	%d2-%d7/%a2-%a6,%sp@-
+		PRINT	%pc@(msg_testname)
+
+		TEST	test0
+		TEST	test1
+		TEST	test2
+		TEST	test63
+
+		PRINT	%pc@(msg_crlf)
+		moveml	%sp@+,%d2-%d7/%a2-%a6
+		rts
+
+test:
+		moveml	%a2@+,%d0-%d2		| %d0:%d1 = value
+						| %d2     = count
+		moveml	%d0-%d2,%sp@-
+		jbsr	__ashldi3
+		leal	%sp@(12),%sp
+
+		cmpl	%a2@+,%d0		| compare high word
+		jne	fail
+		cmpl	%a2@+,%d1		| compare low word
+		jne	fail
+		PRINT	%pc@(msg_ok)
+		rts
+fail:
+		PRINT	%pc@(msg_fail)
+		rts
+
+test0:		| count = 0
+		.long	0x11223344, 0x55667788
+		.long	0
+		.long	0x11223344, 0x55667788
+
+test1:		| count = 1
+		.long	0x11223344, 0x55667788
+		.long	1
+		.long	0x22446688, 0xaaccef10
+
+test2:		| count = 2
+		.long	0x11223344, 0x55667788
+		.long	2
+		.long	0x4488cd11, 0x5599de20
+
+test63:		| count = 63
+		.long	0x11223344, 0x55667789
+		.long	63
+		.long	0x80000000, 0x00000000
+
+msg_testname:
+		.asciz	"__ashldi3"
+msg_ok:
+		.asciz	" ok"
+msg_fail:
+		.asciz	" fail"
+msg_crlf:
+		.asciz	"\r\n"
+
+#endif
Index: src/sys/arch/x68k/stand/xxboot/ashrdi3.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/ashrdi3.S:1.1
--- /dev/null	Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/ashrdi3.S	Sun Aug 16 06:43:43 2020
@@ -0,0 +1,139 @@
+/*	$NetBSD: ashrdi3.S,v 1.1 2020/08/16 06:43:43 isaki Exp $	*/
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+ASENTRY_NOPROFILE(__ashrdi3)
+		moveml	%sp@(4),%d0-%d1/%a0	| %d0:%d1 = quad value
+						| %a0     = shift count
+		jbra	start
+loop:
+		asrl	#1,%d0			| %d0:X >>>= 1
+		roxrl	#1,%d1			| X:%d1 >>= 1
+start:
+		subql	#1,%a0			| sub %a0 doesn't affect ccr,
+		tstl	%a0			|  but this extra TST op is
+						|  smaller than push/pop %d2.
+		jpl	loop
+		rts
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+		.macro	PRINT	msg
+		leal	\msg,%a1
+		IOCS(__B_PRINT)
+		.endm
+
+		.macro	TEST	name
+		leal	\name,%a2
+		jbsr	test
+		.endm
+
+ASENTRY_NOPROFILE(selftest_ashrdi3)
+		moveml	%d2-%d7/%a2-%a6,%sp@-
+		PRINT	%pc@(msg_testname)
+
+		TEST	test0
+		TEST	test1p
+		TEST	test1m
+		TEST	test4p
+		TEST	test4m
+		TEST	test63p
+		TEST	test63m
+
+		PRINT	%pc@(msg_crlf)
+		moveml	%sp@+,%d2-%d7/%a2-%a6
+		rts
+
+test:
+		moveml	%a2@+,%d0-%d2		| %d0:%d1 = value
+						| %d2     = count
+		moveml	%d0-%d2,%sp@-
+		jbsr	__ashrdi3
+		leal	%sp@(12),%sp
+
+		cmpl	%a2@+,%d0		| compare high word
+		jne	fail
+		cmpl	%a2@+,%d1		| compare low word
+		jne	fail
+		PRINT	%pc@(msg_ok)
+		rts
+fail:
+		PRINT	%pc@(msg_fail)
+		rts
+
+test0:		| count = 0
+		.long	0x11223344, 0x55667788
+		.long	0
+		.long	0x11223344, 0x55667788
+
+test1p:		| count = 1
+		.long	0x11223344, 0x55667788
+		.long	1
+		.long	0x089119a2, 0x2ab33bc4
+
+test1m:		| count = 1 (negative value)
+		.long	0x91223344, 0x55667788
+		.long	1
+		.long	0xc89119a2, 0x2ab33bc4
+
+test4p:		| count = 4
+		.long	0x11223344, 0x55667788
+		.long	4
+		.long	0x01122334, 0x45566778
+
+test4m:		| count = 4 (negative value)
+		.long	0x91223344, 0x55667788
+		.long	4
+		.long	0xf9122334, 0x45566778
+
+test63p:	| count = 63
+		.long	0x41223344, 0x55667788
+		.long	63
+		.long	0x00000000, 0x00000000
+
+test63m:	| count = 63 (negative value)
+		.long	0x91223344, 0x55667788
+		.long	63
+		.long	0xffffffff, 0xffffffff
+
+msg_testname:
+		.asciz	"__ashrdi3"
+msg_ok:
+		.asciz	" ok"
+msg_fail:
+		.asciz	" fail"
+msg_crlf:
+		.asciz	"\r\n"
+
+#endif
Index: src/sys/arch/x68k/stand/xxboot/memcmp.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/memcmp.S:1.1
--- /dev/null	Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/memcmp.S	Sun Aug 16 06:43:43 2020
@@ -0,0 +1,150 @@
+/*	$NetBSD: memcmp.S,v 1.1 2020/08/16 06:43:43 isaki Exp $	*/
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized (but slow) version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+|
+| int memcmp(const void *b1, const void *b2, size_t len)
+|
+ASENTRY_NOPROFILE(memcmp)
+		moveml	%sp@,%d0-%d1/%a0-%a1	| %d0: (return address)
+						| %d1: b1
+						| %a0: b2
+						| %a1: len
+
+		exg	%d1,%a1			| %d1: len
+						| %a0: b2
+						| %a1: b1
+		moveql	#0,%d0
+loop:
+		subql	#1,%d1			| if (--len < 0)
+		jcs	exit			|  goto exit
+compare:
+		cmpmb	%a0@+,%a1@+
+		jeq	loop
+		| To comply with standards, recalc exact return value.
+		| Although everyone expects only 0 or not...
+		moveq	#0,%d1
+		moveb	%a1@-,%d0
+		moveb	%a0@-,%d1
+		subl	%d1,%d0			| (uint)*b1 - (uint)*b2
+exit:
+		rts
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+		.macro	PRINT	msg
+		leal	\msg,%a1
+		IOCS(__B_PRINT)
+		.endm
+
+		.macro	TEST	name
+		leal	\name,%a2
+		jbsr	test
+		.endm
+
+ASENTRY_NOPROFILE(selftest_memcmp)
+		moveml	%d2-%d7/%a2-%a6,%sp@-
+		PRINT	%pc@(msg_testname)
+
+		TEST	test1
+		TEST	test2
+		TEST	test3
+		TEST	test4
+		TEST	test5
+
+		PRINT	%pc@(msg_crlf)
+		moveml	%sp@+,%d2-%d7/%a2-%a6
+		rts
+
+test:
+		movel	%a2@+,buf:W		| contents of b1
+		movel	%a2@+,(buf+4):W		| contents of b2
+		movel	%a2@+,%sp@-		| push len
+		peal	(buf+4):W		| push b2
+		peal	(buf):W			| push b1
+		jbsr	memcmp
+		leal	%sp@(12),%sp
+
+		cmpl	%a2@,%d0		| compare return value
+		jne	fail
+		PRINT	%pc@(msg_ok)
+		rts
+fail:
+		PRINT	%pc@(msg_fail)
+		rts
+
+test1:
+		| b1 == b2 within length
+		.long 	0x11223344		| b1
+		.long	0x11223355		| b2
+		.long	3			| len
+		.long	0			| expected
+
+test2:
+		| b1 > b2 before the last
+		.long	0x11813344		| b1
+		.long	0x11013344		| b2
+		.long	3			| len
+		.long	0x00000080		| expected
+
+test3:
+		| b1 < b2 in the last byte
+		.long	0x11220044		| b1
+		.long	0x11220144		| b2
+		.long	3			| len
+		.long	-1			| expected
+
+test4:		| len == 0
+		.long	0x11223344		| b1
+		.long	0x11223344		| b2
+		.long	0			| len
+		.long	0			| expected
+
+test5:		| *b1 - *b2 = 0 - 255 = -255
+		.long	0x00000000		| b1
+		.long	0xff000000		| b2
+		.long	1			| len
+		.long	-255			| expected
+
+msg_testname:
+		.asciz	"memcmp"
+msg_ok:
+		.asciz	" ok"
+msg_fail:
+		.asciz	" fail"
+msg_crlf:
+		.asciz	"\r\n"
+
+		BSS(buf, 8)
+#endif
Index: src/sys/arch/x68k/stand/xxboot/memcpy.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/memcpy.S:1.1
--- /dev/null	Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/memcpy.S	Sun Aug 16 06:43:43 2020
@@ -0,0 +1,181 @@
+/*	$NetBSD: memcpy.S,v 1.1 2020/08/16 06:43:43 isaki Exp $	*/
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized (but slow) version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+|
+| void bcopy(const void *src, void *dst, size_t len);
+|
+ASENTRY_NOPROFILE(bcopy)
+		moveml	%sp@,%d0-%d1/%a0-%a1	| %d0: (return address)
+						| %d1: src
+						| %a0: dst
+						| %a1: count
+		jbra	memmove_common
+|
+| void *memcpy(void *dst, const void *src, size_t count);
+| void *memmove(void *dst, const void *src, size_t count);
+|
+ASENTRY_NOPROFILE(memcpy)
+ASENTRY_NOPROFILE(memmove)
+		moveml	%sp@,%d0-%d1/%a0-%a1	| %d0: (return address)
+						| %d1: dst
+						| %a0: src
+						| %a1: count
+
+		exg	%d1,%a0			| %d1: src
+						| %a0: dst
+						| %a1: count
+memmove_common:
+		exg	%d1,%a1			| %d1: count
+						| %a0: dst
+						| %a1: src
+		moveql	#0,%d0
+						| %d0: offset in forward mode.
+						| %d1: offset in backward mode
+						|  and also loop counter.
+		jbra	2f
+loop:
+		| if src(=%a1) > dst(=%a0), then this is forward copy,
+		|  %d0 is already forward offset.
+		| Otherwise backward copy.  Copy %d1(backward offset) to %d0.
+		cmpl	%a1,%a0
+		jcs	1f
+		movel	%d1,%d0
+1:
+		moveb	%a1@(%d0.l),%a0@(%d0.l) | %d0: offset
+		addql	#1,%d0			| increment forward counter,
+						|  though it's pointless in
+						|  backward mode
+2:
+		subql	#1,%d1			| if (--count < 0)
+		jcc	loop			|  goto exit
+exit:
+		rts				| %a0 holds return value (=dst)
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+		.macro	PRINT	msg
+		leal	\msg,%a1
+		IOCS(__B_PRINT)
+		.endm
+
+		.macro	TEST	name
+		leal	\name,%a2
+		jbsr	test
+		.endm
+
+ASENTRY_NOPROFILE(selftest_memmove)
+		moveml	%d2-%d7/%a2-%a6,%sp@-
+		PRINT	%pc@(msg_testname)
+
+		TEST	test1
+		TEST	test2
+		TEST	test3
+		TEST	test4
+
+		PRINT	%pc@(msg_crlf)
+		moveml	%sp@+,%d2-%d7/%a2-%a6
+		rts
+
+test:
+		movel	%a2@+,buf:W		| initial contents of buffer
+		movew	%a2@+,(buf+4):W		|  (6 bytes total)
+		movel	%a2@+,%sp@-		| push len
+		movel	%a2@+,%sp@-		| push src
+		movel	%a2@+,%a3		| keep dst and
+		movel	%a3,%sp@-		| push dst
+		jbsr	memmove
+		leal	%sp@(12),%sp
+
+		cmpal	%a3,%a0			| compare return value
+		jne	fail
+		movel	%a2@+,%d0		| compare buf[0..3]
+		cmpl	buf:W,%d0
+		jne	fail
+		movew	%a2@+,%d0		| compare buf[4..5]
+		cmpw	(buf+4):W,%d0		| compare buf[4..5]
+		jne	fail
+		PRINT	%pc@(msg_ok)
+		rts
+fail:
+		PRINT	%pc@(msg_fail)
+		rts
+
+test1:
+		| src=buf+1: 1 2 3 4 5 6
+		|               \ \
+		| dst=buf+2: 1 2 2 3 5 6
+		.byte	1, 2, 3, 4, 5, 6	| initial buf
+		.long	2			| len
+		.long	buf+1			| src
+		.long	buf+2			| dst
+		.byte	1, 2, 2, 3, 5, 6	| expected buf
+
+test2:
+		| src=buf+2: 1 2 3 4 5 6
+		|               / /
+		| dst=buf+1: 1 3 4 4 5 6
+		.byte	1, 2, 3, 4, 5, 6	| initial buf
+		.long	2			| len
+		.long	buf+2			| src
+		.long	buf+1			| dst
+		.byte	1, 3, 4, 4, 5, 6	| expected buf
+
+test3:
+		| src == dst
+		.byte	1, 2, 3, 4, 5, 6	| initial buf
+		.long	2			| len
+		.long	buf+1			| src
+		.long	buf+1			| dst
+		.byte	1, 2, 3, 4, 5, 6	| expected buf
+
+test4:
+		| len == 0
+		.byte	1, 2, 3, 4, 5, 6	| initial buf
+		.long	0			| len
+		.long	buf+1			| src
+		.long	buf+1			| dst
+		.byte	1, 2, 3, 4, 5, 6	| expected buf
+
+msg_testname:
+		.asciz	"memmove"
+msg_ok:
+		.asciz	" ok"
+msg_fail:
+		.asciz	" fail"
+msg_crlf:
+		.asciz	"\r\n"
+
+		BSS(buf, 8)
+#endif
Index: src/sys/arch/x68k/stand/xxboot/memset.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/memset.S:1.1
--- /dev/null	Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/memset.S	Sun Aug 16 06:43:43 2020
@@ -0,0 +1,138 @@
+/*	$NetBSD: memset.S,v 1.1 2020/08/16 06:43:43 isaki Exp $	*/
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized (but slow) version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+|
+| void bzero(void *dst, size_t len)
+|
+ASENTRY_NOPROFILE(bzero)
+		moveml	%sp@,%d0-%d1/%a1	| %d0: (return address)
+						| %d1: dst
+						| %a1: len
+
+		subal	%a0,%a0			| %a0: c = 0
+		jbra	memset_common
+
+|
+| void *memset(void *dst, int c, size_t len);
+|
+ASENTRY_NOPROFILE(memset)
+		moveml	%sp@,%d0-%d1/%a0-%a1	| %d0: (return address)
+						| %d1: dst
+						| %a0: c
+						| %a1: len
+memset_common:
+		addal	%d1,%a1			| %a1: loop start+1 address
+
+		exg	%d1,%a0			| %d1: c
+						| %a0: initial dst
+						|  for return value and
+						|  loop-end condition address
+		jbra	2f
+1:
+		moveb	%d1,%a1@-		| memset in reverse direction
+2:
+		cmpl	%a1,%a0
+		jne	1b			| if condition met, %a0 = dst
+		rts
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+		.macro	PRINT	msg
+		leal	\msg,%a1
+		IOCS(__B_PRINT)
+		.endm
+
+		.macro	TEST	name
+		leal	\name,%a2
+		jbsr	test
+		.endm
+
+ASENTRY_NOPROFILE(selftest_memset)
+		moveml	%d2-%d7/%a2-%a6,%sp@-
+		PRINT	%pc@(msg_testname)
+
+		TEST	test1
+		TEST	test2
+
+		PRINT	%pc@(msg_crlf)
+		moveml	%sp@+,%d2-%d7/%a2-%a6
+		rts
+
+test:
+		movel	%a2@+,buf:W		| initial contents of buffer
+		movel	%a2@+,%sp@-		| push len
+		movel	%a2@+,%sp@-		| push c
+		movel	%a2@+,%a3		| keep dst and
+		movel	%a3,%sp@-		| push dst
+		jbsr	memset
+		leal	%sp@(12),%sp
+
+		cmpal	%a3,%a0			| compare return value
+		jne	fail
+		movel	%a2@+,%d0		| compare buf[0..4]
+		cmpl	buf:W,%d0
+		jne	fail
+		PRINT	%pc@(msg_ok)
+		rts
+fail:
+		PRINT	%pc@(msg_fail)
+		rts
+
+test1:
+		.long	0x11223344		| initial buf
+		.long	2			| len
+		.long	0xaa			| c
+		.long	buf+1			| dst
+		.long	0x11aaaa44		| expected buf
+
+test2:
+		| len == 0
+		.long	0x11223344		| initial buf
+		.long	0			| len
+		.long	0x55			| c
+		.long	buf+1			| dst
+		.long	0x11223344		| expected buf
+
+msg_testname:
+		.asciz	"memset"
+msg_ok:
+		.asciz	" ok"
+msg_fail:
+		.asciz	" fail"
+msg_crlf:
+		.asciz	"\r\n"
+
+		BSS(buf, 8)
+#endif

Index: src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs/Makefile
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs/Makefile:1.1
--- /dev/null	Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs/Makefile	Sun Aug 16 06:43:44 2020
@@ -0,0 +1,11 @@
+#	$NetBSD: Makefile,v 1.1 2020/08/16 06:43:44 isaki Exp $
+
+FS=		ustarfs
+BOOTCPPFLAGS+=	-DXXBOOT_$(FS:tu)
+
+# ustarfs requires printf...
+BOOTSRCS+=	printf.c subr_prf.c panic.c closeall.c consio1.c
+
+TOUCHPROG=	@true
+
+.include "../Makefile.xxboot"

Reply via email to