.MODEL SMALL .286 .CODE MSR EQU 03f8h + 6h ;define loc of MOdem Status Reg. MDMCTL EQU 03f8h + 4h ;define loc of Modem Ctl Reg. DLYCNT EQU 86 ;delay count for bitdly STDLY EQU 78 ;delay count for start bits PUBLIC _send,_pulse,_cal EXTRN _tout:near _send PROC C NEAR pusha ; NOTE - we do this first part with the ; ints still on so as not to ; completely hang the system. We ; allow normal interrupts to run ; while waiting for the blank between ; word blocks from the camera. ; frame: ; wait 4 ms without start bit mov ah,3 ; time counter frame1: mov cx,1250 ; init ms counter for 10mhz rate msdly: loop msdly ; loop to self till done (0.8us/loop) mov dx,MSR ; point to Modem Status Reg in al,dx ; read it and al,04h ; RI state change since last read? jnz frame ; yes - reset counter dec ah ; dec ms counter jnz frame1 ; wait another ms cli ; disable ints. Be careful!!! ; we are in between frames - get ready sync: mov cx,0 ; set to max count for timeout mov dx,MSR ; point to modem status reg sync1: in al,dx ; read status reg and al,40h ; watch for RI=low jnz go ; ready - go for it loop sync1 ; else keep testing timout: ; timed out - restore regs and ints sti ; ints back on call _tout ; call c routine to beep jmp done ; - just exit for now go: mov ah,[_word0] ; get first word to send call start ; sync to start bit call bit ; send lsb call bit call bit call bit call bit call bit call bit call bit ; send msb call stop ; send stop bit bsync: mov cx,0 ; set to max count for timeout mov dx,MSR ; point to modem status reg bsync1: in al,dx ; read status reg and al,40h ; watch for RI=low jnz bgo ; ready - go for it loop bsync1 ; else keep testing jmp timout ; we timed out looking for second start bit bgo: mov ah,[_word1] ; get second word to send call start ; sync to start bit call bit ; send lsb call bit call bit call bit call bit call bit call bit call bit ; send msb call stop ; send stop bit sti ; ints back ON - VERY important!! dec [_fcount] ; see if we have sent command enough times jz done ; do it this way since relative is -127 bytes jmp frame ; nope - do it all over again done: popa ret _send ENDP start: ; sync to trailing edge of start bit mov dx,MDMCTL ; generate 1 small pulse to show we are here mov al,03h ; set DTR , RTS out dx,al ; set RTS low (1 on camera) pusha ; stall for time popa pusha popa mov al,01h ; set back to 'stop bit' again out dx,al ; enough of this nonsense! ; mov cx,STDLY ; delay for rest of start bit time st1: loop st1 ret bit: ; shift ah right - output 1 lsb to RTS pin mov al,03h ; set DTR on by default shr ah,1 ; set cy if lsb is 1 jc bitdly ; not set - output a 1 mov al,01h ; set DTR & RTS for a zero mov al,01h ; delay an extra 2 clocks to stay in time bitdly: ; 12 clocks from bit - delay rest of 1 bit time mov dx,MDMCTL ; point to modem control reg out dx,al ; output bit to RTS pin mov cx,DLYCNT ; delay count - 126 decimal at 10mhz bd1: loop bd1 ; loop till done ret stop: ; send stop bit mov al,01h ; stop bit is high (logic 0 on camera) mov dx,MDMCTL ; set stop bit high then done out dx,al ; since camera generates start bits! ret _pulse PROC NEAR cli ; ints off for timing pusha ; save all regs again: mov ah,01h ; generate count number of 1 ms hi-lo's call bit mov ah,01h ; make 1 bit twice as long as 0 call bit mov ah,00h call bit dec [_fcount] jnz again popa sti ; ints back on ret _pulse ENDP ; The following '_cal' is used to calibrate the time ; delays. first set the start bit delay count (STDLY) ; so the '0' following the start bit starts right at ; the trailing edge of a camera start bit. Then adjust ; DLYCNT for 1 ms bit widths. Requires the start bits ; from the camera to sync up properly. this routine needs ; to look EXACTLY like the _send routine so as to be able ; to set the timing correctly. be sure to move output ; to camera to the dummy load so as to not give strange ; instructions to the camera. This should send the test ; byte in sync with the FIRST start bit of a frame from ; the camera. ; _cal PROC NEAR pusha ; save all regs mov [_fcount],07ffh ; do it lots of times cframe: ; wait 4 ms without start bit mov ah,3 ; time counter cfr1: mov cx,1250 ; init ms counter for 10mhz rate cmsdly: loop cmsdly ; loop to self till done (0.8us/loop) mov dx,MSR ; point to Modem Status Reg in al,dx ; read it and al,04h ; RI state change since last read? jnz cframe ; yes - reset counter dec ah ; dec ms counter jnz cfr1 ; wait another ms cli ; disable ints. Be careful!!! ; we are in between frames - get ready csync: mov cx,0 ; set to max count for timeout mov dx,MSR ; point to modem status reg csync1: in al,dx ; read status reg and al,40h ; watch for RI=low jnz cgo ; ready - go for it loop csync1 ; else keep testing ctimout: ; timed out - restore regs and ints sti ; ints back on call _tout ; call c routine to beep jmp cdone ; - just exit for now cgo: cli ; kill ints (brave arn't we??) cal1: mov ah,0a5h ; alt 10100101 bit pattern call start ; send short start and delay rest of start call bit ; send lsb call bit call bit call bit call bit call bit call bit call bit call stop mov cx,500 ; wait a little bit till next bunch calwait: loop calwait dec [_fcount] ; done yet? jnz cframe ; nope - send it again sti cdone: popa ret _cal ENDP .DATA PUBLIC _fcount, _word0, _word1, _dstr _fcount DW ? _word0 DB ? _word1 DB ? _dstr DB ??time DB " on " DB ??date DB 0h ; C string terminator END