Best way to fill screen in basic?

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Best way to fill screen in basic?

Post by Jbizzel »

Is there a faster way in basic to fill the screen with a SCR file you have placed in memory somewhere... like this?

Code: Select all

1 REM  LOAD "image" CODE 40000,6912
10 LET c=23295
20 LET n=16384: LET i=40000
30 FOR x=1 TO c: POKE n,PEEK 
40 LET n=n+1: LET i=i+1: PRINT AT 0,0;n: NEXT x
another question is how to write the code so that is starts at the top and works its way down line by line, rather than jumping between the 3 areas of the screen.
User avatar
PeterJ
Site Admin
Posts: 6879
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: Best way to fill screen in basic?

Post by PeterJ »

This is something I have been working on @Jbizzel,

This fills the screen from top to bottom, and not in sections.

There is a very good description in 'Delving Deeper into your ZX Spectrum' by Dilwyn Jones. It's one of my favourite Spectrum books.

It was going to be the start of a Woot title, but I lost inspiration temporarily.

I did it in Boriel, but it should run in Sinclair BASIC.

Code: Select all

zxbc screenfill.txt --tzx --BASIC -S 40000 --autorun

Code: Select all

5 PRINT "Insert Game Tape":PAUSE 0
6 LOAD "" CODE 32000
8 CLS
10 FOR Y=0 TO 23
20 FOR L=0 TO 7
30 FOR X=0 TO 31
40 LET ADDRESS=16384+32*(56*INT(Y/8)+Y)+X+L*256
45 LET C=ADDRESS + 15616
50 POKE ADDRESS,PEEK C
60 NEXT X
70 NEXT L
80 NEXT Y

100 FOR A=22528 TO 23295
110 POKE A,PEEK (A+15616)
120 NEXT A
130 PAUSE 0
User avatar
PQR
Manic Miner
Posts: 241
Joined: Sat May 12, 2018 11:35 am
Contact:

Re: Best way to fill screen in basic?

Post by PQR »

If you have a toastrack 128K -- this is still Basic:

Code: Select all

10 SAVE ! "image" CODE 40000,6912
20 LOAD ! "image" CODE 16384
User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Re: Best way to fill screen in basic?

Post by Jbizzel »

@pqr - I did not know this.

@PeterJ that's great. I was working on a similar bit of code, but hadn't quite got there!

My original example could be modified to just the attribute address and it would work nicely with yours to copy a whole screen very slowly, and colour it in.

Perfect for a crap game, or do it faster in Boriel.

Zx0 is another option, but not basic obviously
User avatar
PeterJ
Site Admin
Posts: 6879
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: Best way to fill screen in basic?

Post by PeterJ »

I'm glad it's useful @Jbizzel,

I've settled on either using BASIC complemented with small machine code routines, or Boriel BASIC for projects. My project is a game similar to Catchphrase (in terms of the partially appearing backgrounds), but with Spectrum loading and running screens.

Peter
User avatar
+3code
Manic Miner
Posts: 433
Joined: Sat Mar 19, 2022 7:40 am

Re: Best way to fill screen in basic?

Post by +3code »

You can use this trick http://blog.jafma.net/2020/03/16/effici ... m-iv/#en_5 to move instantly the entire screen from your RAM address to the video address.
berarma
Microbot
Posts: 106
Joined: Thu Mar 09, 2023 10:55 am

Re: Best way to fill screen in basic?

Post by berarma »

This is another version of the proposed code, it might be marginally faster, or slower. I haven't measured.

The only way to do it really fast is using a machine code routine.

Code: Select all

5 PRINT "Insert Game Tape":PAUSE 0
6 LOAD "" CODE 32000
8 CLS
10 FOR A=16384 TO 20480 STEP 2048
20 FOR B=A TO A+255 STEP 32
30 FOR C=B TO B+2015 STEP 256
40 FOR D=C TO C+31
50 POKE D,PEEK (D + 15616)
60 NEXT D
70 NEXT C
80 NEXT B
90 NEXT A

