;*** Bus bit mask .equ SMASK, 0x07 ;S bus is port_d bits 0-2 .equ KMASK, 0x0f ;K bus is port_1 bits 0-3 .equ STMASK, 0x03 ;Status register bits 0-1 on S bus ;*** States for speech recognition chip - S3 S2 S1 .equ NULL, 0x02 ;Null state .equ RDSTATUS, 0x02 ;Read status from K-bus - 010 .equ RDOUTPUT, 0x03 ;Read output buffer from K-bus - 011 .equ WRINPUT, 0x04 ;Write input buffer on K-bus - 100 ;*** Status codes .equ RDYHI, 0x00 ;Ready for second (HI) nibble .equ RDYVOICE, 0x01 ;Ready for voice input .equ RDYCMD, 0x02 ;Ready to receive command .equ RDYLO, 0x03 ;Ready for first (LOW) nibble ;*** Command codes .equ CMDRECOG, 0x01 ;Recognize word .equ CMDTRAIN, 0x02 ;Train a pattern .equ CMDRESULT, 0x04 ;Read result and score .equ CMDRESET, 0x07 ;Clear all patterns from HM2007 ;*** Result codes .equ TOOSLOW, 0x55 ;Voice was too long (slow) .equ TOOFAST, 0x66 ;Voice was too short (fast) .equ NOTFOUND, 0x77 ;Voice was not found .equ flags, 0x20 ;don't let stack overwrite this! ;*** flags (in 0x20) .equ dir_a, 0 ;set = input, clear = output .equ dir_b, 1 .equ dir_c, 2 .equ dir_d, 3 .equ dir_e, 4 .equ dir_f, 5 ;*** 82C55 memory locations .equ port_a, 0x4000 .equ port_b, 0x4001 .equ port_c, 0x4002 .equ port_abc_pgm, 0x4003 .equ port_d, 0x6000 .equ port_e, 0x6001 .equ port_f, 0x6002 .equ port_def_pgm, 0x6003 .org 0x2100 ; setb psw.3 ; clr psw.4 setb psw.3 setb psw.4 MAIN: mov p1, 0x00 lcall INIT lcall TRAINWORDS MAIN1: lcall WORDRECOG cjne a, #1, MAIN1 lcall GETWORD ; lcall SIGNAL sjmp MAIN1 TRAINWORDS: mov r0, #0x09 ;number of words to train WORDS1: cjne r0, #0x00, WORDS2 ret WORDS2: lcall TRAIN dec r0 sjmp WORDS1 TRAIN: mov a, #RDSTATUS lcall OUTS TRAIN1: lcall INST cjne a, #RDYCMD, TRAIN1 mov a, #WRINPUT lcall OUTS mov a, #CMDTRAIN lcall OUTK lcall INK lcall WAIT mov a, #RDSTATUS lcall OUTS TRAIN2: lcall INST cjne a, #RDYCMD, TRAIN3 ljmp TRAIN TRAIN3: cjne a, #RDYLO, TRAIN2 mov a, #WRINPUT lcall OUTS mov a, r0 ;low nibble of word lcall OUTK lcall INK mov a, #RDSTATUS lcall OUTS TRAIN4: lcall INST cjne a, #RDYHI, TRAIN4 mov a, #WRINPUT lcall OUTS mov a, #1 ;High 2 bit of the word lcall OUTK lcall INK mov a, #RDSTATUS lcall OUTS TRAIN5: lcall INST cjne a, #RDYCMD, TRAIN5 ret WORDRECOG: mov a, #RDSTATUS lcall OUTS lcall INST cjne a, #RDYCMD, WORDRECOG1 lcall RECOG mov a, #1 ret WORDRECOG1: clr a ret RECOG: mov a, #RDSTATUS lcall OUTS RECOG1: lcall INST cjne a, #RDYCMD, RECOG1 mov a, #WRINPUT lcall OUTS mov a, #CMDRECOG lcall OUTK lcall INK lcall WAIT mov a, #RDSTATUS lcall OUTS RECOG2: lcall INST cjne a, #RDYCMD, RECOG2 ret INIT: mov a, #RDSTATUS lcall OUTS CLR_1: lcall INST cjne a, #RDYCMD, CLR_1 mov a, #WRINPUT lcall OUTS mov a, #CMDRESET lcall OUTK lcall WAIT mov a, #RDSTATUS lcall OUTS ret GETWORD: mov a, #RDSTATUS lcall OUTS GETWORD1: lcall INST cjne a, #RDYCMD, GETWORD1 mov a, #WRINPUT lcall OUTS mov a, #CMDRESULT lcall OUTK lcall INK lcall WAIT mov r5, #0x01 lcall READLOHI dec r5 lcall READLOHI CHECK1: cjne r1, #0x09, CHECK2 sjmp WORD3 CHECK2: cjne r1, #0x08, CHECK3 sjmp WORD3 CHECK3: cjne r1, #0x07, CHECK4 sjmp WORD3 CHECK4: cjne r1, #0x06, CHECK5 sjmp WORD2 CHECK5: cjne r1, #0x05, CHECK6 sjmp WORD2 CHECK6: cjne r1, #0x04, CHECK7 sjmp WORD2 CHECK7: cjne r1, #0x03, CHECK8 sjmp WORD1 CHECK8: cjne r1, #0x02, CHECK9 sjmp WORD1 CHECK9: cjne r1, #0x01, CHECK10 sjmp WORD1 CHECK10: ret WORD1: ;forward clr p1.1 ljmp PWM WORD2: ;reverse setb p1.1 ljmp PWM WORD3: lcall SIGNAL READLOHI: mov a, #RDSTATUS lcall OUTS RLH1: lcall INST cjne a, #RDYLO, RLH1 mov a, #RDOUTPUT lcall OUTS lcall INK cjne r5, #0x01, RLH2 mov r1, a ;save low word byte RLH2: mov a, #0x05 lcall OUTS mov a, #0x01 lcall OUTS mov a, #0x00 lcall OUTS mov a, #RDSTATUS lcall OUTS RLH3: lcall INST cjne a, #RDYHI, RLH3 mov a, #RDOUTPUT lcall OUTS lcall INK cjne r5, #0x01, RLH4 mov r2, a ;save high word byte RLH4: mov a, #0x05 lcall OUTS mov a, #0x01 lcall OUTS mov a, #0x00 lcall OUTS mov a, #RDSTATUS lcall OUTS lcall INST ret OUTK: ;mov p1, a ;lcall BUSWAIT ;ret lcall wr_port_d lcall BUSWAIT ret OUTS: ;lcall wr_port_a ;mov p1, #KMASK ;lcall BUSWAIT ;ret lcall wr_port_a lcall BUSWAIT ret INK: ;mov acc, p1 ;ret lcall rd_port_d ret INST: ;mov a, p1 ;anl a, #STMASK ;ret lcall rd_port_d anl a, #STMASK ret WAIT: mov a, #255 LOOP: dec a nop nop nop nop nop nop nop nop nop nop nop nop jnz LOOP ret WAIT1: mov r2, #0x0f LOOPC1: mov r1, #0xff LOOPB1: mov r0, #0xff LOOPA1: dec r0 cjne r0, #0x00, LOOPA1 dec r1 cjne r1, #0x00, LOOPB1 dec r2 cjne r2, #0x00, LOOPC1 ret WAIT2: mov r2, #0x01 LOOPC2: mov r1, #0x02 LOOPB2: mov r0, #0x02 LOOPA2: dec r0 cjne r0, #0x00, LOOPA2 dec r1 cjne r1, #0x00, LOOPB2 dec r2 cjne r2, #0x00, LOOPC2 ret BUSWAIT: nop nop ret TEST: mov a, #0xff lcall wr_port_d sjmp TEST SIGNAL: mov a, #0x00 lcall wr_port_f lcall WAIT1 mov a, #0xff lcall wr_port_f lcall WAIT1 ljmp SIGNAL SIGNAL1: mov a, #0x00 lcall wr_port_f lcall WAIT mov a, #0xff lcall wr_port_f lcall WAIT ret PWM: setb p1.0 PWM1: cpl p1.0 mov r2, #0x10 loopc: mov r1, #0x10 loopb: mov r0, #0x10 loopa: dec r0 cjne r0, #0x00, loopa dec r1 cjne r1, #0x00, loopb dec r2 cjne r2, #0x00, loopc sjmp PWM1 ;Code to interact w/ 8255 chips... not efficient, but it makes ;thing easier above. Just call rd_port_x (value returned in acc) ;or wr_port_x (uses value in acc). ;note, dir_a through dir_f must be defined as bit addressable ;locations, which are used to remember what ports are configured ;for input or output. rd_port_a: jnb dir_a, rdpta2 push dpl push dph mov dptr, #port_a clr a movc a, @a+dptr pop dph pop dpl ret rdpta2: setb dir_a lcall cfg_abc sjmp rd_port_a rd_port_b: jnb dir_b, rdptb2 push dpl push dph mov dptr, #port_b clr a movc a, @a+dptr pop dph pop dpl ret rdptb2: setb dir_b lcall cfg_abc sjmp rd_port_b rd_port_c: jnb dir_c, rdptc2 push dpl push dph mov dptr, #port_c clr a movc a, @a+dptr pop dph pop dpl ret rdptc2: setb dir_c lcall cfg_abc sjmp rd_port_c rd_port_d: jnb dir_d, rdptd2 push dpl push dph mov dptr, #port_d clr a movc a, @a+dptr pop dph pop dpl ret rdptd2: setb dir_d lcall cfg_def sjmp rd_port_d rd_port_e: jnb dir_e, rdpte2 push dpl push dph mov dptr, #port_e clr a movc a, @a+dptr pop dph pop dpl ret rdpte2: setb dir_e lcall cfg_def sjmp rd_port_e rd_port_f: jnb dir_f, rdptf2 push dpl push dph mov dptr, #port_f clr a movc a, @a+dptr pop dph pop dpl ret rdptf2: setb dir_f lcall cfg_def sjmp rd_port_f wr_port_a: jb dir_a, wrpta2 push dpl push dph mov dptr, #port_a movx @dptr, a pop dph pop dpl ret wrpta2: clr dir_a lcall cfg_abc sjmp wr_port_a wr_port_b: jb dir_b, wrptb2 push dpl push dph mov dptr, #port_b movx @dptr, a pop dph pop dpl ret wrptb2: clr dir_b lcall cfg_abc sjmp wr_port_b wr_port_c: jb dir_c, wrptc2 push dpl push dph mov dptr, #port_c movx @dptr, a pop dph pop dpl ret wrptc2: clr dir_c lcall cfg_abc sjmp wr_port_c wr_port_d: jb dir_d, wrptd2 push dpl push dph mov dptr, #port_d movx @dptr, a pop dph pop dpl ret wrptd2: clr dir_d lcall cfg_def sjmp wr_port_d wr_port_e: jb dir_e, wrpte2 push dpl push dph mov dptr, #port_e movx @dptr, a pop dph pop dpl ret wrpte2: clr dir_e lcall cfg_def sjmp wr_port_e wr_port_f: jb dir_f, wrptf2 push dpl push dph mov dptr, #port_f movx @dptr, a pop dph pop dpl ret wrptf2: clr dir_f lcall cfg_def sjmp wr_port_f cfg_abc: push acc push dpl push dph clr a mov c, dir_a mov acc.0, c mov c, dir_b mov acc.1, c mov c, dir_c mov acc.2, c mov dptr, #cfg_table movc a, @a+dptr mov dptr, #port_abc_pgm movx @dptr, a pop dph pop dpl pop acc ret cfg_def: push acc push dpl push dph clr a mov c, dir_d mov acc.0, c mov c, dir_e mov acc.1, c mov c, dir_f mov acc.2, c mov dptr, #cfg_table movc a, @a+dptr mov dptr, #port_def_pgm movx @dptr, a pop dph pop dpl pop acc ret cfg_table: .db 10000000b ;c=out b=out a=out .db 10010000b ;c=out b=out a=in .db 10000010b ;c=out b=in a=out .db 10010010b ;c=out b=in a=in .db 10001001b ;c=in b=out a=out .db 10011001b ;c=in b=out a=in .db 10001011b ;c=in b=in a=out .db 10011011b ;c=in b=in a=in