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

📄 ashos_lc3b.asm

📁 单总线开源CPU-LC3的简单操作系统。
💻 ASM
字号:
;	Ash LC-3b Operating System 1.00
;	(c) Ashley Wise, 2003
;	awise@crhc.uiuc.edu
;
;	AshOS_LC3b.asm must be linked with the user code.
;	AsmOS_LC3b.ah should be be included in the user code.
;	R0 is used for passing values to/from OS functions.
;	R6 is expected to be the User Stack Pointer (USP).
;	R7 is overwritten by the TRAP instruction (return address).
;	All other registers are preserved.
;	Remember to NULL-terminate strings.

INCLUDE "AshOS_LC3b.ah"

ORIGIN 0
SEGMENT

BootCode:
SEGMENT
	; Jumps over the trap vector table.
	trap MAIN
	; Might want to perform some check code after "main" exits
	trap HALT
	
TrapVectorTable:
SEGMENT 4x40

	GETC: data2 _GETC
	OUT: data2 _OUT
	PUTS: data2 _PUTS
	IN: data2 _IN
	HALT: data2 _HALT
	MAIN: data2 _MAIN

	STRUCTDEF UndefVector data2 _UNDEF END
	STRUCT UndefVector[4x5A] ?

ExceptionVectorTable:
SEGMENT 4xC0
; The program will load the pointer to their handlers here.
	Privilege: data2 _Privilege
	IllegalInstr: data2 _IllegalInstr

InterruptVectorTable:
SEGMENT 4x80
; The program will load the pointer to their handlers here.
	Keyboard: data2 _Keyboard

TrapFunctions:
SEGMENT 4x80

; Note that in order for the trap functions to work correctly,
; the user code must have preserved R6 as the User Stack Pointer
; (USP). R6 is initialized to this value when the simulator boots.
; If you clobber R6, trap functions might not work.
; You can define NO_USP (as a global define, not in your code)
; which will tell the OS to use local storage rather than the USP.
; However, due to a limitation of the LC-3b ISA, the TRAP functions
; will clobber any value in R5 to achieve this. So if you define
; NO_USP, don't expect R5 to be preserved.
	STRUCTDEF RegisterStack
		Reg: data2[8] ?
	END
IFDEF NO_USP
	MACRO PushRegs0(LocalRegStack)
		lea r5, LocalRegStack
		str r0, r5, RegisterStack.Reg[0]
		PushRegs(LocalRegStack)
	END
	MACRO PushRegs(LocalRegStack)
		lea r5, LocalRegStack
		str r1, r5, RegisterStack.Reg[1]
		str r2, r5, RegisterStack.Reg[2]
		str r3, r5, RegisterStack.Reg[3]
		str r7, r5, RegisterStack.Reg[7]
	END
	MACRO PopRegs0(LocalRegStack)
		lea r5, LocalRegStack
		ldr r0, r5, RegisterStack.Reg[0]
		PopRegs(LocalRegStack)
	END
	MACRO PopRegs(LocalRegStack)
		lea r5, LocalRegStack
		ldr r1, r5, RegisterStack.Reg[1]
		ldr r2, r5, RegisterStack.Reg[2]
		ldr r3, r5, RegisterStack.Reg[3]
		ldr r7, r5, RegisterStack.Reg[7]
		and r5, r5, 0
	END
ELSE
	MACRO PushRegs0(LocalRegStack)
		Push(r0)
		PushRegs(LocalRegStack)
	END
	MACRO PushRegs(LocalRegStack)
		Push(r1)
		Push(r2)
		Push(r3)
		Push(r7)
	END
	MACRO PopRegs0(LocalRegStack)
		PopRegs(LocalRegStack)
		Pop(r0)
	END
	MACRO PopRegs(LocalRegStack)
		Pop(r7)
		Pop(r3)
		Pop(r2)
		Pop(r1)
	END
END

	; Pointers to the MMIO register locations
	pDSR: data2 DSR
	pDDR: data2 DDR
	pKBSR: data2 KBSR
	pKBDR: data2 KBDR
	pMCR: data2 MCR

