1201342Snyan/*-
2201342Snyan * Copyright (c) 2008-2009 TAKAHASHI Yoshihiro
3201342Snyan * All rights reserved.
4201342Snyan *
5201342Snyan * Redistribution and use in source and binary forms, with or without
6201342Snyan * modification, are permitted provided that the following conditions
7201342Snyan * are met:
8201342Snyan * 1. Redistributions of source code must retain the above copyright
9201342Snyan *    notice, this list of conditions and the following disclaimer.
10201342Snyan * 2. Redistributions in binary form must reproduce the above copyright
11201342Snyan *    notice, this list of conditions and the following disclaimer in the
12201342Snyan *    documentation and/or other materials provided with the distribution.
13201342Snyan *
14201342Snyan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15201342Snyan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16201342Snyan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17201342Snyan * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18201342Snyan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19201342Snyan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20201342Snyan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21201342Snyan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22201342Snyan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23201342Snyan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24201342Snyan * SUCH DAMAGE.
25201342Snyan *
26201342Snyan * $FreeBSD: stable/11/stand/pc98/boot2/boot1.S 229462 2012-01-04 03:49:41Z nyan $
27201342Snyan */
28201342Snyan
29201342Snyan/* Memory Locations */
30201342Snyan		.set STACK_OFF,0x6000		# Stack offset
31201342Snyan		.set LOAD_SIZE,8192		# Load size
32201342Snyan		.set DAUA,0x0584		# DA/UA
33201342Snyan		.set MEM_REL,0x700		# Relocation address
34201342Snyan		.set MEM_ARG,0x900		# Arguments
35201342Snyan		.set MEM_BUF,0x8cec		# Load area
36201342Snyan		.set MEM_BTX,0x9000		# BTX start
37201342Snyan		.set MEM_JMP,0x9010		# BTX entry point
38201342Snyan		.set MEM_USR,0xa000		# Client start
39201342Snyan
40201342Snyan/* PC98 machine type from sys/pc98/pc98/pc98_machdep.h */
41201342Snyan		.set MEM_SYS,		0xa100	# System common area segment
42201342Snyan		.set PC98_MACHINE_TYPE,	0x0620	# PC98 machine type
43201342Snyan		.set EPSON_ID,		0x0624	# EPSON machine id
44201342Snyan
45201342Snyan		.set M_NEC_PC98,	0x0001
46201342Snyan		.set M_EPSON_PC98,	0x0002
47201342Snyan		.set M_NOT_H98,		0x0010
48201342Snyan		.set M_H98,		0x0020
49201342Snyan		.set M_NOTE,		0x0040
50201342Snyan		.set M_NORMAL,		0x1000
51201342Snyan		.set M_8M,		0x8000
52201342Snyan
53201342Snyan/* Partition Constants */
54201342Snyan		.set PRT_OFF,0x1be		# Partition offset
55201342Snyan
56201342Snyan/* Misc. Constants */
57201342Snyan		.set SIZ_PAG,0x1000		# Page size
58201342Snyan		.set SIZ_SEC,0x200		# Sector size
59201342Snyan
60201342Snyan		.set NSECT,0x10
61201342Snyan
62201342Snyan		.globl start
63201342Snyan		.globl read
64201342Snyan		.globl putc
65201342Snyan		.code16
66201342Snyan
67201342Snyanstart:		jmp main
68201342Snyan
69201342Snyanboot_cyl:	.org 4
70201342Snyan		.ascii "IPL1   "
71201342Snyan
72201342Snyanmain:		cld
73201342Snyan
74201342Snyan		/* Setup the stack */
75201342Snyan		xor %si,%si
76201342Snyan		mov %si,%ss
77201342Snyan		mov $STACK_OFF,%sp
78201342Snyan
79201342Snyan		push %cx
80201342Snyan
81201342Snyan		/* Relocate ourself to MEM_REL */
82201342Snyan		push %cs
83201342Snyan		pop %ds
84201342Snyan		mov %si,%es
85201342Snyan		mov $MEM_REL,%di
86201342Snyan		mov $SIZ_SEC,%cx
87201342Snyan		rep
88201342Snyan		movsb
89201342Snyan
90201342Snyan		/* Transfer PC-9801 system common area */
91201342Snyan		xor %ax,%ax
92201342Snyan		mov %ax,%si
93201342Snyan		mov %ax,%ds
94201342Snyan		mov %ax,%di
95201342Snyan		mov $MEM_SYS,%ax
96201342Snyan		mov %ax,%es
97201342Snyan		mov $0x0600,%cx
98201342Snyan		rep
99201342Snyan		movsb
100201342Snyan
101201342Snyan		/* Transfer EPSON machine type */
102201342Snyan		mov $0xfd00,%ax
103201342Snyan		mov %ax,%ds
104201342Snyan		mov (0x804),%eax
105201342Snyan		and $0x00ffffff,%eax
106201342Snyan		mov %eax,%es:(EPSON_ID)
107201342Snyan
108201342Snyan		/* Set machine type to PC98_SYSTEM_PARAMETER */
109201342Snyan#ifdef SET_MACHINE_TYPE
110201342Snyan		call set_machine_type
111201342Snyan#else
112201342Snyan		mov $M_NEC_PC98+M_NOT_H98,%eax
113201342Snyan		mov %eax,%es:(PC98_MACHINE_TYPE)
114201342Snyan#endif
115201342Snyan
116201342Snyan		/* Setup graphic screen */
117201342Snyan		mov $0x42,%ah		/* 640x400 */
118201342Snyan		mov $0xc0,%ch
119201342Snyan		int $0x18
120201342Snyan		mov $0x40,%ah		/* graph on */
121201342Snyan		int $0x18
122201342Snyan
123201342Snyan		/* Setup text screen */
124201342Snyan		mov $0x0a00,%ax		/* 80x25 */
125201342Snyan		int $0x18
126201342Snyan		mov $0x0c,%ah		/* text on */
127201342Snyan		int $0x18
128201342Snyan		mov $0x13,%ah		/* cursor home */
129201342Snyan		xor %dx,%dx
130201342Snyan		int $0x18
131201342Snyan		mov $0x11,%ah		/* cursor on */
132201342Snyan		int $0x18
133201342Snyan
134201342Snyan		/* Setup keyboard */
135201342Snyan		mov $0x03,%ah
136201342Snyan		int $0x18
137201342Snyan
138201342Snyan		pop %cx
139201342Snyan
140201342Snyan		/* bootstrap passes */
141201342Snyan		xor %edi,%edi
142201342Snyan		mov %di,%ds
143201342Snyan		mov %di,%es
144201342Snyan		mov %cs,%bx
145201342Snyan		cmp $0x1fe0,%bx
146201342Snyan		jz boot_fd
147201342Snyan		cmp $0x1fc0,%bx
148201342Snyan		jnz boot_hd
149201342Snyan		xor %cx,%cx
150201342Snyan		mov (DAUA),%al
151201342Snyan		and $0xf0,%al
152201342Snyan		cmp $0x30,%al
153201342Snyan		jz boot_fd
154201342Snyan		cmp $0x90,%al
155201342Snyan		jnz boot_hd
156201342Snyanboot_fd:	xor %cx,%cx
157201342Snyan		jmp boot_load
158201342Snyanboot_hd:	test %cx,%cx
159201342Snyan		jnz boot_load
160201342Snyan		mov %cs:(boot_cyl),%cx
161201342Snyanboot_load:	mov %cx,MEM_ARG		/* Save cylinder number */
162201342Snyan		mov %cx,%di
163201342Snyan		xor %dx,%dx
164201342Snyan		mov $LOAD_SIZE,%bx
165201342Snyan		mov $MEM_BUF,%bp
166201342Snyan		push %cs
167201342Snyan		callw read
168201342Snyan		jc error
169201342Snyan
170201342Snyan		/* Transfer boot2.bin */
171201342Snyan		mov $MEM_BTX,%bx
172201342Snyan		mov 0xa(%bx),%si	/* BTX size */
173201342Snyan		add %bx,%si		/* start of boot2.bin */
174201342Snyan		mov $MEM_USR+SIZ_PAG*2,%di
175201342Snyan		mov $MEM_BTX+(NSECT-1)*SIZ_SEC,%cx
176201342Snyan		sub %si,%cx
177201342Snyan		rep
178201342Snyan		movsb
179201342Snyan
180201342Snyan		/* Enable A20 */
181201342Snyan		xor %ax,%ax
182201342Snyan		outb %al,$0xf2
183201342Snyan		mov $0x02,%al
184201342Snyan		outb %al,$0xf6
185201342Snyan
186201342Snyan		/* Start BTX */
187201342Snyan		ljmp $0x0000,$MEM_JMP
188201342Snyan
189201342Snyan/*
190201342Snyan * Reads sectors from the disk.
191201342Snyan * Call with:
192201342Snyan *
193201342Snyan * %bx		- bytes to read
194201342Snyan * %cx		- cylinder
195201342Snyan * %dh		- head
196201342Snyan * %dl		- sector
197201342Snyan * %edi		- lba
198201342Snyan * %es:(%bp)	- buffer to read data into
199201342Snyan */
200201342Snyanread:		xor %ax,%ax
201201342Snyan		mov %ax,%ds
202201342Snyan		mov $0x06,%ah
203201342Snyan		mov (DAUA),%al
204201342Snyan		mov %ax,%si
205201342Snyan		and $0xf0,%al
206201342Snyan		cmp $0x30,%al		/* 1.44MB FDD */
207201342Snyan		jz read_fd
208201342Snyan		cmp $0x90,%al		/* 1MB FDD */
209201342Snyan		jz read_fd
210201342Snyan		cmp $0xa0,%al		/* Is SCSI device? */
211201342Snyan		jnz read_load
212201342Snyan		push %cx
213201342Snyan		mov %si,%cx
214201342Snyan		and $0x0f,%cl
215201342Snyan		inc %cl
216201342Snyan		mov (0x482),%ah
217201342Snyan		shr %cl,%ah		/* Is SCSI HDD? */
218201342Snyan		pop %cx
219201342Snyan		jc read_load
220201342Snyan		and $0xff7f,%si		/* SCSI MO */
221201342Snyan		mov %di,%cx
222229462Snyan		shr $16,%edi
223201342Snyan		mov %di,%dx
224201342Snyan		jmp read_load
225201342Snyanread_fd:	or $0xd000,%si
226201342Snyan		or $0x0200,%cx
227201342Snyan		inc %dx
228201342Snyanread_load:	mov %si,%ax
229201342Snyan		int $0x1b
230201342Snyan		lret
231201342Snyan
232201342Snyan/*
233201342Snyan * Print out the error message, wait for a keypress, and then reboot
234201342Snyan * the machine.
235201342Snyan */
236201342Snyanerror:		push %cs
237201342Snyan		pop %ds
238201342Snyan		mov $msg_eread,%si
239201342Snyan		call putstr
240201342Snyan		xor %ax,%ax		/* Get keypress */
241201342Snyan		int $0x18
242201342Snyan		xor %ax,%ax		/* CPU reset */
243201342Snyan		outb %al,$0xf0
244201342Snyanhalt:		hlt
245201342Snyan		jmp halt		/* Spin */
246201342Snyan
247201342Snyan/*
248201342Snyan * Display a null-terminated string.
249201342Snyan */
250201342Snyanputstr.0:	push %cs
251201342Snyan		callw putc
252201342Snyanputstr:		lodsb
253201342Snyan		test %al,%al
254201342Snyan		jne putstr.0
255201342Snyan		ret
256201342Snyan
257201342Snyan/*
258201342Snyan * Display a single char.
259201342Snyan */
260201342Snyanputc:		pusha
261201342Snyan		xor %dx,%dx
262201342Snyan		mov %dx,%ds
263201342Snyan		mov MEM_REL+cursor-start,%di
264201342Snyan		mov $0xa000,%bx
265201342Snyan		mov %bx,%es
266201342Snyan		mov $(80*2),%cx
267201342Snyan
268201342Snyan		cmp $0x08,%al
269201342Snyan		je putc.bs
270201342Snyan		cmp $0x0d,%al
271201342Snyan		je putc.cr
272201342Snyan		cmp $0x0a,%al
273201342Snyan		je putc.lf
274201342Snyan		cmp $0x5c,%al			/* \ */
275201342Snyan		jne 1f
276201342Snyan		mov $0xfc,%al
277201342Snyan1:		movb $0xe1,%es:0x2000(%di)
278201342Snyan		stosw
279201342Snyan		jmp putc.scr
280201342Snyanputc.bs:	test %di,%di
281201342Snyan		jz putc.move
282201342Snyan		dec %di
283201342Snyan		dec %di
284201342Snyan		movb $0xe1,%es:0x2000(%di)
285201342Snyan		movw $0x20,%es:(%di)
286201342Snyan		jmp putc.move
287201342Snyanputc.cr:	mov %di,%ax
288201342Snyan		div %cx
289201342Snyan		sub %dx,%di
290201342Snyan		jmp putc.move
291201342Snyanputc.lf:	add %cx,%di
292201342Snyanputc.scr:	cmp $(80*2*25),%di		/* Scroll screen */
293201342Snyan		jb putc.move
294201342Snyan		push %ds
295201342Snyan		mov %bx,%ds
296201342Snyan		mov $(80*2),%si
297201342Snyan		xor %di,%di
298201342Snyan		mov $(80*24/2),%cx
299201342Snyan		rep
300201342Snyan		movsl
301201342Snyan		xor %ax,%ax
302201342Snyan		mov $0x20,%al
303201342Snyan		mov $80,%cl
304201342Snyan		rep
305201342Snyan		stosw
306201342Snyan		pop %ds
307201342Snyan		mov $(80*24*2),%di
308201342Snyanputc.move:	mov %di,MEM_REL+cursor-start	/* Move cursor */
309201342Snyan		mov $0x13,%ah
310201342Snyan		mov %di,%dx
311201342Snyan		int $0x18
312201342Snyan		popa
313201342Snyan		lret
314201342Snyan
315201342Snyancursor:		.word 0
316201342Snyan
317201342Snyan#ifdef SET_MACHINE_TYPE
318201342Snyan/*
319201342Snyan * Set machine type to PC98_SYSTEM_PARAMETER.
320201342Snyan */
321201342Snyanset_machine_type:
322201342Snyan		xor %edx,%edx
323201342Snyan		mov %dx,%ds
324201342Snyan//		mov $MEM_SYS,%ax
325201342Snyan//		mov %ax,%es
326201342Snyan
327201342Snyan		/* Wait V-SYNC */
328201342Snyanvsync.1:	inb $0x60,%al
329201342Snyan		test $0x20,%al
330201342Snyan		jnz vsync.1
331201342Snyanvsync.2:	inb $0x60,%al
332201342Snyan		test $0x20,%al
333201342Snyan		jz vsync.2
334201342Snyan
335201342Snyan		/* ANK 'A' font */
336201342Snyan		xor %al,%al
337201342Snyan		outb %al,$0xa1
338201342Snyan		mov $0x41,%al
339201342Snyan		outb %al,$0xa3
340201342Snyan
341201342Snyan		/* Get 'A' font from CG window */
342201342Snyan		push %ds
343201342Snyan		mov $0xa400,%ax
344201342Snyan		mov %ax,%ds
345201342Snyan		xor %eax,%eax
346201342Snyan		xor %bx,%bx
347201342Snyan		mov $4,%cx
348201342Snyanfont.1:		add (%bx),%eax
349201342Snyan		add $4,%bx
350201342Snyan		loop font.1
351201342Snyan		pop %ds
352201342Snyan		cmp $0x6efc58fc,%eax
353201342Snyan		jnz m_epson
354201342Snyan
355201342Snyanm_pc98:		or $M_NEC_PC98,%edx
356201342Snyan		mov $0x0458,%bx
357201342Snyan		mov (%bx),%al
358201342Snyan		test $0x80,%al
359201342Snyan		jz m_not_h98
360201342Snyan		or $M_H98,%edx
361201342Snyan		jmp 1f
362201342Snyanm_epson:	or $M_EPSON_PC98,%edx
363201342Snyanm_not_h98:	or $M_NOT_H98,%edx
364201342Snyan
365201342Snyan1:		inb $0x42,%al
366201342Snyan		test $0x20,%al
367201342Snyan		jz 1f
368201342Snyan		or $M_8M,%edx
369201342Snyan
370201342Snyan1:		mov $0x0400,%bx
371201342Snyan		mov (%bx),%al
372201342Snyan		test $0x80,%al
373201342Snyan		jz 1f
374201342Snyan		or $M_NOTE,%edx
375201342Snyan
376201342Snyan1:		mov $PC98_MACHINE_TYPE,%bx
377201342Snyan		mov %edx,%es:(%bx)
378201342Snyan		ret
379201342Snyan#endif
380201342Snyan
381201342Snyan/* Messages */
382201342Snyan
383201342Snyanmsg_eread:	.asciz "Error\r\n"
384201342Snyan
385201342Snyan		.org PRT_OFF,0x90
386201342Snyan
387201342Snyan/* Partition table */
388201342Snyan
389201342Snyan		.fill 0x30,0x1,0x0
390201342Snyan		.byte 0x80, 0x00, 0x01, 0x00
391201342Snyan		.byte 0xa5, 0xff, 0xff, 0xff
392201342Snyan		.byte 0x00, 0x00, 0x00, 0x00
393201342Snyan		.byte 0x50, 0xc3, 0x00, 0x00
394201342Snyan
395201342Snyan		.word 0xaa55			# Magic number
396