+therealbountybob Posted December 16, 2009 Share Posted December 16, 2009 I'm starting to run out of memory below is what I think I have, please correct/advise thanks :!: Im using graphics mode 28 (approx 4 pages including modifying display list) and have loaded two fonts (4 pages each) into a string in RAM and moved MEMTOP down by 12 pages so far so good. My basic code is 88 pages; calculated by using fre(0) before and after loading. The PMG system I'm using from the book Atari Player Missile Graphics In Basic uses a filler string to get the PMG strings into a 1K boundary { DIM FILLER1$(1),FILLER2$((INT(ADR(FILLER1$)/1024)+1)*1024-ADR$(D$)-1) } I think the PMG strings use about 4 pages too. So I make this 4+4+4+88+4=104 pages out of a total of 128 (32k available) I have 16 player images (animations) in other strings say 20 rows in each, plus other strings. When I try and load a third font I haven't enough RAM free to run the code. Questions: Im toggling CHBAS to animate the character graphics between the two fonts. Can I toggle this to half a font e.g. shift CHBAS by 2 pages instead of 4 (it doesn't seem to work!) Can I load the fonts strings in a loader program then load my main program, can I force the strings to remain protected in RAM How can I tell how much RAM all the strings are taking up (as opposed to my program code) Thanks Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 16, 2009 Share Posted December 16, 2009 Can't you use the string relocation trick like normal Atari Basic? That way, you just DIM your strings as 1 byte, then hack the variable pointers and DIM length values and don't lose any extra memory as opposed to kludging away wasting memory to get an alignment. How much RAM are your strings using? Well, not sure about Turbo, but normal Atari Basic will reserve the full amount you DIM the string as, regardless of how much you actually use. If you CBF'd checking through your program, you could just compare FRE(0) before and after issuing a CLR. Charsets - you can only have 1/2 K boundary in Graphics 1 or 2 (Antic 6/7), since those modes only use 64 characters. Back to the strings/PMG thing... don't bother doing PMGs that way unless you're using string operations to do your vertical movement. Otherwise you're just better off changing location 106 before your GRAPHICS statement to reserve RAM at top of available space. Actually, with the string relocation hack you'd be doing that kind of thing anyway. Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted December 16, 2009 Author Share Posted December 16, 2009 Hi, Yes I am using the strings for animation and vertical movement. The problem is the strings are not initialising as they are hitting the display list/screen RAM once I have the third font in RAM (and moved MEMTOP down by 16 pages). Is there a maximum total string length or is this determined by free RAM Where does the first string initialized sit in RAM (is it right after the actual code) I have it at page 150 with my screen at page 151) (fonts are ok as they are at MEMTOP page 185-188ish) OK just had Mapping the Atari out - think the answer is it's based on free RAM and I need to read on locations 140-141 STARP I'll Post anyway as may be useful to others p.s. I tried to get clever to use the open command to load a playfield using a computed string for the filename e.g. FN$="D:SCREEN.001" where 001 was the level number, was pleased with this but it failed with error 130, doesn't recognise this as device D: ... think synthpopalooza had a dirty way of opening levels in one of his tubo-bsaic games will take a look. Quote Link to comment Share on other sites More sharing options...
Synthpopalooza Posted December 17, 2009 Share Posted December 17, 2009 (edited) Hi, Yes I am using the strings for animation and vertical movement. The problem is the strings are not initialising as they are hitting the display list/screen RAM once I have the third font in RAM (and moved MEMTOP down by 16 pages). Is there a maximum total string length or is this determined by free RAM Where does the first string initialized sit in RAM (is it right after the actual code) I have it at page 150 with my screen at page 151) (fonts are ok as they are at MEMTOP page 185-188ish) OK just had Mapping the Atari out - think the answer is it's based on free RAM and I need to read on locations 140-141 STARP I'll Post anyway as may be useful to others p.s. I tried to get clever to use the open command to load a playfield using a computed string for the filename e.g. FN$="D:SCREEN.001" where 001 was the level number, was pleased with this but it failed with error 130, doesn't recognise this as device D: ... think synthpopalooza had a dirty way of opening levels in one of his tubo-bsaic games will take a look. Something like this: 1000 POSITION 0,0 1010 PRINT "ENTER ""D:LEVEL1.LST""":PRINT 1020 PRINT "POKE 842,12:CONT" 1030 POSITION 0,0:POKE 842,13:STOP 1040 REM rest of the program here you might want to do a poke 559,0 or somesuch to turn off the screen while this process is happening. What happens is, you send the Atari into forced read mode where it automatically pushes the return key and enters commands as you print them on the screen. This is how I was able to load my sky scraper levels. Downside to this: You will not be able to compile this program. Also, have a look for my convert.bas program (it's on this forum somewhere) to learn how to allocate strings to memory locations. What you are doing is making sure that the string you want to act on is the first declared in your program, then modifying the variable name table to point to a memory location, for example CHBAS. Then any operation you perform on the string gets reflected to that memory location, allowing you to redefine an entire character set in a flash. A form of block PEEK and POKE. Note that this will not work in immediate mode, it will cause a crash. The string can also be set to point to your PMBASE, or to SCREEN - DPEEK(88), or anywhere else you like. Excellent if you want to do screen animation, just have code which sets the string equal to each screen, and it gets rewritten immediately. String length is dynamic far as I know ... limited only by your ram. Another thing you can do, is design your screens using my textdraw.tur utility ... save the screens, then use this command to load them each time: 100 OPEN #1,4,0,"D:LEVEL1.SCR" 110 BGET #1,DPEEK(88),960 120 CLOSE #1 That's it. here's a link to textdraw.tur: http://gury.atari8.info/details_source_code/4158.htm Edited December 17, 2009 by Synthpopalooza Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 17, 2009 Share Posted December 17, 2009 You could save some memory by preloading stuff like PMG shapes and character set into high memory then just RUN "D: " the main program. Of course, tricks like the forced entry and chaining programs can be a pain in the dev phase. But if you're using the emulator you could just ditch DOS and use H: instead. You can save more memory by using the cassette buffer. That's 131 bytes down around $3FD-$47F - maybe not enough for a Display List for bitmap but you can use it for something. In Basic programs themselves you can save by using longer lines. A single statement per line adds something like 3 bytes compared to seperating with colons. You can also save memory by storing data in strings or files (even better) rather than as numbers. The breaker here is 155 (Return) as it doesn't have a matching Esc character but you can get around that. 1 Quote Link to comment Share on other sites More sharing options...
Synthpopalooza Posted December 17, 2009 Share Posted December 17, 2009 Oh, here's a link to an .atr containing textdraw.tur textdraw.zip 1 Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted January 6, 2010 Author Share Posted January 6, 2010 I've adapted the level load routine to this (below) and it works fine loading a screen based on the level number 24010 BAR$(22,25)=STR$(1000+LE(PL)):BAR$(1,22)="OPEN #1,4,0, D:SCREEN.":BAR$(13,13)=CHR$(34):BAR$(26,26)=CHR$(34) 24020 GRAPHICS 0:POSITION 2,4:? BAR$(1,26);":POKE 842,12:CONT":POSITION 2,0:POKE 842,13:STOP 24030 GRAPHICS 28:POKE 756,MTOP:BGET #%1,DPEEK(88),960:CLOSE #1:RETURN My 'program' is running in gr.28 with a modified DL in situ, however when I re-issue the Graphics.28 statement, after dropping to gr.0 for this screen load routine, my PMG strings are being moved on by 60 bytes. This causies my PMGs to shift down the screen. I've tried various things to resolve this without success I have the following: 5x1024 character sets at memtop. memtop lowered by 20 pages. Display list modified in situ. free ram strings 1st pmg string (buffer$) set to start on K boundary using a filler$ as detailed in earlier posts. It is at 40960/40K before the gr.28 call and 40960 after the gr.28 statement; it's definitely the gr. call that moves the strings addresses. my turbo-basic program low mem p.s. Textdraw looks really useful Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted January 13, 2010 Author Share Posted January 13, 2010 Can anyone help me with the above post DL Questions: I currently modify the DL where it sits. If I put the DL data in Page 6, will this free up RAM (to allow more Tbasic code) How do I activate the DL? I have a version of atariksi's DL to change the colours (from other thread here). I understand how to enable this on a particular line, activate this, run it from different areas of RAM etc. How would I add a second DLI to change the colours at another line I'm asking as I set location 512/513 (VDSLST) to the address of the first DLI so how do I reference another one Thanks Quote Link to comment Share on other sites More sharing options...
+Stephen Posted January 14, 2010 Share Posted January 14, 2010 Here's an example of a "chained" DLI. Each DLI must reference the next. The other issue with multiple DLIs is the need to synchronize them so the 1st DLI always triggers in the correct spot. This is accomplished with a simple bit of VBI code. See my blog for those details. All it requires is this simple code in the immediate VBI (designed with the DLI residing at $B200 - for yours, you would want to store $06 in memory location $201) : org $600 lda #$00 sta $200 ;Synchronize top DLI lda #$B2 ;with code at $B200 sta $201 ;The DLI will then walk itself down screen Note - to enable this code you must do : ;EQUATES SETVBV equ $E45C ;Immediate VBI ;run this code to set the Immediate VBI vector ;AFTER the above code is loaded pla ;since calling from BASIC, clear stack ldy #$00 ;lo-byte ldx #$06 ;hi-byte lda #$06 ;Immediate VBI jsr SETVBV ;"inject" code into immediate VBI rts ;All done - return control to BASIC Note, you can discard the initialization code once it has been called to free up a few bytes. You can do it from TB via the following USR call. You would obviously replace the string in quotes with the ATASCII values of the compiled code from above, it's 11 bytes. ? USR(ADR("INSERT STRING HERE") To enable the DLI, do the following: 10 POKE $D40E,$C0:REM ENABLE DLIs 20 POKE $22F,0:REM TURN OFF DMA BEFORE SETTING DLI LOCATION 30 POKE $230,0:REM DLIST=$B200 40 POKE $231,$B2:REM DLIST=$B200 50 POKE $22F,$22:REM TURN ON DMA AFTER SETTING DLI LOCATION Here is code demonstrating a triple DLI ;EQUATES GRAFP0 equ $D00D GRAFP1 equ $D00E GRAFP2 equ $D00F GRAFP3 equ $D010 PRIOR equ $D01B GRACTL equ $D01D DMACTL equ $D400 WSYNC equ $D40A org $B200 ;DLI #1 pha ;Save A ;DO STUFF HERE lda <D2 ;point to DLI#2 sta $200 ;$201 will still have $B2 pla ;Restore A rti ;DLI #2 D2 pha ;save A ;DO STUFF HERE lda <D3 ;point to DLI#3 sta $200 ;$201 will still have $B2 pla ;Restore A rti ;DLI #3 D3 pha ;save A ;DO STUFF HERE lda #$00 ;point to DLI#1 sta $200 ;$201 will still have $B2 pla ;Restore A rti Stephen Anderson Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 14, 2010 Share Posted January 14, 2010 (edited) Have you used the cassette buffer yet? That's 131 bytes waiting to be put to use. How are you doing your Assembler stuff? Most efficient way is to have them in seperate file/s. Most wasteful way is in DATA, then POKEing them into RAM - you're using as much as 5 times the memory just to do that (including the destination where the actual code will go). Next wasteful is having them in strings. One thing that I've not tried yet... for short Asm stuff, you could have something like: 1000 ROUT=ADR("<assembler stuff>") to keep short routines. I think it'd work - BASIC programs shouldn't move around while running, only if entering new statements. Of course, that trick's only good if it's relocatable and less than 110 bytes or so. The saving there is that the routine is imbedded in your Basic program and the RAM use is 1:1 - plus the few extra bytes overhead for the line, tokens and variable space. Edited January 14, 2010 by Rybags Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted January 15, 2010 Author Share Posted January 15, 2010 Thanks for the info guys I'm not using assembler just yet, Turbo basic and finally sussing PMGs is enough of a jump for this project, I'm just trying out various things that I haven't managed before; finally Mapping the Atari is starting to make sense and my copy of De Re Atari arrived a few days ago I did have a look at assembler many years ago and got a guy zipping around the screen, and will probably have another go once I get more up to speed. I will inevitably conclude that speed is still not enough even in Turbo basic (and I can't compile as am using several character sets for animation) so will need m/c routines (analmux's engine maybe) eventually. I've just been modifying other peoples DLI routines (yes the wasteful way using data statements while I learn!). Yes have sussed using cassette buffer. I'll take a look at the chaining DLI routines info. Back to the creeping string issue (holding my PMGs). This is to do with the amount of text on the GR.0 screen. If you have a program that runs in gr.28, dim a string, check its address, drop out to gr.0 and do the 'forced input mode' then return via 'cont' and re-check the address of the string it has moved. The more you add to the gr.0 statements the more bytes are added to this: :!: Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 15, 2010 Share Posted January 15, 2010 Forced input mode to enter new program statements will move strings, variables and arrays upwards in RAM. But why would you be wanting to build program code after you've initialized everything? I suppose if you've got certain stuff in DATA, it'd be valid to then delete those lines once they've been used. Then you have the problem that the program will behave differently once it's run again. Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted January 17, 2010 Author Share Posted January 17, 2010 Forced input mode to enter new program statements will move strings, variables and arrays upwards in RAM. But why would you be wanting to build program code after you've initialized everything? I suppose if you've got certain stuff in DATA, it'd be valid to then delete those lines once they've been used. Then you have the problem that the program will behave differently once it's run again. I have my PMGs setup in strings (for vertical movement and animation) and then wanted to load each level's playfield from file, not a major problem, I'll try and work around things, was just looking at what was possible 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.