Attachment 'interruptBS.asm'

Download

   1 .eqv	IOSIZE	64
   2 .eqv	IOSZB	63
   3 
   4 .macro	push	%r
   5 	addi	$sp $sp -4
   6 	sw	%r ($sp)
   7 .end_macro
   8 
   9 .macro	pop	%r
  10 	lw	%r ($sp)
  11 	addi	$sp $sp 4
  12 .end_macro
  13 
  14 .text
  15 	#li	$v0 22
  16 	#syscall
  17 	
  18 	lw	$t0 0xffff0000
  19 	ori	$t0 $t0 2		# Включили клавиатуру
  20 	sw	$t0 0xffff0000
  21 
  22 loop:	li	$v0 22			# НОВЫЙ syscall
  23 	syscall
  24 	bltz	$v0 noinput
  25 	beq	$v0 0x1b end		# ESC — выход
  26 	move	$a0 $v0	
  27 	li	$v0 1			# выведем
  28 	syscall
  29 	li	$a0 0x20		# с пробелом
  30 	li	$v0 11
  31 	syscall
  32 	j	loop			# есть ещё ввод?
  33 noinput:
  34 	jal	sleeprnd
  35 	j	loop
  36 end:	li	$v0 10
  37 	syscall
  38 	
  39 	# прождать случайное время
  40 sleeprnd:
  41 	li	$a0 0
  42 	li	$a1 100000
  43 	li	$v0 42
  44 	syscall
  45 sleepnext:
  46 	subi	$a0 $a0 1
  47 	blez	$a0 sleepdone
  48 	mul.d	$f0 $f0 $f0
  49 	j	sleepnext		
  50 sleepdone:
  51 	jr	$ra
  52 	
  53 .ktext	0x80000180
  54 	mfc0	$k0 $12
  55 	andi	$k0 $k0 0xfffe
  56 	mtc0	$k0 $12			# Запрет прерываний
  57 
  58 	move	$k0 $at			# спрячем $at
  59 	move	$k1 $sp			# спрячем $sp
  60 	lw	$sp ksp			# Новый $sp! можно сохранять ВСЁ
  61 	push	$k0			# спрятанный $at
  62 	push	$k1			# спрятанный $sp
  63 	
  64 	mfc0	$k0 $13                 # Причина
  65 	andi	$k1 $k0 0x7c		# Исключение или прерывание?
  66 	bnez	$k1 exception		# …исключение
  67 	andi	$k1 $k0 0x100		# Клавиатура?
  68 	beqz	$k1 other		# …не клавиатура
  69 	lw	$k0 0xffff0004		# считаем код
  70 	
  71 	lw	$k1 kinhi		# Свободное место в буфере
  72 	sb	$k0 kin($k1)		# сложим туда байт
  73 	addi	$k1 $k1 1		# следующее место
  74 	andi	$k1 $k1 IOSZB		# кольцо
  75 	lw	$k0 kinlo
  76 	beq	$k0 $k1 final		# переполнение буфера
  77 	sw	$k1 kinhi		# сохраним индекс в кольце
  78 	
  79 	j	final
  80 
  81 other:
  82 	j final
  83 
  84 exception:
  85 	beq	$k1 0x20 sysexc		# syscall
  86 fatalexc:				# необрабатываемое исключение
  87 	la	$a0 kmsgexc		# можно пользоваться любыми регистрами
  88 	li	$v0 4			# всё равно аварийный останов
  89 	syscall
  90 	sra	$a0 $k1 2
  91 	li	$v0 34
  92 	syscall
  93 	la	$a0 kmsgat
  94 	li	$v0 4
  95 	syscall
  96 	mfc0	$a0 $14
  97 	li	$v0 34
  98 	syscall
  99 	li	$v0 17
 100 	syscall	
 101 	
 102 sysexc:	beq	$v0 22 sysin
 103 	j	fatalexc
 104 sysin:		
 105 	lw	$k0 kinhi		# есть ли в буфере данные
 106 	lw	$k1 kinlo		# hilo
 107 	bne	$k0 $k1 sysinY		# есть
 108 	li	$v0 -1			# нету
 109 	j	exfinal
 110 sysinY:	lb	$v0 kin($t1)		# очередной символ
 111 	addi	$t1 $t1 1		# буфер прокрутим
 112 	andi	$t1 $t1 IOSZB
 113 	sw	$t1 kinlo
 114 	j	exfinal
 115 exfinal:
 116 	mfc0	$k0 $14			# Завершаем исключение
 117 	addiu	$k0 $k0 4
 118 	mtc0	$k0 $14
 119 final:
 120 	pop	$k1
 121 	pop	$k0
 122 	sw	$sp ksp
 123 	move	$sp $k1
 124 	move	$at $k0
 125 
 126 	mtc0	$zero $13		# зануляем причину
 127 	mfc0	$k0 $12                 # 
 128 	ori	$k0 0x01                # 
 129 	mtc0	$k0 $12                 # разрешаем прерывания
 130 	
 131 	eret	
 132 
 133 .kdata
 134 ksp:	.word	0x90400000		# Kernel SP
 135 kinhi:	.word	0
 136 kinlo:	.word	0
 137 kin:	.space	IOSIZE
 138 kmsgexc:.asciiz	"Exception "
 139 kmsgat:	.asciiz	" at "

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.