Motorola MDT 9100-386

Repurposing a 90s "secure" data terminal

Introduction

[To be written]

PC Speaker Sound

The PC Speaker in this system has a volume control and enable setting, and by default it seems to reset to off after a cold restart/boot. Enabling, the volume level, and key click sounds are controllable using a custom Windows 3.1 control panel SPKPNL.CPL provided by Motorola. The settings appear to be set using methods in C:\SYSSW\HWEVNT.DLL which exports a number of hardware related functions:

The library describes itself as "Hardware Event support library for Motorola Dolphin"

Of interest to us for controlling the PC Speaker are SETSPEAKERVOLUME, ENABLESPEAKER, SETKEYCLICKS, and possibly SETSPEAKERPOT. Disassembling the file the key port being accessed is 308h though the procedures for setting seem a bit overly complex, especially the volume setting.

The state of these settings is saved in MOTO_SYS.INI in the Windows folder:

[SPEAKER]
SPK_ENABLE=TRUE
SPK_VOLUME=15
KEY_CLICKS=TRUE
KEY_CLICK=TRUE

EnableSpeaker

This function is the simplest of them all, and a good spot to start. Skipping over the function prolog the key section is as follows:

	cli
	mov dx, 308h
	in  al, dx
	and al, 6Fh
	mov cx, [bp+06]
	cmp cx, 0
	jne skip
	or  al, 80h
skip:	out dx, al
	or  al, 10h
	out dx, al
	sti

From this we can gather a bit of information on the properties of port 308h. It's read/write for one, as well bit 4 (10h) seems that it might be important to be 0 when changing values, but returned to 1 after. The key bit for enabling the speaker is clearly bit 7 (80h). If we assume the parameter to EnableSpeaker to be a BOOLEAN then it would seem that bit 7 set disables the speaker and clear enables it, though this will be confirmed by testing.

SetSpeakerVolume

This function appears to be oddly complicated for it's functionality, involving x87 floating point instructions as well as looping through multiple OUT instructions in setting the value. The start is rather tame and the argument for the volume appears to be an integer argument as is limited to the range of 0 to 15:

	cmp WORD PTR [bp+06], 0Fh
	jbe skip
	mov WORD PTR [bp+06], 0Fh
skip:

What follows though seems a bit silly, the integer value is pushed onto the x87 stack (along with 3 empty words to turn it into a QWORD), then multiplied by the QWORD at DS:0378h (0x3FC1111111111111 = 0.13333333333333333 in double format), stored into SS:EDI, a complex function (5:0216h) is called which does too many floating point instructions to keep track of. I suspect this function is performing some kind of exponentiation. Then [edi] is reloaded and (5:0242h) converts it back to an integer in dx:ax with only ax being used. Before this computed value is used we get our first odd manipulation:

 	cli
	mov dx, 308h
	in  al, dx
	and al, 4Fh
	mov cx, 64h  ; 100 in decimal
	shl cx, 1    ; Now 200, why not just mov cx, 0C8h??
l:	xor al, 40h 
	out dx, al
	loop l

This appears to toggle the 6th bit 200 times after clearing bits 7, 5, and 4. (B0h)
After this the value calculated before is reloaded into cx, multipled by 2, then bit 5 is set and bit 6 is then toggled cx*2 times.

	mov cx, [bp+06]
	shl cx, 1
	or  al, 20h
l2:	xor al, 40h
	out dx, al
	loop l2

My interpretation of these events is that there's 100 levels of volume control and it is controlled by pulsing bit 6. When bit 5 is cleared pulsing bit 6 high then low decreases the volume by 1, and when it is high doing the same will increase the volume by 1. I believe the floating point code is converting the 16 levels from the windows control to the range of 0-100, possibly using a logarithmic/exponetial scale of some kind, though doing so would require reverse engineering the (5:216h) subroutine to know for sure.

SetSpeakerPot

This function is a bit mysterious as it takes no arguments, it simply changes a few bits in the 308h port:

	cli
	mov dx, 308h
	in  al, dx
	and al, 0EFh	
	out dx, al	; Clear bit 4 (enable changes?)
	or  al, 40h	; Set bit 6 (pulsed for volume control)
	out dx, al
	or  al, 10h	; Set bit 4 
	out dx, al
	sti

Much like EnableSpeaker it appears to use bit 4 to allow a write to happen on another bit, and then it sets bit 6. Bit 6 was used in SetSpeakerVolume to pulse the volume control up and down, which was also done with bit 4 cleared. Leaving bit 6 high seems to be the same state that SetSpeakerVolume leaves it as well.

SetKeyclicks

