News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_HAL6128

Fast way of deleting / reset a 512 kB memory expansion

Started by HAL6128, 12:55, 25 July 24

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

HAL6128

Hi,

I'm looking for a fast way how to delete or reset an external memory expansion (512 kB) by filling it with zeros. I have to approches so far, but maybe somebody a better way or idea to do it? 

1.
ld b,0 ;256
ld de,#0800 ;256 > 256*2048 = 512 kB
Clear_loop:
push bc
xor a
ld bc,PORT
out (c),a
pop bc
djnz  Clear_loop
dec de
ld a,e
or d
jr nz, Clear_loop

2. (faster):
xor a ; A = 0
[font=Verdana, Arial, Helvetica, sans-serif]ld de,0 ; > #FFFF = 65535 (64 kb) >>[/font]
ld bc,PORT
CLEAR_LOOP:
; 64kB x 8 = 512 kB

out (c),a ; address + &00
out (c),a ; address + &01
out (c),a ; address + &02
out (c),a ; address + &03
out (c),a ; address + &04
out (c),a ; address + &05
out (c),a ; address + &06
out (c),a ; address + &07

dec de
ld a,e
or d
jp nz, CLEAR_LOOP
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

roudoudou


512K of memory expansion, you have to go trough all pages with "gate array"

#C4, #C5, #C6, #C7, #CC, #CD, #CE, #CF
#D4, #D5, #D6, #D7, #DC, #DD, #DE, #DF
#E4, #E5, #E6, #E7, #EC, #ED, #EE, #EF
#F4, #F5, #F6, #F7, #FC, #FD, #FE, #FF

Then raz memory

slower

ld hl,#4000 : ld de,#4001 : ld (hl),l : ldir
faster (interrupt disabled)

ld sp,#8000 : ld hl,0 : ld b,0
.raz repeat 32 : push hl : rend : djnz .raz



andycadley

Your examples don't seem to actually write to memory, so aren't doing what you think they're doing.

A bigger question is why? What advantage do you imagine there is to filling RAM with zero?

HAL6128


Oh, sorry. Always with my mind two steps to fast.
@roudoudou: thanks for the second example. Creative idea. As I understood you are "pushing" 32 x 256 x 2 Bytes = 16kB

Forgot to mention that this memory is the VRAM of V9990 GFX card and I want to clear it (fill it with zero).
In the example above you first set the target address (in my example that will be the start at #00 00 00) which is not shown.
With the OUT command to the PORT a value will be sent then to the target VRAM address (the VDP increases automatically the pointer to the next VRAM address). Therefore, another OUT sends the next byte and so on...
Just wanted to know if there's a simple and fast way of looping an OUT command 524288 times?

...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

roudoudou

so simply unroll loop :)
and optimize the test

instead of
dec de
ld a,e
or d
jp nz, CLEAR_LOOP

dec e
jr nz,clear_loop
dec d
jr nz,clear_loop



Prodatron

If its the VRAM of a V9990 its a lot faster to use its blitter to fill the RAM with 0.

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

HAL6128

Quote from: Prodatron on 17:48, 25 July 24If its the VRAM of a V9990 its a lot faster to use its blitter to fill the RAM with 0.
Hi Prodatron, yes you are right. There's the LMMV command which could do that in a fraction of a second, pretty astonishing! I was just curious if there's a way or idea from the CPC side which does this faster than my code on the top of the thread.
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

Prodatron

Now I just wonder if you have a new secret V9990 project with memory, which can be accessed like a memory expansion for the CPC as well? :)

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

HAL6128

Oh no, no secret project.  :)

Just got angry (or curious) about my V9990 card, having it, just lying around and nothing happens. So, I wanted to learn and started playing a little bit with it. And especially I want to know more about the P1 mode (with the extra layers & sprite possibilities).

I've downloaded a MSX demo ( GitHub - albs-br/msx-samurai: Unplayable demo of the old fighting game. MSX+V9990. Just a POC.) which is well documented and adapted it to the CPC. Just got the background visible.
See the attached image (left monitor = V9990 result / right monitor = CPC).
Thanks to the M4 26kB image file is uploaded into the VRAM within 2-3 sec. I'm working with the firmware (e.g. CAS_IN_CHAR), so being as compatible as possible.

The VRAM clearing is for the reset state in the beginning. Yes, with the LMMV command is much faster, but it's always good to know what kind of algorithm are possible because you always need to transfer data from CPC to VRAM (e.g. palette data, name tables and so on).

