1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-20 18:28:06 +11:00

recipes/trs80: use grid module

Not much of a gain in terms of usability (a bit of a loss in fact, things are
a bit slow and glitchy), but it's a necessary move if we want to use upcoming
grid-enabled userspace apps, such as a visual text editor.
This commit is contained in:
Virgil Dupras 2020-02-26 16:27:27 -05:00
parent a442c46935
commit 92ddc7ebc1
5 changed files with 118 additions and 38 deletions

View File

@ -12,8 +12,10 @@
; can access those cells by their (X, Y) address. In addition to this, we have ; can access those cells by their (X, Y) address. In addition to this, we have
; the concept of an active cursor, which will be indicated visually if possible. ; the concept of an active cursor, which will be indicated visually if possible.
; ;
; Additionally, this module provides a PutC routine, suitable for plugging into ; This module provides PutC and GetC routines, suitable for plugging into stdio.
; stdio. ; PutC, for obvious reasons, GetC, for less obvious reasons: We need to wrap
; GetC because we need to update the cursor before calling actual GetC, but
; also, because we need to know when a bulk update ends.
; ;
; *** Defines *** ; *** Defines ***
; ;
@ -21,7 +23,9 @@
; GRID_ROWS: Number of rows in the grid ; GRID_ROWS: Number of rows in the grid
; GRID_SETCELL: Pointer to routine that sets cell at row D and column E with ; GRID_SETCELL: Pointer to routine that sets cell at row D and column E with
; character in A. If C is nonzero, this cell must be displayed, ; character in A. If C is nonzero, this cell must be displayed,
; if possible, as the cursor. ; if possible, as the cursor. This routine is never called with
; A < 0x20.
; GRID_GETC: Routine that gridGetC will wrap around.
; ;
; *** Consts *** ; *** Consts ***
.equ GRID_SIZE GRID_COLS*GRID_ROWS .equ GRID_SIZE GRID_COLS*GRID_ROWS
@ -31,6 +35,10 @@
.equ GRID_CURX GRID_RAMSTART .equ GRID_CURX GRID_RAMSTART
; Cursor's row ; Cursor's row
.equ GRID_CURY @+1 .equ GRID_CURY @+1
; Whether we scrolled recently. We don't refresh the screen immediately when
; scrolling in case we have many lines being spit at once (refreshing the
; display is then very slow). Instead, we wait until the next gridGetC call
.equ GRID_SCROLLED @+1
; Grid's in-memory buffer of the contents on screen. Because we always push to ; Grid's in-memory buffer of the contents on screen. Because we always push to
; display right after a change, this is almost always going to be a correct ; display right after a change, this is almost always going to be a correct
; representation of on-screen display. ; representation of on-screen display.
@ -53,7 +61,7 @@ _gridPlaceCell:
ld hl, GRID_BUF ld hl, GRID_BUF
ld a, d ld a, d
or a or a
ret z jr z, .setcol
push de ; --> lvl 1 push de ; --> lvl 1
ld de, GRID_COLS ld de, GRID_COLS
.loop: .loop:
@ -61,10 +69,18 @@ _gridPlaceCell:
dec a dec a
jr nz, .loop jr nz, .loop
pop de ; <-- lvl 1 pop de ; <-- lvl 1
.setcol:
; We're at the proper row, now let's advance to cell ; We're at the proper row, now let's advance to cell
ld a, e ld a, e
jp addHL jp addHL
; Ensure that A >= 0x20
_gridAdjustA:
cp 0x20
ret nc
ld a, 0x20
ret
; Push row D in the buffer onto the screen. ; Push row D in the buffer onto the screen.
gridPushRow: gridPushRow:
push af push af
@ -78,6 +94,7 @@ gridPushRow:
ld b, GRID_COLS ld b, GRID_COLS
.loop: .loop:
ld a, (hl) ld a, (hl)
call _gridAdjustA
; A, C, D and E have proper values ; A, C, D and E have proper values
call GRID_SETCELL call GRID_SETCELL
inc hl inc hl
@ -98,11 +115,10 @@ gridClrRow:
push hl push hl
ld e, 0 ld e, 0
call _gridPlaceCell call _gridPlaceCell
xor a ld a, ' '
ld b, GRID_COLS ld b, GRID_COLS
call fill call fill
call gridPushRow call gridPushRow
pop hl pop hl
pop de pop de
pop bc pop bc
@ -131,6 +147,7 @@ gridSetCur:
call _gridPlaceCell call _gridPlaceCell
pop af \ push af ; <--> lvl 1 pop af \ push af ; <--> lvl 1
ld (hl), a ld (hl), a
call _gridAdjustA
call GRID_SETCELL call GRID_SETCELL
pop af ; <-- lvl 1 pop af ; <-- lvl 1
pop hl pop hl
@ -166,19 +183,10 @@ gridLF:
push de push de
push af push af
ld a, (GRID_CURY) ld a, (GRID_CURY)
call .incA ; increase A
ld d, a
call gridClrRow
ld (GRID_CURY), a
xor a
ld (GRID_CURX), a
pop af
pop de
ret
.incA:
inc a inc a
cp GRID_ROWS cp GRID_ROWS
ret nz ; no rollover jr nz, .noscroll
; bottom reached, stay on last line and scroll screen ; bottom reached, stay on last line and scroll screen
push hl push hl
push de push de
@ -187,11 +195,21 @@ gridLF:
ld hl, GRID_BUF+GRID_COLS ld hl, GRID_BUF+GRID_COLS
ld bc, GRID_SIZE-GRID_COLS ld bc, GRID_SIZE-GRID_COLS
ldir ldir
ld hl, GRID_SCROLLED
inc (hl) ; mark as scrolled
pop bc pop bc
pop de pop de
pop hl pop hl
call gridPushScr
dec a dec a
.noscroll:
; A has been increased properly
ld d, a
call gridClrRow
ld (GRID_CURY), a
xor a
ld (GRID_CURX), a
pop af
pop de
ret ret
gridBS: gridBS:
@ -242,3 +260,16 @@ gridPutC:
call gridLF call gridLF
pop af ; <-- lvl 1 pop af ; <-- lvl 1
ret ret
gridGetC:
ld a, (GRID_SCROLLED)
or a
jr z, .nopush
; We've scrolled recently, update screen
xor a
ld (GRID_SCROLLED), a
call gridPushScr
.nopush:
ld a, ' '
call gridSetCurH
jp GRID_GETC

