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

📄 cruntime.s90

📁 Outputs messages to a 2line LCD
💻 S90
📖 第 1 页 / 共 2 页
字号:
	extern	_true,_false,?cmp
	public	_ult,_ugt,_uge,_ule
; Unsigned integer less than
_ult	rcall	?cmp
	brsh	_false
	rjmp	_true

_ugt	rcall	?cmp
	brlo	_false
	breq	_false
	rjmp	_true

_uge	rcall	?cmp
	brlo	_false
	rjmp	_true

_ule	rcall	?cmp
	brlo	_true
	breq	_true
	rjmp	_false
	endmod

;------------------------------------------------------------
; Commons

	module	cmp
	rseg	scode
	public	?cmp
?cmp	sub	r26,r30
	sbc	r27,r31
	ret
	endmod

;------------------------------------------------------------
	module	tf
	rseg	scode
	public	_false,_true
_false	clr	r30
	rjmp	_condx
_true	ldi	r30,1
_condx	clr	r31
	ret
	endmod

;------------------------------------------------------------
	module	lcmp
	rseg	scode
	public	_cmp_l
_cmp_l	sub	r22,r26
	sbc	r23,r27
	sbc	r24,r30
	sbc	r25,r31
	ret
	endmod

;------------------------------------------------------------
; Case

	module	case
	rseg	scode
	public	_case
; standard C case statement
_case	mov	r25,r31		; save switch value
	mov	r24,r30
	ld	r31,y+		; get table address
	ld	r30,y+
_cs1	rcall	_cs4		; get case value into Y
	cp	r26,r24		; compare
	cpc	r27,r25
	brne	_cs2
	rcall	_cs4		; get case label
	breq	_cs3		; end, go to default
	mov	r31,r27
	mov	r30,r26
_cs1a	asr	r31
	ror	r30
	ijmp			; jump to respective case
_cs2	rcall	_cs4		; get case label
	brne	_cs1		; do next case
; default jump
_cs3	sbiw	r30,4
	lpm
	mov	r25,r0
	adiw	r30,1
	lpm
	mov	r31,r0
	mov	r30,r25
	rjmp	_cs1a
; load from table
_cs4	lpm
	mov	r26,r0
	adiw	r30,1
	lpm
	mov	r27,r0
	adiw	r30,1		; read for next
	or	r0,r26
	ret
	endmod

;------------------------------------------------------------
; Divide by zero check

	module	dcheck
	rseg	scode
	public	_CheckDivZero
_CheckDivZero
	clr	r31
	clr	r30
	sbrc	r0,1
	adiw	r30,1
	ret
	endmod

;------------------------------------------------------------
; Long multiply & divide

	module	muldiv32
	rseg	scode
	public	_mul_l,_umul_l,_div_l,_udiv_l
	extern	_neg_l
_umul_l	rcall	_m32
	ret

_udiv_l	rcall	_d32
	ret
	
_mul_l	rcall	_lchksn
	rcall	_m32
_lmd1	sbrc	r0,0
	rcall	_dolneg
	ret
	
_div_l	rcall	_lchksn
	rcall	_d32
	bld	r0,1
	rjmp	_lmd1

;------------------------------------------------------------
; 32-bit multiply.
; Enter with 32-bit multiplier in r25-22, 32-bit multiplicand in r31-26.
; Returns with 32-bit result in r31-26, overflow in r25-22.

_m32	push	r29
	mov	r21,r25		; copy multiplicand into r21-18
	mov	r20,r24
	mov	r19,r23
	mov	r18,r22
	clr	r25		; clear product low (r25-22)
	clr	r24
	clr	r23
	clr	r22
	ldi	r29,33		; make a counter
	clc			; clear carry
	rjmp	_m32c
	
_m32a	brcc	_m32b		; skip if no bit
	add	r22,r18		; add multiplicand to partial product
	adc	r23,r19
	adc	r24,r20
	adc	r25,r21

_m32b	lsr	r25		; right shift partial product
	ror	r24
	ror	r23
	ror	r22	
_m32c	ror	r31		; right shift multiplier into carry
	ror	r30
	ror	r27
	ror	r26

	dec	r29		; all done
	brne	_m32a		; yes
	pop	r29
	ret

