|
|
;****************************************************************************** ; ; Simulator 16 ; ; Author : Chandan Chauhan ; ; Date : 1/28/91 ; ;******************************************************************************
include incs.inc ; segment definitions
MAXSIZE EQU 1024 ; 1k length
Arg1 EQU [bp+6] Arg2 EQU [bp+8]
WOW32_Buffer EQU [bp+6] ; buffer address WOW32_Size EQU [bp+8] ; length of VDM memory WOW32_Off EQU [bp+10] ; off of VDM memory WOW32_Sel EQU [bp+12] ; sel of VDM memory WOWStackNP EQU [bp+6] ; WOWStack WOWStackOff EQU [bp+6] WOWStackSel EQU [bp+8]
extrn Initialize:near
MAIN_DATA SEGMENT PUBLIC TransmitPkt, ReceivePkt, ReceivePktPtr, RespPkt, ToWOW32Pkt PUBLIC ACKPkt, NAKPkt, GetMemPkt, SetMemPkt, WAKEUPPkt PUBLIC fReceive, fRxCount, fRxError, RxPktLen PUBLIC fTxCount, fTransmitting PUBLIC fInitTime PUBLIC VDMAddress PUBLIC WOWStack, WOW32Buffer
Reserved DB 16 DUP (0) ; reserved
TransmitPkt DD -1 ; packet being transmitted TransmitPktLen DW 0 ; packet being transmitted TransmitPktPtr DW 0 ; byte to Tx
ReceivePkt DB MAXSIZE DUP (0FFh) ; packet being received ReceivePktPtr DW 0 ; packet being received
RespPkt DB MAXSIZE DUP (0FFh) ; packet being transmitted
ToWOW32Pkt DB 9 DUP (?) ; ToWOW32 packet DB 0
WAKEUPPkt DB 9 DUP (0) ; WAKEUP packet DB 0
ACKPkt DB 5 DUP (?) ; ACK packet DB 0
NAKPkt DB 5 DUP (?) ; NAK packet DB 0
GetMemPkt DB MAXSIZE DUP (?) ;*************** SetMemPkt DB MAXSIZE DUP (?) ;***************
VDMAddress DD -1 ; stores VDM sel:off VDMLength DW -1 ; number of bytes
WOW32Buffer DD -1 ; ptr caller's buffer WOWStack DD -1 ; ptr to caller's WOWStack
fTxCount DW 0 fTransmitting DW 0
fReceive DW 0 fRxCount DW 0 fRxError DW 0
fInitTime DW 0 fInitDLL DW 0
RxPktLen DW 0
Stack DW 256 DUP (?) StackTop DW ? OldSS DW ? OldSP DW ? Scratch DW ? fStackUse DW -1
IntRoutines LABEL WORD DW COMISR_MSR DW COMISR_Transmit DW COMISR_Receive DW COMISR_LSR
HelloString DB cr, lf, 'WOW Simulator *****', cr, lf, lf DB 'Hello, this is a test string !!!!!!!!!!', cr, lf HelloStringLen EQU $ - HelloString
MAIN_DATA ENDS
MAIN_CODE SEGMENT ASSUME CS:MAIN_CODE, DS:MAIN_DATA, ES:NOTHING
;***************************************************************************** ; S I M U L A T O R L A Y E R ;*****************************************************************************
;***************************************************************************** ; ; Sim32SendSim16 ; ;*****************************************************************************
;***************
PROCEDURE Sim32SendSim16 PUBLIC, FAR
push bp ; save stack frame mov bp, sp
pusha ; temps... push ds ; temps... push es ; temps...
mov bx, ds
mov ax, SEG MAIN_DATA mov ds, ax mov si, OFFSET WAKEUPPkt ; DS:SI -> WAKEUP packet
mov ax, WOWStackNP mov WOWStack._off, ax mov WOWStack._sel, bx
cmp fInitTime, 0 je Sim32SendSim16_Init
les bx, WOWStack ; ES:BX -> SS:SP of WOW VDM task mov ax, es:[bx]._off ; get SP mov [si].MEM_OFF, ax mov ax, es:[bx]._sel ; get SS mov [si].MEM_SEL, ax
call Xceive
Sim32SendSim16_Ret: les bx, WOWStack ; ES:BX -> SS:SP of WOW VDM task mov di, OFFSET ReceivePkt mov ax, [di].ToWOW32_OFF mov es:[bx]._off, ax mov ax, [di].ToWOW32_SEL mov es:[bx]._sel, ax
pop es ; temps... pop ds ; temps... popa ; temps...
mov sp, bp pop bp
ret 2
Sim32SendSim16_Init: call Receive inc fInitTime call Initialize jmp SHORT Sim32SendSim16_Ret
Sim32SendSim16 ENDP
;***************************************************************************** ; ; Sim32GetVDMMemory ; ;*****************************************************************************
;***************
PROCEDURE Sim32GetVDMMemory PUBLIC, FAR
push bp ; save stack frame mov bp, sp
pusha ; temps... push ds ; temps... push es ; temps...
mov bx, ds
mov ax, SEG MAIN_DATA mov ds, ax mov si, OFFSET GetMemPkt ; DS:SI -> ToWOW32 packet
mov ax, WOW32_Buffer ; get buffer's address mov WOW32Buffer._off, ax mov ax, bx mov WOW32Buffer._sel, ax
mov ax, WOW32_Off mov [si].MEM_OFF, ax
mov ax, WOW32_Sel mov [si].MEM_SEL, ax
mov cx, WOW32_Size ; get the length
cmp cx, 3B6h jg Sim32GetMem_Error
mov [si].MEM_LENGTH, cx
call Xceive ; send GetMem packet and pickup ; the response mov cx, WOW32_Size
les di, WOW32Buffer ; ES:DI -> WOW32 buffer mov si, OFFSET ReceivePkt+4
rep movsb
pop es ; temps... pop ds ; temps... popa ; temps...
mov sp, bp pop bp
ret 8
Sim32GetMem_Error: int 3
Sim32GetVDMMemory ENDP
;***************************************************************************** ; ; Sim32SetVDMMemory ; ;*****************************************************************************
;***************
PROCEDURE Sim32SetVDMMemory PUBLIC, FAR
push bp ; save stack frame mov bp, sp
pusha ; temps... push ds ; temps... push es ; temps...
mov bx, ds
mov ax, SEG MAIN_DATA mov ds, ax mov di, OFFSET SetMemPkt ; DS:DI -> SetMem packet
mov ax, WOW32_Buffer ; get buffer's address mov WOW32Buffer._off, ax mov ax, bx mov WOW32Buffer._sel, ax
mov ax, WOW32_Off mov [di].MEM_OFF, ax
mov ax, WOW32_Sel mov [di].MEM_SEL, ax
mov cx, WOW32_Size
cmp cx, 3B6h jg Sim32SetMem_Error
mov [di].MEM_LENGTH, cx mov bx, 11 add bx, cx mov [di].Len, bx add di, 0Ah mov bx, ds mov es, bx
lds si, WOW32Buffer ; DS:SI -> Buffer rep movsb mov BYTE PTR es:[di], EOT
mov ds, bx mov si, OFFSET SetMemPkt ; DS:SI -> SetMem packet
call Xceive
pop es ; temps... pop ds ; temps... popa ; temps...
mov sp, bp pop bp
ret 8
Sim32SetMem_Error: int 3
Sim32SetVDMMemory ENDP
;***************************************************************************** ; ; Sim16SendSim32 ; ;*****************************************************************************
PROCEDURE Sim16SendSim32 PUBLIC, FAR
push bp ; save stack frame mov bp, sp
pusha ; temps... push ds ; temps... push es ; temps...
mov bx, ds mov ax, SEG MAIN_DATA mov ds, ax mov si, OFFSET ToWOW32Pkt ; DS:SI -> ToWOW32 packet
cmp fInitDLL, 0 jne @f
pusha call Initialize popa
inc fInitDLL
@@:
; prepare ToWOW32 packet
mov ax, WOWStackOff mov [si].ToWOW32_OFF, ax ; mov ax, WOWStackSel mov [si].ToWOW32_SEL, ax ;
; send it
call Xceive ; send ToWOW32 packet and pick up ; the response
Sim16SendSim32_Loop:
mov di, OFFSET Receivepkt mov ax, [di].MEM_OFF ; get sel:off and length from mov VDMAddress._off, ax ; packet mov ax, [di].MEM_SEL mov VDMAddress._sel, ax mov ax, [di].MEM_LENGTH mov VDMLength, ax
Sim16SendSim32_GetMem:
cmp [di].Command, GETMEM jne Sim16SendSim32_SetMem
call GetVDMMemory ; get vdm memory
call Xceive ; send response and get next packet
jmp SHORT Sim16SendSim32_Loop
Sim16SendSim32_SetMem:
cmp [di].Command, SETMEM jne Sim16SendSim32_PszLen
call SetVDMMemory ; get vdm memory
call Xceive ; send response and get next packet
jmp SHORT Sim16SendSim32_Loop
Sim16SendSim32_PszLen:
cmp [di].Command, PSZ jne Sim16SendSim32_WakeUp
call PszLen
call Xceive ; send response and get next packet
jmp SHORT Sim16SendSim32_Loop
Sim16SendSim32_WakeUp:
cmp [di].Command, WAKEUP jne Sim16SendSim32_Error
Sim16SendSim32_Done:
pop es ; temps... pop ds ; temps... popa ; temps...
IFDEF STACKSWITCH cli mov sp, VDMAddress._off mov ss, VDMAddress._sel ; could be a task switch ! sub sp, 8 sti ENDIF
pop bp
ret 4
Sim16SendSim32_Error:
int 3 mov si, OFFSET NAKPkt call Xceive jmp SHORT Sim16SendSim32_Loop
Sim16SendSim32 ENDP
;***************************************************************************** ; ; GetVDMMemory ; ;*****************************************************************************
PROCEDURE GetVDMMemory, PUBLIC ASSUME CS:MAIN_CODE, DS:DGROUP
push di push es push ds
mov ax, ds mov es, ax
mov di, OFFSET RespPkt+4 ; ES:DI -> Response Packet
mov cx, VDMLength lds si, VDMAddress ; DS:SI -> memory to get
rep movsb
pop ds pop es pop di
mov si, OFFSET RespPkt ; DS:SI -> Resp packet mov ax, si
mov cx, VDMLength add cx, 5 mov [si].Len, cx add si, cx dec si mov [si], BYTE PTR EOT
mov si, ax ; DS:SI -> Resp packet
ret
GetVDMMemory ENDP
;***************************************************************************** ; ; SetVDMMemory ; ;*****************************************************************************
PROCEDURE SetVDMMemory, PUBLIC ASSUME CS:MAIN_CODE, DS:DGROUP
push di push es
lea si, ReceivePkt.DataM ; DS:SI -> Data to set
mov cx, VDMLength les di, VDMAddress ; DS:SI -> memory to set
rep movsb
mov si, OFFSET RespPkt ; DS:DI -> Response Packet
mov [si].Len, 7 mov [si].MEM_OFF, 0AAh mov BYTE PTR [si].MEM_SEL, EOT
pop es pop di
ret
SetVDMMemory ENDP
;***************************************************************************** ; ; PszLen ; ; This routine returns the length of the null terminated string ; address specified by VDMAddress. ; ;*****************************************************************************
PROCEDURE PszLen, PUBLIC ASSUME CS:MAIN_CODE, DS:DGROUP
push di push es
les di, VDMAddress ; ES:DI -> String mov cx, 0FFFFh
sub ax, ax ; look for null repne scasb jnz PszLen_Notfound
xor cx, 0FFFFh ; CX = length of string mov si, OFFSET RespPkt ; DS:DI -> Response Packet
mov [si].Len, 7 mov [si].MEM_OFF, cx mov BYTE PTR [si].MEM_SEL, EOT
pop es pop di
ret
PszLen_Notfound:
int 3
pop es pop di
ret
PszLen ENDP
;***************************************************************************** ; T R A N S P O R T L A Y E R ;*****************************************************************************
;***************************************************************************** ; ; Xceive - TransCeive ; ; DS:SI -> Packet to be transmitted ; ;*****************************************************************************
PROCEDURE Xceive, PUBLIC ASSUME CS:MAIN_CODE, DS:DGROUP
mov RxPktLen, -1 mov ReceivePktPtr, 0 mov fReceive, 0 mov fRxCount, 0 mov fRxError, 0
call StartTransmitter
Xceive_Loop: cmp fReceive, 0 je Xceive_Loop
mov fReceive, 0
cmp fRxError, 0 jne Xceive_NAK
cmp ReceivePkt, SOH jne Xceive_NAK
mov bx, ReceivePkt.Len dec bx
cmp ReceivePkt.[bx], EOT jne Xceive_NAK
xor ax, ax ret
Xceive_NAK: cmp fRxCount, MAXCOUNT jg Xceive_Error
inc fRxCount
mov si, OFFSET NAKPkt
jmp SHORT Xceive_Loop
Xceive_Error:
int 3 mov ax, 1 ret
Xceive ENDP
;***************************************************************************** ; ; Receive ; ;*****************************************************************************
PROCEDURE Receive, PUBLIC ASSUME CS:MAIN_CODE, DS:DGROUP
mov RxPktLen, -1 mov ReceivePktPtr, 0 mov fReceive, 0 mov fRxCount, 0
Receive_Loop: cmp fReceive, 0 je Receive_Loop
mov fReceive, 0
cmp fRxError, 0 jne Receive_NAK
xor ax, ax ret
Receive_NAK:
cmp fRxCount, MAXCOUNT jg Receive_Error
inc fRxCount
mov si, OFFSET NAKPkt
call StartTransmitter
jmp SHORT Receive
Receive_Error:
int 3 mov ax, 1 ret
Receive ENDP
;***************************************************************************** ; S E R I A L D R I V E R ;*****************************************************************************
;***************************************************************************** ; ; Start Transmitter ; ;*****************************************************************************
PROCEDURE StartTransmitter, PUBLIC ASSUME CS:MAIN_CODE, DS:DGROUP
StartTransmitter_Loop: cmp fTransmitting, 1 je StartTransmitter_Loop
mov TransmitPkt._sel, ds mov TransmitPkt._off, si mov ax, [si].Len ; get packet length mov TransmitPktLen, ax mov TransmitPktPtr, 0
mov fTransmitting, 1
cmp TransmitPktLen, 0 je StartTransmitter_Ret
mov dx, SERIALPORT ; COM1 or COM2 mov dl, IER ; turn on interrupts on 8250 in al, dx DELAY
or al, TxInt out dx, al DELAY
StartTransmitter_Ret: ret
StartTransmitter ENDP
;***************************************************************************** ; ; Interrupt Routine ; ;*****************************************************************************
PUBLIC COMISR, COMISR_LSR, COMISR_Receive, COMISR_Transmit, COMISR_MSR
COMISR: push ax push ds
mov ax, SEG DGROUP mov ds, ax
DISABLE
call NewStack
pusha push es
COMISR_More: mov dx, SERIALPORT mov dl, IIR in al, dx test al, IntPending ; is int pending ? jnz COMISR_Ret ; no int is pending
xor ah, ah mov di, ax shr di, 1 add di, di jmp [di].IntRoutines ; service int
COMISR_LSR: INT3 mov fRxError, 1 mov dx, SERIALPORT mov dl, LSR in al, dx DELAY
jmp SHORT COMISR_More
COMISR_Receive: mov dx, SERIALPORT in al, dx DELAY
mov bx, ReceivePktPtr mov [bx].ReceivePkt, al inc ReceivePktPtr
cmp bx, 03 jne COMISR_ReceiveNext
mov ax, WORD PTR ReceivePkt+2 dec ax mov RxPktLen, ax
COMISR_ReceiveNext: cmp bx, RxPktLen jne @f
mov fReceive, 1 ; receive Done ! @@: jmp SHORT COMISR_More
COMISR_Transmit: cmp TransmitPktLen, 0 jne COMISR_Send
mov dx, SERIALPORT mov dl, IER ; turn off interrupts on 8250 in al, dx DELAY
and al, NOT TxInt out dx, al DELAY
mov fTransmitting, 0
jmp SHORT COMISR_More
COMISR_Send: les bx, DWORD PTR TransmitPkt mov di, TransmitPktPtr mov al, BYTE PTR es:[bx][di] mov dx, SERIALPORT out dx, al DELAY inc TransmitPktPtr dec TransmitPktLen
jmp COMISR_More
COMISR_MSR: INT3 mov fRxError, 1 mov dx, SERIALPORT mov dl, MSR in al, dx DELAY
jmp COMISR_More
COMISR_Ret: DELAY
pop es popa
call OldStack
DISABLE
mov al, EOI out PIC, al pop ds pop ax iret
;***************************************************************************** ; ; New Stack ; ;*****************************************************************************
PROCEDURE NewStack, PUBLIC ASSUME CS:MAIN_CODE, DS:DGROUP
inc fStackUse jnz NewStack_Ret
pop Scratch mov OldSS, ss mov OldSP, sp push ds pop ss mov sp, OFFSET StackTop push Scratch
NewStack_Ret: ret
NewStack ENDP
;***************************************************************************** ; ; Old Stack ; ;*****************************************************************************
PROCEDURE OldStack, PUBLIC ASSUME CS:MAIN_CODE, DS:DGROUP
DISABLE cmp fStackUse, 0 jne OldStack_Ret
pop Scratch mov ss, OldSS mov sp, OldSP push Scratch
OldStack_Ret: dec fStackUse ENABLE ret
OldStack ENDP
MAIN_CODE ENDS
END
|