Skip to content

Commit

Permalink
Merge pull request #6 from bjt42/wip
Browse files Browse the repository at this point in the history
Pull 1.4 from wip
  • Loading branch information
bjt42 committed Jul 26, 2013
2 parents e1fa59b + c3d1373 commit e1b134b
Show file tree
Hide file tree
Showing 13 changed files with 228 additions and 89 deletions.
6 changes: 3 additions & 3 deletions README
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
----------------------------------------------
SoftMPU 1.3 by bjt - Software MPU-401 Emulator
SoftMPU 1.4 by bjt - Software MPU-401 Emulator
----------------------------------------------
Copyright (C) 2013 bjt
Copyright (C) 2002-2013 The DOSBox Team
----------------------------------------------

Release Notes (09/07/13)
Release Notes (26/07/13)

WHAT IS IT?

Expand All @@ -24,7 +24,7 @@ work with the basic MPU interface found on sound cards.

REQUIREMENTS

- MS-DOS 6.0 or later. SoftMPU will not work from within Windows
- MS-DOS 6.2 or later. SoftMPU will not work from within Windows
- EMM386 must be loaded
- Sound Blaster (or compatible) sound card with an MPU-401 interface
supporting UART mode (e.g. Sound Blaster 16/AWE, Yamaha YMF71x)
Expand Down
Binary file modified SOFTMPU.EXE
Binary file not shown.
32 changes: 32 additions & 0 deletions SRC/APPSTR.ASM
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
;
; Copyright (C) 2013 bjt
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
;

; ------------------------------------------
; SoftMPU by bjt - Software MPU-401 Emulator
; ------------------------------------------
;
; App ID substrings
;

; Disable SB interrupts for these intelligent mode apps
AppIDStrings DB 'FB.E' ; Flashback
DB 'MM3.' ; Might and Magic III
DB 'SOC.' ; Sensible Soccer
DB 'UNVG' ; Waxworks
DB 'WC2.' ; Wing Commander II
DB 00h ; End
1 change: 1 addition & 0 deletions SRC/EXPORT.H
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef enum EventID {MPU_EVENT,RESET_DONE,EOI_HANDLER,NUM_EVENTS} EventID;
void PIC_Update(bool blocking);

void MPU401_Init(Bitu sbport,Bitu irq,Bitu mpuport,bool delaysysex);
void MPU401_SetEnableSBIRQ(bool enable);
Bitu MPU401_ReadStatus(void);
void MPU401_WriteCommand(Bitu val);
Bitu MPU401_ReadData(void);
Expand Down
81 changes: 58 additions & 23 deletions SRC/INTHAND.ASM
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
; SoftMPU by bjt - Software MPU-401 Emulator
; ------------------------------------------
;
; RTC, SB DMA and IRQ 2/8 Watchdog interrupt handlers
; RTC, SB DMA, DOS exec and IRQ watchdog interrupt handlers
;

IntStackSize EQU 0100h ; 256 byte stack for handler
Expand Down Expand Up @@ -54,7 +54,7 @@ Int70Handler: ASSUME ds:_DATA ; Access local vars via
mov sp,ax

; Disable virtualised port access
mov NoVirtualise,1
mov VirtualisePorts,0
; Handle timer tick
; MPU lib has been initialised
Expand All @@ -68,7 +68,7 @@ Int70Handler: ASSUME ds:_DATA ; Access local vars via
popa

; Enable virtualised port access
mov NoVirtualise,0
mov VirtualisePorts,1
; Interrupts are still disabled
; Read status register C to clear pending interrupt
Expand Down Expand Up @@ -100,9 +100,15 @@ Int70Handler: ASSUME ds:_DATA ; Access local vars via

SBIntHandler: ASSUME ds:_DATA ; Access local vars via cs

; Ensure interrupts are disabled, in case something's chained us
; Early out if required
pushf
cli
cmp SBIRQGen,1
je @@SBIntHandler2
popf
jmp OldSBISR

