Checking Free RAM in ML
Moderator: Moderators
Checking Free RAM in ML
Was wondering if their is a way to check free RAM in machine language. Was wanting to try writing a program similar to Mike's clock program that would show a running total of memory in the bottom 6 screen locations under the border as you were entering it into memory. Maybe even the line you are typing as you type it. That might be a feat in itself though. Might even be useful when a basic program is running to see memory being used.
Any ideas?
Any ideas?
Rob
- Kweepa
- Vic 20 Scientist
- Posts: 1302
- Joined: Fri Jan 04, 2008 5:11 pm
- Location: Austin, Texas
- Occupation: Game maker
Here's what BASIC does when you call FRE(0) (taken from http://www.mdawson.net/vic20chrome/vic2 ... sembly.txt):
You should probably skip the garbage collection call if you're doing this in an interrupt, since it won't play nicely with BASIC.
You could print AY in hex to that part of the screen pretty easily. Alternatively you could use a routine from here:
http://www.codebase64.org/doku.php?id=b ... conversion
to convert to decimal first for printing.
Very nice idea, by the way!
As for the size of the line as you are entering it, as you say that would be a feat - as far as I know, the VIC doesn't attempt to "enter" the line until you press the RETURN key. You'd probably have to parse the line yourself, using the screen line link table at $D9 to find the start of the line.
Code: Select all
JSR $D526 ; go do garbage collection
SEC ; set carry for subtract
LDA $33 ; get bottom of string space low byte
SBC $31 ; subtract end of arrays low byte
TAY ; copy result to Y
LDA $34 ; get bottom of string space high byte
SBC $32 ; subtract end of arrays high byte
You could print AY in hex to that part of the screen pretty easily. Alternatively you could use a routine from here:
http://www.codebase64.org/doku.php?id=b ... conversion
to convert to decimal first for printing.
Very nice idea, by the way!
As for the size of the line as you are entering it, as you say that would be a feat - as far as I know, the VIC doesn't attempt to "enter" the line until you press the RETURN key. You'd probably have to parse the line yourself, using the screen line link table at $D9 to find the start of the line.
Where are you planning to put your code? The tape buffer could be a good choice.
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
Yeah, that was my first choice. If I can make it small enough, maybe the rs-232 buffer. I've been thinking of other things that might be interesting to implement as well. Having a running total of free memory will be nice, but I'm thinking about being able to toggle variable, array and string space used. Might be helpful while a program is running to see these on the fly. Maybe a CTRL-F7 to switch between them. Depends on what I can squeeze into one of the buffers. LOL or maybe both of them. I definitely don't want to use any basic ram. So, I'm thinking the bottom of the screen will look something like this:
F28159:for free ram
V00032:for variables
A:arrays, S:string ect...
Who knows, may even sound a buzzer and flash the screen red when free ram is getting short. Getting kinda bloated now.
I haven't touched any code in over a year now, so it is gonna be a relearning experience for me.
I noticed that their is a Start of Variables, an End of variables and only an End of Strings, and an End of Arrays. Is the Start of Variables and End of Variables all inclusive? Meaning does it include strings, arrays, integer ect...? Are all they variables grouped together? How are the stacked in memory? Which is first, second ect..?
F28159:for free ram
V00032:for variables
A:arrays, S:string ect...
Who knows, may even sound a buzzer and flash the screen red when free ram is getting short. Getting kinda bloated now.
I haven't touched any code in over a year now, so it is gonna be a relearning experience for me.
I noticed that their is a Start of Variables, an End of variables and only an End of Strings, and an End of Arrays. Is the Start of Variables and End of Variables all inclusive? Meaning does it include strings, arrays, integer ect...? Are all they variables grouped together? How are the stacked in memory? Which is first, second ect..?
Rob
- Kweepa
- Vic 20 Scientist
- Posts: 1302
- Joined: Fri Jan 04, 2008 5:11 pm
- Location: Austin, Texas
- Occupation: Game maker
From the kernal disassembly again, here is the memory map:
Note that every time you create a new variable, it has to move the arrays up in memory to accommodate it! You can see this in action at $D11D.
You could let the program cycle automatically through its outputs.
Code: Select all
BASIC program
VARIABLES
ARRAYS
free space
STRINGS (growing down)
top of RAM
You could let the program cycle automatically through its outputs.
-
- Vic 20 Afficionado
- Posts: 352
- Joined: Tue Apr 14, 2009 8:15 am
- Website: http://wimbasic.webs.com
- Location: Netherlands
- Occupation: farmer
WimBasic implementation
You mention the RS232 buffer. In VIC20, when you open an RS232 device, a receive buffer and a transmit buffer of each 256 bytes is grabbed from the top of Basic RAM.
The following code is the implementation of the MEM command in WimBasic. The MEM command sits behind the f8 key per default.
It uses $DDCD to display A:X in decimal on the screen. You cannot use that while in an interrupt routine because it might conflict with STR$ or LIST.
Regards,
Wim.
The following code is the implementation of the MEM command in WimBasic. The MEM command sits behind the f8 key per default.
It uses $DDCD to display A:X in decimal on the screen. You cannot use that while in an interrupt routine because it might conflict with STR$ or LIST.
Regards,
Wim.
Code: Select all
;
LA021 .BYTE $0D
.TEXT "MEMORY"
.BYTE $BA
.TEXT "PROGRAM"
.BYTE $BA
.TEXT "VARIABLES"
.BYTE $BA
.TEXT "ARRAYS"
.BYTE $BA
.TEXT "STRINGS"
.BYTE $BA
.TEXT "FREE"
.BYTE $BA
LA029 .TEXT "BYTES"
.BYTE $8D
;
LTAB2 .BYTE $37
.BYTE $2D
.BYTE $2F
.BYTE $31
.BYTE $37
.BYTE $33
;
LTAB3 .BYTE $2B
.BYTE $2B
.BYTE $2D
.BYTE $2F
.BYTE $33
.BYTE $31
;
;
LDX #$FA
LDY #$00
STY $84
STY $86
.BYTE $2C
LLOOP LDY $87
LDA LTAB2-$FA,X
STA $83
LDA LTAB3-$FA,X
STA $85
TXA
PHA
JSR LA87B
STY $87
LDY #$00
LDA ($83),Y
SBC ($85),Y
TAX
INY
LDA ($83),Y
SBC ($85),Y
LDY #$0A
STY $D3
JSR $DDCD
LDY #$10
STY $D3
LDY #LA029-LA021
JSR LA87B
PLA
TAX
INX
BNE LLOOP
RTS
LA87B LDA LA021,Y
PHP
AND #$7F
JSR $CB47
INY
PLP
BPL LA87B
RTS
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
My mistake. Not a buffer, but the memory area 664-767.
I'm glad you said something about $ddcd not working in an interrupt. I've been looking at about 50 bytes of code for the past 2 days wondering why it has been crashing on me. I'm using it right now just to get the rest of the program working. When finished, I'll have to STA each individual decimal number in it's place.
Thank you for the listing, this should be enough to get this thing working.
By the way, I have never ran into this before can you explain?
I'm glad you said something about $ddcd not working in an interrupt. I've been looking at about 50 bytes of code for the past 2 days wondering why it has been crashing on me. I'm using it right now just to get the rest of the program working. When finished, I'll have to STA each individual decimal number in it's place.
Thank you for the listing, this should be enough to get this thing working.
By the way, I have never ran into this before can you explain?
Code: Select all
LDY #LA029-LA021
Rob
That equates to the number of bytes between those labes.GreyGhost wrote:By the way, I have never ran into this before can you explain?
Code: Select all
LDY #LA029-LA021
Things like this are common practice:
Code: Select all
msg:
dc.b "string"
MSG_LEN equ *-msg
Last edited by tlr on Tue Oct 22, 2013 10:43 am, edited 1 time in total.
-
- Vic 20 Afficionado
- Posts: 352
- Joined: Tue Apr 14, 2009 8:15 am
- Website: http://wimbasic.webs.com
- Location: Netherlands
- Occupation: farmer
Hello Rob,
Just like tlr said. The assembler will compute the number of bytes between the two labels and will build an appriopriate LDY # instruction.
At runtime Y will be loaded with the value and the routine at LA87B will then print the text "BYTES", followed by <CR>.
Regards,
Wim.
Just like tlr said. The assembler will compute the number of bytes between the two labels and will build an appriopriate LDY # instruction.
At runtime Y will be loaded with the value and the routine at LA87B will then print the text "BYTES", followed by <CR>.
Regards,
Wim.
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
- Mike
- Herr VC
- Posts: 4976
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
The addresses from 659 to 672 inclusive are used by the KERNAL for the Pseudo 6551 registers. There's a 'free' area from 673 upwards, up to address 767 (the so-called program indirects). Actually, the Super Expander uses that area for workspace.GreyGhost wrote:My mistake. Not a buffer, but the memory area 664-767.
That pretty much applies to *any* routine within BASIC interpreter and KERNAL. Most of these are not intended to be called from an interrupt. If you do so, it can happen that you re-enter a routine which has just half-executed as the interrupt occured. The second call from within the interrupt will then likely disturb internal state variables of that routine, and this leads to undefined behaviour once the interrupt exits to the foreground again.I'm glad you said something about $ddcd not working in an interrupt. I've been looking at about 50 bytes of code for the past 2 days wondering why it has been crashing on me.
- Mike
- Herr VC
- Posts: 4976
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
Re: Checking Free RAM in ML
I thought it might be a good idea a post a working solution before this thread dies of old age ...
The code doesn't quite fit into the area 673..767, for this reason I had to put it into the tape buffer.
What is output as 'free space' is the difference between 'top of arrays + 1' (stored at $31/$32) and 'bottom of string space' (stored at $33/$34), neatly converted from binary to BCD to PETSCII. I reused a routine in MINIPAINT which is used there to output the block counts in the directory display, except it now doesn't bother to crop the leading zeroes.
In both versions I took the bin to BCD conversion from an example by Andrew Jacobs posted at http://www.6502.org. Otherwise, I'm not going to provide source code this time - you'll have to infer yourself how it works ...
... and if anyone wants to put an equivalent routine into 673 .. 767 - go ahead.
Code: Select all
10 FORT=828TO951:READA:POKET,A:NEXT:SYS828
11 DATA 120,169,83,141,20,3,169,3,141,21,3,173,3,144,41,128,9,48,141,3,144,88,96,216,56
12 DATA 165,51,229,49,133,251,165,52,229,50,133,252,248,169,0,133,3,133,4,133,5,162,16
13 DATA 6,251,38,252,165,3,101,3,133,3,165,4,101,4,133,4,165,5,101,5,133,5,202,208,231
14 DATA 216,169,250,133,251,133,253,174,136,2,232,134,252,138,41,3,9,148,133,254,160,0
15 DATA 169,3,162,4,6,3,38,4,38,5,42,202,208,246,145,251,173,134,2,145,253,200,192,6
16 DATA 208,230,76,191,234
What is output as 'free space' is the difference between 'top of arrays + 1' (stored at $31/$32) and 'bottom of string space' (stored at $33/$34), neatly converted from binary to BCD to PETSCII. I reused a routine in MINIPAINT which is used there to output the block counts in the directory display, except it now doesn't bother to crop the leading zeroes.
In both versions I took the bin to BCD conversion from an example by Andrew Jacobs posted at http://www.6502.org. Otherwise, I'm not going to provide source code this time - you'll have to infer yourself how it works ...
... and if anyone wants to put an equivalent routine into 673 .. 767 - go ahead.
-
- Vic 20 Afficionado
- Posts: 352
- Joined: Tue Apr 14, 2009 8:15 am
- Website: http://wimbasic.webs.com
- Location: Netherlands
- Occupation: farmer
Re: Checking Free RAM in ML
The code below takes 92 bytes and fits in the 673-767 area. Start with SYS673.
Regards,
Wim.
Regards,
Wim.
Code: Select all
.org 673
sei
lda #ticket & $ff
sta $0314
lda #ticket >> 8
sta $0315
lda $9003
and #$80
ora #$30
sta $9003
cli
rts
ticket sec
lda $33
sbc $31
sta $fb
lda $34
sbc $32
sta $fc
lda #$fa
sta $03
sta $05
lda $0288
adc #$00
sta $04
and #$03
ora #$94
sta $06
ldy #$05
div3 ldx #$10
lda #$00
div2 asl $fb
rol $fc
rol a
cmp #$0a
bcc div1
sbc #$0a
inc $fb
div1 dex
bne div2
ora #'0'
sta ($03),y
lda $0286
sta ($05),y
dey
bpl div3
jmp $eabf
.end
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
- Mike
- Herr VC
- Posts: 4976
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
Re: Checking Free RAM in ML
Now, that's quite a feat. And you even kept the niceties I put in to adapt to the different RAM configurations, especially regarding the screen and colour RAM base addresses.wimoos wrote:The code below takes 92 bytes and fits in the 673-767 area. Start with SYS673.
I'd still keep the CLD in front of the interrupt server, though, in case the foreground program executes some instructions in decimal mode.
Cheers,
Michael
P.S. in case anyone is wondering about the use of the zeropage addresses 3..6 here, they're supposed to contain vectors to two routines for conversion between ASCII/PETSCII <-> FAC (floating point accumulator). As it happens, even though BASIC initialises these 4 bytes, neither BASIC itself, nor any program I know uses these vectors to jump to the corresponding routines, they're always directly called. Consequently, I regard these four bytes as essentially free (similar to $FB .. $FE) for own projects.
-
- Vic 20 Afficionado
- Posts: 352
- Joined: Tue Apr 14, 2009 8:15 am
- Website: http://wimbasic.webs.com
- Location: Netherlands
- Occupation: farmer
Re: Checking Free RAM in ML
Just like the Zp $03-$06 and $FB-FE are never used in CBM Basic or the Kernal, there is no instance of a SED. So a CLD would not be needed....I'd still keep the CLD in front of the interrupt server, though, in case the foreground program executes some instructions in decimal mode.
Regards,
Wim.
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic