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

📄 ashos_lc3.asm3

📁 单总线开源CPU-LC3的简单操作系统。
💻 ASM3
字号:
;	ash lc-3b operating system 1.00
;	(c) ashley wise, 2003
;	awise@crhc.uiuc.edu
;
;	ashos_lc3.asm must be linked with the user code.
;	asmos_lc3.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_LC3.ah"

origin 0
segment

bootcode:
segment
	; jumps over the trap and interrupt vector tables.
	trap main
	; might want to perform some check code after "main" exits
	trap halt
	
trapvectortable:
segment 4x20

	getc: data2 _getc
	out: data2 _out
	puts: data2 _puts
	in: data2 _in
	putsp: data2 _putsp
	halt: data2 _halt
	main: data2 _main

	structdef undefvector data2 _undef end
	struct undefvector[4xd9] ?

exceptionvectortable:
segment 4xe0
; 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.
	structdef registerstack
		reg: data2[8] ?
	end
ifdef no_usp
	macro pushregs0(localregstack)
		st r0, localregstack.reg[0]
		pushregs(localregstack)
	end
	macro pushregs(localregstack)
		st r1, localregstack.reg[1]
		st r2, localregstack.reg[2]
		st r3, localregstack.reg[3]
		st r4, localregstack.reg[4]
		st r5, localregstack.reg[5]
		st r7, localregstack.reg[7]
	end
	macro popregs0(localregstack)
		ld r0, localregstack.reg[0]
		popregs(localregstack)
	end
	macro popregs(localregstack)
		ld r1, localregstack.reg[1]
		ld r2, localregstack.reg[2]
		ld r3, localregstack.reg[3]
		ld r4, localregstack.reg[4]
		ld r5, localregstack.reg[5]
		ld r7, localregstack.reg[7]
	end
else
	macro pushregs0(localregstack)
		push(r0)
		pushregs(localregstack)
	end
	macro pushregs(localregstack)
		push(r1)
		push(r2)
		push(r3)
		push(r4)
		push(r5)
		push(r7)
	end
	macro popregs0(localregstack)
		popregs(localregstack)
		pop(r0)
	end
	macro popregs(localregstack)
		pop(r7)
		pop(r5)
		pop(r4)
		pop(r3)
		pop(r2)
		pop(r1)
	end
end

; 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)
	waitforkb:
		ldi r2, pkbsr
		brzp waitforkb
	ldi r0, pkbdr
	popregs(getcregstack)
	ret
	getcregstack: struct registerstack ?
	pkbsr: data2 kbsr
	pkbdr: data2 kbdr

; out function
; write the character in r0[7:0] to the console.
_out:
	pushregs0(outregstack)
	waitfordisplay:
		ldi r2, pdsr
		brzp waitfordisplay
	sti r0, pddr
	popregs0(outregstack)
	ret
	outregstack: struct registerstack ?

; puts function
; write the string pointed to by r0 to the console.
; there is one character per memory location.
; make sure the string is null-terminated!
_puts:
	pushregs0(putsregstack)
	displayloop2:
		ldr r3, r0, 0
		brz displaydone2
		waitfordisplay2:
			ldi r2, pdsr
			brzp waitfordisplay2
		sti r3, pddr
		add r0, r0, 1
		brnzp displayloop2
	displaydone2:
	popregs0(putsregstack)
	ret
	putsregstack: struct registerstack ?
	pdsr: data2 dsr
	pddr: data2 ddr

; 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
	ld r0, endl
	trap out
	add r0, r1, 0
	popregs(inregstack)
	ret
	inregstack: struct registerstack ?
	inmessage: data2[] "\nPlease input a single character: \0"
	endl: data2 '\n'

; putsp function
; write the string pointed to by r0 to the console.
; there are two characters per memory location. the low-byte character
; [7:0] is written first. if there are an odd number of characters,
; the high-byte [15:8] is 4x00. there must still be a full 4x0000
; location at the end of the string.
; make sure the string is null-terminated!
_putsp:
	pushregs0(putspregstack)
	displayloop3:
		ldr r4, r0, 0
		brz displaydone3

		;write the lower char first
		waitfordisplay3a:
			ldi r2, pdsr
			brzp waitfordisplay3a
		sti r4, pddr

		;move upper char into lower char
		ld  r3, upperchar
		and r4, r4, r3	;clear out the lower part of the current double-char
		and r3, r3, 0	;zero the result
		and r5, r5, 0
		add r5, r5, bitmirrors$len	;loop count
		lea r7, bitmirrors	;setup address
		;r5 holds loop count
		;r4 holds upper char value
		;r3 holds result of moving upper char to lower char
		;r7 holds address of current mirror mask
		;r2 holds current mirror mask
		;r1 is temporary use
		;r0 keeps string pointer for putsp
		mirrorloop:
			ldr r2, r7, 0
			add r7, r7, 1
			and r1, r2, r4	;see if this bit is set in the upper char
			brz bitnotset
				add r3, r3, r2	;add this bit to the lower char
			bitnotset:
			add r5, r5, -1
			brp mirrorloop

		;now write the upper char (which is now in the lower char location)
		waitfordisplay3b:
			ldi r2, pdsr
			brzp waitfordisplay3b
		sti r3, pddr

		add r0, r0, 1
		brnzp displayloop3
	displaydone3:
	popregs0(putspregstack)
	ret
	putspregstack: struct registerstack ?
	upperchar: data2 4xff00
	bitmirrors: data2[] 4x0101, 4x0202, 4x0404, 4x0808, 4x1010, 4x2020, 4x4040, 4x8080

; halt function
; halt execution and print a message to the console.
_halt:
	pushregs0(haltregstack)
	lea r0, haltmessage;
	trap puts
	ldi r2, pmcr
	ld r0, mask
	and r0, r0, r2
	sti r0, pmcr
	nop
	popregs0(haltregstack)
	ret
	haltregstack: struct registerstack ?
	haltmessage: data2[] "\nStopping program execution.\n\0"
	mask: data2 4x7fff
	pmcr: data2 mcr

; 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: data2[] "\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: data2[] "\nRTI instruction executed in unprivileged mode. Skipping over instruction.\n\0"

; illegalinstr exception function
; halt execution and print a message to the console.
_illegalinstr:
	rti
	illmessage: data2[] "\nIllegal instruction executed. Skipping over instruction.\n\0"

; 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 + -