System Simulator Call (SSC)

This document provides a high level description of console, disk and miscellaneous SSC calls.

The main data types are:

CONSOLE

The three main calls to set up and interact with the console are: Before using the keyboard calls, an interrupt bit in IRR0-3 must be associated with the keyboard interrupt. This is done by using the SscConnectInterrupt call. The interrupt bit cannot be in group 0 (interrupts 0-15).

SscConnectInterrupt(interrupt, bit_position)

SscConnectInterrupt associates an interrupt with a bit in IRR0-3. The input parameters specify the interrupt and the bit_position. The following interrupts are legal:
SSC_DISK_INTERRUPT
SSC_MOUSE_INTERRUPT
SSC_KEYBOARD_INTERRUPT
SSC_CLOCK_TIMER_INTERRUPT
SSC_PROFILE_TIMER_INTERRUPT
SSC_APC_INTERRUPT
SSC_DPC_INTERRUPT
The following assembly instructions show the calling sequence:
 
mov r32 = SSC_KEYBOARD_INTERRUPT
mov r33 = INTERRUPT_BIT_POS
mov r15 = CONST_SscConnectInterrupt
break SSCI_KCALL_CODE

SSC_set_KB_mode(on)

This call initializes the console and keyboard and sets up mailboxes for gambit and the console. The only parameter for this call is a flag to turn on the keyboard and console. In order to initialize the console, the value passed in must be zero. A sample calling sequence in assembly is shown below:
 
mov r32 = 0x0
mov r15 = CONST_SSC_set_KB_mode
break SSCI_KCALL_CODE

SSC_char_out(char)

This call puts a character onto the console. The input character char must be passed in register r32 as shown in the following example:
 
ld1 r32 = [r4], r2
mov r15 = CONST_SSC_char_out
break SSCI_KCALL_CODE
add r4 = 0x1, r4

SSC_char_in

This call returns the next character in the keyboard buffer. The character is returned in register r32.
 
mov r15 = CONST_SSC_char_in
break SSCI_KCALL_CODE
cmp.ne.unc p4, p0 = 0xa, r32

DISK ACCESS

The following calls facilitate access to the disk and other devices. SSC_HANDLE and SSC_BOOL are of type U32. All size and offset fields must be specified in bytes.

Before using the disk calls, an interrupt bit in IRR0-3 must be associated with the disk interrupt. This is done by using the SscConnectInterrupt call.

SSC_HANDLE SscDiskOpenVolume(U64 VolumeName, DWORD AccessMode)

This call opens a device or file. The access modes allowed are read, write and read|write. The call returns the volume handle in register r8. The following example shows how a disk file can be opened for reading.
 
movl r32 = vol_name
mov r33 = ssc_read
mov r15 = CONST_SscDiskOpenVolume
break SSCI_KCALL_CODE

SSC_BOOL SscDiskCloseVolume(SSC_HANDLE VolumeHandle)

This call closes a device or file identified the given volume handle. SSC_HANDLE is a 32 bit quantity. The call returns true if successful in register r8.
 
mov r32 = r3 // r3 has the volume handle
mov r15 = CONST_SscDiskCloseVolume
break SSCI_KCALL_CODE

SSC_BOOL SscDiskReadVolume(SSC_HANDLE VolumeHandle, DWORD NReq, U64 RequestPtr, U64 VolumeOffset)

SscDiskReadVolume reads 512 byte multiples of data from the specified device or file. If successful, the call returns TRUE in register r8.

The request_ptr is of type SSC_DISK_REQUEST.
 

typedef struct _SSC_DISK_REQUEST {
    U64 DiskBufferAddress;
    U32 DiskByteCount;
} *PSSC_DISK_REQUEST, SSC_DISK_REQUEST;


read_file:

 
mov r32 = r8 // r8 has handle from gambit, gambit_handle <> os_handle
mov r33 = 0x1 // reading in only one buff/cnt pair
movl r4 = ssc_disk_req
movl r34 = disk_buf // address of the buffer
st8 [r4] = r34
mov r34 = r4
mov r35 = 0x0 // Volume offset, we want to read from the beginning
mov r15 = CONST_SscDiskReadVolume
break SSCI_KCALL_CODE

SSC_BOOL SscDiskWriteVolume(SSC_HANDLE VolumeHandle, DWORD NReq, U64 RequestPtr, U64 VolumeOffset)

SscDiskWriteVolume writes 512 byte multiples of data to the specified device or file. If successful, the call returns TRUE in register r8. A sample calling sequence is shown below.
 
mov r32 = r8 // r8 has handle from gambit, gambit_handle <> os_handle
mov r33 = 0x1 // reading in only one buff/cnt pair
movl r34 = ssc_disk_req
mov r35 = 0x0 // Volume offset, we want to read from the beginning
mov r15 = CONST_SscDiskWriteVolume
break SSCI_KCALL_CODE

SSC_BOOL SscDiskGetCompletion(U64 DiskCompletionPtr)