100 FOR A=22528 TO 23295
110 POKE A,PEEK (A+15616)
120 NEXT A
130 PAUSE 0
User avatar
Red Zebra
Drutt
Posts: 36
Joined: Fri Jan 20, 2023 7:53 am

Re: Best way to fill screen in basic?

Post by Red Zebra »

Thought I'd have a crack at this.

It's a bit of BASIC that will POKE a super simple bit of machine code that LDIR's 6912 bytes from a location in memory to screen/attribute memory.
The variable U specifies where to POKE the routine (12 bytes needed), and V specifies where to copy data from.

I've set the defaults to be 65535-12 (top of memory) for the routine location and 40000 (as per your example snippet) as the source data location.

Code: Select all

9000 LET u = 65535-12 : LET v = 40000
9010 POKE u,1:POKE u+1,0:POKE u+2,27:POKE u+3,17:POKE u+4,0:POKE u+5,64:POKE u+6,33:POKE u+7,v-256*INT(v/256):POKE u+8,INT(v/256):POKE u+9,237:POKE u+10,176:POKE u+11,201
9020 RANDOMIZE USR u
User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Re: Best way to fill screen in basic?

Post by Jbizzel »

@Red Zebra OMG that is perfect. Blink and you miss it. This is a basic code snippet worth holding on to. I think @PeterJ could just this too, its fast!
User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Re: Best way to fill screen in basic?

Post by Jbizzel »

Red Zebra wrote: Tue Dec 05, 2023 11:57 am Thought I'd have a crack at this.

It's a bit of BASIC that will POKE a super simple bit of machine code that LDIR's 6912 bytes from a location in memory to screen/attribute memory.
The variable U specifies where to POKE the routine (12 bytes needed), and V specifies where to copy data from.

I've set the defaults to be 65535-12 (top of memory) for the routine location and 40000 (as per your example snippet) as the source data location.

Code: Select all

9000 LET u = 65535-12 : LET v = 40000
9010 POKE u,1:POKE u+1,0:POKE u+2,27:POKE u+3,17:POKE u+4,0:POKE u+5,64:POKE u+6,33:POKE u+7,v-256*INT(v/256):POKE u+8,INT(v/256):POKE u+9,237:POKE u+10,176:POKE u+11,201
9020 RANDOMIZE USR u
OK, i don't get it - not hard for me.

How does it know where the screen memory is? where do you tell it to start at #4000 / 16384 for example? Please help my simple mind understand

OK, I had a go - something like this?

Code: Select all

Ld BC 001b (27)?
ld DE 00,40 (start of the screen memory?)
ld HL with some part of the image - the start?
ldir
ret
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Best way to fill screen in basic?

Post by ParadigmShifter »

Remember byte order is low then high in memory so that is doing

ld bc, 6912
ld de, $4000
ld hl, v ; v = 40000 in the code
ldir
ret


If you are using an emulator the debugger will disassemble the code from any given address when in memory so use that instead of disassembling opcodes by hand.

If you want to learn some machine code, use an emulator and a proper assembler (one in Spin is not very good, use sjasmplus, pasmo or zeus instead) rather than poking opcodes and operands into memory.
User avatar
Red Zebra
Drutt
Posts: 36
Joined: Fri Jan 20, 2023 7:53 am

Re: Best way to fill screen in basic?

Post by Red Zebra »

Jbizzel wrote: Tue Jan 09, 2024 11:15 pm

Code: Select all

ld HL with some part of the image - the start?
As @ParadigmShifter said the byte order is reversed. The Z80 is "little endian" so it stores addresses "back-to-front".

This bit

Code: Select all

POKE u+7,v-256*INT(v/256)
POKE u+8,INT(v/256)
breaks up the 16-bit value stored in V into two 8-bit values that are written in reverse order into memory for the "LD HL,nn" operation.
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: Best way to fill screen in basic?