;------------------------------------------------------------
; 32-bit divide.
; Enter with 32-bit dividend in r25-22, 32-bit divisor in r31-26.
; Returns with 32-bit result in r31-26, remainder in r25-22.

_d32	push	r29
	mov	r21,r31		; copy divisor into r21-18
	mov	r20,r30
	mov	r19,r27
	mov	r18,r26
	clt
	or	r26,r27		; check for zero divisor
	or	r26,r30
	or	r26,r31
	brne	_d32aa
	set			; T will be set for divide by zero
	ret
_d32aa	mov	r31,r25		; copy dividend into r31-26
	mov	r30,r24
	mov	r27,r23
	mov	r26,r22
	clr	r25		; clear
	clr	r24
	clr	r23
	clr	r22
	ldi	r29,32		; make a counter
	
_d32a	lsl	r26		; left shift dividend into remainder
	rol	r27
	rol	r30
	rol	r31
	rol	r22
	rol	r23
	rol	r24
	rol	r25
	sub	r22,r18		; subtract r21-18 from r25-22
	sbc	r23,r19		; answer in r25-22
	sbc	r24,r20
	sbc	r25,r21

	sbr	r26,1		; assume positive, so set result bit
	brcc	_d32b		; jump if result positive

	add	r22,r18		; negative, restore result
	adc	r23,r19
	adc	r24,r20
	adc	r25,r21
	cbr	r26,1		; and clear result bit
	
_d32b	dec	r29		; all done?
	brne	_d32a		; ..no
	pop	r29
	ret

;------------------------------------------------------------
; Negate the numbers in r31-28 and r25-22

_dolneg	rcall	_neg_l
	rcall	_negb_l
	ret

;------------------------------------------------------------
; Negate the 4-byte number in r25-22

_negb_l	clt
	sbrs	r25,7
	ret
	com	r22
	com	r23
	com	r24
	com	r25
	subi	r22,0xff
	sbci	r23,0xff
	sbci	r24,0xff
	sbci	r25,0xff
	set
	ret

;------------------------------------------------------------
_lchksn	clr	r0
	clt
	sbrs	r31,7
	rjmp	_lchs1
	rcall	_neg_l
	set
_lchs1	bld	r0,0
	rcall	_negb_l
	bld	r1,0
	eor	r0,r1
	ret

	endmod

;------------------------------------------------------------
; Long overflow check

	module	mchecklong
	rseg	scode
	public	_CheckLongOverflow
	; Returns Z non-zero if overflow
_CheckLongOverflow
	clr	r31
	clr	r30
	or	r30,r25
	or	r30,r24
	or	r30,r23
	or	r30,r22
	ret
	endmod

;------------------------------------------------------------
; Return Long Overflow

	module	getlongovf
	rseg	scode
	public	_GetLongOverflow
_GetLongOverflow
	mov	r31,r25
	mov	r30,r24
	mov	r27,r23
	mov	r26,r22
	ret
	endmod

;------------------------------------------------------------
; 16-bit Multiply & divide

	module	muldiv
	rseg	scode
	public	_mul,_umul,_div,_udiv
	extern	_neg
_umul	clr	r0
	clt
	rcall	_m16
	rjmp	_md1a

_udiv	clr	r0
	clt
	rcall	_d16
	ret
	
_mul	rcall	_chksn
	rcall	_m16
_md1	sbrc	r0,0
	rcall	_doneg
_md1a	or	r26,r27		; check for overflow
	breq	_md2
	set
_md2	ret

_div	rcall	_chksn
	rcall	_d16
	bld	r0,1
	rjmp	_md1

_chksn	clr	r0
	clt
	sbrs	r31,7
	rjmp	_chks1
	rcall	_neg
	set
_chks1	bld	r0,0
	rcall	_negb
	bld	r1,0
	eor	r0,r1
	ret

;------------------------------------------------------------
; 16-bit divide.
; Enter with 16-bit dividend in r27-26, 16-bit divisor in r31-30.
; Returns with 16-bit result in r31-30, remainder in r27-26. 