View File

@ -1,7 +1,9 @@
; vid - TRS-80's video ; vid - TRS-80's video
; ;
; Implement PutC using TRS-80's SVC calls so that character it put on video ; Implement PutC and GRID_SETCELL using TRS-80's SVC calls.
; display.
.equ TRS80_COLS 80
.equ TRS80_ROWS 24
trs80PutC: trs80PutC:
push af push af
@ -14,3 +16,44 @@ trs80PutC:
pop bc pop bc
pop af pop af
ret ret
trs80SetCell:
push af
push bc
push hl ; HL altered by @VDCTL
push de ; DE altered by @VDCTL
ex de, hl
bit 0, c
ld c, a ; save A now
jr z, .skip ; Z from BIT above. cursor not set
; set cursor
ld a, 0x0f ; @VDCTL
ld b, 3 ; move cursor fn
rst 0x28
; HL altered.
; Our Row/Col is our currently-pushed DE value. Let's take advantage of
; that.
pop hl \ push hl ; HL altered. bring back from stack
.skip:
ld a, 0x0f ; @VDCTL
ld b, 2 ; display char
rst 0x28
pop de
pop hl
pop bc
pop af
ret
; This is a much faster version of gridPushScr. Use it in your glue code, but
; you need to set HL to GRID_BUF first.
trs80PushScr:
push af
push bc
ld a, 0x0f ; @VDCTL
ld b, 5 ; move from RAM to vid
; HL is already set by caller
rst 0x28
pop bc
pop af
cp a ; ensure Z
ret

View File