Post by Dr beep »

User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Re: Best way to fill screen in basic?

Post by Jbizzel »

Thank you guys.

Let me set out what I am trying to do.

In this thread is some basic code, ran in USR0 mode to display a gigascreen. The screens are actually 2 normal spectrum screens of 6912 size - on this thread you will see a picture of my son, displayed on a real spectrum.

viewtopic.php?p=134622#p134622

Now.... Velesoft made some gigascreen images as part of a zip file some time ago. I was interested in viewing them. These are .SCR files that are size 13824 (6912 * 2)

I couldn't find a way to view them. What I can confirm is that they are 2 normal spectrum screens wrapped up in to one screen file. I have confirmed this by loading the full file in to memory and then using the code from Red Zebra to display both screens on my spectrum.

Then I thought, if I mash both bits of code together - the gigaviewer code and the code example from Red Zebra then I can actually view the images from Velesoft on my spectrum.

So that is what I have been trying to do. My code is a bit messy because a) it loads the machine code twice, which it doesn't need to do. But more importantly it loads 1 images OK, but not the second.



Here is my code. It must be ran under USR0. It almost works, but something is wrong. Any help is apricated!

Code: Select all

5 CLEAR 39999
6 LET v=40000: LET o=49152
10 LOAD "" CODE 40000,13824
200 REM POKE 23739,111
210 OUT 32765,21
220 GO SUB 9000
230 OUT 32765,23
240 LET v=46912
250 GO SUB 9000
430 PAUSE 1
440 OUT 32765,16
450 PAUSE 1
460 OUT 32765,24
470 IF INKEY$<>"" THEN STOP 
480 GO TO 4308000 STOP 
9000 LET u=65535-12
9010 POKE u,1: POKE u+1,0: POKE u+2,27: POKE u+3,17: POKE u+4,0: POKE u+5,192: POKE u+6,33: POKE u+7,v-256*INT (v/256): POKE u+8,INT (v/256): POKE u+9,237: POKE u+10,176: POKE u+11,2019020 RANDOMIZE USR u
9030 RETURN 
here is the gigascreen viewer code, so it is easier to see what I have tried to do

Code: Select all

370 CLEAR 49151
380 POKE 23739,111 
390 OUT 32765,21 
400 LOAD "" CODE 49152 
410 OUT 32765,23 
420 LOAD "" CODE 49152 
430 PAUSE 1 
440 OUT 32765,16 
450 PAUSE 1 
460 OUT 32765,24
470 IF INKEY$<>"" THEN GO TO 370
480 GO TO 430
not quite there....

Image
AndyC
Dynamite Dan
Posts: 1408
Joined: Mon Nov 13, 2017 5:12 am

Re: Best way to fill screen in basic?

Post by AndyC »

You're not paying attention to your memory map. When you change the 128K banking you're paging out your copy routine (which is right at the top of memory). You'll also be paging out the memory that contains part of your second screen, if my back of a fag packet maths is correct.
User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Re: Best way to fill screen in basic?

Post by Jbizzel »

Well, this is what I was worried was happening, but I don't understand paging at all!
AndyC
Dynamite Dan
Posts: 1408
Joined: Mon Nov 13, 2017 5:12 am

Re: Best way to fill screen in basic?

Post by AndyC »

Paging is really not that complicated. Essentially you're picking which bit of memory is located between 49152 and 65535. When you change the bank, all that memory at that location instantly changes.

So any code or data you want to access needs to be below 49152 before you start swapping memory around.
User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Re: Best way to fill screen in basic?

Post by Jbizzel »

whoo-hoo!

thanks Andy

Code: Select all

