Snippet:KStack

From veswiki
Jump to: navigation, search

Warning: The below are NOT FUNCTIONAL as of 11/24/2004. I'm still working on them. Admin 21:54, 24 Nov 2004 (CST)

These are modified versions of the PushK and PopK functions from the bios source. They save a little more time than the original functions, but especially, they load the stack from the top down, not up, so you can go more than four levels deep if you so desire. Also, you can place registers in the r50-r58 range if you know you'll never go too many levels deep, and still keep your registers organized.

Below that there are two experimental functions, shift and unshift the stack. They loop through the stack and push up or pull down every word, and then either deletes the original or adds a new word in.

Call this code at the beginning of the cartridge to set the correct stack pointer:


	li	57
	lisu	7
	lisl	3
	lr	S, A

These are the KStack functions:

;==================;
; KStack Functions ;
;==================;

; the K stack is an emulated stack using the register r59
; as a stack pointer, which holds the register number for
; the top of the stack, which first points at r57. when
; pushk is called, K is pushed to the first two registers
; on the stack, and the pointer is increased.

;-------------;
; KStack Push ;
;-------------;

; pushes register K (r12-13) onto a stack using r59 as
; the stack pointer
;
; modifies: r07

kstack.push:
	; backup the ISAR
	lr	A, IS
	lr	0, A

	; get the top of the stack
	lisu	7
	lisl	3			; r59, stack pointer
	lr	A, S
	lr	IS, A			; load the referenced register
	; push K onto the stack
	lr	A, Ku
	lr	I, A			; push high byte of K
	lr	A, Kl
	lr	D, A			; push low byte of K
	; adjust pointer to the top of the stack
	lr	A, IS
	ai	%11111110		; subtract two
	lisu	7
	lisl	3
	lr	S, A			; save the register number to the stack pointer

	; restore the ISAR
	lr	A, 0
	lr	IS, A

	; return from the subroutine
	pop

;------------;
; KStack Pop ;
;------------;

; retrieves a 16-bit value from the K stack and
; stores it in K, using r59 as the stack pointer
;
; modifies: r0
                
kstack.pop:
	; backup the ISAR
	lr	A, IS
	lr	0, A

	; retrieve K from the stack
	lisu	7
	lisl	3
	lis	2			; add two to the stack pointer
	as	S			; to get the first word on the stack
	lr	IS, A			; set the ISAR to this register
	lr	A, I
	lr	Ku, A			; load upper byte of K 
	lr	A, D
	lr	Kl, A			; load lower byte of K
	; adjust pointer to the top of the stack
	lr	A, IS
	lisu	7
	lisl	3
	lr	S, A			; save the register number to the stack pointer

	; restore the ISAR
	lr	A, 0
	lr	IS, A

	; return from the subroutine
	pop

;--------------;
; KStack Shift ;
;--------------;

; deletes the bottom-most word and moves up the K stack
;
; modifies: r0, r1, r2, r3
                
kstack.shift:
	; backup the ISAR
	lr	A, IS
	lr	0, A

	; loop through the registers
	lisu	7
	lisl	3
	lr	A, S
	lr	1, A			; save bottom of stack
	lisu	6
	lisl	7			; load starting register, r55
kstack.shift.loop:
	; shift two registers up two
	lr	A, I
	lr	2, A
	lr	A, I
	lr	3, A
	lr	A, 2
	lr	I, A
	lr	A, 3
	lr	I, A

	lr	A, IS
	ai	%11111010		; subtract six
	lr	IS, A

	ai	2			; add two
	xs	1			; compare with bottom of the stack
	bnz	kstack.shift.loop	; if we're not at the end, loop

kstack.shift.loop.end:
	; adjust pointer to the top of the stack
	lr	A, IS
	lisu	7
	lisl	3
	lr	S, A			; save the register number to the stack pointer

	; restore the ISAR
	lr	A, 0
	lr	IS, A

	; return from the subroutine
	pop

;----------------;
; KStack Unshift ;
;----------------;

; inserts K as the bottom-most word and moves down the K stack
;
; modifies: r0, r1, r2, r3
                
kstack.unshift:
	; backup the ISAR
	lr	A, IS
	lr	0, A

	; loop through the registers
	lisu	7
	lisl	3
	lr	A, S
	lr	1, A			; save bottom of stack
	ai	2			; add two
	lr	IS, A			; load starting register
kstack.unshift.loop:
	; shift two registers down two
	lr	A, I
	lr	2, A
	lr	A, D
	lr	3, A
	lr	A, D			; just subtract one from the ISAR
	lr	A, 3
	lr	D, A
	lr	A, 2
	lr	S, A

	lr	A, IS
	ai	4			; subtract four
	lr	IS, A

	ci	59			; compare ISAR with r59
	bnz	kstack.unshift.loop	; if we're not at the end, loop

kstack.unshift.loop.end:
	; save K
	lr	A, D			; just subtract one from the ISAR
	lr	A, Kl
	lr	D, A			; save k lower
	lr	A, Ku
	lr	D, A			; save k upper
	; adjust pointer to the top of the stack
	lisu	7
	lisl	3
	lr	A, S			; load original bottom of stack
	ai	%11111110		; subtract two
	lr	S, A			; save the register number to the stack pointer

	; restore the ISAR
	lr	A, 0
	lr	IS, A

	; return from the subroutine
	pop