~vertigo/forthbox

e96c145b04a8123f95ddbd13f7e6eb46f527b652 — Samuel A. Falvo II 4 months ago 245380a main
Console WIP: Implement lowest-level logicfor cursor manipulation.
2 files changed, 319 insertions(+), 1 deletions(-)

A sysf.disk0/bios.console.s
M sysf.disk0/kernel.state.s
A sysf.disk0/bios.console.s => sysf.disk0/bios.console.s +311 -0
@@ 0,0 1,311 @@
W		= 80			; Maximum width of the text display in characters.
H		= 60			; Maximum height of the text display in characters.
FONTHEIGHT	= 8			; Display font height, in pixels.
FONTWIDTH	= 256			; Display font width, in bytes.

FW		= FONTWIDTH
FH		= FONTHEIGHT

FBSIZE		= W * H * FONTHEIGHT	; Size, in bytes, of the frame buffer bitmap.
FRAMEBUF	= $FE0000		; Base address of the frame buffer.


;;;; console_init
;;
;; SYNOPSIS
;;	JSR console_init
;;
;; DESCRIPTION
;;	Private function.
;;
;;	Initializes the console output state to reset conditions.
;;	Note that this does NOT clear the framebuffer; however,
;;	the cursor is located in the upper-lefthand corner of the
;;	screen.
;;
;;	The cursor is assumed to be in the erased state, and turned
;;	off.
;;
;;	This function is assumed to be called by the BIOS start-up
;;	code, not by application software.  Thus, it is invoked with
;;	JSR, not JSL.
;;

console_init:
	.al
	.xl
.(
	php

	lda #$00
	sta cursorOffset	; zero cursor offset, implying X=Y=0
	sta frameBuffer		; set low word of pointer
	_AS
	sta cursorX
	sta cursorY
	sta cursorDrawn
	_AL
	lda #$FE
	sta frameBuffer+2	; set high byte of pointer
	lda #$01
	sta offCounter		; Cursor is assumed off

	plp
	rts
.)


;;;; console_mv_cursor_right
;;
;; SYNOPSIS
;;	JSR console_mv_cursor_right
;;
;; DESCRIPTION
;;	Private function.
;;
;;	Moves the cursor to the right one character position.
;;
;; PRECONDITION
;;	0 <= cursorX < W-1
;;	0 <= cursorOffset < FBSIZE-1
;;
;; POSTCONDITION
;;	0 < cursorX < W
;;	0 < cursorOffset < FBSIZE
;;

console_mv_cursor_right:
	.al
	.xl
.(
	php

	; 0 <= cursorX < W-1 implies 0 <= cursorX < W
	; 0 < cursorX+1 <= W-1

	_AS
	inc cursorX
	_AL
	inc cursorOffset

	; 0 < cursorX <= W-1, still implying 0 < cursorX < W

	plp
	rts
.)

;;;; console_mv_cursor_down
;;
;; SYNOPSIS
;;	JSR console_mv_cursor_down
;;
;; DESCRIPTION
;;	Private function.
;;
;;	Moves the cursor down one character position.
;;
;; PRECONDITION
;;	0 <= cursorY < H-1
;;	0 <= cursorOffset < FBSIZE
;;
;; POSTCONDITION
;;	0 < cursorY < H
;;	0 < cursorOffset < FBSIZE-W
;;

console_mv_cursor_down:
	.al
	.xl
.(
  	php
	pha

	; 0 <= cursorY < H-1   =>  0 <= cursorY < H
	; 0 < cursorY+1 < H-1  =>  0 <= cursorY+1 < H
	_AS
	inc cursorY
	_AL
	clc
	lda #W
	adc cursorOffset
	sta cursorOffset

	; 0 < cursorY < H-1   =>  0 <= cursorY < H

	pla
	plp
	rts
.)


