;--------------------------------------------------------- ; cavr64 : c64<->avr protocol ; target system: hummerdtv ; ; (c) 2006 by doug garmon ; gnu public license ; http://www.gnu.org/copyleft/gpl.html ;--------------------------------------------------------- ; primary commands -- 8 total (3 bits) ;--------------------------------------------------------- cmd_status = %00000000 ; 0 read status cmd_user1 = %00100000 ; 32 user 1 cmd_rd_adcarray = %01000000 ; 64 read multi adc values based on AVR array cmd_rd_keys = %01100000 ; 96 read button presses cmd_user2 = %10000000 ; 128 user 2 cmd_user3 = %10100000 ; 160 user 3 cmd_rd_data = %11000000 ; 192 multibyte read cmd_extended = %11100000 ; 224 extended command ;---------------------------------------------------------- ; extended commands -- 512 possible (9 bits) ;---------------------------------------------------------- ; cmd read/write ; # bytes ext_null = 0 ; - ext_reset = 1 ; - reset settings/variables ext_hardreset = 2 ; - hard reset on AVR now functional ext_test = 3 ; - ext_reset_status = 4 ; - reset status msgs to start ext_adcchan = 10 ; W1 set channel for single adc read ext_adcarray = 11 ; W4 set the array values, 2/byte, upper/lower nibbles ext_adcarraymax = 12 ; W1 total # of channels to read ext_data_nterm = 64 ; - set data sent to null-terminated ext_data_blk = 65 ; - set data send to block ext_data_ldinfo = 66 ; R5 get loadadd/length of block ext_data_name = 67 ; R24 get filename ext_toggle_0 = 200 ; - toggle output line 0 ext_output_reset = 216 ; - output to default state ;---------------------------------------------------------- ; signals clk_lo = %00001000 ; clk lo, always holding attn hi clk_hi = %00011000 ; clk hi, attn still hi attn_hi = clk_lo ; attn hi -- normal wait state attn_lo = $00 ; attn lo -- attn activate ddr_output = %11111111 ; ddr output setting ddr_input = %00011111 ; ddr input setting datamask = %11100000 ; 3 data transfer bits ddr = $dd03 ; ddr for io ioport = $dd01 ; io port (userport for hummer) store = $fb ; variable zstore = $fd ; zeropage variable inbuffer = $cf00 ; data buffer chrout = $f1ca ; kernal print ;---------code begins here-------------------------------- *=$c000 jumptable jmp read jmp readdata jmp printdata jmp sendextcmd jmp sendextdata jmp getextdata jmp readbinary jmp gimme8 jmp gimme8 jmp gimme8 ;---------------------------------------------------------- ; data section command .byte cmd_rd_adcarray datatosend .word ext_adcchan ; 9 bits to send (word) ; default # for ext_adcarray extended cmd sendlen .byte 4 ; # of bytes to send (sendextdata) recvlen .byte 5 ; # of byte to return (getextdata) ; i/o buffers sendbuffer .byte 5, 4, 3, 2, 1, 0, 0, 0 readbuffer .byte 0, 0, 0, 0, 0, 0, 0, 0 ;---------------------------------------------------------- ; sent attn sig start lda #ddr_output ; set ddr to output sta ddr lda #attn_hi ; set attn sig hi sta ioport lda #attn_lo ; drop attn lo sta ioport jsr delay ; a short delay lda #attn_hi ; reset attn hi sta ioport rts ;-------------------------------------------------- ; send std command sendcmd lda #clk_hi ; set ioport with the cmd and clk hi ora command sta ioport jsr delay ; short delay lda #clk_lo ; clk lo sta ioport jsr delay ; short delay rts ;--------------------------------------------------- ; read 3x3 data read9bits lda #ddr_input ; reset ddr to input on 3 data lines sta ddr lda #$00 ; blank the hi bit sta store+1 lda #clk_hi ; clk hi sta ioport lda ioport ; get first nip (lsbits) and #datamask lsr a lsr a lsr a ; shift bits right 5 places lsr a lsr a sta store ; store bits lda #clk_lo ; drop the clock sta ioport lda #clk_hi ; clk hi sta ioport lda ioport ; get second nip and #datamask lsr a lsr a ; shift bits right 2 places ora store ; store sta store lda #clk_lo ; drop the clock sta ioport lda #clk_hi ; clk hi sta ioport lda ioport ; get last nip and #datamask clc rol a ; move MSbit to z+1 rol store+1 ora store ; store the rest sta store lda #clk_lo ; finish with clk lo, attn hi sta ioport rts ;--------------------------------------------------- ; send 3x3 data ; datatosend & datatosend+1 must be set before calling write9bits lda #ddr_output ; reset ddr to output (write) on 3 data lines sta ddr lda datatosend+1 ;MSBit of data sta store lda datatosend ; first nip asl a asl a asl a ; shift bits left 5 places (LSBits first) asl a asl a ora #clk_hi ; set clk-hi (and attn-hi) bit sta ioport ; write data & clkhi to port jsr delay ; delay lda #clk_lo ; drop the clock sta ioport lda datatosend ; second nip asl a ; shift bits left 2 places asl a and #datamask ora #clk_hi ; set clkhi sta ioport ; write data & clkhi to port jsr delay ; delay lda #clk_lo ; drop the clock sta ioport lda datatosend ; last nip ror store ror a and #datamask ora #clk_hi ; set clkhi sta ioport ; write data & clkhi to port jsr delay ; delay lda #clk_lo ; drop the clock sta ioport rts ;------------------------------------------------------- ; read -- general read cmd ; send immediate cmd, receive one 3x3 transfer ; set 'command' before calling read jsr start jsr sendcmd jsr read9bits rts ;-------------------------------------------------------- ; send an extended command sendextcmd lda #cmd_extended ; primary cmd sta command ; set the actual extended command in datatosend jsr start jsr sendcmd jsr write9bits rts ;-------------------------------------------------------- ; send an extended command w/data ; bytes only so far, not the whole 9-bits ; Extended CMD in datatosend/datatosend+1 first ; # bytes to send in sendlen ; NOTE: extended command must be reentered in datatosend before each call: ; sending the extra data resets datatosend sendextdata jsr sendextcmd ldx #0 ; zero the count sta datatosend+1 ; ignoring the msbit sendmore lda sendbuffer,x ; get the byte sta datatosend jsr write9bits ; send it inx cpx sendlen ; check if all bytes sent bne sendmore ; no, go back rts ;-------------------------------------------------------- ; send an extended command, and get return data ; bytes only so far, not the whole 9-bits ; Extended CMD in datatosend/datatosend+1 first ; # of bytes to receive: recvlen getextdata jsr sendextcmd ldx #0 ge1 jsr read9bits ; get byte lda store sta readbuffer,x ; copy to buffer inx cpx recvlen ; check if all bytes received bne ge1 ; no, go back rts ;------------------------------------------------------- ; multibyte receive ; setup for char data only, for now ; 256 bytes max (size of the buffer is the limiting factor) readdata lda #cmd_rd_data sta command ldx #0 jsr start jsr sendcmd rd1 jsr read9bits lda store ; get the byte (8 bits only so far, sorry) beq rdone ; if zero terminator, done (char data only) sta inbuffer,x ; otherwise, store data in buffer inx ; increm the index bne rd1 ; exit if index wraps around to zero rdone rts ;------------------------------------------------------- ; multibyte receive, dump to scrn ; setup for char data (null terminator) ; No buffer used/needed--can dump an unlimited # of bytes to scrn ; (this will loop forever without the null char) printdata lda #cmd_rd_data sta command jsr start jsr sendcmd pd1 jsr read9bits lda store ; get the byte (8 bits only so far, sorry) beq pddone ; if zero terminator, done (char data only) jsr chrout ; otherwise, print it jmp pd1 ; only terminated by a null byte pddone rts ;------------------------------------------------------- ; set data read to block/binary blockread lda #0 sta datatosend+1 ; none of these extcmds > 255 lda #ext_data_blk ; set data type to block sta datatosend lda #cmd_extended sta command jsr sendextcmd rts ;---- ; get info about load getloadstats lda #05 ; 5 bytes in a loadinfo struct sta recvlen lda #ext_data_ldinfo ; get load addr and len sta datatosend lda #cmd_extended sta command jsr getextdata rts ;------------------------------------------------------- ; binary data receive ; readbinary jsr blockread jsr getloadstats lda readbuffer+2 ; load addr (not using 3rd addr byte --) sta zstore ; (the flash load byte) lda readbuffer+3 sta zstore+1 lda #cmd_rd_data sta command jsr start jsr sendcmd ldy #0 rb1 jsr read9bits ; get the byte (8 bits only so far, sorry) lda store sta (zstore),y ; store data in memory dec readbuffer lda #255 cmp readbuffer bne rb2 lda readbuffer+1 beq rbdone dec readbuffer+1 rb2 iny bne rb1 inc zstore+1 jmp rb1 rbdone rts ;-------------------------------------------------------- ; gimme8 ; convert 9-bit value to 8-bit (from last transfer) gimme8 ror store+1 ror store rts ;-------------------------------------------------------- ; delay delay ldy #8 dloop dey bne dloop rts