5 CLEAR 34999
6 LET v=35000: LET o=49152
10 LOAD "" CODE v,13824
200 REM POKE 23739,111
210 OUT 32765,21
220 GO SUB 9000
230 OUT 32765,23
240 LET v=v+6912
250 GO SUB 9000
430 PAUSE 1
440 OUT 32765,16
450 PAUSE 1
460 OUT 32765,24
470 IF INKEY$<>"" THEN STOP 
480 GO TO 430
8000 STOP 
9000 LET u=49100-12
9010 POKE u,1: POKE u+1,0: POKE u+2,27: POKE u+3,17: POKE u+4,0: POKE u+5,192: POKE u+6,33: POKE u+7,v-256*INT (v/256): POKE u+8,INT (v/256): POKE u+9,237: POKE u+10,176: POKE u+11,201
9020 RANDOMIZE USR u
9030 RETURN 
9999 LET o=49152: PRINT o-256*INT (o/256)
Image
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Best way to fill screen in basic?

Post by catmeows »

Well, perhaps you could just change CHARS and print string like "abcdefghijklmn .... " for each character line.
Proud owner of Didaktik M
User avatar
+3code
Manic Miner
Posts: 433
Joined: Sat Mar 19, 2022 7:40 am

Re: Best way to fill screen in basic?

Post by +3code »

@Jbizzel

Nice, but I don't get it. In the original code the images need to be placed at 49152, in this last code are placed at 35000+6912?


Edited by PJ
User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Re: Best way to fill screen in basic?

Post by Jbizzel »

The file here is twice the size of a normal scr file.

6912 *2 but as one combined file.

Within that file is 2 normal screen files that can be displayed independently.

The 35000+6912 is the start of the second screen within the file.

Does that make sense?

There may well be a better way to do it.

I have made a huge tap file with this program and loads of velesofts images (not the anime nudes!) 😅 I'll share it later.

If you press a key it loads the next image on a loop.
User avatar
+3code
Manic Miner
Posts: 433
Joined: Sat Mar 19, 2022 7:40 am

Re: Best way to fill screen in basic?

Post by +3code »

All these gigascreen BASIC stuff is gibing me an idea for a CSCGC entry or something.
User avatar
ParadigmShifter
Manic Miner
Posts: 670
Joined: Sat Sep 09, 2023 4:55 am

Re: Best way to fill screen in basic?

Post by ParadigmShifter »

Jbizzel wrote: Thu Jan 11, 2024 4:27 pm There may well be a better way to do it.
I'm sure you don't have to poke everything at the beginning of the subroutine.

If the problem is the ASM getting paged out put the ASM in an unpaged area and only poke it once. The routine looks relocatable.

If you need to modify the address to copy from just modify the 2 bytes in the ASM (the ones which use v).

You can probably tweak it so it copies 6912*2 bytes instead of 6912 and make the data contiguous.

I don't know anything about paging on the 128K though so I may be wrong.

EDIT: But if it ain't broke don't fix it also applies if you have something you can use and are happy with of course.

If you can disassemble opcodes by hand that tells me you should be learning how to write your own routines in assembler really, it's easy these days with emulation/cross assemblers on the PC and you will learn a lot of useful stuff.
AndyC
Dynamite Dan
Posts: 1408
Joined: Mon Nov 13, 2017 5:12 am

Re: Best way to fill screen in basic?

Post by AndyC »

ParadigmShifter wrote: Thu Jan 11, 2024 7:47 pm
You can probably tweak it so it copies 6912*2 bytes instead of 6912 and make the data contiguous.

I don't know anything about paging on the 128K though so I may be wrong.
You can't arrange the memory such that both screens are contiguous (each one occupies the first 6912 bytes of a RAM bank, either page 5 or 7 depending on the screen) so you will always need to do two separate copies to locate the results in the correct location.
User avatar
Jbizzel
Dynamite Dan
Posts: 1537
Joined: Mon May 04, 2020 4:34 pm
Location: Hull
Contact:

Re: Best way to fill screen in basic?

Post by Jbizzel »

Ive uploaded the tap files here if people want to look at the gigascreen images:

https://jbizzel.itch.io/giga-screenzx

And here is a video too:

Post Reply