Compare commits

...

5 Commits

Author SHA1 Message Date
Virgil Dupras
abafd6d67b ti84: fix glitches 2020-05-09 15:31:41 -04:00
Virgil Dupras
e06d6c5345 ti84: we have a prompt 2020-05-09 14:28:55 -04:00
Virgil Dupras
4ce0727c72 ti84: kbd driver wip 2020-05-09 11:55:58 -04:00
Virgil Dupras
2f1e635b9d ti84: tidy up driver code
Pushed all words directly interfacing with ports and memory offsets to
low level layers. This saves us the need for keeping those variables in
runtime memory.
2020-05-09 08:50:55 -04:00
Virgil Dupras
b2d71cb1ee ti84: add Z offset mechanism 2020-05-09 08:13:49 -04:00
20 changed files with 121 additions and 36 deletions

View File

@ -4,6 +4,7 @@ VARIABLE XCURRENT
: XCOFF 0x02 RAM+ CURRENT* ! ;
: (xentry) XCON (entry) XCOFF ;
: XCREATE (xentry) 11 C, ;
: XCODE XCON CODE XCOFF ;

View File

@ -5,4 +5,11 @@ CODE 2DROP
chkPS,
;CODE
( a b -- a b a b )
CODE 2DUP
HL POPqq, ( b ) DE POPqq, ( a )
chkPS,
DE PUSHqq, HL PUSHqq,
DE PUSHqq, HL PUSHqq,
;CODE

View File

@ -7,7 +7,6 @@
SWAP DROP
;
: 2DUP OVER OVER ;
: 2OVER 3 PICK 3 PICK ;
: 2SWAP 3 ROLL 3 ROLL ;

View File

@ -3,4 +3,4 @@ TI-84+ Recipe
Support code for the TI-84+ recipe. Contains drivers for the
keyboard and LCD.
551 LCD
551 LCD 564 Keyboard

View File

@ -1,7 +1,7 @@
TI-84+ LCD driver
Implement (emit) on TI-84+ (for now)'s LCD screen. Load with
"555 LOAD".
Implement (emit) on TI-84+ (for now)'s LCD screen. The low
level part are blocks 555-557 and high level ones are 558-560.
The screen is 96x64 pixels. The 64 rows are addressed directly
with CMD_ROW but columns are addressed in chunks of 6 or 8 bits

View File

@ -12,5 +12,5 @@ that line will go up 8 pixels, wrapping itself to the bottom of
the screen.
The principle is this: The active line is always the bottom
one. Therefore, when active row is 0, Z is FNT_HEIGHT+1, when
row is 1, Z is (FNT_HEIGHT+1)*2, When row is 8, Z is 0. (cont.)
one. Therefore, when active row is 0, Z is FNTH+1, when row is
1, Z is (FNTH+1)*2, When row is 8, Z is 0. (cont.)

10
blk/553
View File

@ -8,9 +8,9 @@ only 16 characters per line, which is hardly usable.
This is why we have this buffering system. How it works is that
we're always in 8-bit mode and we hold the whole area (8 pixels
wide by FNT_HEIGHT high) in memory. When we want to put a glyph
to screen, we first read the contents of that area, then add
our new glyph, offsetted and masked, to that buffer, then push
the buffer back to the LCD. If the glyph is split, move to the
next area and finish the job.
wide by FNTH high) in memory. When we want to put a glyph to
screen, we first read the contents of that area, then add our
new glyph, offsetted and masked, to that buffer, then push the
buffer back to the LCD. If the glyph is split, move to the next
area and finish the job.
(cont.)

10
blk/555
View File

@ -1,15 +1,13 @@
( Required config: TI_MEM )
: TI_MEM+ [ TI_MEM LITN ] @ + ;
TI_MEM : TI_MEM [ LITN ] ;
: LCD_PORT_CMD 0x10 ; : LCD_PORT_DATA 0x11 ;
( Required config: LCD_MEM )
: _mem+ [ LCD_MEM LITN ] @ + ;
: FNTW 3 ; : FNTH 5 ;
( Wait until the lcd is ready to receive a command. It's a bit
weird to implement a waiting routine in asm, but the forth
version is a bit heavy and we don't want to wait longer than
we have to. )
CODE LCDWAIT
CODE _wait
BEGIN,
0x10 INAn,
0x10 ( CMD ) INAn,
RLA, ( When 7th bit is clr, we can send a new cmd )
JRC, AGAIN,
;CODE