This call determines if any I/O transaction was completed. If a transaction was completed, the volume handle and the number of bytes transfered are returned. The call returns TRUE if an I/O was indeed completed. This call can be used in an interrupt handler. It should be called more than once on interrupt, because one interrupt may report one or more an one I/O completion. Only one I/O transaction can be in progress for a given volume handle.
 
typedef struct _SSC_DISK_COMPLETION {
    SSC_HANDLE VolumeHandle;
    DWORD XferBytes;
} *PSSC_DISK_COMPLETION, SSC_DISK_COMPLETION;


write_file:

 
mov r32 = r8 // r8 has handle from gambit, gambit_handle <> os_handle
mov r33 = 0x1 // reading in only one buff/cnt pair
movl r34 = ssc_disk_req
mov r35 = 0x0 // Volume offset, we want to read from the beginning
mov r15 = CONST_SscDiskWriteVolume
break SSCI_KCALL_CODE

SSC_BOOL SscDiskWaitIoCompletion(U64 DiskCompletionPtr)

SscDiskWaitIoCompletion will synchronize with a previously made read or write call. If an interrupt has already been delivered, the call will return false and no completion values will be returned. If the call is successful, no interrupt will be delivered.
 
mov r32 = ssc_disk_completion
st4 [r32] = r3 // r3 has the volume handle
mov r15 = CONST_SscDiskWaitIoCompletion
break SSCI_KCALL_CODE

Miscellaneous SSCs

SscExit (U32 status)

SscExit exits the OS application and returns the status to simdb. If simdb was in console, gui or batch mode, simdb prints the status. If simdb was invoked with the "-d" option, the application exits and simdb terminates. Currently, the application exit status is not returned to the system by simdb.
 
mov r32 = 5 // return exit status of 5
mov r15 = CONST_SscExit
break SSC_KCALL_CODE

VOID SscSetPeriodicInterruptInterval(DWORD InterruptSource, ULONG IntervalInNanoSeconds)

The SscSetPeriodicInterruptInterval call can be used to cause an interrupt periodically. The source of the interrupt is specified by InterruptSource. The interrupt is posted every IntervalInNanoSeconds. This call can be used to generate clock timer and profile timer interrupts periodically.

The interrupt source must be either SSC_CLOCK_TIMER_INTERRUPT or SSC_PROFILE_TIMER_INTERRUPT. An interval value of zero will stop existing periodic interrupts for the given source.

The interrupt source must have been connected by issuing the SscConnectInterrupt call.

 
mov r32 = SSC_CLOCK_TIMER_INTERRUPT // Clock timer
mov r33 = interval_in_nanosecs // Interval
mov r15 = CONST_SscSetPeriodicInterruptInterval
break SSCI_KCALL_CODE

VOID SscGenerateInterrupt(DWORD InterruptSource)

The SscGenerateInterrupt call can be used to cause Gambit to deliver an interrupt. The source of the interrupt is specified by InterruptSource. Gambit sets the corresponding bit in IRR0-3. The interrupt source must have been connected by issuing the SscConnectInterrupt call.

Valid values for InterruptSource are:

For example:
 
mov r32 = SSC_KEYBOARD_INTERRUPT
mov r33 = INTERRUPT_BIT_POS
mov r15 = CONST_SscConnectInterrupt
break SSCI_KCALL_CODE
...
mov r32 = SSC_KEYBOARD_INTERRUPT
mov r15 = CONST_SscGenerateInterrupt
break SSCI_KCALL_CODE

VOID SscQueryRealTimeClock (U64 TimeFieldsPtr)

TimeFieldsPtr is a pointer to the TIME_FIELDS structure that specifies the current time.
typedef struct _TIME_FIELDS {
    DWORD year;
    DWORD month;
    DWORD day;
    DWORD hour;
    DWORD minute;
    DWORD second;
    DWORD milliseconds;
    DWORD week_day;
} SSC_TIME_FIELDS, *PSSC_TIME_FIELDS;


The SscQueryRealTimeClock call returns the current time in this structure.

 
movl r32 = ssc_time_fields_ptr
mov r15 = CONST_SscQueryRealTimeClock
break SSCI_KCALL_CODE

int SscDbgLoadImageSymbols(U32 LoadType, U64 LoadPtr, U64 LoadBase, U32 ProcessId)

SscDbgLoadImageSymbols reinitializes the virtual symbol table and loads the new symbol table from the file pointed to by the LoadPtr.
 
mov r32 = 0x0 // not implemented yet
movl r33 = file_name // pointer to the file name to load symbols
mov r34 = 0x0 // not implemented yet
mov r35 = 0x0 // not implemented yet
mov r15 = CONST_SscDbgLoadImageSymbols
break SSCI_KCALL_CODE

int SscDbgSymbolToAddr(U64 Symbol, U64 Address)

 
movl r32 = symbol_name // pointer to the symbol name
movl r33 = address // pointer to receive address
mov r15 = CONST_SscDbgSymbolToAddr
break SSCI_KCALL_CODE

int SscDbgAddrToSymbol(U64 Symbol, U64 Address)

 
movl r32 = symbol_name // pointer to receive the symbol+offset
movl r33 = address // pointer to address
mov r15 = CONST_SscDbgAddrToSymbol
break SSCI_KCALL_CODE