; GETC function
; Reads a single character from the keyboard. The character is not echoed
; onto the console. Its ASCII code is copied into R0. The high eight bits
; of R0 are cleared.
_GETC:
	PushRegs(GetCRegStack)
	lea r1, TrapFunctions
	WaitForKB:
		ldi r2, r1, pKBSR
		BRzp WaitForKB
	ldi r0, r1, pKBDR
	PopRegs(GetCRegStack)
	ret
	GetCRegStack: STRUCT RegisterStack ?

; OUT function
; Write the character in R0[7:0] to the console
_OUT:
	PushRegs0(OutRegStack)
	lea r1, TrapFunctions
	WaitForDisplay:
		ldi r2, r1, pDSR
		BRzp WaitForDisplay
	sti r0, r1, pDDR
	PopRegs0(OutRegStack)
	ret
	OutRegStack: STRUCT RegisterStack ?

; PUTS function
; Write the string pointed to by R0 to the console.
; Make sure the string is NULL-terminated!
_PUTS:
	PushRegs0(PutsRegStack)
	lea r1, TrapFunctions
	DisplayLoop2:
		ldb r3, r0, 0
		brz DisplayDone2
		WaitForDisplay2:
			ldi r2, r1, pDSR
			BRzp WaitForDisplay2
		sti r3, r1, pDDR
		add r0, r0, 1
		brnzp DisplayLoop2
	DisplayDone2:
	PopRegs0(PutsRegStack)
	ret
	PutsRegStack: STRUCT RegisterStack ?

; IN function
; Print a prompt to the screen and read a single character from the keyboard.
; The character is echoed onto the console along with a newline, and its
; ASCII code is copied into R0. The high eight bits of R0 are cleared.
_IN:
	PushRegs(InRegStack)
	lea r0, InMessage;
	trap PUTS
	trap GETC
	trap OUT
	add r1, r0, 0
	lea r2, ENDL
	ldb r0, r2, ENDL$BASEREL
	trap OUT
	add r0, r1, 0
	PopRegs(InRegStack)
	ret
	InRegStack: STRUCT RegisterStack ?
	InMessage: DATA1[] "\nPlease input a single character: \0"
	ALIGN 2
	ENDL: data1 '\n'

ALIGN 2
; HALT function
; Halt execution and print a message to the console.
_HALT:
	PushRegs0(HaltRegStack)
	lea r0, HaltMessage;
	trap PUTS
	and r0, r0, 0
	lea r1, TrapFunctions
	ldi r2, r1, pMCR
	lea r3, Mask
	ldr r0, r3, Mask$BASEREL
	and r0, r0, r2
	sti r0, r1, pMCR
	nop
	PopRegs0(HaltRegStack)
	ret
	HaltRegStack: STRUCT RegisterStack ?
	HaltMessage: DATA1[] "\nStopping program execution.\n\0"
	ALIGN 2
	Mask: DATA2 4x7FFF

ALIGN 2
; Undef function
; Default function if an undefined trap vector is called.
; Halt execution and print a message to the console.
_UNDEF:
	PushRegs0(UndefRegStack)
	lea r0, UndefMessage;
	trap PUTS
	and r0, r0, 0
	PopRegs0(UndefRegStack)
	ret
	UndefRegStack: STRUCT RegisterStack ?
	UndefMessage: DATA1[] "\nUndefined trap vector executed.\n\0"

; These functions are not yet implemented because the architectural
; use of the stack pointers is still not defined.
; The simulator will print a message and break on exceptions.

; Privilege exception function
; Halt execution and print a message to the console.
_Privilege:
	rti
	PrivMessage: DATA1[] "\nRTI instruction executed in unprivileged mode. Skipping over instruction.\n\0"

ALIGN 2
; IllegalInstr exception function
; Halt execution and print a message to the console.
_IllegalInstr:
	rti
	IllMessage: DATA1[] "\nIllegal instruction executed. Skipping over instruction.\n\0"

ALIGN 2
; Keyboard interrupt function
; Doesn't do anything. The user program should define and install their own handler.
_Keyboard:
	rti

;The start of the user code space
_MAIN:
SEGMENT 4x2E00

⌨️ 快捷键说明

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