By playing with the parameters, I'm starting get knowing the VDP better and better. Next step will be the sprites available.

("In principle the V9990 VDP could act as a 512 kB memory expansion if you don't use the graphics features, but transfer time is far too slow to get a real use!?")
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

Prodatron

Oh now I got it! :) Sorry, didn't have a deeper look at the later posts here.
The process of transfering data between the V9990 VRAM and the CPC ram is as fast as copying memory in the classic way, as OUTI/INI has the same speed as LDI. You just need to use some unrolled code, as you can't use B for OTIR/INIR anyway on the CPC because of the 16bit I/O. So if you would use the VRAM as a ram disc, there wouldn't be big differences. Just the overhead of setting the start/destination address maybe a little bit more. On the other hand, copying rectangle bitmaps from CPC to V9990 is even faster compared to the CPCs own screen, as you don't have additional "screen next line" code. TBH I am not sure how this works in pattern mode, as I never used this.
Your example looks very nice! I am looking forward to this!

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

GUNHED

Quote from: HAL6128 on 14:44, 25 July 24Oh, sorry. Always with my mind two steps to fast.
@roudoudou: thanks for the second example. Creative idea. As I understood you are "pushing" 32 x 256 x 2 Bytes = 16kB

Forgot to mention that this memory is the VRAM of V9990 GFX card and I want to clear it (fill it with zero).
In the example above you first set the target address (in my example that will be the start at #00 00 00) which is not shown.
With the OUT command to the PORT a value will be sent then to the target VRAM address (the VDP increases automatically the pointer to the next VRAM address). Therefore, another OUT sends the next byte and so on...
Just wanted to know if there's a simple and fast way of looping an OUT command 524288 times?


If you delete RAM by using an OUT commend, then I suggest you to use the "DB &ED,&71" construction, this in in effect an OUT (C),0 - the quickest way to write a 0 to the (BC) port.

Now use 16x "DB &ED,&71" to write 16 bytes to the I/O port.


EDIT: Yes, you can use the 512 KB of the VDP9990 as RAM disc. The access time is roughly like working with IDE devices.
http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

HAL6128

Oh, I didn't know or better I made a false assumption...

Normally I use Notepad++ and RASM for assembling and transfer it directly via xfer onto the M4.

But for testing purposes, and the step-by-step debugging, I tried that code "OUT (C),0" in WinApe on a PC, but it complained during assembling. So, I assumed - of course false - it will not work on RASM too.

Maybe I should start working in a different environment like ACE DL & RASM & Notepad++? Is there a way to combine both ACE_DL & RASM??

or this one (somebody tried it?):
KC IDE - Visual Studio Marketplace

Nevertheless, thanks for the hint.
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

andycadley

OUT (C),0 is technically an undocumented instruction so assemblers won't necessarily handle it. Also some CPU variants do OUT (C),255 instead so you never quite know (though all CPUs officially used in the CPC send 0).

GUNHED

On CPC OUT (C),0 is what it is an works well.

Only if someone does replace the Z80 by a CMOS version, it becomes a problem. But why would you do that anyway.

Lot's of software is using this instruction (Sound Players, FutureOS, Symbos, other stuff...)

It's quick, short and save  :) :) :)
http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

HAL6128

... now I was able to adapt the code and visualize the first sprite on the right.
It's a huge sprite!

In P1-mode each visual screen is a field out of 27 rows x 31 or 32 columns tile / pattern. Each tile / pattern consists of is 8 x 8 pixel with 16 colours. The image displayed could be much bigger (64 x 64 tiles in case you want to scroll). In P1-mode you can use two independent screens (not used here - so, P2-mode - which is similar w/o a second screen - would also be useful).
A sprite is defined by 16 x 16 pixel (independent 16 colours). To create such a huge sprite in the image attached, 8 x 8 sprites (or also tiles) = 64 different sprites (from the sprite pattern / table) were necessary.
The maximum number of sprites are 125 with max. 16 sprites in one row.
So, a second similar huge sprite could be displayed on the left.

On the screen it looks like a CPC mode 1 but with 16 colours (4bit/dot).
From its capabilities I see the V9990 VDP technically somewhere between the NES and SNES? What do think?

next step: I'm curious how fast sprites can be displayed for movements.  :D
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

Prodatron

Looks cool! :D
Is it possible with the V9990 to link sprites? (I know this feature from the Spectrum Next)
Anyway, changing a few sprite coordinates is still faster than anything else we ever had on the CPC o.G.

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

HAL6128

You mean the capability to group sprites relative to a reference, like an object which inherits properties?
As far as I have read from the manual this is not available per hardware of the VDP. But - honestly - I don't know.
The Spectrum Next seems to be more advanced.
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

HAL6128

A short question:
I have an ASCII file on my disc, and I want to open it via assembly with CAS_IN_OPEN, but it is recognized as a BASIC file. AFTER CAS_IN_OPEN register A gave me "00" (for BASIC file) back instead of "16". So, CAS_IN_CHAR doesn't work anymore properly afterwards.
Due to firmware guide I had the chance of an unlikely situation, hadn't I?
(By the way: I changed the first byte of the file and then it is recognized properly, but I don't want to do this).

Does anybody have an idea to work around this issue?

 
"...Unprotected ASCII files do no have header. All other AMSDOS files have a single header in the first 128 bytes of the file, the header record. These headers are detected by checksumming the first 67 bytes of the record. If the checksum is as expected then a header is present, if not then there is no header. Thus it is possible, though unlikely, that a file without a header could be mistaken for one with a header..."
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

McArti0

If you manually change something in the header, you must also correct the checksum.  Byte 67-68 (&43-&44)
Checksum its sum 0-66 header bytes.

What value do you put into the first byte for it to work and what value do you replace?
CPC 6128, Whole 6128 and Only 6128, with .....
NewPAL v3 for use all 128kB RAM by CRTC as VRAM
One chip drver for 512kB extRAM 6128
TYPICAL :) TV Funai 22FL532/10 with VGA-RGB-in.

HAL6128

The file has no header as it is an ASCII or raw image file to be loaded into memory. Just a byte sequence (not for the CPC but for the V9990). I just changed the first byte from the file from &00 into &FF and then it worked. But as it is an raw image file it will also change its appearance on screen.
Ok, I think I have to change the values manually as you suggested in RAM (&A750?) after CAS_IN_OPEN.
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

McArti0

If, by some coincidence, bytes 67-68 are the sum of bytes 0-66, it is a header even if you didn't want it to be. Count and see if you got it right.
If your first 140 bytes are zero then 67*0 is zero. All is correct its basic file zero length.
CPC 6128, Whole 6128 and Only 6128, with .....
NewPAL v3 for use all 128kB RAM by CRTC as VRAM
One chip drver for 512kB extRAM 6128
TYPICAL :) TV Funai 22FL532/10 with VGA-RGB-in.

