git @ Cat's Eye Technologies BefOS / master src / kernel / screen.s
master

Tree @master (Download .tar.gz)

screen.s @masterraw · history · blame

;--- CONSTANTS -----------------------------------------------;

;--- DATA ----------------------------------------------------;

SEGMENT .bss

winbuf:		RESW	4096

SEGMENT	.data

winbufptr:	dw	winbuf

;--- CODE ----------------------------------------------------;

SEGMENT	.text

		;;--------------------------------------------;
		;; Given a row and a column, determine offset.
		;; al: row (0-based) -> GARBAGE
		;; ah: column (0-based) -> GARBAGE
		;; cx: * -> GARBAGE
		;; dx: * -> GARBAGE
		;; di: * -> offset
CalcScreenOffset:mov	cl, ah
		xor	ch, ch
		xor	ah, ah
		xor	dx, dx
		mul	word [bytesperline]
		shl	cx, 1
		add	ax, cx
		mov	di, ax
		ret



		;;--------------------------------------------;
		;; Save a row of the screen to a buffer.
		;; di: ptr to start of screen row -> INCREMENTED
		;; cl: length of row -> 0
		;; ax: * -> GARBAGE
		;; si: * -> GARBAGE
SaveScreenRow:	mov	si, [winbufptr]
.Loop:		mov	ax, [es:di]
		mov	[ds:si], ax
		inc	di
		inc	di
		inc	si
		inc	si
		dec	cl
		jnz	.Loop
		mov	[winbufptr], si
		ret

		;;--------------------------------------------;
		;; Save a portion of the screen to a buffer.
		;; al: row (0-based) of upper-left corner ->
		;; ah: column (0-based) of upper-left corner ->
		;; bl: height of portion to save -> 0
		;; bh: width of portion to save ->
		;; cx: * -> GARBAGE
		;; di: * -> GARBAGE
SaveScreen:	push	ax
		push	bx
		call	CalcScreenOffset
.Loop:		mov	cl, bh
		push	di
		call	SaveScreenRow
		pop	di
		add	di, [bytesperline]
		dec	bl
		jnz	.Loop
		mov	di, [winbufptr]
		pop	bx
		pop	ax
		mov	[ds:di], ax
		inc	di
		inc	di
		mov	[ds:di], bx
		inc	di
		inc	di
		mov	[winbufptr], di
		ret


		;;--------------------------------------------;
		;; Restore a row of the screen from the buffer.
		;; di: ptr to start of screen row -> INCREMENTED
		;; cl: length of row -> 0
		;; ch: * -> GARBAGE
		;; ax: * -> GARBAGE
		;; si: * -> GARBAGE
RestoreScreenRow:xor	ch, ch
		mov	si, [winbufptr]
		mov	ax, cx
		shl	ax, 1
		sub	si, ax
		mov	[winbufptr], si
.Loop:		mov	ax, [ds:si]
		mov	[es:di], ax
		inc	di
		inc	di
		inc	si
		inc	si
		dec	cl
		jnz	.Loop
		ret


		;;--------------------------------------------;
		;; Restore a portion of the screen from buffer.
		;; *: * -> GARBAGE
RestoreScreen:	mov	di, [winbufptr]
		dec	di
		dec	di
		mov	bx, [ds:di]		; bl = height, bh = width
		dec	di
		dec	di
		mov	ax, [ds:di]		; al = row, ah = column
		mov	[winbufptr], di
		add	al, bl			; work from bot to top!
		dec	al
		call	CalcScreenOffset	; di = offset
.Loop:		mov	cl, bh
		push	di
		call	RestoreScreenRow
		pop	di
		sub	di, [bytesperline]
		dec	bl
		jnz	.Loop
		ret

PopUpTest:	mov	ax, 200ah
		mov	bx, 0a05h
		call	SaveScreen

		mov	bh, 0
		mov	cx, 0a20h		; (10,32)-
		mov	dx, 0e29h		; (14,41)
		mov	ax, 0600h		; BIOS clear rectangle
		int	10h

		; draw a border here!

		call	GetKey
		
		call	RestoreScreen
		ret


;--- END -----------------------------------------------------;