Sky Runner Posted November 5, 2004 Share Posted November 5, 2004 I am in the process of relearning my Atari programming skills (limited though they maybe) and have been experimenting with things in BASIC to refresh my memory on the simplest of things before I get back to assembly language. Can anyone tell me what's the best way to read a screen and return the character number at a given screen location ? I always thought there was a command like LOCATE, but that will only tell me the colour of that position. Any BASIC suggestions ? Quote Link to comment Share on other sites More sharing options...
zenassem Posted November 6, 2004 Share Posted November 6, 2004 Sky Runner, I'm not sure what the best method is, but I can offer two ideas on how I would approach it. (keep in mind that I, like you am returning to the atari, so there may be a command that does this that I have forgotten). Which method I would use depends on how versatile you need it and whether you are only referring to graphics 0. 1) (gr.0) you can POSITION the cursor and then peek at: location 93 (OLDCHR) CURSOR CHARACTER SAVE/RESTORE: the value contains the character that is underneath the cursor. It's used to restore the original character when the cursor moves. z=peek(93) 2) Or you can find the start of the screen adress memory and peek at the offset from the beginning of screen memory to find the character. To find the starting adress of the screen (any mode) you peek at locations 88 and 89. Here's the forumla for combing the two locations and retrieve the decimal address: SCN=PEEK(88)=256*PEEK(89) Now all you have to do is start a SCN and index into the location you want to check. For graphics mode 0 it would look like this C=PEEK(SCN+X+20*Y) Just note that C will have the value of Atari's Internal character set value not ASCII. So, the character 'A' would be equal to 33 not ASCII 65. Depending on what you need to do you can convert to ASCII. I know a few other methods but I will have to refresh my memory on them. ~Zen Quote Link to comment Share on other sites More sharing options...
zenassem Posted November 6, 2004 Share Posted November 6, 2004 oops that one line should have read SCN=PEEK(88)+256*PEEK(89) ~zen[/code] Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted November 6, 2004 Share Posted November 6, 2004 Actually, LOCATE X,Y,Z will leave a character code in Z if you happen to be in a text mode (it works regardless of the mode). But since it needs to determine this, using PEEK instead executes quicker. More on Basic GFX commands... http://www.atariarchives.org/c1bag/page003.php Quote Link to comment Share on other sites More sharing options...
zenassem Posted November 6, 2004 Share Posted November 6, 2004 Oh I need an EDIT feature... Just wanted to clear up that you can't just use the POSITION command, as that It doesn't actually move the cursor. You need to follow it with a print command. So, heres the trick: in your actual POSITION statement make Y -1 of what you intend. Then follow the command with a Down cursor movement chr$(29) so if you wanted to look at location 20,20 do this: POSITION 20,19: PRINT CHR$(29) ======= I also should have read your post more carefully. Because if you were using gr.0 Locate would work just fine. But, you may want to prevent Locate from advancing the cursor position. 10 OPEN #6,12,0,"S:" 15 REM SAVE Row(84) AND Column(85) locations 20 P1=PEEK(84):P2=PEEK(85) 30 LOCATE X,Y,AV 35 REM RESTORE row and column 40 POKE 84,P1:POKE 85,P2 It would help me if I knew more detail of what you are trying to do. ~zen Quote Link to comment Share on other sites More sharing options...
zenassem Posted November 6, 2004 Share Posted November 6, 2004 Here's some routines from Compute!'s Third book of Atari In case you need to look at memory locations that utilize the Internal Code (ICODE) and need to convert to (ATASCII) or vice-versa. ATASCII-ICODE Conversion routine 800 IV=0:IF AC>127 THEN IV=1:AC=AC-128 810 IF AC<32 THEN IC=AC+64+128*IV:RETURN 820 IF AC<96 THEN IC=AC-32+128*IV:RETURN 830 IC=AC+128*IV:RETURN When you GOSUB to this subroutine, the variable AC must contain the ATASCII value of the character you want converted to ICODE. When you return from the subroutine, the variable IC will contain the ICODE value. You can POKE it to screen memory: [/code] POKE PEEK(88)+256*PEEK(89)+OFFSET,IC [/code] OFFSET=0 is the Top-Left Corner of the screen. ICODE TO ATASCII Conversion routine 200 IV=0:IF IC>127 THEN IV=1:IC=IC-128 210 IF IC<64 THEN AC=IC+32+128*IV:RETURN 220 IF IC<96 THEN AC=IC-64+128*IV:RETURN 230 AC=IC+128*IV:RETURN When you GOSUB to this routine, the variable IC contains the ICODE value of the character you want converted. When you return from the subroutine, the variable AC will contain the value that , when PRINTed, will cause the character to be displayed. PRINT CHR$(AC) In both subroutines, the variable IV is used to keep track of whether the character was inverse or not. Quote Link to comment Share on other sites More sharing options...
zenassem Posted November 6, 2004 Share Posted November 6, 2004 I just had one last thought. It just dawned on me that you must be using graphics mode 1 or 2. So when your using Locate x,y,z - you are getting values that you might be assuming is JUST the color, but actually it is the color AND the character. In basic modes 1 and 2 you will have two character sets that are comprIsed of 64 characters. Each character (with some exceptions) has 4 possible values depending on which color register was used. So normally the letter 'A' is equivalent to ATASCII 65. In modes 1 & 2, that holds true if the text is using color register 0. But if it using color register 1 it would be 65+32=98. I'll list a few characters and the values. color regsister 0 1 2 3 Character Std. Alt. 'A' 'a' 65 97 193 225 'B' 'b' 66 98 194 226 'C' 'c' 67 99 195 228 ... To change between std. and alt. sets Std.= POKE 756,224 Alt.= POKE 756,226 Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted November 6, 2004 Share Posted November 6, 2004 That last bit is not that simple. Once you switch to the alternate character set (to use the lower-case letters instead of upper case), the screen is going to fill up with hearts (because the heart graphic is the first one in the character set data). So you would need to copy the character set data from rom (@ address 57344) and dump it into ram, zero out the heart bitmap, and switch to the new character set by using POKE 756,X (where X is the memory location of the new set divided by 256). Quote Link to comment Share on other sites More sharing options...
zenassem Posted November 6, 2004 Share Posted November 6, 2004 Thanks for correcting that Nukey. Twice I typed an '8' where I meant '7'. 65+32=98 should be 97 and 'C' 'c' 67 99 195 228 228 should be 227 Quote Link to comment Share on other sites More sharing options...
Nukey Shay Posted November 6, 2004 Share Posted November 6, 2004 Oops...the standard set begins at address 57344. The alternate set begins at 57856. The entire set runs from 57344 to 58367. The location of the new set must begin at a multiple of 1024 (or a multiple of 512 if you are using GR.1 or 2)...and you'll need to change Basic's top of memory pointer manually before you copy the data (by changing the value in address 104). Here's an example of copying the character set: 10 CHARSET=PEEK(104)-4 15 POKE 104,CHARSET 20 GRAPHICS 1+16 25 FOR I = 0 TO 1023 30 POKE CHARSET*256+I,PEEK(57344+I) 35 NEXT I 40 FOR I = 512 TO 519 45 POKE CHARSET*256+I,0 50 NEXT I 55 POKE 756,CHARSET 60 POSITION 0,0 65 PRINT#6;"THIS IS UPPER CASE" 70 FOR I = 1 TO 500 75 NEXT I 80 POKE 756,CHARSET+2 85 POSITION 0,0 90 PRINT#6;"THIS IS LOWER CASE" 95 FOR I = 1 TO 500 100 NEXT I 105 GOTO 55 Line 10 & 15 reserve the memory needed - 4 pages of it to hold all 1024 bytes. Because the Atari OS will push the graphics area to the highest memory location that it "sees", you should call the GRAPHICS command directly after (I also added 16 to it...which makes the mode full-screen). Lines 25 to 35 copy over the data from Rom memory to Ram...and lines 40 to 50 zero out the heart bitmap. Line 55 and 80 switch to the first set and the alternate set. Then, lines 60-65 and 85-90 print the corresponding message at the top of the screen (when you use graphic modes other than the editor, channel #6 is automatically opened to handle it). All the text in the quotes is in uppercase, so it will be using the first color register (default=orange-red). Lines 70-75 and 95-100 use small loops as a delay...and then line 105 jumps back up to 55 and repeats from line 55 infinitely. I'm going off memory...but that should be about it. You'll be able to print text in 4 colors (depending on if the text in the quotes is upper case, lower case, and if the inverse toggle is on). You can change the pallette colors by POKEing to addresses 708 to 712 (712 is the background color)...or by using the SETCOLOR command. Quote Link to comment Share on other sites More sharing options...
Sky Runner Posted November 6, 2004 Author Share Posted November 6, 2004 Thanks so much for all your advice and input, guys. I am mostly using GR.1 and 2. Zen's advice about where screen memory starts and using offsets to find my way around the screen was exactley what I was after. Thanks again for the thorough input !! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.