; BUS bit 0 = Polaroid 6500 INIT ; BUS bit 1 = Polaroid 6500 BLNK ; BUS bit 2 = Polaroid 6500 BINH ; Port 1 bit 3 = Polaroid 6500 ECHO ; Port 2 bit 0 = RS-232 in ; Port 2 bit 1 = RS-232 out ; Port 2 bit 2 ; Port 2 bit 3 = Sonar stepper reset sensor (1 = sensor is zeroed) ; Port 2 bit 4 = Sonar stepper coil 1 direction 1 ; Port 2 bit 5 = Sonar stepper coil 1 direction 2 ; Port 2 bit 6 = Sonar stepper coil 2 direction 1 ; Port 2 bit 7 = Sonar stepper coil 2 direction 2 ; RS-232 is 2400 bps, 1 start, 2 stop, no parity ; Assumes a 4 MHz clock data .equ 64 ; start of the data area echos .equ 5 ; maximum # echos to record step .equ 126 ; current stepper motor control output blanki .equ 127 ; internal blanking interval location .org 0 jmp main ; reset .org 7 jmp ovrflw ; timer overflow ; Wait for stuff to stabilize, initialize the ports, wait for valid command main mov a,#$0f ; turn off stepper switched first outl p2,a mov a,#$f8 ; initialize ports outl bus,a ; make sure INIT is low mov a,#$ff outl p1,a mov r0,#blanki ; store default blanking interval mov @r0,a clr a ; store initial stepper motor sequence mov r0,#step mov @r0,a ; do not use r2 in any routines called from here! mov r5,#stmsg ; startup message call prtmsg ; print it mainlp call datain ; read a byte from serial port orl a,#$20 ; make lower case letter mov r2,a ; save the byte add a,#-'p ; is it the ping command? jnz m2 mov r0,#blanki ; set internal blanking interval mov a,@r0 mov r0,a call ping ; ping the sonar call dump ; print the data jmp mainlp m2 mov a,r2 ; retrieved saved command add a,#-'b ; blanking interval command? jnz m3 call blank ; set blanking interval jmp mainlp m3 mov a,r2 ; retrieve saved command add a,#-'l ; move stepper left command? jnz m4 call stepl ; step left mov r5,#donmsg ; print "Done." call prtmsg mov a,#$0f ; turn motor off outl p2,a jmp mainlp m4 mov a,r2 ; retrieve saved command add a,#-'r ; move stepper right command? jnz m5 call stepr ; step right mov r5,#donmsg ; print "Done." call prtmsg mov a,#$0f ; turn motor off outl p2,a jmp mainlp m5 mov a,r2 ; retrieve saved command add a,#-'z ; zero stepper position? jnz m6 call zero ; step left mov r5,#donmsg ; print "Done." call prtmsg mov a,#$0f ; turn motor off outl p2,a jmp mainlp m6 jmp mainlp ; Read a hex constant from the serial port. Not case sensitive. ; Must be in the form of: FF (no spaces, no $). Returns value in A ; Uses r0, r1, r5, r6, r7 ; MUST NOT use r2! gethex call hexchr ; get first hex character jf0 gh1 ; error, exit rl a ; multiply by 16 rl a rl a rl a mov r1,a call hexchr ; get second character add a,r1 ; add to first nybble * 16 gh1 ret ; Read a hex character from serial port and perform error checking ; Uses r0. Sets f0 if error. ; NOTE: when adding a two's complement number to the accumulator the carry ; will be set if the accumulator is >= the positive two's complement ; number hexchr call datain ; read first data byte clr f0 ; no errors, yet mov r0,a ; save A while validating the character add a,#-'0 ; is character >= '0'? jnc error ; no, < '0', error! mov a,r0 add a,#-': ; is character <= '9'? (':' is after '9') jnc numeral ; yes, character is a numeral mov a,r0 anl a,#$df ; make upper case mov r0,a add a,#-'A ; is character >= 'A'? jnc error ; no, < 'A" ^ > '9', error! mov a,r0 add a,#-'G ; is character <= 'F'? jc error ; no, > 'F', error! mov a,r0 ; valid alpha character add a,#-'A+10 ; A = 10, B = 11, etc. hc1 ret numeral mov a,r0 ; valid numeric character add a,#-'0 ; '0' = 0, '1' = 1, etc jmp hc1 ; Output an error message error mov r5,#errmsg cpl f0 jmp prtmsg ; Send a message to the terminal - uses r5, r6, r7 and A ; r5 points to the zero-terminated message in page 3 to send prtmsg mov a,r5 ; next character index movp3 a,@a ; get character jz stm2 ; zero terminates call dataout ; send the character inc r5 ; point to next one jmp prtmsg ; keep printing stm2 ret ; Set a new blanking interval and store at blanki ; uses r0, r1, r5, r6, r7 ; MUST NOT use r2! blank call gethex ; read the blanking interval mov r0,#blanki ; store it mov @r0,a mov r5,#bnkmsg ; print "Blanking interval set to $??" call prtmsg mov r1,#blanki call byteout mov a,#13 call dataout mov a,#10 jmp dataout ; Send the "Pinging..." message ; Reset timer ; Use r0 to determine internal blanking interval ; Record up to 5 return pulses and print them ; BUS bit 0 = Polaroid 6500 INIT ; BUS bit 1 = Polaroid 6500 BLNK ; BUS bit 2 = Polaroid 6500 BINH ; Port 1 bit 3 = Polaroid 6500 ECHO ping clr a mov t,a ; clear the timer mov r5,#pngmsg ; print the pinging message call prtmsg mov a,#$f9 outl bus,a ; BINH=Low, BLNK=Low, INIT=Hi strt t ; start timing the echo en tcnti ; allow updating of r5 when overflow plp3 djnz r0,plp3 ; wait for internal blanking mov a,#$fd outl bus,a ; BINH=Hi, BLNK=Low, INIT=Hi mov r0,#data ; start of data storage area mov r5,#0 ; timer MSB = 0 mov r6,#echos ; maximum number of echos to store ; Has the pulse had time to make the 35' loop? (r5=2, t=6) plp1 dis tcnti ; don't update timer while checking time mov a,r5 add a,#-2 jnz ppt1 mov a,t add a,#-6 jnc ppt1 ; Time's up, turn everything off and return mov a,#$f8 ; BINH=Low, BLNK=Low, INIT=Low outl bus,a stop tcnt ; stop counting echo time ret ; Check if an echo has returned ppt1 en tcnti ; allow r5 to be updated for overflow in a,p1 ; is ECHO hi? anl a,#$08 jz plp1 ; no, check to see if time's up ; Reset ECHO and wait for the entire pulse to come through ppt2 mov a,#$fb ; BINH = Low, BLNK = Hi, INIT = Hi outl bus,a mov a,#80 ; was 60 plp2 dec a jnz plp2 mov a,#$f9 ; BINH = Low, BLNK = Low, INIT = Hi outl bus,a ; Record the time and continue looking for more echos mov a,r6 ; maximum number of echos stored? jz plp1 dec r6 dis tcnti ; no, store another mov a,r5 ; r5 holds MSB of timer mov @r0,a ; store the MSB of the time inc r0 mov a,t mov @r0,a ; store the LSB of the time inc r0 ; point to next location jmp plp1 .org $100 ; Send data out from the serial port. Data is grouped in 16-bit ; words with a carriage return/line feed at the ; end. For example: $FFFF[CR][LF] dump mov r5,#scanmsg ; print the "scan data" message call prtmsg mov r1,#data ; point to begining of data tlp mov a,r1 ; compare r1 and r0, if same then done cpl a add a,r0 cpl a jz tdone ; all data sent mov a,#'$ call dataout call byteout ; output the byte at r1 call byteout ; and the next one mov a,#13 ; CR LF call dataout mov a,#10 call dataout jmp tlp ; get next byte tdone mov r5,#donmsg ; print "Done." jmp prtmsg ; Convert an eight bit word stored at the location pointed by r1 to a ; hex string and send to serial port. Increment R1 byteout mov a,@r1 ; get the byte swap a ; use the top nybble first anl a,#$0f add a,#hexcon ; point to the hex conversion table movp3 a,@a ; get the hex number call dataout ; print it mov a,@r1 ; do the same thing with the lower nybble anl a,#$0f add a,#hexcon movp3 a,@a call dataout inc r1 ; point to next byte ret ; When the timer overflows a call is made here to increment the most ; significant byte (MSB) of the echo time stored in r5. ovrflw inc r5 ; increment MSB of timer retr ; read data from serial port into A ; uses r7, r6, and r5 datain in a,p2 ; wait for reset of start bit rrc a jnc datain ; hold while data line is low in2 in a,p2 ; read port 2 bit 0 rrc a ; shift serial data into carry jc in2 ; wait for start bit call hdelay ; get into middle of start bit clr a ; clear current byte mov r7,#8 ; 8 data bits in1 rr a ; shift data byte right 1 byte (1) mov r5,a ; (1) call hdelay ; delay to middle of next bit (4) call hdelay nop in a,p2 ; read data bit (2) anl a,#$01 ; keep only the serial bit (2) orl a,r5 ; put with rest of data byte (1) djnz r7,in1 ; read all 8 bits (2) rr a ; set proper bit placement ret ; send the data in A with one start bit and ~two stop bits ; uses r7, r6 dataout anl p2,#$fd ; send start bit call hdelay ; delay 1/2 baud call hdelay ; delay 1 baud nop call rsout ; send data byte orl p2,#$02 ; send stop bits call hdelay call hdelay call hdelay mov r7,#9 do1 djnz r7,do1 jmp hdelay ; send the byte in A out the RS-232 port at 2400 baud ; uses r7,r6 rsout mov r7,#8 ; send 8 bits send2 rrc a ; shift out LSB jnc send1 ; send carry to p2b7 orl p2,#$02 ; send a 1 jmp send send1 anl p2,#$fd ; send a 0 nop nop send call hdelay ; delay 1/2 baud call hdelay ; delay 1 baud nop ; timing djnz r7,send2 ; send all 8 bits rrc a ; restore A ret ; delay for 1/2 baud time for 2400 baud at 4MHz (55 total cycles per ; half delay; 14 per full-bit delay, 7 per half-bit delay from caller) ; uses r6 hdelay mov r6,#22 ; 2 cycles delay1 djnz r6,delay1 ; 2 cycle2 x r6 = 44 ret ; 2 cycles .org $200 ; Step the sonar motor one step to the left ; Uses A, R0, R1 ; Step sequence: ; 1110 ; 1010 ; 1011 ; 1001 ; 1101 ; 0101 ; 0111 ; 0110 stepl mov r0,#step ; step cycle variable mov a,@r0 ; get the step cycle number inc a ; next cycle number mov r1,a ; if cycle number = 8 then cycle number = 0 add a,#-8 jnz sl1 mov r1,#0 sl1 mov a,r1 mov @r0,a ; save the new step cycle number add a,#stepseq ; index into stepper control values movp3 a,@a outl p2,a ret ; Step the sonar motor one step to the right ; Step sequence is the same as for left step but read from ; bottom to top ; Uses A, R0, R1 stepr mov r0,#step ; step cycle variable mov a,@r0 ; get the step cycle number dec a ; previous cycle number mov r1,a ; if cycle number = -1 then cycle number = 7 cpl a jnz sr1 mov r1,#7 sr1 mov a,r1 mov @r0,a ; save the new step cycle number add a,#stepseq ; index into stepper control values movp3 a,@a outl p2,a ret ; Move the sonar motor to the zero position ; Motor is stepped left until the zero position indicator is 1 ; Uses A, R0, R1 zero mov r0,#0 ; time delay mov r1,#8 zlp1 djnz r0,zlp1 djnz r1,zlp1 call stepl ; step left in a,p2 ; is the zero indicator set? jb3 zero ; yes, return ret .org $300 stmsg .byte 12, "Ralph's Sonar System 1.0" .byte 13, 10 rdymsg .byte 13, 10, "Ready.", 13, 10, 0 scanmsg .byte 13, 10, "Scan Data:", 13, 10, 0 errmsg .byte 13, 10, "Error.", 13, 10, 0 pngmsg .byte "Pinging...", 13, 10, 0 donmsg .byte "Done.", 13, 10, 0 bnkmsg .byte "Internal blanking interval " .byte "set to $", 0 hexcon .byte "0123456789ABCDEF" ; 1110 ; 1010 ; 1011 ; 1001 ; 1101 ; 0101 ; 0111 ; 0110 stepseq .byte $ef,$af,$bf,$9f,$df,$5f,$7f,$6f .end