This function is rather different that the speaker related ones and does not make use of the 308h register, instead it makes use of function HC11Send (5:10h) which appears to communicate with the 68HC11 sub-processor on the daughter card. This observation comes from the function SetHC11_ShutdownTimeout which also makes use of (5:10h), implying this function is for that communication. This communication makes use of ports 64h and 60h.

If the argument to SetKeyclicks is 0 then 0DCh is sent to HC11Send, otherwise 0D8h is sent. From this seemingly bit 2 of this byte controls the enabling or disabling of clicks.

(5:10h) "HC11Send"

This function while not named appears to be responsible for communicating with the 68HC11 sub-processor. It is called by the aptly named SetHC11_ShutdownTimeout, as well as SetKeyclicks.

It first tries 65536 times reading port 64h for bit 1 (02h) to be clear, if it never gets clear then it gives up and returns an error. Once this bit is set though the argument passed in ah is then written to port 60h. Then port 64h is read until bit 0 (01h) is set, using the same cx counter from before, if it never gets set then it errors out. Once that bit is set, port 60h is read again, getting the response byte from the 68HC11. If the response is 0FAh then the function returns, if not it tries again up to 3 more times. repeating the entire procedure.

HC11Send:
	push cx
	push bx
	mov bl, 3	; Retry counter
	xor cx, cx	; Timeout loop
try:	in al, 64h	; Get status
	test al, 02h	; Is HC11 ready for a command?
	loopnz try	; Keep reading till ready
	jcxz fail	; If never ready then fail
	mov al, ah
	out 60h, al	; Send message to HC11
await:	in al, 64h	; Check status
	test al, 01h	; Wait for response
	loopz await
	jcxz fail	; Never got a response
	in al, 60h	; Read response
	cmp al, 0FAh	; Message acknowledged (?)
	je exit		; Sent successfully
	dec bl		; Retry counter
	jne try		; Try again
fail:	or bl, 01h 	; Failed? But we restore bx...
exit:	pop bx
	pop cx
	ret

SetLED

This method is rather simple and simply passes it's BYTE argument to port 80h directly.

	mov al, [bp+6]	; 1st Argument
	mov dx, 80h
	cli
	out dx, al
	sti

SysScreenBlank

Screen blanking appears to be accomplished at its core with a call to int 15h function AH=5Fh. With AL being 0 or 1 to control the state of the screen.

 

Included Software

PWD_DRV.SYS

Path C:\DOS\PWD_DRV.SYS
Source Motorola
Function Password protection
Original Arguments DEVICE=C:\DOS\PWD_DRV.SYS
Suspected Parameters None

Some kind of basic password protection system that is included first in CONFIG.SYS. It provides for both password protection and also changing the current password. I have not fully examined this module fully as I have no need for such a protection, it can safely be removed from CONFIG.SYS.

Messages (From examining file contents)

9100-386 Security System V1.0
Copyright: Motorola, Inc.

Password: 
New Password: Retype: 
Access Denied
Press CTRL+ALT+DEL to reboot system
Press CTRL+ALT+ENTER to shut down system
Passwords do not match, not modified

MIRROR_C.SYS
 

Path C:\DOS\MIRROR_C.SYS
Source Motorola
Function Flash ROM Editing/Flashing
Original Arguments DEVICE=C:\DOS\MIRROR_C.SYS
Suspected Parameters None

To enter programming mode you want to hit Left Shift + Alt while this utility displays the message "Scanning". Doing so will create a 3960kB RAM disk, the same size and parameters as the Flash ROM filesystem. The utility will then copy he contents of drive C: (ROM disk) to drive D: (RAM disk). In autoexec.bat this will then be checked for by looking for the file MOTOROLA.WDG on the RAM disk, and if it exists will display a message to the user on the flash update procedure. The presence of MOTOROLA.WDG on D: is also used by the SYNC utility to determine if MIRROR_C.SYS was used to create the RAM disk.

Boot Message (not installed):

Motorola MIRROR_C version 1.01 virtual disk D:
Scanning
MIRROR_C not installed

Boot Message (installed):

Motorola MIRROR_C version 1.01 virtual disk D:
Scanning

You have initiated the flash update procedure.
This procedure will delete all files on the unit's
RAMDISK. Do you wish to proceed ? 

(Press y here to continue)

    Type of memory:                 Extended
    Size of memory:                 3960 KBytes
    Maximum root directory entries: 64
    Sector size:                    512
    Allocation unit:                2 sector(s)
    Number of existing directories: 0
    Number of existing files:       0
    Amount of memory in use:        0 KBytes
    Amount of memory free:          3960 KBytes

