diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index ef9997b0..595d7cce 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -29,6 +29,7 @@ Version 3.6 - WBW: Preliminary support for S100 Computers Z80 CPU - HJB: Added MSX platform - M?R: Update Timer app with "zero" option +- HJB: Update PPIDE driver, add support for MSX BEER IDE interface Version 3.5.1 ------------- diff --git a/Source/Doc/Hardware.md b/Source/Doc/Hardware.md index 36b1b553..8c9beaa4 100644 --- a/Source/Doc/Hardware.md +++ b/Source/Doc/Hardware.md @@ -631,6 +631,8 @@ It also has an interface to the RetroBrew bus (ECB) for access to additional per Support for standard MSX hardware by Henk Berends +The default configuration is for a European MSX 2 (PAL) with international keyboard and 512KB RAM Mapper extension. + #### ROM Image File: MSX_std.rom | | | @@ -654,10 +656,16 @@ Support for standard MSX hardware by Henk Berends - MD: TYPE=RAM - IDE: MODE=RC, IO=16, MASTER - IDE: MODE=RC, IO=16, SLAVE +- PPIDE: MODE=MSX_BEER, IO=48, MASTER +- PPIDE: MODE=MSX_BEER, NO SLAVE - AY38910: MODE=MSX, IO=160, CLOCK=1789772 HZ #### Notes: +- MSX 1 can be used with the TMS VDP set to 40 columns mode. +- Storage options are the BEER IDE and SODA IDE interfaces. +- Serial option is a 16550 UART interface. + `\clearpage`{=latex} ## NABU w/ RomWBW Option Board diff --git a/Source/HBIOS/Config/MSX_std.asm b/Source/HBIOS/Config/MSX_std.asm index 5d673eca..04dd6b76 100644 --- a/Source/HBIOS/Config/MSX_std.asm +++ b/Source/HBIOS/Config/MSX_std.asm @@ -82,7 +82,7 @@ VRCENABLE .SET FALSE ; VRC: ENABLE VGARC VIDEO/KBD DRIVER (VRC.ASM) EFENABLE .SET FALSE ; EF: ENABLE EF9345 VIDEO DRIVER (EF.ASM) FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) IDEENABLE .SET TRUE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) (MSX_NOTE: REQUIRES SODA IDE CART) -PPIDEENABLE .SET FALSE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) SDENABLE .SET FALSE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) CHENABLE .SET FALSE ; CH: ENABLE CH375/376 USB SUPPORT PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) diff --git a/Source/HBIOS/cfg_MSX.asm b/Source/HBIOS/cfg_MSX.asm index a75e7179..123fb35a 100644 --- a/Source/HBIOS/cfg_MSX.asm +++ b/Source/HBIOS/cfg_MSX.asm @@ -302,18 +302,18 @@ IDE2DATHI .SET $00 ; IDE 2: DATA HI PORT FOR 16-BIT I/O IDE2A8BIT .SET TRUE ; IDE 2A (MASTER): 8 BIT XFER IDE2B8BIT .SET TRUE ; IDE 2B (MASTER): 8 BIT XFER ; -PPIDEENABLE .SET FALSE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) PPIDETRACE .SET 1 ; PPIDE: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) PPIDECNT .SET 1 ; PPIDE: NUMBER OF PPI CHIPS TO DETECT (1-3), 2 DRIVES PER CHIP -PPIDE0MODE .SET PPIDEMODE_STD ; PPIDE 0: DRIVER MODE: IDEMODE_[STD|S100A|S100B] +PPIDE0MODE .SET PPIDEMODE_MSX ; PPIDE 0: DRIVER MODE: IDEMODE_[STD|S100A|S100B|MSX] PPIDE0BASE .SET $30 ; PPIDE 0: PPI REGISTERS BASE ADR PPIDE0A8BIT .SET FALSE ; PPIDE 0A (MASTER): 8 BIT XFER PPIDE0B8BIT .SET FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER -PPIDE1MODE .SET PPIDEMODE_STD ; PPIDE 1: DRIVER MODE: IDEMODE_[STD|S100A|S100B] +PPIDE1MODE .SET PPIDEMODE_MSX ; PPIDE 1: DRIVER MODE: IDEMODE_[STD|S100A|S100B|MSX] PPIDE1BASE .SET $00 ; PPIDE 1: PPI REGISTERS BASE ADR PPIDE1A8BIT .SET FALSE ; PPIDE 1A (MASTER): 8 BIT XFER PPIDE1B8BIT .SET FALSE ; PPIDE 0B (SLAVE): 8 BIT XFER -PPIDE2MODE .SET PPIDEMODE_STD ; PPIDE 2: DRIVER MODE: IDEMODE_[STD|S100A|S100B] +PPIDE2MODE .SET PPIDEMODE_MSX ; PPIDE 2: DRIVER MODE: IDEMODE_[STD|S100A|S100B|MSX] PPIDE2BASE .SET $00 ; PPIDE 2: PPI REGISTERS BASE ADR PPIDE2A8BIT .SET FALSE ; PPIDE 2A (MASTER): 8 BIT XFER PPIDE2B8BIT .SET FALSE ; PPIDE 2B (SLAVE): 8 BIT XFER diff --git a/Source/HBIOS/ppide.asm b/Source/HBIOS/ppide.asm index 633101fb..541d320f 100644 --- a/Source/HBIOS/ppide.asm +++ b/Source/HBIOS/ppide.asm @@ -30,11 +30,32 @@ PPIDE_DIR_WRITE .EQU %10000000 ; IDE BUS DATA OUTPUT MODE PPIDE_CTL_DA0 .EQU %00000001 ; DRIVE ADDRESS BUS - BIT 0 (DA0) PPIDE_CTL_DA1 .EQU %00000010 ; DRIVE ADDRESS BUS - BIT 1 (DA1) PPIDE_CTL_DA2 .EQU %00000100 ; DRIVE ADDRESS BUS - BIT 2 (DA2) +; +; MSX_NOTE: +; CONTROL SIGNALS ARE NOT INVERTED, CS3 and DRIVE RESET SIGNALS NOT IMPLEMENTED +; SETTING THE DIRECTION OF THE PORTS WILL RESET THE OUTPUT PORTS I.E. CONTROL SIGNALS +; PPI IDE CONTROL BIT: +; 0 IDE REGISTER BIT 0 +; 1 IDE REGISTER BIT 1 +; 2 IDE REGISTER BIT 2 +; 3 NOT USED +; 4 NOT USED +; 5 /CS SELECT +; 6 /WR WRITE DATA +; 7 /RD READ DATA +; +#IF (PPIDE0MODE == PPIDEMODE_MSX) +PPIDE_CTL_CS1 .EQU %11000000 ; DRIVE CHIP SELECT 0 (ACTIVE LOW) +PPIDE_CTL_DIOW .EQU %01000000 ; DRIVE I/O WRITE (ACTIVE LOW) +PPIDE_CTL_DIOR .EQU %10000000 ; DRIVE I/O READ (ACTIVE LOW) +PPIDE_IDLE .EQU %11100111 ; SET DRIVE IN IDLE STATE +#ELSE PPIDE_CTL_CS1 .EQU %00001000 ; DRIVE CHIP SELECT 0 (ACTIVE LOW, INVERTED) PPIDE_CTL_CS3 .EQU %00010000 ; DRIVE CHIP SELECT 1 (ACTIVE LOW, INVERTED) PPIDE_CTL_DIOW .EQU %00100000 ; DRIVE I/O WRITE (ACTIVE LOW, INVERTED) PPIDE_CTL_DIOR .EQU %01000000 ; DRIVE I/O READ (ACTIVE LOW, INVERTED) PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) +#ENDIF ; ; +-----------------------------------------------------------------------+ ; | CONTROL BLOCK REGISTERS (CS3FX) | @@ -140,9 +161,11 @@ PPIDE_REG_BCL .EQU PPIDE_CTL_CS1 | $04 ; PKT BYTE COUNT LOW (BITS 0-7) (R/W) PPIDE_REG_BCH .EQU PPIDE_CTL_CS1 | $05 ; PKT BYTE COUNT HIGH (BITS 8-15) (R/W) PPIDE_REG_STAT .EQU PPIDE_CTL_CS1 | $07 ; STATUS REGISTER (R) PPIDE_REG_CMD .EQU PPIDE_CTL_CS1 | $07 ; COMMAND REGISTER (EXECUTE) (W) +#IF (PPIDE0MODE != PPIDEMODE_MSX) PPIDE_REG_ALTSTAT .EQU PPIDE_CTL_CS3 | $06 ; ALTERNATE STATUS REGISTER (R) PPIDE_REG_CTRL .EQU PPIDE_CTL_CS3 | $06 ; DEVICE CONTROL REGISTER (W) PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3 | $07 ; DRIVE ADDRESS REGISTER (R) +#ENDIF ; ; COMMAND BYTES ; @@ -244,6 +267,9 @@ PPIDE_DEV0M: ; DEVICE 0, MASTER #ENDIF #IF (PPIDE0MODE == PPIDEMODE_S100B) DEVECHO "S100B" + #ENDIF + #IF (PPIDE0MODE == PPIDEMODE_MSX) + DEVECHO "MSX_BEER" #ENDIF DEVECHO ", IO=" DEVECHO PPIDE0BASE @@ -253,7 +279,11 @@ PPIDE_DEV0M: ; DEVICE 0, MASTER PPIDE_DEV0S: ; DEVICE 0, SLAVE .DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) .DB PPIDE0MODE ; DRIVER DEVICE MODE + #IF (PPIDE0MODE == PPIDEMODE_MSX) + .DB PPIDE_STNOMEDIA ; SLAVE UNIT NOT SUPPORTED + #ELSE .DB 0 ; DEVICE STATUS + #ENDIF .DB 0 ; DEVICE TYPE .DB (PPIDE0B8BIT & PPIDE_ACC_8BIT) ; UNIT ACCESS FLAGS .DB 0 ; MEDIA FLAGS @@ -277,14 +307,18 @@ PPIDE_DEV0S: ; DEVICE 0, SLAVE #IF (PPIDE0MODE == PPIDEMODE_S100B) DEVECHO "S100B" #ENDIF + #IF (PPIDE0MODE == PPIDEMODE_MSX) + DEVECHO "MSX_BEER, NO SLAVE\n" + #ELSE DEVECHO ", IO=" DEVECHO PPIDE0BASE DEVECHO ", SLAVE" DEVECHO "\n" + #ENDIF ; #ENDIF ; -#IF (PPIDECNT >= 2) +#IF (PPIDECNT >= 2) & (PPIDE1MODE != PPIDEMODE_MSX) ; PPIDE_DEV1M: ; DEVICE 1, MASTER .DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) @@ -352,7 +386,7 @@ PPIDE_DEV1S: ; DEVICE 1, SLAVE ; #ENDIF ; -#IF (PPIDECNT >= 3) +#IF (PPIDECNT >= 3) & (PPIDE2MODE != PPIDEMODE_MSX) ; PPIDE_DEV2M: ; DEVICE 2, MASTER .DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) @@ -500,10 +534,13 @@ PPIDE_INIT2B: PPIDE_INIT3: CALL PPIDE_RESET ; RESET THE BUS CALL PPIDE_INIT5 ; DETECT/INIT MASTER +; MSX_NOTE: SLAVE UNIT NOT SUPPORTED +#IF (PPIDE0MODE != PPIDEMODE_MSX) PUSH IY ; SAVE CFG PTR CALL PPIDE_GOPARTNER ; SWITCH IY TO PARTNER CFG CALL PPIDE_INIT5 ; DETECT/INIT SLAVE POP IY ; RESTORE CFG PTR +#ENDIF ; PPIDE_INIT4: LD DE,PPIDE_CFGSIZ ; SIZE OF CFG TABLE ENTRY @@ -584,6 +621,13 @@ PPIDE_DETECT: ; WE ARE IN WRITE MODE, AN IDE CONTROLLER WILL NOT BE ABLE TO ; INTERFERE WITH THE VALUE BEING READ. ; +#IF (PPIDE0MODE == PPIDEMODE_MSX) + ; SETTING THE DIRECTION WILL RESET THE CONTROL SIGNALS + LD A,$A5 + CALL PPIDE_OUT ; USE THE CORRECT SIGNAL SEQUENCE + .DB PPIDE_REG_DATA + LD C,(IY+PPIDE_DATALO) ; PPI PORT A, DATALO +#ELSE LD A,PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE LD C,(IY+PPIDE_PPI) ; PPI CONTROL WORD EZ80_IO @@ -593,6 +637,7 @@ PPIDE_DETECT: LD A,$A5 ; TEST VALUE EZ80_IO OUT (C),A ; PUSH VALUE TO PORT +#ENDIF EZ80_IO IN A,(C) ; GET PORT VALUE #IF (PPIDETRACE >= 3) @@ -1221,6 +1266,15 @@ PPIDE_GET: PRTS(" GET$") #ENDIF ; +#IF (PPIDE0MODE == PPIDEMODE_MSX) + ; FIRST SETUP THE PPI TO READ THEN WAIT FOR BUFFER + ; + ; SETUP PPI TO READ + LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ + LD C,(IY+PPIDE_PPI) ; PPI CONTROL WORD + EZ80_IO + OUT (C),A ; WRITE IT + ; ; WAIT FOR BUFFER PUSH BC PUSH HL @@ -1228,13 +1282,22 @@ PPIDE_GET: POP HL POP BC RET NZ ; BAIL OUT IF TIMEOUT -; +#ELSE + ; WAIT FOR BUFFER + PUSH BC + PUSH HL + CALL PPIDE_WAITDRQ ; WAIT FOR BUFFER READY + POP HL + POP BC + RET NZ ; BAIL OUT IF TIMEOUT + ; ; SETUP PPI TO READ LD A,PPIDE_DIR_READ ; SET DATA BUS DIRECTION TO READ ;OUT (PPIDE_REG_PPI),A ; DO IT LD C,(IY+PPIDE_PPI) ; PPI CONTROL WORD EZ80_IO OUT (C),A ; WRITE IT +#ENDIF ; ; SELECT READ/WRITE IDE REGISTER LD A,PPIDE_REG_DATA ; DATA REGISTER @@ -1319,6 +1382,25 @@ PPIDE_PUT: PRTS(" PUT$") #ENDIF ; +#IF (PPIDE0MODE == PPIDEMODE_MSX) + ; SETTING THE DIRECTION WILL RESET THE CONTROL SIGNALS + ; THE WORKAROUND FOR WRITE IS TO USE A SMALL DELAY INSTEAD OF WAITING FOR BUFFER READY + ; + ; SETUP PPI TO WRITE + LD A,PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE + LD C,(IY+PPIDE_PPI) ; PPI CONTROL WORD + EZ80_IO + OUT (C),A ; WRITE IT + ; + ; SMALL DELAY FOR BUFFER READY + PUSH BC + LD B,$30 +WR_WAIT: + EX (SP),HL + EX (SP),HL + DJNZ WR_WAIT + POP BC +#ELSE ; WAIT FOR BUFFER PUSH BC PUSH HL @@ -1326,13 +1408,14 @@ PPIDE_PUT: POP HL POP BC RET NZ ; BAIL OUT IF TIMEOUT -; + ; ; SETUP PPI TO WRITE LD A,PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE ;OUT (PPIDE_REG_PPI),A ; DO IT LD C,(IY+PPIDE_PPI) ; PPI CONTROL WORD EZ80_IO OUT (C),A ; WRITE IT +#ENDIF ; ; SELECT READ/WRITE IDE REGISTER LD A,PPIDE_REG_DATA ; DATA REGISTER @@ -1341,7 +1424,7 @@ PPIDE_PUT: EZ80_IO OUT (C),A ; DO IT LD E,A ; E := WRITE UNASSERTED - XOR PPIDE_CTL_DIOW ; SWAP THE READ LINE BIT + XOR PPIDE_CTL_DIOW ; SWAP THE WRITE LINE BIT LD D,A ; D := WRITE ASSERTED ; ; LOOP SETUP @@ -1448,6 +1531,12 @@ PPIDE_RESET: LD C,(IY+PPIDE_PPI) ; PPI CONTROL WORD EZ80_IO OUT (C),A ; WRITE IT +#IF (PPIDE0MODE == PPIDEMODE_MSX) + ; SET DRIVE TO IDLE + LD A,PPIDE_IDLE + DEC C + OUT (C),A +#ENDIF ; ; IF A DSKYNG IS ACTIVE AND IS ON THE SAME PPI PORT AS THE PPIDE BEING ; RESET, THEN THE DSKYNG WILL ALSO BE RESET. SO, THE RESET CODE IS @@ -1473,6 +1562,9 @@ PPIDE_RESET_PKD1: #IF (PPIDETRACE >= 3) PRTS(" HARD$") #ENDIF +; +; MSX_NOTE: RESET SIGNAL NOT IMPLEMENTED, /RESET OF PPI 8255 IS CONNECTED TO Z80 BUS /RESET +#IF (PPIDE0MODE != PPIDEMODE_MSX) LD A,PPIDE_CTL_RESET ;OUT (PPIDE_REG_CTL),A LD C,(IY+PPIDE_CTL) ; SET IDE ADDRESS @@ -1543,6 +1635,8 @@ PPIDE_RESET3: LD DE,20 ; DELAY 320US (SPEC IS >= 25US) CALL VDELAY ; +#ENDIF ; PPIDEMODE_MSX +; PPIDE_RESET5: LD HL,PPIDE_TONORM ; NORMAL TIMEOUT NOW LD (PPIDE_TIMEOUT),HL ; AND RESTORE IT @@ -1555,8 +1649,11 @@ PPIDE_RESET5: BIT 0,(IY+PPIDE_ACC) ; MASTER? CALL Z,PPIDE_GOPARTNER ; IF NOT, SWITCH TO MASTER CALL PPIDE_INITUNIT ; INIT CURRENT UNIT +; MSX_NOTE: SLAVE UNIT NOT SUPPORTED +#IF (PPIDE0MODE != PPIDEMODE_MSX) CALL PPIDE_GOPARTNER ; POINT TO SLAVE CALL PPIDE_INITUNIT ; INIT PARTNER UNIT +#ENDIF POP IY ; RECOVER ORIG CFG PTR ; XOR A ; SIGNAL SUCCESS @@ -2053,7 +2150,11 @@ PPIDE_IN: DEC C ; SET IDE ADDRESS ; 4TS EZ80_IO OUT (C),B ; SET ADDRESS LINES ; 12TS + #IF (PPIDE0MODE == PPIDEMODE_MSX) + RES 7,B ; CLEAR /READ BIT (READ ON) + #ELSE SET 6,B ; TURN ON READ BIT ; 8TS + #ENDIF EZ80_IO OUT (C),B ; ASSERT READ LINE ; 12TS ; @@ -2065,7 +2166,11 @@ PPIDE_IN: INC C ; 4TS INC C ; 4TS ; + #IF (PPIDE0MODE == PPIDEMODE_MSX) + LD B,PPIDE_IDLE ; SET DRIVE TO IDLE (READ OFF) + #ELSE RES 6,B ; CLEAR READ BIT ; 8TS + #ENDIF EZ80_IO OUT (C),B ; DEASSERT READ LINE ; 12TS POP BC ; RECOVER INCOMING BC ; 10TS @@ -2093,10 +2198,24 @@ PPIDE_OUT: DEC C ; SET IDE ADDRESS EZ80_IO OUT (C),B ; SET ADDRESS LINES +; +#IF (PPIDE0MODE == PPIDEMODE_MSX) + ; FIRST SEND DATA VALUE THEN ASSERT WRITE LINE + DEC C + DEC C + EZ80_IO + OUT (C),A ; SEND DATA VALUE TO DEVICE + INC C + INC C + RES 6,B ; CLEAR /WRITE BIT (WRITE ON) + EZ80_IO + OUT (C),B + LD B,PPIDE_IDLE ; SET DRIVE TO IDLE (WRITE OFF) +#ELSE SET 5,B ; TURN ON WRITE BIT EZ80_IO OUT (C),B ; ASSERT WRITE LINE -; + ; DEC C DEC C ;OUT (PPIDE_REG_DATALO),A ; SEND DATA VALUE TO DEVICE @@ -2104,8 +2223,9 @@ PPIDE_OUT: OUT (C),A ; SEND DATA VALUE TO DEVICE INC C INC C -; + ; RES 5,B ; CLEAR WRITE BIT +#ENDIF EZ80_IO OUT (C),B ; DEASSERT WRITE LINE POP BC ; RECOVER INCOMING BC diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 104a11a4..d6ef4a49 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -227,6 +227,7 @@ PPIDEMODE_NONE .EQU 0 PPIDEMODE_STD .EQU 1 ; STANDARD PPIDEMODE_S100A .EQU 2 ; S100 PRIMARY INTERFACE PPIDEMODE_S100B .EQU 3 ; S100 SECONDARY INTERFACE +PPIDEMODE_MSX .EQU 4 ; MSX BEER IDE INTERFACE ; ; SD MODE SELECTIONS ;