6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat May 11, 2024 7:57 am

All times are UTC




Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: how is this possible?
PostPosted: Sun Sep 28, 2003 2:05 am 
Offline

Joined: Sun Sep 28, 2003 2:00 am
Posts: 7
if i have a line of code such as

eg1: .db "abcdefg",0
.db "hijklmn",0

how can i output this on screen? i cannot find any doc's to help me with this.


Thanks.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Sep 28, 2003 6:25 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
The .db is an assembler directive which tells the assembler to fill the next bytes in memory with the data bytes (hence the ".db") shown on the line instead of instructions or variable space or anything else. In this case, each ".db" would add 8 bytes-- 7 for the text characters, and a 00 byte to signal the end of the string. How you display the string will depend heavily on what hardware you have, and what routines are already there. It sounds like you're dealing with a commercially made computer, so it would no doubt have routines built in that you can use for putting strings in the display. For example, I believe the Apple II and the AIM-65 had one labeled "OUTCH" for "OUTput a CHaracter" which took care of the details for displaying a character once the cursor was where you want it. That's probably all the help we can offer without knowing any more specifics about what you're working with.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Sep 28, 2003 6:38 am 
Offline

Joined: Sun Sep 28, 2003 2:00 am
Posts: 7
Im simply using a 6502 emulator to do a project at school, but i cannot figure out how to output each line of code, when i try to load it in, it asks for an X or Y reference, ive tried everything i know, but i cannot load the characters into the accumulator, or output them.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Sep 28, 2003 7:38 am 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
for me, I cannot think too well right now (too much county fair day),, but I would do something like this:

StringStorage db. "textstringToOutput",$00

ldx #$00 ; sets your pointer the first time

Loop lda (StringStorage),x ; load in the charactetr
; do whatever is needed out here, most likely STA where you need it

cmp #$00 ; is the characer a 00 delimiter?
beq Done
inx
jmp Loop

Done keep going with your routine...


something like that. the lda (StringStorage),X is an implied, which is based on the StringStorage place in memory, and added the offest of X. the compare and branch if equal checks for the 00 and sends it on its way when done.

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Sep 28, 2003 3:52 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1685
Location: Sacramento, CA
Tony,

I would like to correct a part of your code. You would not use the indirect addressing since you are pointing directly to the data to be output. If you were using a zero-page variable to point to the text, then you would use indirect addressing.

Here's how I would write the code:

Code:
StringStorage  db.  "textstringToOutput",$00
output         =    $xxxx           ; where xxxx is your output port
                                    ; address

               ldx  #$00            ; sets your pointer the first time
Loop           lda  StringStorage,x ; load in the charactetr
               cmp  #$00            ; is the characer a 00 delimiter?
               beq  Done            ; if so, exit without printing it
                                    ; do whatever is needed out here,
                                    ; most likely STA where you need it
               sta  output          ; send accumulator to the output
                                    ; port
               inx                  ; advance pointer to next character
               jmp  Loop            ; get next character
Done                                ; continue on with your code


Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Sep 28, 2003 6:05 pm 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
Thanks.w as dead ot the world and wasnt thinking too clearly (its still slow, I consult with my Roger Wagner book on assembly all the time in the making of things... :)

blame it on a 400 acre county fair and picking up some haunted house things, picking up more today...but thanks, tis a good learner for me too there...

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Sep 28, 2003 9:59 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
Again guys, you NEVER need a CMP #00 immediately after an LDA. Putting a CMP #0 is redundant because it's already implied as part of the LDA instruction. It's automatic. You can put your BEQ immediately after the LDA. It's one of the many little advantages the 6502 has over other 8-bitters. The same goes for several other 6502 instructions: LDX, LDY, ROR, ADC, AND, ASL, DEC, DEX, DEY, EOR, INC, INX, INY, LSR, ORA, PLA, PLX, PLY, ROL, ROR, SBC, TAX, TAY, TSX, TXA, TXS, and TYA. If you have the 65816, you also have in addition PLB, PLD, TCD, TCS, TDC, TXY, TYX, and XBA. Naturally the ones that affect X have the implied CPX #00 instead of CMP, etc..


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Sep 29, 2003 2:20 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1685
Location: Sacramento, CA
GARTHWILSON wrote:
Again guys, you NEVER need a CMP #00 immediately after an LDA. Putting a CMP #0 is redundant because it's already implied as part of the LDA instruction. It's automatic. You can put your BEQ immediately after the LDA.


You are right, of course Garth. In my hurry to post, I didn't take time to review all of my changes. :oops:

Here's the corrected code:
Code:
StringStorage  db.  "textstringToOutput",$00
output         =    $xxxx           ; where xxxx is your output port
                                    ; address

               ldx  #$00            ; sets your pointer the first time
Loop           lda  StringStorage,x ; load in the charactetr
               beq  Done            ; if characer is 00, exit
                                    ; without printing it
                                    ; do whatever is needed out here,
                                    ; most likely STA where you need it
               sta  output          ; send accumulator to the output
                                    ; port
               inx                  ; advance pointer to next character
               jmp  Loop            ; get next character
Done                                ; continue on with your code


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Sep 30, 2003 2:39 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
> it is spose to be a maze. i cannot figure out how to output this to
> screen, or be able to reference a point in the maze to make checks so
> that we can design an program to navigate through it.This array bit of
> code cannot be changed.
> Thanks for the help in the other post, i think everyone was just abit
> confused about what i was trying to achieve.

Mr. qwerty123, please do not click "new topic" for each new question on the same topic. It really clutters the forum and makes it more of a maze for others to look back through and read the archives in the future. Thanks.