; Ensure interrupts are disabled, in case something's chained us
@@SBIntHandler2:cli

; Save scratch registers
mov SavedAX,ax
Expand All @@ -118,7 +124,7 @@ SBIntHandler: ASSUME ds:_DATA ; Access local vars via
test al,01h ; 8-bit IRQ flag
jz @@ExitISR ; Was the interrupt meant for us?
mov SBDetected,1 ; Signal detection success
cmp NoSBEOI,1 ; Do we want to EOI?
cmp SBEOI,0 ; Do we want to EOI?
je @@ExitISR

; Acknowledge interrupt
Expand Down Expand Up @@ -159,45 +165,74 @@ TimerIntHandler:ASSUME ds:_DATA ; Access local vars via
jmp SHORT $+2 ; Enforce short pause between read & write
out 021h,al ; Set new mask

; Make sure IRQ 8 (RTC) is unmasked
; It's needed to drive the MPU timers
@@IRQ2OK: in al,0A1h ; Get current mask
test al,01h
jz @@IRQ8OK
and al,0FEh
jmp SHORT $+2 ; Enforce short pause between read & write
out 0A1h,al ; Set new mask

; Restore scratch registers
@@IRQ8OK: mov ax,SavedAX
@@IRQ2OK: mov ax,SavedAX

; Chained ISR will have already sent an EOI
iret ; Will restore int flag

DOSIntHandler: ASSUME ds:_DATA ; Access local vars via cs

; Check for exec call (4Bh)
; Check for exec call (AH=04Bh,AL=00h)
pushf
cmp ah,04Bh
jne @@ExitISR3
cmp al,0
jne @@ExitISR3

; Disable interrupts to keep setting changes atomic
cli

mov NoSBEOI,0 ; Reset SB EOI control
; Default settings
mov SBEOI,1 ; Enable SB EOI
mov SBIRQGen,1 ; Enable SB IRQ generation

; Parse filename for app detection substrings
push si
push eax
push ebx
mov si,dx
cld ; Auto increment si
@@ParseFilename:lodsd ; Get a dword from the filename
cmp al,0 ; Check for null terminator
je @@ExitISR2

; Should we disable EOI?
cmp eax,'.EGU' ; It Came From The Desert (HUGE.EXE)
je @@DisableSBEOI
sub si,3 ; Only step a byte at a time
jmp @@CheckIRQGen
@@DisableSBEOI: mov SBEOI,0 ; Don't send SB EOI

@@CheckIRQGen: ; Should we disable SB IRQ generation?
push ds
push si
mov ebx,eax ; Save comparison string
mov ax,cs
mov ds,ax ; Copy cs->ds for data access
mov si,OFFSET AppIDStrings
@@ParseAppStrings:
lodsd ; Get an ID string
cmp al,0 ; Check for null terminator
je @@ExitISR2
je @@NextChar
cmp eax,ebx
je @@DisableIRQGen ; Found a match
jmp @@ParseAppStrings
@@DisableIRQGen:mov SBIRQGen,0 ; Disable SB interrupts
@@NextChar: pop si
pop ds
sub si,3 ; Only step a byte at a time
jmp @@ParseFilename ; Next char

@@DisableSBEOI: mov NoSBEOI,1 ; Don't send SB EOI
@@ExitISR2: pop eax
@@ExitISR2: pop ebx
pop eax ; Finished parsing
pop si

; Now commit our changes
pusha
push ds
mov ax,SEG _DATA
mov ds,ax
INVOKE MPU401_SetEnableSBIRQ,SBIRQGen
pop ds
popa
@@ExitISR3: popf
jmp OldDOSISR
2 changes: 1 addition & 1 deletion SRC/MIDI.C
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ typedef int Bits;
#define SYSEX_SIZE 1024
#define RAWBUF 1024

static char* MIDI_welcome_msg="\xf0\x41\x10\x16\x12\x20\x00\x00 SoftMPU v1.3 \x2a\xf7"; /* SOFTMPU */
static char* MIDI_welcome_msg="\xf0\x41\x10\x16\x12\x20\x00\x00 SoftMPU v1.4 \x29\xf7"; /* SOFTMPU */

