⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pbs.s

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 S
字号:
/* * FAT Partition Boot Sector. Loaded at 0x7C00: *	8a pbs.s; 8l -o pbs -l -H3 -T0x7C00 pbs.8 * Will load the target at LOADSEG*16+LOADOFF, so the target * should be probably be loaded with LOADOFF added to the * -Taddress. * If LOADSEG is a multiple of 64KB and LOADOFF is 0 then * targets larger than 64KB can be loaded. * * This code uses the traditional INT13 BIOS interface and can * therefore only access the first 8.4GB of the disc. * * It relies on the _volid field in the FAT header containing * the LBA of the root directory. */#include "x16.h"#define LOADSEG		(0x10000/16)	/* where to load code (64KB) */#define LOADOFF		0#define DIROFF		0x0200		/* where to read the root directory *//* * FAT directory entry. */#define Dname		0x00#define Dext		0x08#define Dattr		0x0B#define Dtime		0x16#define Ddate		0x18#define Dstart		0x1A#define Dlengthlo	0x1C#define Dlengthhi	0x1E#define Dirsz		0x20/* * Data is kept on the stack, indexed by rBP. */#define Xdap		0x00		/* disc address packet */#define Xrootsz		0x10		/* file data area */#define Xdrive		0x12		/* boot drive, passed by BIOS or MBR */#define Xtotal		0x14		/* sum of allocated data above */TEXT _magic(SB), $0	BYTE $0xEB; BYTE $0x3C;		/* jmp .+ 0x3C  (_start0x3E) */	BYTE $0x90			/* nop */TEXT _version(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00TEXT _sectsize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _clustsize(SB), $0	BYTE $0x00TEXT _nresrv(SB), $0	BYTE $0x00; BYTE $0x00TEXT _nfats(SB), $0	BYTE $0x00TEXT _rootsize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _volsize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _mediadesc(SB), $0	BYTE $0x00TEXT _fatsize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _trksize(SB), $0	BYTE $0x00; BYTE $0x00TEXT _nheads(SB), $0	BYTE $0x00; BYTE $0x00TEXT _nhiddenlo(SB), $0	BYTE $0x00; BYTE $0x00TEXT _nhiddenhi(SB), $0	BYTE $0x00; BYTE $0x00;TEXT _bigvolsize(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;TEXT _driveno(SB), $0	BYTE $0x00TEXT _reserved0(SB), $0	BYTE $0x00TEXT _bootsig(SB), $0	BYTE $0x00TEXT _volid(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;TEXT _label(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00	BYTE $0x00; BYTE $0x00; BYTE $0x00TEXT _type(SB), $0	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;	BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;_start0x3E:	CLI	CLR(rAX)	MTSR(rAX, rSS)			/* 0000 -> rSS */	MTSR(rAX, rDS)			/* 0000 -> rDS, source segment */	MTSR(rAX, rES)	LWI(_magic-Xtotal(SB), rSP)	MW(rSP, rBP)			/* set the indexed-data pointer */	SBPB(rDL, Xdrive)		/* save the boot drive */	STI	LWI(confidence(SB), rSI)	/* for that warm, fuzzy feeling */	CALL(BIOSputs(SB))	CALL(dreset(SB))_jmp00:	LW(_volid(SB), rAX)		/* Xrootlo */	LW(_volid+2(SB), rDX)		/* Xroothi */	LWI(_magic+DIROFF(SB), rBX)	CALL(BIOSread(SB))		/* read the root directory */	LWI((512/Dirsz), rBX)	LWI(_magic+DIROFF(SB), rDI)	/* compare first directory entry */_cmp00:	PUSHR(rDI)			/* save for later if it matches */	LWI(bootfile(SB), rSI)	LWI(Dattr, rCX)	REP	CMPSB	POPR(rDI)	JEQ _jmp02	DEC(rBX)	JEQ _jmp01	ADDI(Dirsz, rDI)	JMP _cmp00_jmp01:	CALL(buggery(SB))_jmp02:	CLR(rBX)			/* a handy value */	LW(_rootsize(SB), rAX)		/* calculate and save Xrootsz */	LWI(Dirsz, rCX)	MUL(rCX)	LW(_sectsize(SB), rCX)	PUSHR(rCX)	DEC(rCX)	ADD(rCX, rAX)	ADC(rBX, rDX)	POPR(rCX)			/* _sectsize(SB) */	DIV(rCX)	PUSHR(rAX)			/* Xrootsz */	/*	 * rDI points to the matching directory entry.	 */	LXW(Dstart, xDI, rAX)		/* starting sector address */	DEC(rAX)			/* that's just the way it is */	DEC(rAX)	LB(_clustsize(SB), rCL)	CLRB(rCH)	MUL(rCX)	LW(_volid(SB), rCX)		/* Xrootlo */	ADD(rCX, rAX)	LW(_volid+2(SB), rCX)		/* Xroothi */	ADC(rCX, rDX)	POPR(rCX)			/* Xrootsz */	ADD(rCX, rAX)	ADC(rBX, rDX)	PUSHR(rAX)			/* calculate how many sectors to read */	PUSHR(rDX)	LXW(Dlengthlo, xDI, rAX)	LXW(Dlengthhi, xDI, rDX)	LW(_sectsize(SB), rCX)	PUSHR(rCX)	DEC(rCX)	ADD(rCX, rAX)	ADC(rBX, rDX)	POPR(rCX)			/* _sectsize(SB) */	DIV(rCX)	MW(rAX, rCX)	POPR(rDX)	POPR(rAX)	LWI(LOADSEG, rBX)		/* address to load into (seg+offset) */	MTSR(rBX, rES)			/*  seg */	LWI(LOADOFF, rBX)		/*  offset */_readboot:	CALL(BIOSread(SB))		/* read the sector */	LW(_sectsize(SB), rDI)		/* bump addresses/counts */	ADD(rDI, rBX)	JCC _incsecno	MFSR(rES, rDI)			/* next 64KB segment */	ADDI(0x1000, rDI)	MTSR(rDI, rES)_incsecno:	CLR(rDI)	INC(rAX)	ADC(rDI, rDX)	LOOP _readboot	LWI(LOADSEG, rDI)		/* set rDS for loaded code */	MTSR(rDI, rDS)	FARJUMP16(LOADSEG, LOADOFF)	/* no deposit, no return */TEXT buggery(SB), $0	LWI(error(SB), rSI)	CALL(BIOSputs(SB))_wait:	CLR(rAX)			/* wait for almost any key */	SYSCALL(0x16)_reset:	CLR(rBX)			/* set ES segment for BIOS area */	MTSR(rBX, rES)	LWI(0x0472, rBX)		/* warm-start code address */	LWI(0x1234, rAX)		/* warm-start code */	POKEW				/* MOVW	AX, ES:[BX] */	FARJUMP16(0xFFFF, 0x0000)	/* reset *//* * Read a sector from a disc. On entry: *   rDX:rAX	sector number *   rES:rBX	buffer address * For SYSCALL(0x13): *   rAH	0x02 *   rAL	number of sectors to read (1) *   rCH	low 8 bits of cylinder *   rCL	high 2 bits of cylinder (7-6), sector (5-0) *   rDH	head *   rDL	drive *   rES:rBX	buffer address */TEXT BIOSread(SB), $0	LWI(5, rDI)			/* retry count (ATAPI ZIPs suck) */_retry:	PUSHA				/* may be trashed by SYSCALL */	PUSHR(rBX)	LW(_trksize(SB), rBX)	LW(_nheads(SB), rDI)	IMUL(rDI, rBX)	OR(rBX, rBX)	JZ _ioerror_okay:	DIV(rBX)			/* cylinder -> rAX, track,sector -> rDX */	MW(rAX, rCX)			/* save cylinder */	ROLI(0x08, rCX)			/* swap rC[HL] */	SHLBI(0x06, rCL)		/* move high bits up */	MW(rDX, rAX)	CLR(rDX)	LW(_trksize(SB), rBX)	DIV(rBX)			/* head -> rAX, sector -> rDX */	INC(rDX)			/* sector numbers are 1-based */	ANDI(0x003F, rDX)		/* should not be necessary */	OR(rDX, rCX)	MW(rAX, rDX)	SHLI(0x08, rDX)			/* form head */	LBPB(Xdrive, rDL)		/* form drive */	POPR(rBX)	LWI(0x0201, rAX)		/* form command and sectors */	SYSCALL(0x13)			/* CF set on failure */	JCC _BIOSreadret	POPA	DEC(rDI)			/* too many retries? */	JEQ _ioerror	CALL(dreset(SB))	JMP _retry_ioerror:	LWI(ioerror(SB), rSI)	CALL(BIOSputs(SB))	JMP _wait_BIOSreadret:	POPA	RETTEXT dreset(SB), $0	PUSHA	CLR(rAX)			/* rAH == 0 == reset disc system */	LBPB(Xdrive, rDL)	SYSCALL(0x13)	ORB(rAH, rAH)			/* status (0 == success) */	POPA	JNE _ioerror	RET/* * Output a string to the display. * String argument is in rSI. */TEXT BIOSputs(SB), $0	PUSHA	CLR(rBX)_BIOSputs:	LODSB	ORB(rAL, rAL)	JEQ _BIOSputsret	LBI(0x0E, rAH)	SYSCALL(0x10)	JMP _BIOSputs_BIOSputsret:	POPA	RETTEXT error(SB), $0	BYTE $'B'; BYTE $'a'; BYTE $'d'; BYTE $' ';	BYTE $'f'; BYTE $'o'; BYTE $'r'; BYTE $'m';	BYTE $'a'; BYTE $'t'; BYTE $' '; BYTE $'o';	BYTE $'r'; BYTE $' ';TEXT ioerror(SB), $0	BYTE $'I'; BYTE $'/'; BYTE $'O'; BYTE $' ';	BYTE $'e'; BYTE $'r'; BYTE $'r'; BYTE $'o';	BYTE $'r'; BYTE $'\r';BYTE $'\n';	BYTE $'P'; BYTE $'r'; BYTE $'e'; BYTE $'s';	BYTE $'s'; BYTE $' '; BYTE $'a'; BYTE $'l';	BYTE $'m'; BYTE $'o'; BYTE $'s'; BYTE $'t';	BYTE $' '; BYTE $'a'; BYTE $'n'; BYTE $'y';	BYTE $' '; BYTE $'k'; BYTE $'e'; BYTE $'y';	BYTE $' '; BYTE $'t'; BYTE $'o'; BYTE $' ';	BYTE $'r'; BYTE $'e'; BYTE $'b'; BYTE $'o';	BYTE $'o'; BYTE $'t';	BYTE $'.'; BYTE $'.'; BYTE $'.';	BYTE $'\z';#ifdef USEBCOMTEXT bootfile(SB), $0	BYTE $'B'; BYTE $' '; BYTE $' '; BYTE $' ';	BYTE $' '; BYTE $' '; BYTE $' '; BYTE $' ';	BYTE $'C'; BYTE $'O'; BYTE $'M';	BYTE $'\z';#elseTEXT bootfile(SB), $0	BYTE $'9'; BYTE $'L'; BYTE $'O'; BYTE $'A';	BYTE $'D'; BYTE $' '; BYTE $' '; BYTE $' ';	BYTE $' '; BYTE $' '; BYTE $' ';	BYTE $'\z';#endif /* USEBCOM */TEXT confidence(SB), $0	BYTE $'P'; BYTE $'B'; BYTE $'S'; BYTE $'.';	BYTE $'.'; BYTE $'.';	BYTE $'\z';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -