mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 12:08:07 +11:00
sms: add support for VDP's text mode
Because that mode behaves exactly like in a regular TMS9918, a new driver for TMS9918 has been added in blkfs and SMS' VDP now uses it. Also, fix broken 5x7 font.
This commit is contained in:
parent
09c01c4a43
commit
d1718a90c7
@ -1,16 +1,11 @@
|
|||||||
VDP Driver
|
( VDP Driver. requires TMS9918 driver. Load range B602-B604. )
|
||||||
|
CREATE _idat
|
||||||
Implement (emit) on the console. Characters start at the top
|
0b00000100 C, 0x80 C, ( Bit 2: Select mode 4 )
|
||||||
left. Every (emit) call converts the ASCII char received to its
|
0b00000000 C, 0x81 C,
|
||||||
internal font, then put that char on screen, advancing the
|
0b00001111 C, 0x82 C, ( Name table: 0x3800, *B0 must be 1* )
|
||||||
cursor by one. When reaching the end of the line (33rd char),
|
0b11111111 C, 0x85 C, ( Sprite table: 0x3f00 )
|
||||||
wrap to the next.
|
0b11111111 C, 0x86 C, ( sprite use tiles from 0x2000 )
|
||||||
|
0b11111111 C, 0x87 C, ( Border uses palette 0xf )
|
||||||
In the future, there's going to be a scrolling mechanism when
|
0b00000000 C, 0x88 C, ( BG X scroll )
|
||||||
we reach the bottom of the screen, but for now, when the end of
|
0b00000000 C, 0x89 C, ( BG Y scroll )
|
||||||
the screen is reached, we wrap up to the top.
|
0b11111111 C, 0x8a C, ( Line counter (why have this?) )
|
||||||
|
|
||||||
When reaching a new line, we clear that line and the next to
|
|
||||||
help readability.
|
|
||||||
|
|
||||||
Load range: 623-628
|
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
CODE _ctl ( a -- sends LSB then MSB )
|
: _zero ( x -- send 0 _data x times )
|
||||||
HL POP, chkPS,
|
( x ) 0 DO 0 _data LOOP ;
|
||||||
A L LDrr, VDP_CTLPORT OUTiA,
|
( Each row in ~FNT is a row of the glyph and there is 7 of
|
||||||
A H LDrr, VDP_CTLPORT OUTiA,
|
them. We insert a blank one at the end of those 7. For each
|
||||||
;CODE
|
row we set, we need to send 3 zero-bytes because each pixel in
|
||||||
CODE _data
|
the tile is actually 4 bits because it can select among 16
|
||||||
HL POP, chkPS,
|
palettes. We use only 2 of them, which is why those bytes
|
||||||
A L LDrr, VDP_DATAPORT OUTiA,
|
always stay zero. )
|
||||||
;CODE
|
: _sfont ( a -- Send font to VDP )
|
||||||
|
7 0 DO C@+ _data 3 _zero LOOP DROP
|
||||||
|
( blank row ) 4 _zero ;
|
||||||
|
: CELL! ( tilenum pos )
|
||||||
|
2 * 0x7800 OR _ctl ( tilenum )
|
||||||
|
0x5e MOD _data 1 _zero ;
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
CODE _blank ( this is way too slow in Forth )
|
: VDP$
|
||||||
A XORr, VDP_CTLPORT OUTiA,
|
9 0 DO _idat I 2 * + @ _ctl LOOP _blank
|
||||||
A 0x40 LDri, VDP_CTLPORT OUTiA,
|
( palettes )
|
||||||
HL 0x4000 LDdi,
|
0xc000 _ctl
|
||||||
BEGIN,
|
( BG ) 1 _zero 0x3f _data 14 _zero
|
||||||
A XORr, VDP_DATAPORT OUTiA,
|
( sprite, inverted colors ) 0x3f _data 15 _zero
|
||||||
HL DECd, HLZ,
|
0x4000 _ctl 0x5e 0 DO ~FNT I 7 * + _sfont LOOP
|
||||||
JRNZ, AGAIN,
|
( bit 6, enable display, bit 7, ?? ) 0x81c0 _ctl ;
|
||||||
;CODE
|
|
||||||
|
: COLS 32 ;
|
||||||
|
: LINES 24 ;
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
CREATE _idat
|
|
||||||
0b00000100 C, 0x80 C, ( Bit 2: Select mode 4 )
|
|
||||||
0b00000000 C, 0x81 C,
|
|
||||||
0b00001111 C, 0x82 C, ( Name table: 0x3800, *B0 must be 1* )
|
|
||||||
0b11111111 C, 0x85 C, ( Sprite table: 0x3f00 )
|
|
||||||
0b11111111 C, 0x86 C, ( sprite use tiles from 0x2000 )
|
|
||||||
0b11111111 C, 0x87 C, ( Border uses palette 0xf )
|
|
||||||
0b00000000 C, 0x88 C, ( BG X scroll )
|
|
||||||
0b00000000 C, 0x89 C, ( BG Y scroll )
|
|
||||||
0b11111111 C, 0x8a C, ( Line counter (why have this?) )
|
|
@ -1,12 +0,0 @@
|
|||||||
: _zero ( x -- send 0 _data x times )
|
|
||||||
( x ) 0 DO 0 _data LOOP ;
|
|
||||||
|
|
||||||
( Each row in ~FNT is a row of the glyph and there is 7 of
|
|
||||||
them. We insert a blank one at the end of those 7. For each
|
|
||||||
row we set, we need to send 3 zero-bytes because each pixel in
|
|
||||||
the tile is actually 4 bits because it can select among 16
|
|
||||||
palettes. We use only 2 of them, which is why those bytes
|
|
||||||
always stay zero. )
|
|
||||||
: _sfont ( a -- Send font to VDP )
|
|
||||||
7 0 DO C@+ _data 3 _zero LOOP DROP
|
|
||||||
( blank row ) 4 _zero ;
|
|
@ -1,3 +0,0 @@
|
|||||||
: CELL! ( tilenum pos )
|
|
||||||
2 * 0x7800 OR _ctl ( tilenum )
|
|
||||||
0x5e MOD _data 1 _zero ;
|
|
@ -1,11 +0,0 @@
|
|||||||
: VDP$
|
|
||||||
9 0 DO _idat I 2 * + @ _ctl LOOP _blank
|
|
||||||
( palettes )
|
|
||||||
0xc000 _ctl
|
|
||||||
( BG ) 1 _zero 0x3f _data 14 _zero
|
|
||||||
( sprite, inverted colors ) 0x3f _data 15 _zero
|
|
||||||
0x4000 _ctl 0x5e 0 DO ~FNT I 7 * + _sfont LOOP
|
|
||||||
( bit 6, enable display, bit 7, ?? ) 0x81c0 _ctl ;
|
|
||||||
|
|
||||||
: COLS 32 ;
|
|
||||||
: LINES 24 ;
|
|
@ -4,8 +4,8 @@
|
|||||||
0xddca CONSTANT PS_ADDR
|
0xddca CONSTANT PS_ADDR
|
||||||
RS_ADDR 0x80 - CONSTANT SYSVARS
|
RS_ADDR 0x80 - CONSTANT SYSVARS
|
||||||
0xc000 CONSTANT HERESTART
|
0xc000 CONSTANT HERESTART
|
||||||
0xbf CONSTANT VDP_CTLPORT
|
0xbf CONSTANT TMS_CTLPORT
|
||||||
0xbe CONSTANT VDP_DATAPORT
|
0xbe CONSTANT TMS_DATAPORT
|
||||||
SYSVARS 0x70 + CONSTANT GRID_MEM
|
SYSVARS 0x70 + CONSTANT GRID_MEM
|
||||||
SYSVARS 0x72 + CONSTANT CPORT_MEM
|
SYSVARS 0x72 + CONSTANT CPORT_MEM
|
||||||
0x3f CONSTANT CPORT_CTL
|
0x3f CONSTANT CPORT_CTL
|
||||||
@ -27,7 +27,8 @@ CURRENT @ XCURRENT !
|
|||||||
283 335 LOADR ( boot.z80 )
|
283 335 LOADR ( boot.z80 )
|
||||||
353 LOAD ( xcomp core low )
|
353 LOAD ( xcomp core low )
|
||||||
CREATE ~FNT CPFNT7x7
|
CREATE ~FNT CPFNT7x7
|
||||||
603 608 LOADR ( VDP )
|
470 472 LOADR ( TMS9918 )
|
||||||
|
602 604 LOADR ( VDP )
|
||||||
402 404 LOADR ( Grid )
|
402 404 LOADR ( Grid )
|
||||||
625 626 LOADR ( SMS ports )
|
625 626 LOADR ( SMS ports )
|
||||||
612 617 LOADR ( PAD )
|
612 617 LOADR ( PAD )
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
0xddca CONSTANT PS_ADDR
|
0xddca CONSTANT PS_ADDR
|
||||||
RS_ADDR 0x80 - CONSTANT SYSVARS
|
RS_ADDR 0x80 - CONSTANT SYSVARS
|
||||||
0xc000 CONSTANT HERESTART
|
0xc000 CONSTANT HERESTART
|
||||||
0xbf CONSTANT VDP_CTLPORT
|
0xbf CONSTANT TMS_CTLPORT
|
||||||
0xbe CONSTANT VDP_DATAPORT
|
0xbe CONSTANT TMS_DATAPORT
|
||||||
SYSVARS 0x70 + CONSTANT GRID_MEM
|
SYSVARS 0x70 + CONSTANT GRID_MEM
|
||||||
SYSVARS 0x72 + CONSTANT CPORT_MEM
|
SYSVARS 0x72 + CONSTANT CPORT_MEM
|
||||||
0x3f CONSTANT CPORT_CTL
|
0x3f CONSTANT CPORT_CTL
|
||||||
@ -28,7 +28,8 @@ CURRENT @ XCURRENT !
|
|||||||
283 335 LOADR ( boot.z80 )
|
283 335 LOADR ( boot.z80 )
|
||||||
353 LOAD ( xcomp core low )
|
353 LOAD ( xcomp core low )
|
||||||
CREATE ~FNT CPFNT7x7
|
CREATE ~FNT CPFNT7x7
|
||||||
603 608 LOADR ( VDP )
|
470 472 LOADR ( TMS9918 )
|
||||||
|
602 604 LOADR ( VDP )
|
||||||
402 404 LOADR ( Grid )
|
402 404 LOADR ( Grid )
|
||||||
625 626 LOADR ( SMS ports )
|
625 626 LOADR ( SMS ports )
|
||||||
620 LOAD ( PAD ) : (ps2kc) (ps2kcA) ; 411 414 LOADR
|
620 LOAD ( PAD ) : (ps2kc) (ps2kcA) ; 411 414 LOADR
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
0xddca CONSTANT PS_ADDR
|
0xddca CONSTANT PS_ADDR
|
||||||
RS_ADDR 0x80 - CONSTANT SYSVARS
|
RS_ADDR 0x80 - CONSTANT SYSVARS
|
||||||
0xc000 CONSTANT HERESTART
|
0xc000 CONSTANT HERESTART
|
||||||
0xbf CONSTANT VDP_CTLPORT
|
0xbf CONSTANT TMS_CTLPORT
|
||||||
0xbe CONSTANT VDP_DATAPORT
|
0xbe CONSTANT TMS_DATAPORT
|
||||||
SYSVARS 0x70 + CONSTANT GRID_MEM
|
SYSVARS 0x70 + CONSTANT GRID_MEM
|
||||||
SYSVARS 0x72 + CONSTANT CPORT_MEM
|
SYSVARS 0x72 + CONSTANT CPORT_MEM
|
||||||
0x3f CONSTANT CPORT_CTL
|
0x3f CONSTANT CPORT_CTL
|
||||||
@ -29,7 +29,8 @@ CURRENT @ XCURRENT !
|
|||||||
283 335 LOADR ( boot.z80 )
|
283 335 LOADR ( boot.z80 )
|
||||||
353 LOAD ( xcomp core low )
|
353 LOAD ( xcomp core low )
|
||||||
CREATE ~FNT CPFNT7x7
|
CREATE ~FNT CPFNT7x7
|
||||||
603 608 LOADR ( VDP )
|
470 472 LOADR ( TMS9918 )
|
||||||
|
602 604 LOADR ( VDP )
|
||||||
402 404 LOADR ( Grid )
|
402 404 LOADR ( Grid )
|
||||||
625 626 LOADR ( SMS ports )
|
625 626 LOADR ( SMS ports )
|
||||||
620 LOAD ( PAD ) : (ps2kc) (ps2kcA) ; 411 414 LOADR
|
620 LOAD ( PAD ) : (ps2kc) (ps2kcA) ; 411 414 LOADR
|
||||||
|
42
arch/z80/sms/xcomptextmode.fs
Normal file
42
arch/z80/sms/xcomptextmode.fs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
( xcomp using the Text Mode if the VDP. Only works on actual
|
||||||
|
SMS. The Megadrive's VDP doesn't have TMS9918 modes in it. )
|
||||||
|
( 8K of onboard RAM )
|
||||||
|
0xdd00 CONSTANT RS_ADDR
|
||||||
|
( Memory register at the end of RAM. Must not overwrite )
|
||||||
|
0xddca CONSTANT PS_ADDR
|
||||||
|
RS_ADDR 0x80 - CONSTANT SYSVARS
|
||||||
|
0xc000 CONSTANT HERESTART
|
||||||
|
0xbf CONSTANT TMS_CTLPORT
|
||||||
|
0xbe CONSTANT TMS_DATAPORT
|
||||||
|
SYSVARS 0x70 + CONSTANT GRID_MEM
|
||||||
|
SYSVARS 0x72 + CONSTANT CPORT_MEM
|
||||||
|
0x3f CONSTANT CPORT_CTL
|
||||||
|
0xdc CONSTANT CPORT_D1
|
||||||
|
0xdd CONSTANT CPORT_D2
|
||||||
|
SYSVARS 0x73 + CONSTANT PS2_MEM
|
||||||
|
5 LOAD ( z80 assembler )
|
||||||
|
: ZFILL, ( u ) 0 DO 0 A, LOOP ;
|
||||||
|
262 LOAD ( xcomp )
|
||||||
|
523 LOAD ( font compiler )
|
||||||
|
282 LOAD ( boot.z80.decl )
|
||||||
|
270 LOAD ( xcomp overrides )
|
||||||
|
|
||||||
|
DI, 0x100 JP, 0x62 ZFILL, ( 0x66 )
|
||||||
|
RETN, 0x98 ZFILL, ( 0x100 )
|
||||||
|
( All set, carry on! )
|
||||||
|
CURRENT @ XCURRENT !
|
||||||
|
0x100 BIN( !
|
||||||
|
283 335 LOADR ( boot.z80 )
|
||||||
|
353 LOAD ( xcomp core low )
|
||||||
|
CREATE ~FNT CPFNT5x7
|
||||||
|
470 472 LOADR ( VDP )
|
||||||
|
402 404 LOADR ( Grid )
|
||||||
|
625 626 LOADR ( SMS ports )
|
||||||
|
620 LOAD ( PAD ) : (ps2kc) (ps2kcA) ; 411 414 LOADR
|
||||||
|
390 LOAD ( xcomp core high )
|
||||||
|
(entry) _
|
||||||
|
( Update LATEST )
|
||||||
|
PC ORG @ 8 + !
|
||||||
|
," TMS$ 0 0 AT-XY PS2$ (im1) " EOT,
|
||||||
|
ORG @ 0x100 - 256 /MOD 2 PC! 2 PC!
|
||||||
|
H@ 256 /MOD 2 PC! 2 PC!
|
3
blk/001
3
blk/001
@ -9,4 +9,5 @@ MASTER INDEX
|
|||||||
400 AT28 EEPROM driver 401 Grid subsystem
|
400 AT28 EEPROM driver 401 Grid subsystem
|
||||||
410 PS/2 keyboard subsystem 418 Z80 SPI Relay driver
|
410 PS/2 keyboard subsystem 418 Z80 SPI Relay driver
|
||||||
420 SD Card subsystem 440 8086 boot code
|
420 SD Card subsystem 440 8086 boot code
|
||||||
470-519 unused 520 Fonts
|
470 Z80 TMS9918 driver
|
||||||
|
480-519 unused 520 Fonts
|
||||||
|
12
blk/470
Normal file
12
blk/470
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
( Z80 driver for TMS9918. Implements grid protocol. Requires
|
||||||
|
TMS_CTLPORT, TMS_DATAPORT and ~FNT from the Font compiler at
|
||||||
|
B520. Load range B470-472 )
|
||||||
|
CODE _ctl ( a -- sends LSB then MSB )
|
||||||
|
HL POP, chkPS,
|
||||||
|
A L LDrr, TMS_CTLPORT OUTiA,
|
||||||
|
A H LDrr, TMS_CTLPORT OUTiA,
|
||||||
|
;CODE
|
||||||
|
CODE _data
|
||||||
|
HL POP, chkPS,
|
||||||
|
A L LDrr, TMS_DATAPORT OUTiA,
|
||||||
|
;CODE
|
9
blk/471
Normal file
9
blk/471
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
CODE _blank ( this is way too slow in Forth )
|
||||||
|
A XORr, TMS_CTLPORT OUTiA,
|
||||||
|
A 0x40 LDri, TMS_CTLPORT OUTiA,
|
||||||
|
HL 0x4000 LDdi,
|
||||||
|
BEGIN,
|
||||||
|
A XORr, TMS_DATAPORT OUTiA,
|
||||||
|
HL DECd, HLZ,
|
||||||
|
JRNZ, AGAIN,
|
||||||
|
;CODE
|
16
blk/472
Normal file
16
blk/472
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
( Each row in ~FNT is a row of the glyph and there is 7 of
|
||||||
|
them. We insert a blank one at the end of those 7. )
|
||||||
|
: _sfont ( a -- Send font to TMS )
|
||||||
|
7 0 DO C@+ _data LOOP DROP
|
||||||
|
( blank row ) 0 _data ;
|
||||||
|
: CELL! ( tilenum pos )
|
||||||
|
0x7800 OR _ctl ( tilenum )
|
||||||
|
0x5e MOD _data ;
|
||||||
|
: COLS 40 ; : LINES 24 ;
|
||||||
|
: TMS$
|
||||||
|
0x8100 _ctl ( blank screen ) _blank
|
||||||
|
0x4000 _ctl 0x5e 0 DO ~FNT I 7 * + _sfont LOOP
|
||||||
|
0x820e _ctl ( name table 0x3800 )
|
||||||
|
0x8400 _ctl ( patter table 0x0000 )
|
||||||
|
0x87f0 _ctl ( colors 0 and 1 )
|
||||||
|
0x8000 _ctl 0x81d0 _ctl ( text mode, display on ) ;
|
4
blk/523
4
blk/523
@ -9,7 +9,7 @@
|
|||||||
DUP I 5 * + _g
|
DUP I 5 * + _g
|
||||||
LOOP ;
|
LOOP ;
|
||||||
: CPFNT5x7
|
: CPFNT5x7
|
||||||
0 , 0 , 0 C, ( space char )
|
0 , 0 , 0 , 0 C, ( space char )
|
||||||
534 532 DO I BLK@ BLK( 12 _l 448 + 12 _l DROP LOOP ( 72 )
|
535 532 DO I BLK@ BLK( 12 _l 448 + 12 _l DROP LOOP ( 72 )
|
||||||
535 BLK@ BLK( 12 _l 448 + 10 _l DROP ( 94! )
|
535 BLK@ BLK( 12 _l 448 + 10 _l DROP ( 94! )
|
||||||
;
|
;
|
||||||
|
@ -34,7 +34,7 @@ static xcb_gcontext_t fg;
|
|||||||
static xcb_drawable_t win;
|
static xcb_drawable_t win;
|
||||||
|
|
||||||
// pixels to draw. We draw them in one shot.
|
// pixels to draw. We draw them in one shot.
|
||||||
static xcb_rectangle_t rectangles[VDP_SCREENW*VDP_SCREENH];
|
static xcb_rectangle_t rectangles[(32*8)*(24*8)];
|
||||||
|
|
||||||
static Machine *m;
|
static Machine *m;
|
||||||
static VDP vdp;
|
static VDP vdp;
|
||||||
@ -144,19 +144,19 @@ void draw_pixels()
|
|||||||
xcb_clear_area(
|
xcb_clear_area(
|
||||||
conn, 0, win, 0, 0, geom->width, geom->height);
|
conn, 0, win, 0, 0, geom->width, geom->height);
|
||||||
// Figure out inner size to maximize our screen's aspect ratio
|
// Figure out inner size to maximize our screen's aspect ratio
|
||||||
int psize = geom->height / VDP_SCREENH;
|
int psize = geom->height / vdp.tms.height;
|
||||||
if (geom->width / VDP_SCREENW < psize) {
|
if (geom->width / vdp.tms.width < psize) {
|
||||||
// width is the constraint
|
// width is the constraint
|
||||||
psize = geom->width / VDP_SCREENW;
|
psize = geom->width / vdp.tms.width;
|
||||||
}
|
}
|
||||||
int innerw = psize * VDP_SCREENW;
|
int innerw = psize * vdp.tms.width;
|
||||||
int innerh = psize * VDP_SCREENH;
|
int innerh = psize * vdp.tms.height;
|
||||||
int innerx = (geom->width - innerw) / 2;
|
int innerx = (geom->width - innerw) / 2;
|
||||||
int innery = (geom->height - innerh) / 2;
|
int innery = (geom->height - innerh) / 2;
|
||||||
free(geom);
|
free(geom);
|
||||||
int drawcnt = 0;
|
int drawcnt = 0;
|
||||||
for (int i=0; i<VDP_SCREENW; i++) {
|
for (int i=0; i<vdp.tms.width; i++) {
|
||||||
for (int j=0; j<VDP_SCREENH; j++) {
|
for (int j=0; j<vdp.tms.height; j++) {
|
||||||
if (vdp_pixel(&vdp, i, j)) {
|
if (vdp_pixel(&vdp, i, j)) {
|
||||||
int x = innerx + (i*psize);
|
int x = innerx + (i*psize);
|
||||||
int y = innery + (j*psize);
|
int y = innery + (j*psize);
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "sms_vdp.h"
|
#include "sms_vdp.h"
|
||||||
|
|
||||||
|
static bool _is_mode4(VDP *vdp)
|
||||||
|
{
|
||||||
|
return (vdp->tms.regs[0]&0x4);
|
||||||
|
}
|
||||||
|
|
||||||
void vdp_init(VDP *vdp)
|
void vdp_init(VDP *vdp)
|
||||||
{
|
{
|
||||||
tms_init(&vdp->tms);
|
tms_init(&vdp->tms);
|
||||||
@ -18,6 +23,7 @@ void vdp_cmd_wr(VDP *vdp, uint8_t val)
|
|||||||
vdp->tms.curaddr = TMS_VRAM_SIZE + (vdp->tms.cmdlsb&0x1f);
|
vdp->tms.curaddr = TMS_VRAM_SIZE + (vdp->tms.cmdlsb&0x1f);
|
||||||
} else {
|
} else {
|
||||||
tms_cmd_wr(&vdp->tms, val);
|
tms_cmd_wr(&vdp->tms, val);
|
||||||
|
vdp->tms.width = _is_mode4(vdp) ? 32*8 : 40*6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,13 +52,16 @@ void vdp_data_wr(VDP *vdp, uint8_t val)
|
|||||||
|
|
||||||
uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
|
uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
|
||||||
{
|
{
|
||||||
if (x >= VDP_SCREENW) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (y >= VDP_SCREENH) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
TMS9918 *tms = &vdp->tms;
|
TMS9918 *tms = &vdp->tms;
|
||||||
|
if (!_is_mode4(vdp)) {
|
||||||
|
return tms_pixel(tms, x, y);
|
||||||
|
}
|
||||||
|
if (x >= tms->width) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (y >= tms->height) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// name table offset
|
// name table offset
|
||||||
uint16_t offset = (tms->regs[2] & 0xe) << 10;
|
uint16_t offset = (tms->regs[2] & 0xe) << 10;
|
||||||
offset += ((y/8) << 6) + ((x/8) << 1);
|
offset += ((y/8) << 6) + ((x/8) << 1);
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#include "tms9918.h"
|
#include "tms9918.h"
|
||||||
|
|
||||||
#define VDP_CRAM_SIZE 0x20
|
#define VDP_CRAM_SIZE 0x20
|
||||||
#define VDP_SCREENW (32*8)
|
|
||||||
#define VDP_SCREENH (24*8)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TMS9918 tms;
|
TMS9918 tms;
|
||||||
|
@ -1,12 +1,34 @@
|
|||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "tms9918.h"
|
#include "tms9918.h"
|
||||||
|
|
||||||
|
static uint8_t COLORS[0x10] = { // TODO: put actual color codes
|
||||||
|
0, // transparent
|
||||||
|
0, // black
|
||||||
|
1, // medium green
|
||||||
|
1, // light green
|
||||||
|
1, // dark blue
|
||||||
|
1, // light blue
|
||||||
|
1, // dark red
|
||||||
|
1, // cyan
|
||||||
|
1, // medium red
|
||||||
|
1, // light red
|
||||||
|
1, // dark yellow
|
||||||
|
1, // light yellow
|
||||||
|
1, // dark green
|
||||||
|
1, // magenta
|
||||||
|
1, // gray
|
||||||
|
1, // white
|
||||||
|
};
|
||||||
|
|
||||||
void tms_init(TMS9918 *tms)
|
void tms_init(TMS9918 *tms)
|
||||||
{
|
{
|
||||||
memset(tms->vram, 0, TMS_VRAM_SIZE);
|
memset(tms->vram, 0, TMS_VRAM_SIZE);
|
||||||
memset(tms->regs, 0, 0x10);
|
memset(tms->regs, 0, 0x10);
|
||||||
tms->has_cmdlsb = false;
|
tms->has_cmdlsb = false;
|
||||||
tms->curaddr = 0;
|
tms->curaddr = 0;
|
||||||
|
tms->width = 40*6;
|
||||||
|
tms->height = 24*8;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tms_cmd_rd(TMS9918 *tms)
|
uint8_t tms_cmd_rd(TMS9918 *tms)
|
||||||
@ -50,5 +72,19 @@ void tms_data_wr(TMS9918 *tms, uint8_t val)
|
|||||||
// Returns a 8-bit RGB value (0b00bbggrr)
|
// Returns a 8-bit RGB value (0b00bbggrr)
|
||||||
uint8_t tms_pixel(TMS9918 *tms, uint16_t x, uint16_t y)
|
uint8_t tms_pixel(TMS9918 *tms, uint16_t x, uint16_t y)
|
||||||
{
|
{
|
||||||
return 0; // no TMS9918 mode implemented yet
|
if ((tms->regs[1]&0x18) == 0x10 && (tms->regs[0]&0x40) == 0) {
|
||||||
|
// Text mode
|
||||||
|
uint16_t nameoff = (tms->regs[2] & 0xf) << 10;
|
||||||
|
uint16_t patternoff = (tms->regs[4] & 0x7) << 11;
|
||||||
|
uint8_t nameid = tms->vram[nameoff+(((y/8) * 40) + (x/6))];
|
||||||
|
uint8_t patternline = tms->vram[patternoff+(nameid*8)+(y%8)];
|
||||||
|
uint8_t color = tms->regs[7];
|
||||||
|
if ((patternline>>(8-(x%6)))&1) {
|
||||||
|
color >>= 4;
|
||||||
|
}
|
||||||
|
color &= 0xf;
|
||||||
|
return color;
|
||||||
|
} else { // unsupported mode
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ typedef struct {
|
|||||||
uint8_t cmdlsb;
|
uint8_t cmdlsb;
|
||||||
bool has_cmdlsb;
|
bool has_cmdlsb;
|
||||||
uint16_t curaddr;
|
uint16_t curaddr;
|
||||||
|
uint16_t width; // in pixels
|
||||||
|
uint16_t height; // in pixels
|
||||||
} TMS9918;
|
} TMS9918;
|
||||||
|
|
||||||
void tms_init(TMS9918 *tms);
|
void tms_init(TMS9918 *tms);
|
||||||
|
Loading…
Reference in New Issue
Block a user