_d16	mov	r25,r31		; copy divisor into r25-24
	mov	r24,r30
	clt
	or	r30,r31		; check for zero divisor
	brne	_d16aa
	set			; T will be set for divide by zero
	ret
_d16aa	mov	r31,r27		; copy dividend into r31-30
	mov	r30,r26
	clr	r27		; clear 
	clr	r26
	ldi	r23,16		; make a counter
	
_d16a	lsl	r30		; left shift dividend into remainder
	rol	r31
	rol	r26
	rol	r27
	sub	r26,r24		; subtract r25-24 from r26-27
	sbc	r27,r25		; answer in r26-27

	sbr	r30,1		; assume positive, so set result bit
	brcc	_d16b		; jump if result positive

	add	r26,r24		; negative, restore result
	adc	r27,r25
	cbr	r30,1		; and clear result bit
	
_d16b	dec	r23		; all done?
	brne	_d16a		; ..no
	ret
	
;------------------------------------------------------------
; 16-bit multiply.
; Enter with 16-bit multiplier in r27-26, 16-bit multiplicand in r31-30.
; Returns with 16-bit result in r31-30, overflow in r27-r26.

_m16	mov	r25,r27		; copy multiplicand into r21-18
	mov	r24,r26
	clr	r27		; clear product low (X)
	clr	r26
	ldi	r23,17		; make a counter
	clc			; clear carry
	rjmp	_m16c
	
_m16a	brcc	_m16b		; skip if no bit
	add	r26,r24		; add multiplicand to partial product
	adc	r27,r25

_m16b	lsr	r27		; right shift partial product
	ror	r26	
_m16c	ror	r31		; right shift multiplier into carry
	ror	r30

	dec	r23		; all done
	brne	_m16a		; yes
	ret

;------------------------------------------------------------
; Negate the number in Y

_negb	clt
	sbrs	r27,7
	ret
	com	r26
	com	r27
	adiw	r26,1
	set
	ret

;------------------------------------------------------------
; Negate the numbers in Z and Y if required

_doneg	rcall	_neg
	rcall	_negb
	ret

	endmod

;------------------------------------------------------------
; Int overflow check

	module	mcheckint
	rseg	scode
	public	_CheckIntOverflow
_CheckIntOverflow
	clr	r31
	or	r30,r27
	or	r30,r26
_cloi	ret
	endmod

;------------------------------------------------------------
; String copy from prom

	module	romcpy
	rseg	scode
	public	_romcpy
_romcpy	ldd	r31,y+0
	ldd	r30,y+1
	ldd	r0,y+2
	ldd	r26,y+3
	mov	r27,r0		; X dest, Z source
_romcpy1
	lpm
	st	x+,r0
	adiw	r30,1
	tst	r0
	brne	_romcpy1
	ret
	endmod	
		
;------------------------------------------------------------
; I/O Functions

	module	in		; x = inp(port)
	rseg	scode
	public	_inp
_inp	ldd	r30,y+1		; port address
	clr	r31
	ldd	r30,z+32	; input
	ret
	endmod
	
;------------------------------------------------------------
	module	out		; outp(port,val)
	rseg	scode
	public	_outp
_outp	ldd	r26,y+1		; port value
	ldd	r30,y+3		; port address
	clr	r31
	std	z+32,r26
	ret
	endmod

;------------------------------------------------------------
	module	sbi		; sbip(port,val)
	rseg	scode
	extern	?posn
	public	_sbip
_sbip	rcall	?posn
	or	r27,r26
	std	z+32,r27
	ret
	endmod
	
;------------------------------------------------------------
	module	cbi		; cbip(port,val)
	rseg	scode
	extern	?posn
	public	_cbip
_cbip	rcall	?posn
	com	r27
	and	r27,r26
	std	z+32,r27
	ret
	endmod
	
;------------------------------------------------------------
	module	posn
	rseg	scode
	public	?posn
?posn	ldd	r26,y+1		; value
	ldd	r30,y+3		; port address
	clr	r31
	ldi	r27,1
	tst	r26
_posn1	breq	_posn2
	lsl	r27
	dec	r26
	rjmp	_posn1
_posn2	ldd	r26,z+32
	ret
	
	end
	



	
	

⌨️ 快捷键说明

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