General Category > Programming

PUSHing data to the screen via stack

(1/2) > >>

redbox:
Hello all,

I am trying to remember how to (in assembler) get data to the CPC screen by moving the stack pointer to the screen address (i.e. &C000 upwards for 16k screen), reading the data from a DEFB (see code example) and then PUSHing it to the screen.

The DEFBs I am using are the ones outputted by ConvImgCPC, for example in a Mode 1 screen you have:


--- Code: ---; Mode 1
; 80x200
        DB      #00, #00, #00, #00, #00, #00, #00, #F8
        DB      #F0, #F0, #F0, #F0, #E3, #00, #00, #00
        DB      #00, #00, #00, #00, #00, #00, #00, #00
...etc...

--- End code ---

If I remember correctly, this technique is fast?

arnoldemu:
the stack goes backwards. So you should point SP at &0000 to start.

You'll need to point to the end of your gfx.

then do something like this:

;; HL = last byte in data
;; note low byte, high byte and order it will be pushed onto the stack!

ld d,(hl)
dec hl
ld e,(hl)
dec hl
ld b,(hl)
dec hl
ld c,(hl)
dec hl
push de
push bc

....

remember to disable interrupts too because this will cause problems and the firmware will not be happy.
Also, remember to restore stack if your using firmware too.

If you don't really need the speed then why not just use LDIR?

redbox:
Thanks for that - I forgot the stack goes backwards! When I did it before I think I was only pushing 1 byte so it didn't really matter.

I am trying to create an animation on the CPC.  For example, if I have two images, I am writing a small program which will detect the difference between the two and record it in a look-up table.  I'm hoping the differences will be not too much, but I still think I need a fast routine to get the data to the screen because I'm assuming there is a limit in how much you can shift in one frame.

I will try a simple routine and see how much I can do...!

redbox:
Okay, my memory of z80 is much worse than I thought - I want to use a look-up table to get a screen location and plot a byte there.

This works:


--- Code: ---ld hl,data
ld a,(hl)
ld de,&c000
ld (de),a

.data
DB #00

--- End code ---

But having the screen address in a table at the end doesn't work:


--- Code: ---ld hl,data
ld a,(hl)
ld de,address
ld (de),a

.data
DB #00

.address
DW #c000

--- End code ---

What am I doing wrong?!

Eventually, I want to be able to loop this, with a data table and a screen table to plot all the changes (excuse the pseudo-code I use before I program the real z80):


--- Code: ---
<count total of data entries>
<put total into register>

.loop
ld hl,data
ld a,(hl)
ld de,address
ld (de),a

<decrease total by 1 and loop again until 0 then exit - jr nz,loop or something>

.data
DB #00, #CF, #32, #00 etc

.address
DW #c000, #D040, #FF00, #E880 etc

--- End code ---

fano:

--- Quote from: redbox on 23:49, 30 November 09 ---
--- Code: ---ld hl,data
ld a,(hl)
ld de,address
ld (de),a

.data
DB #00

.address
DW #c000

--- End code ---

What am I doing wrong

--- End quote ---

This is logical, i you do : ld de,address , you will get adress in DE but if you do ld de,(address) you will get content of adress in DE

When using an address table you may do this :


--- Code: ---ld IX,table
ld HL,data
... do you stuff ...
.loop
ld E,(IX+0)
ld D,(IX+1)
ld A,(HL)
ld (DE),A
inc HL
inc IX
inc IX
...do what you want and loop on .loop
.data
   DB   #00, #CF, #32, #00 etc
.table
   DW    #c000, #D040, #FF00, #E880 etc

--- End code ---

But you may do something better using interleaved data and address , e.g :


--- Code: ---ld HL,table
...other init stuff...

.loop

ld A,(HL)  ;get data
inc HL

ld E,(HL)  ;get scr address (in reverse order)
inc HL
ld D,(HL)
inc HL

ld (DE),A  ;write it

...do your loop to .loop
.table
db #00:dw #C000
db #CF:dw #D040
.....etc....

--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version
Powered by SMFPacks Media Embedder
Powered by SMFPacks Alerts Pro Mod
Powered by SMFPacks Mentions Pro Mod