$title(SIGNETICS Evaluation Board Routine)
$date(8-mar-89)
$pagewidth(132)
$mod751
$debug
$object
;this is the code that went to signetics,not complete but emulates the
;old evaluation board. With cont now initialized!!!!
;
;************************************************************************
; *
; This is the code for the SIGNETIC EVALUATION BOARD. *
; It is based on the code written for the *
; I2C EVALUATION BOARD 1987. *
; *
; PHILIPS (NZ) LTD G.D.MOSS *
; *
;************************************************************************
; This driver will make the board perform like the i2c evaluation
; board. There are conditional statements to enable it to assemble
; for any of the microcontrollers on the board.
;INTERNAL RAM ORGANIZATION
; Internal memory varies from controller to controller, as does
; the special function registers that are present.
; LOCATION USE COMMENTS
; 255 top of ram 87C552, 87C652
; :
; 63 top of ram 87C751, 87C752
; : user ram
; :
; 32 32 to 47 are bit addressable
; 31
; : bank 3 free
; : 8x8
; 24
; 23
; : bank 2 put the stack here
; : 8x8 8 levels deep
; 16
; 15
; : bank 1 used by I2C routines
; : 8x8
; 8
; 7
; : bank 0 for general use
; : 8x8 during programme
; 0 operation
;
;SPECIAL FUNCTION REGISTERS
; * SFR that is bit addressable
; # SFR that is read only
; - SFR that is not on that chip
; ADDRESS 87C51 87C552 87C652 87C751 87C752
; ffh - T3 - - -
; feh - PWMP - - PWENA
; fdh - PWM1 - - -
; fch - PWM0 - - -
; f8h - IP1* - I2STA# I2STA#
; f0h B* B* B* B* B*
; efh - RTE - - -
; eeh - STE - - -
; edh - TMH2# - - -
; ech - TML2# - - -
; ebh - CTCON - - -
; eah - TM2CON - - -
; e8h - IEN1* - - -
; e0h ACC* ACC* ACC* ACC* ACC*
; dbh - S1ADR S1ADR - -
; dah - S1DAT S1DAT - -
; d9h - S1STA# S1STA# - -
; d8h - S1CON* S1CON* I2CFG* I2CFG*
; d0h PSW* PSW* PSW* PSW* PSW*
; cfh - CTH3# - - -
; ceh - CTH2# - - -
; cdh - CTH1# - - -
; cch - CTH0# - - -
; cbh - CMH2 - - -
; cah - CMH1 - - -
; c9h - CMH0 - - -
; c8h - TM2IR* - - -
; c6h - ADCH - - -
; c5h - ADCON - - -
; c4h - P5# - - -
; c0h - P4* - - -
; b8h IP* IP0* IP* - -
; b0h P3* P3* P3* P3* P3*
; afh - CTL3# - - -
; aeh - CTL2# - - -
; adh - CTL1# - - -
; ach - CTL0# - - -
; abh - CML2 - - -
; aah - CML1 - - -
; a9h - CML0 - - -
; a8h IE* IEN0* IE* IE* IE*
; a0h P2* P2* P2* - ADCON*
; 99h SBUF S0BUF S0BUF I2DAT I2DAT
; 98h SCON* S0CON* S0CON* I2CON* I2CON*
; 90h P1* P1* P1* P1* P1*
; 8fh - - - - PWMP
; 8eh - - - - PWCM
; 8dh TH1 TH1 TH1 RTH RTH
; 8ch TH0 TH0 TH0 TH TH
; 8bh TL1 TL1 TL1 RTL RTL
; 8ah TL0 TL0 TL0 TL TL
; 89h TMOD TMOD TMOD - -
; 88h TCON* TCON* TCON* TCON* TCON*
; 87h PCON PCON PCON PCON PCON
; 84h - - - - ADAT
; 83h DPH DPH DPH DPH DPH
; 82h DPL DPL DPL DPL DPL
; 81h SP SP SP SP SP
; 80h P0* P0* P0* P0* P0*
;
;DEFINE REGISTER USAGE
; bank 0
; R0 general purpose pointer into the ram
; R1 points into transfer buffer
; R2 loop counter,general purpose
; R3 general purpose
; R4 free
; R5 program control byte
; bits 1,0 4 mode counter
; R6 switch data
; R7 free
;
; bank 1 for iic communications
; R0 bit counter for 87c751/87c752 routine
; R1 points into tbuff
; R2 iic tx count
; R3 iic rx count
; R4 iic address
; R5 iic loop counter
; R6 free
; R7 free
;
;THE SYSTEM CLOCK IS AT 11.059 MHz
;
;DEFINE CONSTANTS
true equ -1 ;define "true"
false equ not true ;define "false"
c552 equ false ;NOTE: only one of these to
c652 equ false ; be true at any
c751 equ true ; one time!!!
c752 equ false ;
;
if c751 or c752
;redefine bits for i2con for mov instructions
bcxa equ 80h
bidle equ 40h
bcdr equ 20h
bcarl equ 10h
bcstr equ 08h
bcstp equ 04h
bxstr equ 02h
bxstp equ 01h
;redefine bits for i2cfg for mov instructions
bslaven equ 80h
bmastrq equ 40h
bclrti equ 20h
btirun equ 10h
;misc constants for the 87c751/87c752
maxscl equ 00000010b ;ct1,ct0 max xtal of 16MHz
intcon equ 88h ;ea=1, ei2=0, et1=1, ex1=0, et0=0, ex0=0
endif
;
;DEFINE INTERNAL DATA STORAGE
stack data 16 ;8 level stack, allow 2 register banks
cont data stack+16 ;control 'register' bit addressable
clk1 data cont+1 ;clock 1, .10:.01 seconds
clk2 data clk1+1 ;clock 2, 10:1 seconds
clk3 data clk2+1 ;clock 3, 10:1 minutes
clk4 data clk3+1 ;clock 4, 10:1 hours
dat1 data clk4+1 ;clock 5, 10:1 days
dat2 data dat1+1 ;clock 6, 10:1 months
alm1 data dat2+1 ;clock 11, 10:1 minutes
alm2 data alm1+1 ;clock 12, 10:1 hours
mod1 data alm2+1 ;used by clock modify routine
mod2 data mod1+1 ;also used by clock modify routine
dtoa data mod2+1 ;doa output value
keycnt data dtoa+1 ;key input counter
tone data keycnt+1 ;storage for dtmf tone
tbuff data tone+1 ;transfer buffer for I2C operations
ebuff data tbuff+8 ;eeprom buffer
free data ebuff+6 ;first free location
;
if free gt 63 ;keep below 87c751 limit
out of internal memory
endif
;
;DEFINE SFR BIT USAGE, FOR CONT REGISTER LOCATION MUST BE 20H !!
sdv bit 0 ;switch data valid
dmod bit 1 ;data modified
xmode bit 2 ;extra mode switch
aset bit 4 ;alarm is set flag
aring bit 5 ;alarm ringing flag
;
;IIC CHIP ADDRESSES
iop equ 01001110b ;PCF8574
iopa equ 01111110b ;PCF8574A
dtmf equ 01001010b ;PCD3312
irtc equ 01001100b ;SAA3028
led equ 01110110b ;SAA1064
lcd equ 01110100b ;PCF8577
atod equ 10011110b ;PCF8591
clock equ 10100010b ;PCF8583
ram equ 10101110b ;PCF8570
eeprom equ 10100110b ;PCF8582
;
;SERIAL I/O CLOCK FREQUENCY AND CONTROL BYTES
;
;IIC CHIP CONTROL BYTES
lcdctl equ 00000000b ;lcd subaddress
ledctl equ 01000111b ;initial led brightness value
clkctl equ 00001100b ;clock control,masked,alarm active
alctl1 equ 11001001b ;alarm control,no clock alarm,timer
alctl2 equ 11011001b ;alarm control,clock daily alarm,timer
adcctl equ 01000100b ;output on,4 inputs,inc,a/d channel 0
dacctl equ 01000000b ;output on
;
;MISC CONSTANTS
dtmfb equ 00111111b ;tone for second beep 1768Hz
dtmft equ 00110101b ;first tone of alarm ringing 832Hz
dtmfo equ 00000001b ;turns the dtmf oscillator off
keyval equ 5 ;number of key reads before valid
;
;
;THIS IS THE MAIN PROGRAMME.
org 0000h
reset: sjmp start ;allow for all 87c552 interrupts
org 0003h
xint0: sjmp reset ;trap external interrupt 0, 87C652, 87C751
org 000bh
t0of: sjmp reset ;trap timer 0 overflow, 87C652, 87C751
org 0013h
xint1: sjmp reset ;trap external interrupt 1, 87C652, 87C751
org 001bh
t1of: ajmp tout ;trap timer 1 overflow, 87C652, 87C751
org 0023h
uart: sjmp reset ;trap uart interrupt, 87C652
org 002bh
i2c: sjmp reset ;trap i2c interrupt, 87C652
org 0033h
t2ct0: sjmp reset ;trap t2 capture 0 interrupt
org 003bh
t2ct1: sjmp reset ;trap t2 capture 1 interrupt
org 0043h
t2ct2: sjmp reset ;trap t2 capture 2 interrupt
org 004bh
t2ct3: sjmp reset ;trap t2 capture 3 interrupt
org 0053h
adccom: sjmp reset ;trap adc completion interrupt
org 005bh
t2cm0: sjmp reset ;trap t2 compare 0 interrupt
org 0063h
t2cm1: sjmp reset ;trap t2 compare 1 interrupt
org 006bh
t2cm2: sjmp reset ;trap t2 compare 2 interrupt
org 0073h
t2of: sjmp reset ;trap timer 2 overflow
;
org 0080h
;
;************************************************************************
; *
; Here is the initialization routine. *
; The first job is to put the I2C interface into the *
; slave receive mode at the speed set in the equate table. *
; *
;************************************************************************
;NOTE: some chips, inparticular large lcd drivers require some time
;to get ready before you write to them. You may want to alter the delay
;for your aplication.
;initialize iic interface
start: mov r0,#00h
mov r1,#20
djnz r0,$
djnz r1,$-2
if c552 or c652
mov p1,#p1init ;initialize the i/o port
mov s1con,#clkack ;sets up the iic hardware
mov ie,#00h ;turn off all the interupts
endif
if c751 or c752
mov i2cfg,#bslaven+maxscl+btirun
mov ie,#intcon ;interrupt control value
endif
mov sp,#stack-1 ;initialize stack pointer
mov r5,#00h ;set lcd,led mode time,seconds
mov r6,#00h ;clear old data
mov cont,#00h ;initialize control bits in sfr map
mov keycnt,#00h ;initialize key counter
mov tone,#dtmft ;initial tone value
;initialize clock /alarm control modes
mov tbuff,#00h ;word address to 0
mov tbuff+1,#clkctl ;clock control
setb rs0 ;select register bank 1
mov r2,#02h ;tx = 2
mov r3,#00h ;rx = 0
mov r4,#clock ;address = clock
acall iic ;send control to clock
;no need to restore the register bank yet
mov tbuff,#08h ;word address to 8
mov tbuff+1,#alctl1 ;alarm control, no clock alarm
mov r2,#02h ;tx = 2
mov r3,#00h ;rx = 0
mov r4,#clock
acall iic ;send alarm control to clock
;initialize the led brightness and operating mode
mov tbuff,#00h ;instruction to 0
mov tbuff+1,#ledctl
mov r2,#02 ;tx = 2
mov r3,#00 ;rx = 0
mov r4,#led ;address = led
acall iic
;now restore register bank
clr rs0 ;select register bank 0
;
;This is the return point for the main loop
main: acall keytin ;get any key entry
acall rdclk ;get time/alarm data from clock
;now increment and output the dtoa value
dtoaop: inc dtoa ;increment output value
mov tbuff,#dacctl ;set digital control word
mov tbuff+1,dtoa ;output value
setb rs0 ;select register bank 1
mov r2,#02 ;tx = 2
mov r3,#00 ;rx = 0
mov r4,#atod ;address = atod
acall iic
clr rs0 ;select register bank 0
;now get and decode the switch data
swip: jb xmode,swipx ;exit as in modify mode
jb sdv,swip1 ;test key valid flag and jump else
sjmp proc ;otherwise process display modes
swip1: mov a,r6 ;get the switch data
jb acc.2,ledbr ;decrement the led brightness
jb acc.1,almtog ;toggle the alarm on/off
jb acc.0,lcdcnt ;alter lcd mode byte
swipx: sjmp proc
;
;LEDBR controls the led brightness.
;There are 8 steps of led current available. Depending on the
;characteristics of the led used some brightness steps might not be visable.
;The program limits the led brightness to 4 steps because of the above.
ledbr: clr sdv ;zero key valid flag
mov keycnt,#00 ;zero input counter
mov a,r4 ;get old value
add a,#-10h ;decement
mov r4,a ;save new value
anl a,#30h ;limit values to 0 to 3
mov tbuff,#00 ;instruction = 0
add a,#17h ;add 10h + led control bits
mov tbuff+1,a ;so output values 1 to 4
setb rs0 ;select register bank 1
mov r2,#02 ;tx = 2
mov r3,#00 ;rx = 0
mov r4,#led ;address = led
acall iic ;write the led brightness value
clr rs0 ;select register bank 0
sjmp proc ;done
;
;ALMTOG turns the alarm on if it was off and if it was off it
;turns it on. It reverts the display to time so the alarm status
;can be seen.
almtog: clr sdv ;zero key valid flag
mov keycnt,#00 ;zero key counter
mov a,r5
anl a,#00fh ;check mode
jnz almtx ;only turn alarm on if time displayed
cpl aset ;toggle alarm bit
clr aring ;make sure the alarm stops ringing
mov tbuff,#08h ;alarm control register
mov tbuff+1,#alctl2 ;get ready to turn alarm on
jb aset,almt ;jump if turning alarm on
mov tbuff+1,#alctl1 ;get ready to turn alarm off
almt: setb rs0 ;select register bank 1
mov r2,#02
mov r3,#00
mov r4,#clock
acall iic ;send two bytes
clr rs0 ;select register bank 0
mov tbuff,#dtmfo ;turn off any tone
setb rs0 ;select register bank 1
mov r2,#01 ;tx = 1
mov r3,#00 ;rx = 0
mov r4,#dtmf ;address of dtmf
acall iic ;turn tone off
clr rs0 ;select register bank 0
almtx: sjmp proc
;
;LCDCNT controls both the lcd and the led modes of display.
;The lcd has 4 modes 00 = clock(set) 01 = alarm(set)
; 02 = date(set) 03 = A--d(display)
lcdcnt: clr sdv ;zero key valid flag
mov keycnt,#00 ;zero input counter
mov a,r5 ;get programme control byte
inc a
anl a,#0f3h ;2 bit counter, leave led brightness
mov r5,a ;put it back
lcdx: sjmp proc
;
;PROC processes the programme control byte
proc: mov a,r5 ;get programme control byte
anl a,#0fh ;mask program mode
acall jlcd ;decide where to jump
jnb aring,lcddis ;if alarm not ringing display normal
mov a,clk2 ;get the seconds
jb acc.0,lcddis
;blank display if alarm ringing and seconds are odd
mov r1,#tbuff+4
mov r2,#04h
blank: mov a,@r1 ;get non converted data
anl a,#20h ;leave the colon bit
orl a,#10h ;make it a blank
mov @r1,a ;put it back
dec r1
djnz r2,blank ;do all four characters
lcddis: mov tbuff,#lcdctl
mov dptr,#lcdtbl
mov r1,#tbuff+1
mov r2,#04h ;4 to encode
acall cnvrt ;change to displayable
setb rs0 ;select register bank 1
mov r2,#05
mov r3,#00
mov r4,#lcd
acall iic ;send to display
clr rs0 ;select register bank 0
mov a,r5 ;get programme control byte
anl a,#0fh ;mask program mode
acall jled ;decide where to jump
mov tbuff,#01h ;led instruction address 01
mov dptr,#ledtbl
mov r1,#tbuff+1
mov r2,#04h ;4 to encode
acall cnvrt ;change it to displayable
setb rs0 ;select register bank 1
mov r2,#05h
mov r3,#00
mov r4,#led
acall iic ;to display
clr rs0 ;select register bank 0
mov r0,#0ffh ;this delay alters keyboard response
mov r1,#04fh ;and dtoa ramp rate
delay: djnz r0,delay
djnz r1,delay
ajmp main
;
;************************************************************************
; *
; The flow of data from the peripheral devices to the *
; displays is controlled by the low nibble stored in register R5 *
; JLCD directs the programme to the lcd routines. *
; JLED directs the programme to the led routines. *
; NOTE this must be called so that each display processor *
; will return to PROC. *
; *
;************************************************************************
;
jlcd: mov dptr,#jmplcd
rl a
jmp @a+dptr
jled: mov dptr,#jmpled
rl a
jmp @a+dptr
;
; short jumps
jmplcd: ajmp clkp
ajmp almp
ajmp datp
ajmp atodp
;
jmpled: ajmp secp
ajmp secp
ajmp secp
ajmp dtoap
;
atodp: jb xmode,atodm ;jump to xmode routine
;Check to see if button 4 has been pressed etc.
atodp0: jnb sdv,atodpd ;jump if buttons not valid
mov a,r6 ;get key data
jnb acc.3,atodpd ;jump if not button 4
clr sdv ;zero flag so that only 1 keypress
mov keycnt,#00h ;zero input counter
setb xmode ;turn on xmode bit
atodpd: mov tbuff+1,#00ah ;A
mov tbuff+2,#017h ;-
mov tbuff+3,#017h ;-
mov tbuff+4,#00dh ;d
ret
atodm: jnb sdv,atodm1 ;test if valid button, jump if not
clr sdv ;zero flag so that only 1 keypress
mov keycnt,#00h ;zero input counter
clr xmode ;zero extra mode
mov r5,#00h ;lcd = time led = seconds
atodm1: mov tbuff,#adcctl ;set analogue control word
setb rs0 ;select register bank 1
mov r2,#01 ;tx = 1
mov r3,#01 ;rx = 1
mov r4,#atod ;address = atod
acall iic
clr rs0 ;select register bank 0
mov a,tbuff ;get data
mov tbuff+1,#10h ;blank
mov r0,#tbuff+3
acall htod ;convert to bcd
ret ;done
dtoap: mov a,dtoa ;get byte
mov tbuff+1,#10h ;a blank
mov r0,#tbuff+3 ;point to where the 10's digit is to go
acall htod ;convert to decimal
ret
;
;ROMWR write to the PCF8582 eeprom chip.
;Due to the added complexity of the eeprom write routine,any data
;to be transfered is loaded into a special buffer.This buffer is
;10 bytes long but could be made longer by altering the equate table.
;The first byte in the buffer are the number of data bytes.The next
;byte is the internal word address and the rest of the buffer,upto 8
;bytes,is filled with data for consecutive memory locations in the chip.
;The PCB8582 takes 30ms to process each written byte.
;If the PCB8582 is still busy processing the last data written to it,
;it will not acknowledge its write address so the routine will exit
;without altering the buffer contents.If it is sucessful in writing
;upto 2 bytes to the chip then the buffer contents will be altered to
;reflect this fact.
;On exit,the first byte in the buffer will be the number of bytes
;still to be sent.This will be zero when the buffer is free.
;The second byte is the address of the next memory location to be written
;to.The buffer data contents are moved to the start of the buffer ready
;for the next time the routine is used.
romwr: mov r0,#ebuff ;point to eeprom buffer
mov r1,#tbuff ;point to transfer buffer
mov r2,#00h ;number sent counter
mov a,@r0 ;get the number to send
jz romwrx ;exit if none left to send
mov r3,a ;save the number to send
inc r0 ;point to word address
mov a,@r0 ;get the word address
mov @r1,a ;put word address into buffer
inc r0 ;point to 1st data byte
inc r1
mov a,@r0 ;get 1st data byte
mov @r1,a ;put 1st data byte
inc r2 ;up the number sent counter
dec r3 ;down the number to send counter
mov a,r3
jz romwrs ;only 1 to send
inc r0
inc r1
mov a,@r0 ;get 2nd data byte
mov @r1,a ;put 2nd data byte
inc r2
dec r3
romwrs: mov a,r2 ;get the number to send
inc a ;make allowance for word address
setb rs0 ;select register bank 1
mov r2,a ;tx = accu+1
mov r3,#00h ;rx = 0
mov r4,#eeprom ;set the address
acall iic
clr rs0 ;select register bank 0
jnz romwrx ;none zero is a failure
mov r1,#ebuff ;point to start of ebuff
mov a,r3 ;get new number to send
mov @r1,a ;save it for next time
inc r1 ;point to word address
mov a,@r1 ;get the old address
add a,r2 ;add in the number sent
mov @r1,a ;save it for next time
romwrm: inc r1 ;point to first data byte
inc r0 ;point to first non sent byte
mov a,r3 ;get number to send/move
jz romwrx ;if zero exit
mov a,@r0
mov @r1,a
dec r3
sjmp romwrm ;jump back more to move
romwrx: ret ;done until next time
;
;************************************************************************
; THESE ARE THE IIC I/O ROUTINES ONLY *
; THEY EMULATE THE ROUTINES USED ON THE 1987 *
; EVALUATION BOARD.AT THIS TIME THESE ARE NOT *
; PROVEN ON HARDWARE. *
;************************************************************************
; *
; SERIAL INTERFACE SOFTWARE ROUTINES *
; ACCESSED BY call iic *
; REGISTER BANK 1 WILL BE USED EXCLUSIVELY FOR SIO ROUTINES *
; REGISTER USAGE *
; R'0 USED BY 87C751 AS A BIT COUNTER *
; R'1 POINTS TO THE TX/RX BUFFER *
; R'2 HOLDS THE NUMBER TO TRANSMIT *
; R'3 HOLDS THE NUMBER TO RECEIVE *
; R'4 SLAVE ADDRESS R/W BIT = 0 *
; R'5 TX/RX COUNTER *
; *
;************************************************************************
; 8 DATA BYTES IS THE MAXIMUM THAT CAN BE SENT OR RECIEVED *
; THIS IS DUE TO THE SIZE OF TBUFF BUT CAN BE EASILY ALTERED *
; ON ENTRY: *
; R'2 NUMBER OF BYTES TO TX *
; R'3 NUMBER OF BYTE TO RX *
; R'4 SLAVE ADDRESS *
; ON EXIT: *
; ACCU 00 IF TRANSFER OK *
; 01 IF NOT ACKNOWLEDGED *
; FF IF A BUS ERROR OCCURED *
; R'1 POINTS TO LAST READ BYTE *
; *
;************************************************************************
;
;
if c552 or c652
;************************************************************************
; *
; TRIAL I2C ROUTINES FOR THE 80C552/652 DEVICES *
; Incoperating corrections from G.W.DUMBLETON *
; His corrections are in upper case to make them *
; easily seen, but some of them I feel are in fact *
; not required.This will be tested when I have some *
; hardware to play with. *
; *
; 24th NOVEMBER 1987 *
; *
; PHILIPS (NZ) LTD G.D.MOSS *
; *
;************************************************************************
iic: mov r1,#tbuff
mov s1con,#clkack ;reset sio status
;generate the address with the rd/wr bit correctly set
mov a,r2 ;get tx count
jz rdadd ;r/w = 0
mov a,#01h ;set for rx
rdadd: orl a,r4 ;get address
xrl a,#01h ;invert rd wr bit
; mov s1dat,a ;load address to send
MOV R7,A ;TEMP SAVE WHY NOT IN THE DATA REGISTER
setb sta ;generate a start condition
sjmp wsi1 ;wait for si = 1,status should be 08h
;the bus was not busy and a valid start condition was generated 08h
iics: CLR STA ;SO WE DON'T GENERATED REPEATED STARTS
MOV A,R7 ;THIS SHOULD NOT BE REQUIRED
MOV S1DAT,A ;BUT WE WILL SEE WITH SOME HARDWARE
clr si ;this will now transmit the address
sjmp wsi1 ;wait for si = 1,status 18h 20h 40h 48h
;the bus was freed and a restart was generated 10h
iicrs: CLR STA ;NOT REPEATED REPEATED STARTS
mov a,r4 ;get the address
orl a,#01h ;make it a read
mov s1dat,a ;ready it for sending
clr si ;send the address on its way
sjmp wsi1 ;wait for si = 1,status 40h 48h
;now in master tx mode so tx first byte 18h
mtxa: mov a,r2 ;get the number to send
mov r5,a ;load the tx counter with it
mov a,@r1 ;get data to send
mov s1dat,a ;put it where it will be sent from
clr si ;send it on its way
sjmp wsi1 ;wait for si = 1,status 28h 30h
;in master tx mode see if any more to tx 28h
mtxd: djnz r5,mtxd1 ;jump if multiple bytes to send
mov a,r3 ;get number to read
jz stopok ;none so stop
setb sta ;generate a repeated start
CLR SI ;START THE REPEATED START
sjmp wsi1 ;wait for si = 1,status 10h
mtxd1: inc r1 ;point to next byte to send
mov a,@r1
mov s1dat,a ;ready it for sending
clr si
sjmp wsi1 ;wait for si = 1,status 28h 30h
;read address sent and device acknowledged,read first byte 40h
mrxa: mov r1,#tbuff ;point to buffer
mov a,r3 ;get receiver count
mov r5,a ;load the counter with it
djnz r5,rdmlti ;jmup if more than 1 byte to read
rdlast: clr aa ;set interface to not acknowledge
rdmlti: clr si ;start it on its way
sjmp wsi1 ;wait for si = 1,status 50h 58h
;read multiple bytes until its the last byte 50h
mrxd: mov a,s1dat ;get the received byte
mov @r1,a ;put it into tbuff