13
blk/556
View File

@ -1,8 +1,13 @@
( Current Y position on the LCD, that is, where we're going to
spit our next glyph. )
: LCD_CURY 0 TI_MEM+ ;
: LCD_CURX 1 TI_MEM+ ;
( two pixel buffers that are 8 pixels wide (1b) by FNT_HEIGHT
: LCD_CURY 0 _mem+ ;
: LCD_CURX 1 _mem+ ;
( two pixel buffers that are 8 pixels wide (1b) by FNTH
pixels high. This is where we compose our resulting pixels
blocks when spitting a glyph. )
: LCD_BUF 2 TI_MEM+ ;
: LCD_BUF 2 _mem+ ;
: _cmd 0x10 ( CMD ) PC! _wait ;
: _data! 0x11 ( DATA ) PC! _wait ;
: _data@ 0x11 ( DATA ) PC@ _wait ;
: LCDOFF 0x02 ( CMD_DISABLE ) _cmd ;
: LCDON 0x03 ( CMD_ENABLE ) _cmd ;

13
blk/557
View File

@ -1,12 +1,9 @@
: _cmd LCD_PORT_CMD PC! LCDWAIT ;
: _data! LCD_PORT_DATA PC! LCDWAIT ;
: _data@ LCD_PORT_DATA PC@ LCDWAIT ;
: LCDOFF 0x02 ( CMD_DISABLE ) _cmd ;
: LCDON 0x03 ( CMD_ENABLE ) _cmd ;
: _yinc 0x07 _cmd ; : _xinc 0x05 _cmd ;
: _col! ( col -- ) 0x20 ( CMD_COL ) + _cmd ;
: _row! ( row -- ) 0x80 ( CMD_ROW ) + _cmd ;
: _zoff! ( off -- ) 0x40 + _cmd ;
: _col! ( col -- ) 0x20 + _cmd ;
: _row! ( row -- ) 0x80 + _cmd ;
: LCD$
H@ TI_MEM ! FNTH 2 * 2+ ALLOT
H@ [ LCD_MEM LITN ] ! FNTH 2 * 2+ ALLOT
LCDON 0x01 ( 8-bit mode ) _cmd
FNTH 1+ _zoff!
;

View File

@ -10,4 +10,5 @@
( Changes the current line and go back to leftmost column )
: _lf
LCD_CURY C@ FNTH 1+ + DUP 63 > IF DROP 0 THEN
DUP _clrln LCD_CURY C! 0 LCD_CURX C! ;
DUP _clrln DUP FNTH 1+ + _zoff!
LCD_CURY C! 0 LCD_CURX C! ;

16
blk/564 Normal file
View File

@ -0,0 +1,16 @@
Keyboard driver
Low layer range: 566-569
Implement a (key) word that interpret keystrokes from the
builtin keyboard. The word waits for a digit to be pressed and
returns the corresponding ASCII value.
This routine waits for a key to be pressed, but before that, it
waits for all keys to be de-pressed. It does that to ensure
that two calls to _wait only go through after two actual key
presses (otherwise, the user doesn't have enough time to
de-press the button before the next _wait routine registers the
same key press as a second one).
(cont.)

6
blk/565 Normal file
View File

@ -0,0 +1,6 @@
Sending 0xff to the port resets the keyboard, and then we have
to send groups we want to "listen" to, with a 0 in the group
bit. Thus, to know if *any* key is pressed, we send 0xff to
reset the keypad, then 0x00 to select all groups, if the result
isn't 0xff, at least one key is pressed.

14
blk/566 Normal file
View File

@ -0,0 +1,14 @@
( Requires KBD_MEM, KBD_PORT )
( gm -- pm, get pressed keys mask for group mask gm )
CODE _get
HL POPqq,
chkPS,
DI,
A 0xff LDrn,
KBD_PORT OUTnA,
A L LDrr,
KBD_PORT OUTnA,
KBD_PORT INAn,
EI,
L A LDrr, HL PUSHqq,
;CODE

16
blk/567 Normal file
View File

@ -0,0 +1,16 @@
( wait until all keys are de-pressed. To avoid repeat keys, we
require 64 subsequent polls to indicate all depressed keys.
all keys are considered depressed when the 0 group returns
0xff. )
: _wait 64 BEGIN 0 _get 0xff = NOT IF DROP 64 THEN
1- DUP NOT UNTIL DROP ;
( digits table. seach row represents a group. 0 means
unsupported. no group 7 because it has no key. )
CREATE _dtbl
0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0 C,
0xd C, '+' C, '-' C, '*' C, '/' C, '^' C, 0 C, 0 C,
0 C, '3' C, '6' C, '9' C, ')' C, 0 C, 0 C, 0 C,
'.' C, '2' C, '5' C, '8' C, '(' C, 0 C, 0 C, 0 C,
'0' C, '1' C, '4' C, '7' C, ',' C, 0 C, 0 C, 0 C,
0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0x80 ( alpha ) C,
0 C, 0 C, 0 C, 0 C, 0 C, 0x81 ( 2nd ) C, 0 C, 0x7f C,

9
blk/568 Normal file
View File

@ -0,0 +1,9 @@
( alpha table. same as _dtbl, for when we're in alpha mode. )
CREATE _atbl
0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0 C, 0 C,
0xd C, '"' C, 'w' C, 'r' C, 'm' C, 'h' C, 0 C, 0 C,
'?' C, 0 C, 'v' C, 'q' C, 'l' C, 'g' C, 0 C, 0 C,
':' C, 'z' C, 'u' C, 'p' C, 'k' C, 'f' C, 'c' C, 0 C,
0x20 C, 'y' C, 't' C, 'o' C, 'j' C, 'e' C, 'b' C, 0 C,
0 C, 'x' C, 's' C, 'n' C, 'i' C, 'd' C, 'a' C, 0x80 C,
0 C, 0 C, 0 C, 0 C, 0 C, 0x81 ( 2nd ) C, 0 C, 0x7f C,

13
blk/569 Normal file
View File

@ -0,0 +1,13 @@
: _
0 ( gid ) 0 ( dummy )
BEGIN ( loop until a digit is pressed )
DROP
1+ DUP 7 = IF DROP 0 THEN ( inc gid )
1 OVER LSHIFT 0xff -^ ( group dmask ) _get
DUP 0xff = NOT UNTIL
( gid dmask )
0xff XOR ( dpos ) 0 ( dindex )
BEGIN 1+ 2DUP RSHIFT NOT UNTIL 1-
( gid dpos dindex ) SWAP DROP
( gid dindex ) SWAP 8 * + _dtbl + C@ _wait ;
: (key) 0 ( dummy ) BEGIN DROP _ DUP UNTIL ;

Binary file not shown.

View File

@ -21,7 +21,7 @@
#define INTERRUPT_PORT 0x03
#define LCD_CMD_PORT 0x10
#define LCD_DATA_PORT 0x11
#define MAX_ROMSIZE 0x2000
#define MAX_ROMSIZE 0x4000
static xcb_connection_t *conn;
static xcb_screen_t *screen;

View File

@ -1,27 +1,30 @@
0x8000 CONSTANT RAMSTART
0xb000 CONSTANT RS_ADDR
RAMSTART 0x70 + CONSTANT TI_MEM
RAMSTART 0x70 + CONSTANT LCD_MEM
0x01 CONSTANT KBD_PORT
212 LOAD ( z80 assembler )
262 LOAD ( xcomp )
522 LOAD ( font compiler )
: CODE XCODE ;
: IMMEDIATE XIMM ;
: (entry) (xentry) ;
: CREATE XCREATE ; ( for KBD tbls )
: : [ ' X: , ] ;
CURRENT @ XCURRENT !
282 LOAD ( boot.z80 )
555 LOAD ( ti.z80 )
393 LOAD ( icore low )
555 557 LOADR ( LCD low )
566 569 LOADR ( KBD low )
415 LOAD ( icore high )
(entry) ~FNT CPFNT3x5
(entry) _
( Update LATEST )
PC ORG @ 8 + !
422 437 XPACKR ( core )
556 560 XPACKR ( ti )
438 446 XPACKR ( print fmt )
," : _ LCD$ LIT< Hello (print) LIT< World! (print) BYE ; _ "
558 560 XPACKR ( LCD high )
438 451 XPACKR ( print fmt readln )
," : _ LCD$ (ok) RDLN$ ; _ "
ORG @ 256 /MOD 2 PC! 2 PC!
H@ 256 /MOD 2 PC! 2 PC!