Jump to content
IGNORED

Memory use re Turbo-BASIC program


Recommended Posts

I'm starting to run out of memory :o 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 :)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 :ponder:

 

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.

Link to comment
Share on other sites

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 :ponder:

 

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 by Synthpopalooza
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

I've adapted the level load routine to this (below) and it works fine loading a screen based on the level number :thumbsup:

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 :thumbsdown:

 

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 :thumbsup:

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 by Rybags
Link to comment
Share on other sites

Thanks for the info guys :thumbsup:

 

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:

post-19705-126357947753_thumb.png :?: :!:

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 :|

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...