Writing to two memory address sequentially
Writing to two memory address sequentially
Im writing to two memory address sequentially, pressing a key will return two bytes from the radio (data from radio memory $0057 and $0058), which are printed to the screen correctly so i know im getting back both, however I want to take those two bytes and load them into $c008 and $c009 as it pulls it from the receive buffer. It only seems to put in the second byte into the memory location.
What im trying to do takes place in RECVBYTE,transfering recvcount value from A to X and using it to augment the memory location (getbyte,x)
SENDBYTE:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;SPECIAL CODE AREA TO SEND PACKET IN A LOOP FROM THE DATA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;AT THE BOTTOM AT GETEEPROM:
ldx #$00
PTTLOOP:
lda GETEEPROM,x
tay ;remember byte to be transmitted
TESTACIA5:
lda status
and #%00010000
beq TESTACIA5 ;wait for bit #4 to be set
sty data ;give byte to ACIA
inx
cpx #$05
bne PTTLOOP
rts
RECVBYTE: ;fetches a byte from the receive buffer.
lda recvcount ;count of bytes in receive buffer
tax
beq RECVEMPTY ;buffer is empty, indicate to caller
ldy rhead ;pointer to start of buffer
lda (rbuff),y ;fetch byte out of buffer into 'A' register
sta getbyte,x ;location of getbyte is $c008
inc rhead ;point to next slot in buffer
dec recvcount ;and add one to count of bytes in buffer
clc ;indicate that we have a character
rts ;return to your program
RECVEMPTY:
sec ;or whatever flag your program uses to tell that the receive buffer was empty
rts ;and return
TERMINAL:
jsr RECVBYTE ;see if there is a received byte in the recv buffer
bcs TERMTRYSEND ;if not, continue
jsr $FFD2 ;if received byte, print it to the screen (CHROUT)
TERMTRYSEND:
jsr $FFE4 ;try to get a character from the keyboard (GETIN)
cmp #$00 ;was there a keystroke available?
beq TERMINAL ;no--go back to top of polling loop
; cmp #$03 ;check for STOP key
; beq TERMEXIT ; exit if pressed
; jsr $FFD2
jsr SENDBYTE ;have char--put it into the transmit buffer and then
jmp TERMINAL ; go back to top of polling loop
TRANSMIT_BUFFER = *+0
RECEIVE_BUFFER = *+256
PTT:
.byte $00,$00,$00,$00,$08
GETEEPROM:
.byte $00,$57,$00,$00,$BB
What im trying to do takes place in RECVBYTE,transfering recvcount value from A to X and using it to augment the memory location (getbyte,x)
SENDBYTE:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;SPECIAL CODE AREA TO SEND PACKET IN A LOOP FROM THE DATA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;AT THE BOTTOM AT GETEEPROM:
ldx #$00
PTTLOOP:
lda GETEEPROM,x
tay ;remember byte to be transmitted
TESTACIA5:
lda status
and #%00010000
beq TESTACIA5 ;wait for bit #4 to be set
sty data ;give byte to ACIA
inx
cpx #$05
bne PTTLOOP
rts
RECVBYTE: ;fetches a byte from the receive buffer.
lda recvcount ;count of bytes in receive buffer
tax
beq RECVEMPTY ;buffer is empty, indicate to caller
ldy rhead ;pointer to start of buffer
lda (rbuff),y ;fetch byte out of buffer into 'A' register
sta getbyte,x ;location of getbyte is $c008
inc rhead ;point to next slot in buffer
dec recvcount ;and add one to count of bytes in buffer
clc ;indicate that we have a character
rts ;return to your program
RECVEMPTY:
sec ;or whatever flag your program uses to tell that the receive buffer was empty
rts ;and return
TERMINAL:
jsr RECVBYTE ;see if there is a received byte in the recv buffer
bcs TERMTRYSEND ;if not, continue
jsr $FFD2 ;if received byte, print it to the screen (CHROUT)
TERMTRYSEND:
jsr $FFE4 ;try to get a character from the keyboard (GETIN)
cmp #$00 ;was there a keystroke available?
beq TERMINAL ;no--go back to top of polling loop
; cmp #$03 ;check for STOP key
; beq TERMEXIT ; exit if pressed
; jsr $FFD2
jsr SENDBYTE ;have char--put it into the transmit buffer and then
jmp TERMINAL ; go back to top of polling loop
TRANSMIT_BUFFER = *+0
RECEIVE_BUFFER = *+256
PTT:
.byte $00,$00,$00,$00,$08
GETEEPROM:
.byte $00,$57,$00,$00,$BB
Re: Writing to two memory address sequentially
Hi jrubin,
Could you post some more information, maybe the entire listing if there's more?
1. The labels --> status, data, recvcount, rbuff, and rhead don't seem like they are defined anywhere, but are used in the source. PTT does not appear to be used by anything. What is the label for $57-58?
2. RECEIVE_BUFFER appears to have a size of 0 bytes, while TRANSMIT_BUFFER is 256 bytes in size.
3. Calling $FFE4 returns either a keypress (ascii code) or 0 in .A, so the cmp #0 instruction can come out.
4. recvcount doesn't seem to be initialized anywhere so its value could be anything.
I think there might be a couple of other things (the loop design, use index registers instead of memory in the loops), but the items listed above should be addressed first. We'll get you fixed up, don't sweat it. I'm having a little trouble figuring it out without those labels above are for.
When posting assembly source you can highlight the source text and click on the "Select Code" dropdown box, then click on Assembly. It will display the source text in a mono-spaced font. It is very easy to read then.
Could you post some more information, maybe the entire listing if there's more?
1. The labels --> status, data, recvcount, rbuff, and rhead don't seem like they are defined anywhere, but are used in the source. PTT does not appear to be used by anything. What is the label for $57-58?
2. RECEIVE_BUFFER appears to have a size of 0 bytes, while TRANSMIT_BUFFER is 256 bytes in size.
3. Calling $FFE4 returns either a keypress (ascii code) or 0 in .A, so the cmp #0 instruction can come out.
4. recvcount doesn't seem to be initialized anywhere so its value could be anything.
I think there might be a couple of other things (the loop design, use index registers instead of memory in the loops), but the items listed above should be addressed first. We'll get you fixed up, don't sweat it. I'm having a little trouble figuring it out without those labels above are for.
When posting assembly source you can highlight the source text and click on the "Select Code" dropdown box, then click on Assembly. It will display the source text in a mono-spaced font. It is very easy to read then.
Re: Writing to two memory address sequentially
Code: Select all
TRANSMIT_BUFFER = *+0
RECEIVE_BUFFER = *+256
PTT:
.byte $00,$00,$00,$00,$08
GETEEPROM:
.byte $00,$57,$00,$00,$BB
Code: Select all
TRANSMIT_BUFFER = *+0
RECEIVE_BUFFER = *+256
* = * + (2*256) ; move program counter behind RECIEVE_BUFFER
PTT:
.byte $00,$00,$00,$00,$08
GETEEPROM:
.byte $00,$57,$00,$00,$BB
Re: Writing to two memory address sequentially
Sorry I didnt send all of the code, this should straighten out some of the confusion.
Would it make more sense to push it to the stack and move it afterwards?
program starts on sys 8192
Would it make more sense to push it to the stack and move it afterwards?
program starts on sys 8192
Code: Select all
base = $DE00 ;base ACIA address
data = base
status = base+1
command = base+2
control = base+3
getbyte = $C008
rhead = $A7 ;pointer to next byte to be removed from receive buffer
rtail = $A8 ;pointer to location to store next byte received
rbuff = $F7 ;receive-buffer vector
thead = $A9 ;pointer to next byte to be removed from transmit buffer
ttail = $AA ;pointer to location to store next byte in transmit buffer
tbuff = $F9 ;transmit buffer
xmitcount = $AB ;count of bytes remaining in transmit (xmit) buffer
recvcount = $B4 ;count of bytes remaining in receive buffer
errors = $B5 ;DSR, DCD, and received data errors information
xmiton = $B6 ;storage location for model of command register which turn both receive and transmit interrupts on
xmitoff = $BD ;storage location for model of command register which turns the receive interrupt on and the
;transmit interrupts off
NMINV = $0318 ;Commodore Non-Maskable Interrupt vector
OLDVEC = $03fe ;innocuous location to store old NMI vector (two bytes)
;Call the following code as part of system initialization.
;clear all buffer pointers, buffer counters, and errors location
*= $2000 ;change to suit your needs
lda #$00
sta rhead
sta rtail
sta thead
sta ttail
sta xmitcount
sta recvcount
sta errors
;store the addresses of the buffers in the zero-page vectors
lda #<TRANSMIT_BUFFER
sta tbuff
lda #>TRANSMIT_BUFFER
sta tbuff + 1
lda #<RECEIVE_BUFFER
sta rbuff
lda #>RECEIVE_BUFFER
sta rbuff + 1
;load control values
lda #%10011100
sta control
;load command values
lda #%00001001
sta command
sta xmitoff ;store as a model for future use
and #%11110000 ;mask off interrupt bits, keep parity/echo bits
ora #%00000101 ;and set bits to enable both transmit and receive interrupts
sta xmiton ;store also for future use
NEWVEC:
sei ;A stray IRQ shouldnt cause any problems while were changing the NMI vector
lda NMINV ;get low byte of present vector
sta OLDVEC ;and store it for future use
lda NMINV+1 ;do the same
sta OLDVEC+1 ;with the high byte
;come here from the SEI if you're not saving
;the old vector
lda #<NEWNMI ;get low byte of new NMI routine
sta NMINV ;store in vector
lda #>NEWNMI ;and do the same with
sta NMINV+1 ;the high byte
cli ;allow IRQs again
jmp TERMINAL ;go to the example dumb-terminal subroutine
NEWNMI:
sei ;the Kernal routine already does this before jumping
;through the NMINV vector
pha ;save A register
txa
pha ;save X register
tya
pha ;save Y register
lda status
;Now prevent any more NMIs from the ACIA
ldx #%00000011 ;disable all interrupts, bring RTS inactive, and leave DTR active
stx command ;send to ACIA-- code at end of interrupt handler will re-enable interrupts
;Store the status-register data only if needed for error checking.
;The next received byte will clear the error flags.
sta errors ;only if error checking implemented
and #%00011000 ;mask out all but transmit and receive interrupt indicators
beq TEST_DCD_DSR
RECEIVE: ;process received byte
and #%00001000 ;mask all but bit #3
beq XMITCHAR ;if not set, no received byte - if youre using a transmit buffer, the interrupt must have been
;caused by transmit. So, branch to handle.
lda data ;get received byte
ldy rtail ;index to buffer
sta (rbuff),y ;and store it
inc rtail ;move index to next slot
inc recvcount ;increment count of bytes in receive buffer (if used by your program)
XMIT:
lda xmitcount ;if not zero, characters still in buffer fall through to process xmit buffer
beq TEST_DCD_DSR ;no characters in buffer-- go to next check
XMITBYTE:
lda status ;test bit #4
and #%00010000
beq TEST_DCD_DSR ;skip if transmitter still busy
XMITCHAR: ;transmit a character
ldy thead
lda (tbuff),y ;get character at head of buffer
sta data ;place in ACIA for transmit
;point to next character in buffer
inc thead ;and store new index
dec xmitcount ;subtract one from count of bytes in xmit buffer
lda xmitcount
beq TEST_DCD_DSR
lda xmiton ;model to leave both interrupts enabled
;If you don't use DCD or DSR
bne NMICOMMAND ;branch always to store model in command register
TEST_DCD_DSR:
NMIEXIT:
lda xmitoff ;load model to turn transmit interrupts off
;and this line sets the interrupt status to whatever is in the 'A' register.
NMICOMMAND:
sta command
EXITINT: ;restore things and exit
pla ;restore 'Y' register
tay
pla ;restore 'X' register
tax
pla ;restore 'A' register
;If you want to continue processing the interrupt with the Kernal routines,
jmp (OLDVEC) ;continue processing interrupt with Kernal handler
;
;NOTHING:
; lda #$00 ;or whatever flag your program uses to tell that the byte was not transmitted
; rts ;and return
SENDBYTE:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;SPECIAL CODE AREA TO SEND PACKET IN A LOOP FROM THE DATA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;AT THE BOTTOM AT PTT:
ldx #$00
PTTLOOP:
lda GETEEPROM,x
tay ;remember byte to be transmitted
TESTACIA5:
lda status
and #%00010000
beq TESTACIA5 ;wait for bit #4 to be set
sty data ;give byte to ACIA
inx
cpx #$05
bne PTTLOOP
rts
RECVBYTE: ;fetches a byte from the receive buffer.
lda recvcount ;count of bytes in receive buffer
tax
beq RECVEMPTY ;buffer is empty, indicate to caller
ldy rhead ;pointer to start of buffer
lda (rbuff),y ;fetch byte out of buffer into 'A' register
sta getbyte,x ;location of getbyte is $c008
inc rhead ;point to next slot in buffer
dec recvcount ;and add one to count of bytes in buffer
clc ;indicate that we have a character
rts ;return to your program
RECVEMPTY:
sec ;or whatever flag your program uses to tell that the receive buffer was empty
rts ;and return
TERMINAL:
jsr RECVBYTE ;see if there is a received byte in the recv buffer
bcs TERMTRYSEND ;if not, continue
jsr $FFD2 ;if received byte, print it to the screen (CHROUT)
TERMTRYSEND:
jsr $FFE4 ;try to get a character from the keyboard (GETIN)
cmp #$00 ;was there a keystroke available?
beq TERMINAL ;no--go back to top of polling loop
; cmp #$03 ;check for STOP key
; beq TERMEXIT ; exit if pressed
; jsr $FFD2
jsr SENDBYTE ;have char--put it into the transmit buffer and then
jmp TERMINAL ; go back to top of polling loop
TRANSMIT_BUFFER = *+0
RECEIVE_BUFFER = *+256
PTT:
.byte $00,$00,$00,$00,$08
GETEEPROM:
.byte $00,$57,$00,$00,$BB
Re: Writing to two memory address sequentially
Heres a few sections of code running step by step
this is from the bottom of the program, i put it here for reference
What is this value $DA and why is it going to F9 (transmit buffer)
then it loads value from transmit buffer again and gets $20
it loads the same values into the receive buffer
Code: Select all
;store the addresses of the buffers in the zero-page vectors
lda #<TRANSMIT_BUFFER
sta tbuff
lda #>TRANSMIT_BUFFER
sta tbuff + 1
lda #<RECEIVE_BUFFER
sta rbuff
lda #>RECEIVE_BUFFER
sta rbuff + 1
this is from the bottom of the program, i put it here for reference
Code: Select all
TRANSMIT_BUFFER = *+0
RECEIVE_BUFFER = *+256
Code: Select all
.C:2010 A9 DA LDA #$DA - A:00 X:00 Y:0A SP:f2 ..-...Z. 5503706
(C:$2010)
.C:2012 85 F9 STA $F9 - A:DA X:00 Y:0A SP:f2 N.-..... 5503708
(C:$2012)
.C:2014 A9 20 LDA #$20 - A:DA X:00 Y:0A SP:f2 N.-..... 5503711
(C:$2014)
.C:2016 85 FA STA $FA - A:20 X:00 Y:0A SP:f2 ..-..... 5503713
(C:$2016)
.C:2018 A9 DA LDA #$DA - A:20 X:00 Y:0A SP:f2 ..-..... 5503716
(C:$2018)
.C:201a 85 F7 STA $F7 - A:DA X:00 Y:0A SP:f2 N.-..... 5503718
(C:$201a)
.C:201c A9 21 LDA #$21 - A:DA X:00 Y:0A SP:f2 N.-..... 5503721
(C:$201c)
.C:201e 85 F8 STA $F8 - A:21 X:00 Y:0A SP:f2 ..-..... 5503723
(C:$201e)
What is this value $DA and why is it going to F9 (transmit buffer)
then it loads value from transmit buffer again and gets $20
it loads the same values into the receive buffer
Re: Writing to two memory address sequentially
err... you wrote that code, shouldnt you know what it is doing? $da is the low byte of the buffers address. and since they are one page apart the lowbyte is the same for both.
Re: Writing to two memory address sequentially
Hi jrubin,
I have never worked with RS-232 programming, but have meddled some with clearing buffers, and I will admit I have not tried to step through this in VICE. But just by looking at it -- a variable like recvcount is always going to hold a value of +1 of whatever your index is (unless it is 0). That is, if the count is 1 then it should be decremented so that it points to byte #0 for retrieval of the first byte in the buffer. I'm wondering if this has anything to do with what is going on.
Also, and this is nothing major, but a simple re-ordering at the top of the routine can save a couple of cycles:
can be changed to:
This will exit immediately if the count = 0.
The other thing (again, nothing major) is the cmp #0 after JSR $FFE4. That can come out because GETIN returns a 0 if there is nothing pressed so the BEQ by itself will pick that up. (- JSR $FFE4/BEQ -)
Are bytes constantly streaming in? If so, then it seems like the NMI is going to mess up the buffer (and the pointers) because the NMI itself can't be disabled. I would think you have to delay receiving bytes in the NMI itself until the buffer is cleared (until recvcount = 0). The whole getting RS-232 bytes from a buffer via keypress thing seems like it would be prone to big problems. This is just an uneducated guess, though.
Keep working at it. You'll get it. I'll keep checking in (RS-232 is not exactly my strong suit).
I have never worked with RS-232 programming, but have meddled some with clearing buffers, and I will admit I have not tried to step through this in VICE. But just by looking at it -- a variable like recvcount is always going to hold a value of +1 of whatever your index is (unless it is 0). That is, if the count is 1 then it should be decremented so that it points to byte #0 for retrieval of the first byte in the buffer. I'm wondering if this has anything to do with what is going on.
Also, and this is nothing major, but a simple re-ordering at the top of the routine can save a couple of cycles:
Code: Select all
RECVBYTE: ;fetches a byte from the receive buffer.
lda recvcount ;count of bytes in receive buffer
tax
beq RECVEMPTY ;buffer is empty, indicate to caller
Code: Select all
RECVBYTE: ;fetches a byte from the receive buffer.
lda recvcount ;count of bytes in receive buffer
beq RECVEMPTY ;buffer is empty, indicate to caller
tax
The other thing (again, nothing major) is the cmp #0 after JSR $FFE4. That can come out because GETIN returns a 0 if there is nothing pressed so the BEQ by itself will pick that up. (- JSR $FFE4/BEQ -)
Are bytes constantly streaming in? If so, then it seems like the NMI is going to mess up the buffer (and the pointers) because the NMI itself can't be disabled. I would think you have to delay receiving bytes in the NMI itself until the buffer is cleared (until recvcount = 0). The whole getting RS-232 bytes from a buffer via keypress thing seems like it would be prone to big problems. This is just an uneducated guess, though.
Keep working at it. You'll get it. I'll keep checking in (RS-232 is not exactly my strong suit).
Re: Writing to two memory address sequentially
satpro wrote:Hi jrubin,
I have never worked with RS-232 programming, but have meddled some with clearing buffers, and I will admit I have not tried to step through this in VICE. But just by looking at it -- a variable like recvcount is always going to hold a value of +1 of whatever your index is (unless it is 0). That is, if the count is 1 then it should be decremented so that it points to byte #0 for retrieval of the first byte in the buffer. I'm wondering if this has anything to do with what is going on.
Also, and this is nothing major, but a simple re-ordering at the top of the routine can save a couple of cycles:
can be changed to:Code: Select all
RECVBYTE: ;fetches a byte from the receive buffer. lda recvcount ;count of bytes in receive buffer tax beq RECVEMPTY ;buffer is empty, indicate to caller
This will exit immediately if the count = 0.Code: Select all
RECVBYTE: ;fetches a byte from the receive buffer. lda recvcount ;count of bytes in receive buffer beq RECVEMPTY ;buffer is empty, indicate to caller tax
The other thing (again, nothing major) is the cmp #0 after JSR $FFE4. That can come out because GETIN returns a 0 if there is nothing pressed so the BEQ by itself will pick that up. (- JSR $FFE4/BEQ -)
Are bytes constantly streaming in? If so, then it seems like the NMI is going to mess up the buffer (and the pointers) because the NMI itself can't be disabled. I would think you have to delay receiving bytes in the NMI itself until the buffer is cleared (until recvcount = 0). The whole getting RS-232 bytes from a buffer via keypress thing seems like it would be prone to big problems. This is just an uneducated guess, though.
Keep working at it. You'll get it. I'll keep checking in (RS-232 is not exactly my strong suit).
Genuis!!! That looks like the issue, the receieve buffer shouldnt have been incremented by 1, it cuts off the first received byte!!! only tx should be padded.
Its not reliable though, i think ive got too much going on in between the code
Re: Writing to two memory address sequentially
ive tried both ways and found then equally reliable so im no further than I started.
the command $FFD2 in the TERMINAL: always prints both bytes to the scewwn with no issue, I think I just need some viable way of storing A to memry different than what I am doing
the command $FFD2 in the TERMINAL: always prints both bytes to the scewwn with no issue, I think I just need some viable way of storing A to memry different than what I am doing
Re: Writing to two memory address sequentially
I always get 2 bytes back so I just simplified the code, this works error free and is reliable, ill move these two bytes to zero page FB and FC to work on and dump the results to c000
Code: Select all
RECVBYTE: ;fetches a byte from the receive buffer.
lda recvcount ;count of bytes in receive buffer
beq RECVEMPTY ;buffer is empty, indicate to caller
ldy rhead ;pointer to start of buffer
lda (rbuff),y ;fetch byte out of buffer into 'A' register
sta $C000 ;location of getbyte is $c008
jsr $ffd2
inc rhead ;point to next slot in buffer
dec recvcount ;and add one to count of bytes in buffer
ldy rhead ;pointer to start of buffer
lda (rbuff),y ;fetch byte out of buffer into 'A' register
sta $C001 ;location of getbyte is $c008
jsr $ffd2
inc rhead ;point to next slot in buffer
dec recvcount ;and add one to count of bytes in buffer
clc ;indicate that we have a character
rts ;return to your program
Who is online
Users browsing this forum: No registered users and 9 guests