From 7d568bd782e5b9502772e5f435a8ce2c069968d1 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Mon, 2 Nov 2020 18:53:57 -0500 Subject: [PATCH] sms: simplify and solidify ports-related drivers Add _TRA!, _THA!, _TRB!, _THB! routines to easily handle those pins' value without stepping on other pins like the drivers previously did. For SDC driver, it's going to be important soon because it turns out that I can't get away with "always on" CS, so I'll need a scheme where it's important that TH/TR pins have stable values. --- arch/z80/sms/blk/600 | 2 +- arch/z80/sms/blk/613 | 18 +++++------------- arch/z80/sms/blk/620 | 13 ++++++------- arch/z80/sms/blk/621 | 17 ++++++++--------- arch/z80/sms/blk/622 | 12 +++++------- arch/z80/sms/blk/625 | 15 +++++++++++++++ arch/z80/sms/blk/626 | 12 ++++++++++++ arch/z80/sms/xcomp.fs | 6 ++++-- arch/z80/sms/xcompkbd.fs | 41 +++++++++++++++++++++++++++++++++++++++++ arch/z80/sms/xcompsdc.fs | 44 ++++++++++++++++++++++++++++++++++++++++++++ emul/z80/sms.c | 7 ++++++- 11 files changed, 147 insertions(+), 40 deletions(-) create mode 100644 arch/z80/sms/blk/625 create mode 100644 arch/z80/sms/blk/626 create mode 100644 arch/z80/sms/xcompkbd.fs create mode 100644 arch/z80/sms/xcompsdc.fs diff --git a/arch/z80/sms/blk/600 b/arch/z80/sms/blk/600 index f9a9482..f24014a 100644 --- a/arch/z80/sms/blk/600 +++ b/arch/z80/sms/blk/600 @@ -1,4 +1,4 @@ Sega Master System Recipe 602 VDP 610 PAD -620 KBD +620 KBD 625 Ports diff --git a/arch/z80/sms/blk/613 b/arch/z80/sms/blk/613 index 11456d9..c6d4002 100644 --- a/arch/z80/sms/blk/613 +++ b/arch/z80/sms/blk/613 @@ -1,15 +1,7 @@ -CODE _status - A 0b11111101 LDri, ( TH output, unselected ) - PAD_CTLPORT OUTiA, - PAD_D1PORT INAi, - 0x3f ANDi, ( low 6 bits are good ) - H A LDrr, ( let's store them ) +: _status + 1 _THA! ( output, high/unselected ) + _D1@ 0x3f AND ( low 6 bits are good ) ( Start and A are returned when TH is selected, in bits 5 and 4. Well get them, left-shift them and integrate them to B. ) - A 0b11011101 LDri, ( TH output, selected ) - PAD_CTLPORT OUTiA, - PAD_D1PORT INAi, - 0b00110000 ANDi, - A SLA, A SLA, H ORr, - PUSHA, -;CODE + 0 _THA! ( output, low/selected ) + _D1@ 0x30 AND 2 LSHIFT OR ; diff --git a/arch/z80/sms/blk/620 b/arch/z80/sms/blk/620 index 1b1638d..164f362 100644 --- a/arch/z80/sms/blk/620 +++ b/arch/z80/sms/blk/620 @@ -4,10 +4,9 @@ is something to read. When the adapter is finished filling its '164 up, it resets the latch, which output's is connected to TL. When the '164 is full, TL is low. Port A TL is bit 4 ) - 0xdc PC@ 0x10 AND IF 0 EXIT ( nothing ) THEN - 0x3f PC@ DROP 0b11011101 ( Port A TH output, low ) 0x3f PC! - 0xdc PC@ ( bit 3:0 go in 3:0 ) 0x0f AND ( n ) - 0b11111101 ( Port A TH output, high ) 0x3f PC! - 0xdc PC@ ( bit 3:0 go in 7:4 ) 0x0f AND 4 LSHIFT OR ( n ) - ( Port A/B reset ) 0xff 0x3f PC! -; + _D1@ 0x10 AND IF 0 EXIT ( nothing ) THEN + 0 _THA! ( Port A TH output, low ) + _D1@ ( bit 3:0 go in 3:0 ) 0x0f AND ( n ) + 1 _THA! ( Port A TH output, high ) + _D1@ ( bit 3:0 go in 7:4 ) 0x0f AND 4 LSHIFT OR ( n ) + 2 _THA! ( TH input ) ; diff --git a/arch/z80/sms/blk/621 b/arch/z80/sms/blk/621 index 6574f05..dce6c26 100644 --- a/arch/z80/sms/blk/621 +++ b/arch/z80/sms/blk/621 @@ -1,11 +1,10 @@ : (ps2kcB) ( for port B ) ( Port B TL is bit 2 ) - 0xdd PC@ 0x04 AND IF 0 EXIT ( nothing ) THEN - 0x3f PC@ DROP 0b01110111 ( Port B TH output, low ) 0x3f PC! - 0xdc PC@ ( bit 7:6 go in 1:0 ) 6 RSHIFT ( n ) - 0xdd PC@ ( bit 1:0 go in 3:2 ) 0x03 AND 2 LSHIFT OR ( n ) - 0b11110111 ( Port B TH output, high ) 0x3f PC! - 0xdc PC@ ( bit 7:6 go in 5:4 ) 0xc0 AND 2 RSHIFT OR ( n ) - 0xdd PC@ ( bit 1:0 go in 7:6 ) 0x03 AND 6 LSHIFT OR ( n ) - ( Port A/B reset ) 0xff 0x3f PC! -; + _D2@ 0x04 AND IF 0 EXIT ( nothing ) THEN + 0 _THB! ( Port B TH output, low ) + _D1@ ( bit 7:6 go in 1:0 ) 6 RSHIFT ( n ) + _D2@ ( bit 1:0 go in 3:2 ) 0x03 AND 2 LSHIFT OR ( n ) + 1 _THB! ( Port B TH output, high ) + _D1@ ( bit 7:6 go in 5:4 ) 0xc0 AND 2 RSHIFT OR ( n ) + _D2@ ( bit 1:0 go in 7:6 ) 0x03 AND 6 LSHIFT OR ( n ) + 2 _THB! ( TH input ) ; diff --git a/arch/z80/sms/blk/622 b/arch/z80/sms/blk/622 index f8742ac..ae1b24e 100644 --- a/arch/z80/sms/blk/622 +++ b/arch/z80/sms/blk/622 @@ -1,12 +1,10 @@ : (spie) DROP ; ( always enabled ) : (spix) ( x -- x, for port B ) 0 SWAP ( rx tx ) 8 0 DO - ( send bit 7 to bit 6, TR's output bit ) - DUP 1 RSHIFT 0x40 AND ( rx tx bits ) 0x80 OR ( CLK hi ) - 0x3f PC@ OR 0xf3 AND ( TH and TR output ) - DUP 0x3f PC! ( rx tx bits ) - ( CLK low ) 0x7f AND 0x3f PC! ( rx tx ) - ( shift tx ) 1 LSHIFT ( rx tx<< ) - ( read into rx ) SWAP 1 LSHIFT 0xdc PC@ ( tx<< rx<< x ) + ( send current bit to TRB, TR's output bit ) + DUP 7 I - RSHIFT 1 AND _TRB! + 1 _THB! ( CLK hi ) + 0 _THB! ( CLK lo ) + ( read into rx ) SWAP 1 LSHIFT _D1@ ( tx rx<< x ) ( out bit is the 6th ) 6 RSHIFT 1 AND OR SWAP LOOP ( rx tx ) DROP ; diff --git a/arch/z80/sms/blk/625 b/arch/z80/sms/blk/625 new file mode 100644 index 0000000..ece50a1 --- /dev/null +++ b/arch/z80/sms/blk/625 @@ -0,0 +1,15 @@ +( Routines for interacting with SMS controller ports. + Requires CPORT_CTL, CPORT_D1 and CPORT_D2 to be defined. + Will usually be 0x3f, 0xdc, 0xdd. ) +( mode -- set TR pin on mode a on: +0= output low 1=output high 2=input ) +CODE _TRA! HL POP, chkPS, ( B0 -> B4, B1 -> B0 ) + L RR, RLA, RLA, RLA, RLA, L RR, RLA, + 0x11 ANDi, L A LDrr, CPORT_CTL INAi, + 0xee ANDi, L ORr, CPORT_CTL OUTiA, +;CODE +CODE _THA! HL POP, chkPS, ( B0 -> B5, B1 -> B1 ) + L RR, RLA, RLA, RLA, RLA, L RR, RLA, RLA, + 0x22 ANDi, L A LDrr, CPORT_CTL INAi, + 0xdd ANDi, L ORr, CPORT_CTL OUTiA, +;CODE diff --git a/arch/z80/sms/blk/626 b/arch/z80/sms/blk/626 new file mode 100644 index 0000000..8d9c2d6 --- /dev/null +++ b/arch/z80/sms/blk/626 @@ -0,0 +1,12 @@ +CODE _TRB! HL POP, chkPS, ( B0 -> B6, B1 -> B2 ) + L RR, RLA, RLA, RLA, RLA, L RR, RLA, RLA, RLA, + 0x44 ANDi, L A LDrr, CPORT_CTL INAi, + 0xbb ANDi, L ORr, CPORT_CTL OUTiA, +;CODE +CODE _THB! HL POP, chkPS, ( B0 -> B7, B1 -> B3 ) + L RR, RLA, RLA, RLA, RLA, L RR, RLA, RLA, RLA, RLA, + 0x88 ANDi, L A LDrr, CPORT_CTL INAi, + 0x77 ANDi, L ORr, CPORT_CTL OUTiA, +;CODE +CODE _D1@ CPORT_D1 INAi, PUSHA, ;CODE +CODE _D2@ CPORT_D2 INAi, PUSHA, ;CODE diff --git a/arch/z80/sms/xcomp.fs b/arch/z80/sms/xcomp.fs index 4404912..2f7f2a7 100644 --- a/arch/z80/sms/xcomp.fs +++ b/arch/z80/sms/xcomp.fs @@ -10,8 +10,9 @@ SYSVARS 0x70 + CONSTANT VDP_MEM 32 CONSTANT VDP_COLS 24 CONSTANT VDP_ROWS SYSVARS 0x72 + CONSTANT PAD_MEM -0x3f CONSTANT PAD_CTLPORT -0xdc CONSTANT PAD_D1PORT +0x3f CONSTANT CPORT_CTL +0xdc CONSTANT CPORT_D1 +0xdd CONSTANT CPORT_D2 5 LOAD ( z80 assembler ) : ZFILL, ( u ) 0 DO 0 A, LOOP ; 262 LOAD ( xcomp ) @@ -28,6 +29,7 @@ CURRENT @ XCURRENT ! 353 LOAD ( xcomp core low ) CREATE ~FNT CPFNT7x7 603 608 LOADR ( VDP ) +625 626 LOADR ( SMS ports ) 612 617 LOADR ( PAD ) 390 LOAD ( xcomp core high ) (entry) _ diff --git a/arch/z80/sms/xcompkbd.fs b/arch/z80/sms/xcompkbd.fs new file mode 100644 index 0000000..d708b20 --- /dev/null +++ b/arch/z80/sms/xcompkbd.fs @@ -0,0 +1,41 @@ +( xcomp for a SMS with PS/2 keyboard on port A ) +( 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 +SYSVARS 0x70 + CONSTANT VDP_MEM +0xbf CONSTANT VDP_CTLPORT +0xbe CONSTANT VDP_DATAPORT +32 CONSTANT VDP_COLS +24 CONSTANT VDP_ROWS +SYSVARS 0x72 + CONSTANT PS2_MEM +0x3f CONSTANT CPORT_CTL +0xdc CONSTANT CPORT_D1 +0xdd CONSTANT CPORT_D2 +5 LOAD ( z80 assembler ) +: ZFILL, ( u ) 0 DO 0 A, LOOP ; +262 LOAD ( xcomp ) +524 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 CPFNT7x7 +603 608 LOADR ( VDP ) +625 626 LOADR ( SMS ports ) +620 LOAD ( PAD ) : (ps2kc) (ps2kcA) ; 411 414 LOADR +390 LOAD ( xcomp core high ) +(entry) _ +( Update LATEST ) +PC ORG @ 8 + ! +," VDP$ PS2$ (im1) " EOT, +ORG @ 0x100 - 256 /MOD 2 PC! 2 PC! +H@ 256 /MOD 2 PC! 2 PC! diff --git a/arch/z80/sms/xcompsdc.fs b/arch/z80/sms/xcompsdc.fs new file mode 100644 index 0000000..27a17b2 --- /dev/null +++ b/arch/z80/sms/xcompsdc.fs @@ -0,0 +1,44 @@ +( xcomp for a SMS with PS/2 keyboard on port A and SPI relay + on port B, with SD card attached ) +( 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 +SYSVARS 0x70 + CONSTANT VDP_MEM +0xbf CONSTANT VDP_CTLPORT +0xbe CONSTANT VDP_DATAPORT +32 CONSTANT VDP_COLS +24 CONSTANT VDP_ROWS +SYSVARS 0x72 + CONSTANT PS2_MEM +0x3f CONSTANT CPORT_CTL +0xdc CONSTANT CPORT_D1 +0xdd CONSTANT CPORT_D2 +5 LOAD ( z80 assembler ) +: ZFILL, ( u ) 0 DO 0 A, LOOP ; +262 LOAD ( xcomp ) +524 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 CPFNT7x7 +603 608 LOADR ( VDP ) +625 626 LOADR ( SMS ports ) +620 LOAD ( PAD ) : (ps2kc) (ps2kcA) ; 411 414 LOADR +622 LOAD ( SPI ) +1 CONSTANT SDC_DEVID 423 436 LOADR ( SDC ) +390 LOAD ( xcomp core high ) +(entry) _ +( Update LATEST ) +PC ORG @ 8 + ! +," VDP$ PS2$ BLK$ (im1) " EOT, +ORG @ 0x100 - 256 /MOD 2 PC! 2 PC! +H@ 256 /MOD 2 PC! 2 PC! diff --git a/emul/z80/sms.c b/emul/z80/sms.c index 23b31d6..48215c7 100644 --- a/emul/z80/sms.c +++ b/emul/z80/sms.c @@ -76,6 +76,11 @@ static uint8_t iord_kbd() return kbd_rd(&kbd); } +static uint8_t iord_ports_ctl() +{ + return ports_ctl_rd(&ports); +} + static void iowr_vdp_cmd(uint8_t val) { vdp_cmd_wr(&vdp, val); @@ -357,7 +362,7 @@ int main(int argc, char *argv[]) m->iord[VDP_DATA_PORT] = iord_vdp_data; m->iord[PORTS_IO1_PORT] = iord_ports_io1; m->iord[PORTS_IO2_PORT] = iord_ports_io2; - m->iord[PORTS_CTL_PORT] = iord_noop; + m->iord[PORTS_CTL_PORT] = iord_ports_ctl; m->iowr[VDP_CMD_PORT] = iowr_vdp_cmd; m->iowr[VDP_DATA_PORT] = iowr_vdp_data; m->iowr[PORTS_CTL_PORT] = iowr_ports_ctl;