@ -21,10 +21,11 @@
.equ GRID_COLS VDP_COLS .equ GRID_COLS VDP_COLS
.equ GRID_ROWS VDP_ROWS .equ GRID_ROWS VDP_ROWS
.equ GRID_SETCELL vdpSetCell .equ GRID_SETCELL vdpSetCell
.equ GRID_GETC padGetC
.inc "grid.asm" .inc "grid.asm"
.equ STDIO_RAMSTART GRID_RAMEND .equ STDIO_RAMSTART GRID_RAMEND
.equ STDIO_GETC padGetC .equ STDIO_GETC gridGetC
.equ STDIO_PUTC gridPutC .equ STDIO_PUTC gridPutC
.inc "stdio.asm" .inc "stdio.asm"

View File

@ -2,17 +2,13 @@
.equ RAMEND 0xcfff .equ RAMEND 0xcfff
; Address of the *CL driver. Same as in recv.asm ; Address of the *CL driver. Same as in recv.asm
.equ COM_DRV_ADDR 0x0238 .equ COM_DRV_ADDR 0x0238
; in sync with user.h. Last BAS_RAMEND: 0x5705 ; in sync with user.h. Last BAS_RAMEND: 0x600b
.equ USER_CODE 0x5800 .equ USER_CODE 0x6100
; Free memory in TRSDOS starts at 0x3000 ; Free memory in TRSDOS starts at 0x3000
.org 0x3000 .org 0x3000
jp init jp init
; The TRS-80 generates a double line feed if we give it both CR and LF.
; Has to be defined before the jump table.
.equ printcrlf printcr
; *** Jump Table *** ; *** Jump Table ***
jp strncmp jp strncmp
jp upcase jp upcase
@ -45,7 +41,14 @@
.equ FLOPPY_RAMSTART RAMSTART .equ FLOPPY_RAMSTART RAMSTART
.inc "trs80/floppy.asm" .inc "trs80/floppy.asm"
.equ BLOCKDEV_RAMSTART FLOPPY_RAMEND .equ GRID_RAMSTART FLOPPY_RAMEND
.equ GRID_ROWS TRS80_ROWS
.equ GRID_COLS TRS80_COLS
.equ GRID_SETCELL trs80SetCell
.equ GRID_GETC trs80GetC
.equ gridPushScr fastPushScr
.inc "grid.asm"
.equ BLOCKDEV_RAMSTART GRID_RAMEND
.equ BLOCKDEV_COUNT 3 .equ BLOCKDEV_COUNT 3
.inc "blockdev.asm" .inc "blockdev.asm"
; List of devices ; List of devices
@ -54,8 +57,9 @@
.dw blk2GetB, blk2PutB .dw blk2GetB, blk2PutB
.equ STDIO_RAMSTART BLOCKDEV_RAMEND .equ STDIO_RAMSTART BLOCKDEV_RAMEND
.equ STDIO_GETC trs80GetC .equ STDIO_GETC gridGetC
.equ STDIO_PUTC trs80PutC .equ STDIO_PUTC gridPutC
.equ STDIO_SETCUR gridSetCurH
.inc "stdio.asm" .inc "stdio.asm"
.equ FS_RAMSTART STDIO_RAMEND .equ FS_RAMSTART STDIO_RAMEND
@ -91,6 +95,7 @@
init: init:
ld sp, RAMEND ld sp, RAMEND
call gridInit
call floppyInit call floppyInit
call fsInit call fsInit
call basInit call basInit
@ -103,13 +108,6 @@ init:
jp basStart jp basStart
printcr:
push af
ld a, CR
call STDIO_PUTC
pop af
ret
; Receive a byte from *cl and put it in A. ; Receive a byte from *cl and put it in A.
; Returns A > 0xff when receiving the last byte ; Returns A > 0xff when receiving the last byte
recvCmd: recvCmd:
@ -172,6 +170,13 @@ basFindCmdExtra:
.dw recvCmd .dw recvCmd
.db 0xff ; end of table .db 0xff ; end of table
fastPushScr:
push hl
ld hl, GRID_BUF
call trs80PushScr
pop hl
ret
; *** blkdev 1: file handle 0 *** ; *** blkdev 1: file handle 0 ***
blk1GetB: blk1GetB:

View File

@ -1,4 +1,4 @@
.org 0x5800 .org 0x6100
.equ strncmp 0x3003 .equ strncmp 0x3003
.equ upcase @+3 .equ upcase @+3
.equ findchar @+3 .equ findchar @+3