Due to MIRROR_C being installed, HOTDISK will fail as they use the same memory locations.

Motorola HOTDISK - Beta Release 0.1 virtual disk E:
Error in extended memory allocation

MOTOROLA.WDG Contents

Motorola - Wireless Data Group      Release 2.00  "FFSI with TX" 51R69598D03 
 

HOTDISK.SYS

Path: C:\DOS\HOTDISK.SYS
Source: Motorola
Function: Extended Memory RAM-DISK Driver
Original Arguments: DEVICE=C:\DOS\HOTDISK.SYS 1100 512 64 /x
Suspected Parameters: <sector count> <sector size> <root dir ents>
/x -- Use eXtended RAM instead of conventional

The RAM disk on the MDT is battery backed, so assuming the 7.2v NiCD battery pack is still intact and charged this tool will first check if the existing ram disk is still valid, and if not will create it fresh. With the parameters 1100 512 64 /x as my unit came with, it creates a drive of 557,056 bytes with 512 byte allocation units according to CHKDSK.  If we take the 1100 parameter to be a sector count, that would calculate to 563,200 bytes, a difference of 12 sectors which would account for the BPB (1), 2 copies of the FAT (4 sectors each) and root directory (3 sectors).

An odd quirk I noticed is there seems to be two XMS handles allocated according to Norton SysInfo:

I'm not sure entirely where the second allocation is coming from, if it's some kind of backup ram disk, or an unrelated allocation from one of the Cardsoft utilities that just happens to be around the same size.

Boot Message:

Motorola HOTDISK - Beta Release 0.1 virtual disk D:

    Type of memory:                 Extended
    Size of memory:                 550 KBytes
    Maximum root directory entries: 64
    Sector size:                    512
    Allocation unit:                1 sector(s)
    Number of existing directories: 0
    Number of existing files:       1
    Amount of memory in use:        1 KBytes
    Amount of memory free:          549 KBytes


RAMDISK.SYS

Path: C:\DOS\RAMDISK.SYS
Source: Motorola
Function: Extended Memory RAM-DISK Driver
Original Arguments: Not used
Suspected Parameters: <sector count> <sector size> <root dir ents>
/x -- Use eXtended RAM instead of conventional

This module appears to be almost identical to HOTDISK.SYS and likely is the basis for it as well. Both contain the same hidden copyright strings of MRD1.00 and RAMDISK program is the property of Motorola.  I'm not exactly sure as to what the difference between them operationally is. I would suspect that RAMDISK is more general purpose and can be used for additional ram disks besides the one shared between HOTDISK and MIRROR_C. It appears to have the same persistent storage capabilities as HOTDISK with strings mentioning both recovering the disk and the boot message showing the number of existing files.

Boot Message (Based off file and hotdisk output):

Motorola RAMDISK version 1.00 virtual disk A:

    Type of memory:                 Extended
    Size of memory:                 550 KBytes
    Maximum root directory entries: 64
    Sector size:                    512
    Allocation unit:                1 sector(s)
    Number of existing directories: 0
    Number of existing files:       1
    Amount of memory in use:        1 KBytes
    Amount of memory free:          549 KBytes

SCSI.SYS

Path: C:\DOS\SCSI.SYS
Source: Motorola
Function: SCSI Disk Driver
Original Arguments: DEVICE=C:\DOS\SCSI.SYS
Suspected Parameters: None

As the MDT 9100-386 model contains a SCSI controller some provision for that has been provided. Looking at the contents it appears to be designed for just SCSI block devices. I have not yet tested the functionality of this driver, though it would be good to know if it can handle CD-ROM drives. The boot messages seem quite minimal so the functionality may not be too great. It is unknown if it supports more than one device on the chain.

Boot Message (Success)

Motorola Inc. SCSI Driver Version 2.0
Device will be drive X:

Boot Message (Failure)

Motorola Inc. SCSI Driver Version 2.0
Driver Initialization Failed !!

SYNC.BAT

 

SYNC.BIN

SYNC_LDR.EXE

OFF.COM

Path: C:\DOS\OFF.COM
Source: Motorola
Function: Turns the system off
Original Arguments: None
Suspected Parameters: None

A short 12-byte program to turn the system off. You can also turn the system off from the keyboard by pressing Ctrl-Alt-Enter.

Disassembly

WAIT:    IN    AL, 64h
         TEST  AL, 02h
         JNZ   WAIT
         MOV   AL, 0DEh
         OUT   60h, AL
         INT   3
         RET

DOWNLOAD.BAT

Simply launches INTERSVR with the /RCOPY parameter. Used for transferring interlnk files to another computer over a full null modem connection.