Prodatron

IIRC without tricks it's not possible to load files with random binary data (any bytes between 0-255) as ASCII file with Amsdos/CPC OS, as it will stop, when it finds byte 26 (EOF).
Either you use WinApe or tools like ahead.com (SymShell) to add a binary header, or you load the ASCII like a binary with a hack in a fast way, where you use the 2KB buffer and fake the already loaded bytes.

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

HAL6128

#22
Yes, that's what I did. I created a function which loads the ASCII (or raw image file) via CAS_IN_OPEN on first step (e.g. the background for the VDP V9990 above). Read a first CAS_IN_CHAR (which loads the buffer) and transfer the 2048 kB into the VRAM.  Then I manipulate the memory locations of the header, pretend to be the end of CAS_IN_CHAR and then with the next CAS_IN_CHAR another 2048 kB is loaded immediately into memory (transfer it into VRAM again). With that approach I need e.g. 13 cycles for a 26kB file (which is the image), for a 16 kB image > 8 cycles. The cycles are hardcoded.
This approach is not my idea as I've stolen it from here:  Reading disk faster in Amstrad CPC using firmware | by Uto | Medium

It's not exact, because I only transfer an amount of multiplied by 2048, but for the moment it's ok if I set the VRAM location next time correctly.

But the file has to be recognized properly by CAS_IN_OPEN as an ASCII file to do all the stuff. It worked well with the first image and sprite, but not the second one.

Damn, bad luck. By coincidence the first 68 bytes are "00". It says "BASIC" file.
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

Prodatron

Ah, got it! I used this hack in Digitrakker in the 90ies, but never had this issue, as there was always data instead of 0 at the beginning of a MOD or an MDL file.
So what's about just adding some bytes like "V9990BMP" of at the beginning of such a file, which you will skip during loading?

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

HAL6128

Oh, I feel a little bit ashamed because your Idea is so easy and efficient.  :)
Yes, of course. Better than manipulate the header afterwards.
Thank you!
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

Powered by SMFPacks Menu Editor Mod