static Bit8u MIDI_evt_len[256] = {
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00
Expand Down
22 changes: 18 additions & 4 deletions SRC/MPU401.C
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ typedef enum MpuDataType MpuDataType; /* SOFTMPU */

static struct {
bool intelligent;
bool generate_irqs; /* SOFTMPU */
MpuMode mode;
Bitu sbport;
Bitu mpuport;
Expand Down Expand Up @@ -125,7 +126,7 @@ static struct {

static void QueueByte(Bit8u data) {
if (mpu.state.block_ack) {mpu.state.block_ack=false;return;}
if (mpu.queue_used==0 && mpu.intelligent) {
if (mpu.queue_used==0 && mpu.intelligent && mpu.generate_irqs) {
mpu.state.irq_pending=true;
PIC_ActivateIRQ(mpu.sbport); /* SOFTMPU */
}
Expand Down Expand Up @@ -298,7 +299,7 @@ void MPU401_WriteCommand(Bitu val) { /* SOFTMPU */
break;
case 0xff: /* Reset MPU-401 */
/*LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset %X",val);*/ /* SOFTMPU */
PIC_AddEvent(RESET_DONE,MPU401_RESETBUSY);
PIC_AddEvent(RESET_DONE,MPU401_RESETBUSY);
mpu.state.reset=true;
MPU401_Reset();
if (mpu.mode==M_UART) return;//do not send ack in UART mode
Expand All @@ -323,7 +324,7 @@ Bitu MPU401_ReadData(void) { /* SOFTMPU */
}
if (!mpu.intelligent) return ret;

if (mpu.queue_used == 0) PIC_DeActivateIRQ(mpu.sbport); /* SOFTMPU */
if ((mpu.queue_used == 0) && mpu.generate_irqs) PIC_DeActivateIRQ(mpu.sbport); /* SOFTMPU */

if (ret>=0xf0 && ret<=0xf7) { /* MIDI data request */
mpu.state.channel=ret&7;
Expand Down Expand Up @@ -670,6 +671,18 @@ static void MPU401_Reset(void) {
for (i=0;i<8;i++) {mpu.playbuf[i].type=T_OVERFLOW;mpu.playbuf[i].counter=0;}
}

/* SOFTMPU: Enable/disable SB IRQ generation */
void MPU401_SetEnableSBIRQ(bool enable)
{
if (mpu.generate_irqs && !enable)
{
// Acknowledge any waiting IRQ
PIC_DeActivateIRQ(mpu.sbport);
}

mpu.generate_irqs=enable;
}

/* SOFTMPU: Initialisation */
void MPU401_Init(Bitu sbport,Bitu irq,Bitu mpuport,bool delaysysex)
{
Expand All @@ -685,8 +698,9 @@ void MPU401_Init(Bitu sbport,Bitu irq,Bitu mpuport,bool delaysysex)
mpu.mode=M_UART;
mpu.sbport=sbport;
mpu.mpuport=mpuport;
mpu.generate_irqs=true; /* SOFTMPU */

mpu.intelligent = true; /* Default is on */
mpu.intelligent=true; /* Default is on */
if (!mpu.intelligent) return;

/* SOFTMPU: Moved IRQ 9 handler init to asm */
Expand Down
2 changes: 1 addition & 1 deletion SRC/PORTHAND.ASM
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ PortHandler: ASSUME ds:_TEXT ; PM handler, can't read
; So we won't worry about a context switch...
; Interrupts are disabled already in here as well
; If we're inside the interrupt handler, pass through port access
cmp NoVirtualise,0
cmp VirtualisePorts,1
je @@PortHandler2
stc ; Don't virtualise
retf
Expand Down
12 changes: 9 additions & 3 deletions SRC/RESIDENT.ASM
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ SBPortAddr DW 0
SBIRQ DB 0
DelaySysex DB 0

NoVirtualise DB 1 ; Port virtualisation control
NoSBEOI DB 0 ; SBISR EOI control
VirtualisePorts DB 0 ; Port virtualisation control
SBEOI DB 1 ; SB ISR EOI control
SBIRQGen DB 1 ; SB IRQ generation control

OldSBISR LABEL DWORD
OldSBISRAddr DW ?
Expand All @@ -58,9 +59,10 @@ SBDetected DB 0

; Following data needs to be 4-byte aligned
; Might need to add some padding here for detection to work
IDPad DB 0 DUP (?)
IDPad DB 3 DUP (?)
IDString DB '0S2M' ; Detection string

INCLUDE appstr.asm ; App ID substrings
INCLUDE inthand.asm ; Interrupt handlers
INCLUDE porthand.asm ; Port handler code

Expand All @@ -84,9 +86,13 @@ Start: push es
shl di,4 ; Calculate offset to resident end
mov ax,04A15h
mov bx,0
stc ; Fail by default
int 02Fh ; Install handler
pop ds ; Restore ds
jnc @@InitSoftMPU ; Init MPU lib
push es
mov ax,cs
mov es,ax ; Copy cs->es for var access from init
jmp FAR PTR EMMErr ; Fail

@@InitSoftMPU: INVOKE MPU401_Init,cs:SBPortAddr,cs:SBIRQ,cs:MPUDataPortAddr,cs:DelaySysex
Expand Down
5 changes: 5 additions & 0 deletions SRC/SOFTMPU.ASM
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
; - Merged latest DOSBox reset delay patch
; - Fixed "It Came From The Desert"
;
; 1.4
;
; - Fixed games with digital FX
; - Improved EMM386 detection
;
; ------------------------------------------

StackSize EQU 0400h ; 1k stack for init
Expand Down
6 changes: 4 additions & 2 deletions SRC/STRINGS.ASM
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Header DB 0DAh
DB 0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h
DB 0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h
DB 0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0BFh,0Dh,0Ah
DB 0B3h,'SoftMPU 1.3 by bjt ',0FEh,' Software MPU-401 Emulator',0B3h,0Dh,0Ah
DB 0B3h,'SoftMPU 1.4 by bjt ',0FEh,' Software MPU-401 Emulator',0B3h,0Dh,0Ah
DB 0B3h,' ',0B3h,0Dh,0Ah
DB 0B3h,'Copyright (C) 2013 bjt ',0B3h,0Dh,0Ah
DB 0B3h,'Copyright (C) 2002-2013 The DOSBox Team ',0B3h,0Dh,0Ah
Expand All @@ -39,7 +39,7 @@ Header DB 0DAh
DB 0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h
DB 0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0C4h
DB 0C4h,0C4h,0C4h,0C4h,0C4h,0C4h,0D9h,0Dh,0Ah,'$'
NoEMM DB '! Error: EMM386 is not available',0Dh,0Ah,'$'
NoEMM DB '! Error: EMM386 4.46 (or later) is not available',0Dh,0Ah,'$'
EMMError DB '! Error: Port trap failed. Please submit a bug report',0Dh,0Ah,'$'
LoadedError DB '! Error: SoftMPU is already loaded',0Dh,0Ah,'$'
RTCError DB '! Error: Real Time Clock support not detected',0Dh,0Ah,'$'
Expand All @@ -66,3 +66,5 @@ HelpText DB 'Usage: SOFTMPU /SB:nnn /IRQ:nn /MPU:nnn [/DELAY
DB ' /IRQ:nn Sound Blaster interrupt (2-11)',0Dh,0Ah
DB ' /MPU:nnn MPU-401 base I/O port address (220-350)',0Dh,0Ah
DB ' /DELAYSYSEX Prevent Rev.0 MT-32 buffer overflow',0Dh,0Ah,'$'
EMMDevice DB 'EMMXXXX0',00h
EMMDevice2 DB 'EMMQXXX0',00h
Loading

0 comments on commit e1b134b

Please sign in to comment.