;;;; console_mv_cursor_up
;;
;; SYNOPSIS
;;	JSR console_mv_cursor_up
;;
;; DESCRIPTION
;;	Private function.
;;
;;	Moves the cursor up one character position.
;;
;; PRECONDITION
;;	0 < cursorY <= H-1
;;	0 < cursorOffset <= FBSIZE-1
;;
;; POSTCONDITION
;;	0 <= cursorY < H-1
;;	0 <= cursorOffset < FBSIZE-W
;;

console_mv_cursor_up:
	.al
	.xl
.(
  	php
	pha

	; 0 < cursorY <= H-1
	; 0 <= cursorY-1 < H-1

	_AS
	dec cursorY
	_AL
	lda cursorOffset
	sec
	sbc #W
	sta cursorOffset

	; 0 <= cursorY < H-1

	pla
	plp
	rts
.)

;;;; console_constrain_pt
;;
;; SYNOPSIS
;;	PEA y
;;	PEA x
;;	JSR console_constrain_pt
;;	PLA
;;	STA constrained_x
;;	PLA
;;	STA constrained_y
;;
;; DESCRIPTION
;;	Constrain a coordinate to the visible portion of the screen.
;;
;;	For example, negative ordinates are set to zero.  Ordinates that
;;	exceed the width or height of the screen will be limited to the
;;	width or height minus one.
;;
console_constrain_pt:
	.al
	.xl
.(
s_y	= 7
s_x	= 5
s_pc	= 3
s_A	= 1

	pha

	; constrain X first

	lda s_x,s
	bpl x_is_positive
	lda #0
	sta s_x,s

x_is_positive:
	cmp #W
	blt x_is_in_range
	lda #W-1
	sta s_x,s

	; constrain Y next

x_is_in_range:

	lda s_y,s
	bpl y_is_positive
	lda #0
	sta s_y,s

y_is_positive:
	cmp #H
	blt y_is_in_range
	lda #H-1
	sta s_y,s

	pla
	rts
.)

;;;; console_set_cursor_xy
;;
;; SYNOPSIS
;;	PEA y
;;	PEA x
;;	JSR console_set_cursor_xy
;;	PLA
;;	PLA
console_set_cursor_xy:
	.al
	.xl
.(
s_y	= 5
s_x	= 3
s_pc	= 1

	; Constrain new cursor position.

	lda s_y,s
	pha
	lda s_x,s
	pha
	jsr console_constrain_pt
	pla
	sta s_x,s
	pla
	sta s_y,s

	; Let delta be the (signed) difference from the new column to the current column.
	; Add delta to cursorX and to cursorOffset.

	lda s_x,s
	sec
	sbc cursorX		; cursorOffset+(newX-cursorX) = newOffset
	clc
	adc cursorOffset
	sta cursorOffset	; cursorOffset = newOffset

	lda s_x,s
	sta cursorX		; cursorX = newX

	; While new row lies below the current row, do
	;   Move cursor down by 1.
	; end

down_again:
	lda cursorY
	cmp s_y,s
	bge try_up
	jsr console_mv_cursor_down
	jmp down_again

	; While new row lies above the current row, do
	;   Move cursor up by 1.
	; end

try_up:	lda cursorY
	cmp s_y,s
	blt done
	beq done
	jsr console_mv_cursor_up
	jmp try_up

done:	rts
.)


M sysf.disk0/kernel.state.s => sysf.disk0/kernel.state.s +8 -1
@@ 38,7 38,14 @@ Thread1Context  = $0300
Thread2Context  = Thread1Context+th_sizeof
alterbuf        = Thread2Context+th_sizeof
conbuf          = alterbuf+conbuf_sizeof
BIOS						= conbuf+conbuf_sizeof	; JML xx yy zz (total 4 bytes)
BIOS		= conbuf+conbuf_sizeof	; JML xx yy zz (total 4 bytes)
;	BIOS state
frameBuffer	= BIOS+4		; pointer
cursorOffset	= frameBuffer+4		; u16
offCounter	= cursorOffset+2	; u16
cursorX		= offCounter+2		; u8
cursorY		= cursorX+1
cursorDrawn	= cursorY+1		; bool

;       IM/F Re-entry Causes