Now about your output-- You still haven't said what the hardware is. How to output something like that depends heavily on the hardware you're working with and the routines and resources the operating system gives you. But to take the previous example, if the software that's already on the machine has a routine called OUTCH, just replace the "STA output" in Daryl's routine with JSR OUTCH. At the end of each line of output, you probably need to do LDA #$0D (the carriage-return character), followed by JSR OUTCH again. There's probably another routine for locating the cursor where you want to start. If you had to do all this from scratch like some of us have done when writing code for a home-made computer that had no software at all initially, you'd probably write routines to set and clear various register-select or other control bits, use those as building blocks to write different commands to the display, use those as building blocks to feed data to it, which become building blocks for displaying strings or whatever. If you have an intelligent LCD module, those routines will be entirely different from those that would operate a video interface chip (VIC), and one VIC may not operate the same way as another. It's not trivial, but it does not require a Ph.D. either. I don't think such low-level programming is what you're after though. It sounds like you may need to do more manual-reading and learn what parts are done by the hardware, what the processor actually does (no processor has any idea at all what a display is), and the sharing of the software load between your own programming and what the operating system provides.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Sep 30, 2003 4:37 am 
Offline

Joined: Sun Sep 28, 2003 2:00 am
Posts: 7
whoo to technical. Its simple. The assignment we have is to print the maze in the I/O screen on the 6502 emulator, then write some code to go thru the maze checking if the next spot is valid or not. No special hardware at all, just simply the emulator, write the code, and then run the program, and it outputs to the screen. We use io_putc, which basically references some memory location same as OUTPUC or whatever. I dont care about that, i just wanna know whats the deal with the .db "blablabla", 0, and how can i load it to the accumulator, then skip down to the next line.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Sep 30, 2003 5:31 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
Ok, so maybe io_putc (I/O put character?) is what you need after the JSR to do each character. Then you'd still use Daryl's routine, replacing STA OUTPUT with JSR io_putc. That would take the character in the accumulator and do all of the possibly dozens of steps to get that character into the display.

> i just wanna know whats the deal with the .db "blablabla", 0, and how
> can i load it to the accumulator

The accumulator will only hold one character at a time, not a whole line-- not even the whole 16-bit address of the line. That's why you have to use some kind of routine like this. If there's another routine available to handle the whole line (or you write one), you could just give it the address of the string and it would take care of the internal details. You won't find a microprocessor on the planet that has an op code to take a line of text and put it in the display. A routine, tailored for that particular display hardware, is always necessary. If there's a working display, you can bet those routines are there, even if they're hiding behind a higher-level language so the user doesn't have to concern himself with the details. In your case, the character routine appears to be the io_putc, and you call it by using the JSR in Daryl's loop. If you can find another display routine in the system that displays whole strings, then you'll need to store the string address someplace the routine expects to find it, and call the routine. Then the loop will already be taken care of in that routine.


Top
 Profile  
Reply with quote  
 Post subject: got it sorted
PostPosted: Wed Oct 01, 2003 3:07 am 
Offline

Joined: Sun Sep 28, 2003 2:00 am
Posts: 7
ive got it sorted now, i just used array,x to get the char and then used io_putc. Once it got to the end of the line, i made it do a numerical check, so that after char 19, it would position the cursor down the line, then read array, 20... array, 21. Is it possible to do an X,Y reference, say i wanted the char 3 rows down, 5 across, can i reference it somehow by using something like (5,3) as co-ordinates? Or will i have to stick to my original method?
Also, i am getting a phase error, inconsistant label value... what the hell does that mean?


Top
 Profile  
Reply with quote  
 Post subject: Re: got it sorted
PostPosted: Wed Oct 01, 2003 8:39 am 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
qwerty123 wrote:
Also, i am getting a phase error, inconsistant label value... what the hell does that mean?

It means that the calculated value of a label has changed between the first and second passes of the assembler. It's usually caused by defining labels after they are used e.g.
Code:
   .org   $400

   LDA   dummy
home:
   rts

dummy   =   $f0

.. will cause such an error because on the first pass 'dummy' is assumed to be a 16 bit address and to need two bytes, whereas on the second pass it is known to be a zero page address and so will fit in one byte. This in turn means that the 'LDA dummy' now assembles into two bytes instead of three and that 'home:' is now one byte earlier than expected.

This can usually be fixed by moving any label definitions to the top of the assembly file.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Oct 01, 2003 11:52 pm 
Offline

Joined: Sun Sep 28, 2003 2:00 am
Posts: 7
Yep, got that sorted, got my maze to work, now i have to make it back trace until it finds the end. Using the stack, i was reading that JSR puts 2 allocations there, and then RTS pops them off. If i have a BEQ before the RTS, and it follows the BEQ, will those 2 memory locations still sit on the stack?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Oct 02, 2003 1:23 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
Yes, the two bytes that JSR put there as a return address remain unless you intentionally pull them off. You could have tons of branching in one subroutine, and the processor has no way to know if you've done something like branch outside the routine with no intention of coming back.

There are also special cases where you may want to form an address and push it on the stack, and then use RTS to jump to it. In that case, the RTS is not even used to end a subroutine. Another special case is where you use a JSR to a routine that's not a subroutine, just because you want the address of the part of the program that called it. (You can even use this for writing code that can be moved after being loaded. It's not efficient, but yes, you really can have relocatable code on a 6502.)

IOW, JSR and RTS are convenient for subroutines, but there's nothing magical about them. They don't have any secret connections to each other, and the processor just executes instructions without knowing if it's 20 subroutine levels deep or only one, or whether the next stack bytes contain addresses, parameters, or what.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: