CPCWiki forum

General Category => Programming => Topic started by: arnoldemu on 08:59, 04 April 10

Title: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 08:59, 04 April 10
New source:

http://www.cpctech.org.uk/source/normals.asm (http://www.cpctech.org.uk/source/normals.asm)

Software scroll using LDI for copying the scroller.
Mode 1 font (2 bytes wide and 16 lines tall).

I will add to this thread as I release my example sources.
Title: Re: ASM source code
Post by: arnoldemu on 09:16, 04 April 10
New source:

http://www.cpctech.org.uk/source/scrlrast.asm

A   simple single line scrolling horizontal split raster.
Title: Re: ASM source code
Post by: arnoldemu on 19:35, 04 April 10
New source:


http://www.cpctech.org.uk/source/multinst.asm

Example shows how to load your own code into the multiface 2 ram. When the Stop button is pressed your code is executed. The multiface 2 menu is not shown.
Title: Re: ASM source code
Post by: arnoldemu on 21:44, 04 April 10
New source

http://www.cpctech.org.uk/source/hardmess.asm

Horizontal message scroller. Uses hardware scroll (crtc reg 12 and 13).
Note: Code is not optimised, it is meant for example for others to learn.
Title: Re: ASM source code
Post by: arnoldemu on 21:29, 19 April 10
New source

http://www.cpctech.org.uk/source/rotospr.asm

Source shows the type of sprites used in Mission Genocide, Ghosts and Goblins, Bubble Bobble, Ghouls and Ghosts.

Sprites are 3 colours (pen 0 is transparent). Background is 4 colours.
Sprites drawn using logical-OR and erased using logical-AND.

These are also known as "bitplane" sprites.
Title: Re: ASM source code
Post by: redbox on 18:05, 21 April 10
Quote from: arnoldemu on 21:29, 19 April 10
Source shows the type of sprites used in Mission Genocide, Ghosts and Goblins, Bubble Bobble, Ghouls and Ghosts.

That's a really cool example, will have a play around with it.
Title: Re: ASM source code
Post by: arnoldemu on 21:52, 21 April 10
Quote from: redbox on 18:05, 21 April 10
That's a really cool example, will have a play around with it.

:) remember it is not optimised!

The sprite drawing and erase loops could be unrolled to speed it up for example.
Also i use the firmware for checking keys pressed, this could be changed for direct hardware reading.
So there is scope to improve it.

Title: Re: ASM source code
Post by: arnoldemu on 21:54, 21 April 10
New source:

http://www.cpctech.org.uk/source/maskspr.asm (http://www.cpctech.org.uk/source/maskspr.asm)

An example that shows a mode 0 sprite over a background. Pen 0 of sprite is transparent, leaving 15 pens for use with the sprite.
Background can use any of the 16 colours. Sprite is masked when it is drawn to screen.
Background behind sprite is stored in a buffer.

Sprite x movement is by the byte (so 2 pixels at a time in X).
Sprite y movement is by the line (1 pixel in Y).

Again, the code is not optimised.

Code also shows use of a 256-byte aligned mask table, how to create it and how to use it to mask the sprite.

NOTE: Background from internet at a site that claims that the picture is free for use.
Sprite is my own ;)
Title: Re: ASM source code
Post by: Devilmarkus on 21:55, 21 April 10
Cool...
Your asm codes really help me to improve JavaCPC's Z80 assembler ;)
The source for rotosprites compiles well after I found a missing command ;)
Title: Re: ASM source code
Post by: arnoldemu on 21:58, 21 April 10
Quote from: Devilmarkus on 21:55, 21 April 10
Cool...
Your asm codes really help me to improve JavaCPC's Z80 assembler ;)
The source for rotosprites compiles well after I found a missing command ;)

:) helping everyone :)
Title: Re: ASM source code
Post by: Devilmarkus on 21:58, 21 April 10
Funny:
Also the roto sprite in example before and now this disappear in upper half of screen?
Title: Re: ASM source code
Post by: arnoldemu on 22:01, 21 April 10
Quote from: Devilmarkus on 21:58, 21 April 10
Funny:
Also the roto sprite in example before and now this disappear in upper half of screen?
Indeed.
I wait for vsync and first erase the sprite, then I check for keyboard to decide where new sprite coords should be then I draw sprite in new position.
But by this time monitor refresh has gone too far, so either you see no sprite (so time when sprite has been erased and I am checking keyboard), or if you are lucky you see the sprite in time  :P

For example code it works if you move the sprite into the correct place  :P

Well there are ways to fix this: 1. use double buffer 2. erase and draw sprite in same routine, erase a line, draw the line, erase a line, draw the line etc.
Title: Re: ASM source code
Post by: arnoldemu on 21:47, 23 April 10
New source:

http://www.cpctech.org.uk/source/shftspr.asm

This example is for Markus ;)

Shows:
1. ASM version of SPEED KEY 1,1 to speed up key presses (thanks Markus for suggesting it)
2. Only drawing sprite when it has moved (thanks again Markus for suggesting it). The sprite does flicker when moved.
3. Masked mode 1 sprites
4. Pre-shifted sprites. There are 4 sprites used here, each shifted by one more pixel than the other. This is done to move the sprite pixel by pixel.
5. 16-bit X coordinates for positioning sprite on screen
6. Nice background and nice smiley sprite with it's tongue sticking out (I am sure I read that Markus likes these smileys ;) )
Title: Re: ASM source code
Post by: Devilmarkus on 22:46, 23 April 10
Nice example.
Managed to fix another bug thanks your code ;)

But your code is bad!
Compile, run it and move sprite up! (Reset)
Title: Re: ASM source code
Post by: Ynot.zer0 on 11:00, 24 April 10
the disappearing sprite  :P
Title: Re: ASM source code
Post by: arnoldemu on 21:14, 25 April 10
Quote from: Devilmarkus on 22:46, 23 April 10
Nice example.
Managed to fix another bug thanks your code ;)

But your code is bad!
Compile, run it and move sprite up! (Reset)
possibly. I found a bug where pre-shifted sprites overrun the buffer.
Yeah it resets near the top.. so... ?
I'll fix it later ;)

EDIT: New version of code has been uploaded that fixes the bug that Markus reported.
Title: Re: ASM source code
Post by: redbox on 09:13, 27 April 10
Quote from: ynot.zer0 on 11:00, 24 April 10
the disappearing sprite  :P

Proof. Of. Concept.
Title: Re: ASM source code
Post by: Ynot.zer0 on 11:03, 27 April 10
..and very nice PoCs these samples are too.  I'm learning quite a lot from them at the moment.

With the latest code update
buffer_size equ sprite_height*(sprite_width+1)
;; a buffer to store screen behind sprite

sprite_background:
defs buffer_size               <<<<<<<<<<<<<<<<Assemble error here

I found that for some reason it would not compile if referencing sprite_height; but if you replace it with the numeric value it works:

defs 64*sprite_width+1

I'm curious; can anyone explain why?
Title: Re: ASM source code
Post by: Devilmarkus on 11:19, 27 April 10
Quote from: ynot.zer0 on 11:03, 27 April 10
buffer_size equ sprite_height*(sprite_width+1)
;; a buffer to store screen behind sprite

sprite_background:
defs buffer_size               <<<<<<<<<<<<<<<<Assemble error here

Which assembler did you use? (JavaCPC's assembler parses the mathematics correct here. (In progress...))
Title: Re: ASM source code
Post by: Ynot.zer0 on 11:31, 27 April 10
winape 2.0 alpha 17
Title: Re: ASM source code
Post by: arnoldemu on 11:36, 27 April 10
Quote from: ynot.zer0 on 11:03, 27 April 10
..and very nice PoCs these samples are too.  I'm learning quite a lot from them at the moment.

With the latest code update
buffer_size equ sprite_height*(sprite_width+1)
;; a buffer to store screen behind sprite

sprite_background:
defs buffer_size               <<<<<<<<<<<<<<<<Assemble error here

I found that for some reason it would not compile if referencing sprite_height; but if you replace it with the numeric value it works:

defs 64*sprite_width+1

I'm curious; can anyone explain why?
Sorry I didn't check my update with winape.
I did check most of the others.
for winape you probably need to do this:

preshifted_width equ sprite_width+1
buffer_size equ sprite_height*preshifted_width

defs buffer_size


I normally use pasmo for my code because like javacpc it has an assembler that evaluates the mathematical expressions and allows you to bracket them.

If I have time, I'll correct it for winape.
Title: Re: ASM source code
Post by: Devilmarkus on 11:42, 27 April 10
You can try the mathparser I am using in JavaCPC's assembler here:
http://cpc-live.com/calc/ (http://cpc-live.com/calc/)

Simply enter what you want to calculate in the upper text window.
e.g. 20*(40+1)
It also accepts binary input like %10110111*15
Title: Re: ASM source code
Post by: Executioner on 04:07, 28 April 10
Quote from: arnoldemu on 11:36, 27 April 10
I normally use pasmo for my code because like javacpc it has an assembler that evaluates the mathematical expressions and allows you to bracket them.

This was never done in WinAPE simply because it wouldn't be Maxam compatible any longer, and would break lots of existing assembler code. I might include it as an option in the next release though.
Title: Re: ASM source code
Post by: Devilmarkus on 09:32, 28 April 10
I have an option in my assembler.
You can select left-to-right calculation (default, like maxam) or exact math parsing (allows brackets etc...)
Title: Re: ASM source code
Post by: arnoldemu on 21:52, 28 April 10
Updated source:

http://www.cpctech.org.uk/source/shftspr.asm

Now builds with Winape assembler.

New source:

http://www.cpctech.org.uk/source/tilemap.asm

Shows:
1. How to use KM_TEST_KEY to read keyboard (uses key numbers)
2. How to draw a tilemap to the screen (20 tiles wide and 12 tall). The tilemap is for a static screen (no scroll).
3. How to join tilemaps together to make a larger map (you can press up/down/left/right cursors to move to other screens).

Quick tile gfx by Markus. Thanks :)
Title: Re: ASM source code
Post by: Ynot.zer0 on 13:18, 29 April 10
Quote from: arnoldemu on 21:52, 28 April 10
New source:

http://www.cpctech.org.uk/source/tilemap.asm (http://www.cpctech.org.uk/source/tilemap.asm)

Shows:
1. How to use KM_TEST_KEY to read keyboard (uses key numbers)
2. How to draw a tilemap to the screen (20 tiles wide and 12 tall). The tilemap is for a static screen (no scroll).
3. How to join tilemaps together to make a larger map (you can press up/down/left/right cursors to move to other screens).

Quick tile gfx by Markus. Thanks :)


That sample is absolutely SUPERB! It is just what I was after knowing.  Thank you so much for posting these samples they are a tremendous help to us newbie coders  8)   keep 'em coming!

Title: Re: ASM source code
Post by: arnoldemu on 11:36, 30 April 10
Quote from: ynot.zer0 on 13:18, 29 April 10

That sample is absolutely SUPERB! It is just what I was after knowing.  Thank you so much for posting these samples they are a tremendous help to us newbie coders  8)   keep 'em coming!
np. I have a few more ideas (hardware scrolling a tilemap, software scrolling a tilemap, reducing/stopping flicker in sprites, double buffering) and then I will ask for suggestions.
Title: Re: ASM source code
Post by: redbox on 11:53, 30 April 10
Quote from: arnoldemu on 11:36, 30 April 10
hardware scrolling a tilemap, software scrolling a tilemap, reducing/stopping flicker in sprites, double buffering

YES!

I have been slaving over a tilemap routine and it's been great to see how you've done it.

Would definitely like some pointers on quick double buffering (scrolling has been taken care of by the ASIC for me  ;) ).
Title: Re: ASM source code
Post by: Devilmarkus on 21:58, 23 June 10
I also wrote a small assembler routine today.
I use it to load several screens into ram banks.
This routine provides 2 RSX commands for BASIC:
|BANK,bank 
|COPY 

You can load a screen to bank &C4 and copy it to screen: 
10 MEMORY &3FFF 
20 |BANK,&C4:LOAD"MYSCREEN.BIN",&4000
30 |COPY
 
Here's the source:
        nolist
        org #8000

        LD      HL,BufferRsx
        LD      BC,PtrRsx
        JP      #BCD1

PtrRsx:
        DW      RSX_TABLE
        JP      Bank
        JP      Copy

RSX_TABLE:
        DB      "BAN","K"+#80
        DB      "COP","Y"+#80

Bank:
        LD      A,(IX+0)
        LD      B,#7F
        OUT     (C),A
        RET 

Copy:
        LD      HL,#4000
        LD      BC,#4000
        LD      DE,#c000
        LDIR
        RET
       
BufferRsx:
        DS      4
Title: Re: ASM source code
Post by: arnoldemu on 09:42, 24 June 10
Quote from: Devilmarkus on 21:58, 23 June 10
I also wrote a small assembler routine today.
I use it to load several screens into ram banks.
This routine provides 2 RSX commands for BASIC:
|BANK,bank 
|COPY 

You can load a screen to bank &C4 and copy it to screen: 
10 MEMORY &3FFF 
20 |BANK,&C4:LOAD"MYSCREEN.BIN",&4000
30 |COPY
 
Here's the source:
        nolist
        org #8000

        LD      HL,BufferRsx
        LD      BC,PtrRsx
        JP      #BCD1

PtrRsx:
        DW      RSX_TABLE
        JP      Bank
        JP      Copy

RSX_TABLE:
        DB      "BAN","K"+#80
        DB      "COP","Y"+#80

Bank:
        LD      A,(IX+0)
        LD      B,#7F
        OUT     (C),A
        RET 

Copy:
        LD      HL,#4000
        LD      BC,#4000
        LD      DE,#c000
        LDIR
        RET
       
BufferRsx:
        DS      4

A nice example of RSX commands.

Title: Re: ASM source code
Post by: Devilmarkus on 20:31, 27 June 10
The same code but modified with double buffering the screens:
        nolist
        org #8000

        LD      HL,BufferRsx
        LD      BC,PtrRsx
        JP      #BCD1

PtrRsx:
        DW      RSX_TABLE
        JP      Bank
        JP      Copy

RSX_TABLE:
        DB      "BAN","K"+#80
        DB      "COP","Y"+#80

Bank:
        LD      A,(IX+0)
        LD      B,#7F
        OUT     (C),A
        RET 

Copy:
       LD    BC,#BC0C
       OUT    (C),C

       LD    BC,#BD10
       OUT    (C),C        ; switch display to #4000 bank #C0

       LD     HL,#4000
       LD    DE,#C000
       LD    BC,#4000
       LDIR
       LD    BC,#BD30
       OUT    (C),C        ; switch display to #C000
       LD    BC,#7FC0
       OUT    (C),C        ; switch to bank #C0
       LD    HL,#C000
       LD    DE,#4000
       LD    BC,#4000
       LDIR
       RET
       
BufferRsx:
        DS      4
Title: Re: ASM source code
Post by: arnoldemu on 21:27, 16 July 10
New source:

http://www.cpctech.org.uk/source/newflip.asm

This code uses the firmware to show:
1. How to sync with the firmware colour. So if you do ink 1,2,3 you can know for definite when this ink is colour 2 and when it is colour 3 and to ensure it always happens when you want it to.
2. How to set the colours using MC_SET_INK
3. How to define the screen base using SCR_SET_BASE and how to toggle screen between starting at &4000 and &c000.
4. How to change the mode using MC_SET_MODE so that the mode is changed without CLS.

This example is good if you want to make video modes which give the illusion of higher resolution or more colours by "flicking"/swapping the screens, colours and modes.
Title: Re: ASM source code
Post by: arnoldemu on 21:27, 20 July 10
New source:

http://www.cpctech.org.uk/source/sldldr.asm

This code shows:
1. How to get the current drive number
2. How to initialise the disc rom after loading this file (BASIC will disable all roms, effectively going to
cassette mode)
3. How to set the current drive back again
4. Using a list of files, and loading each file one-by-one. When we get to the end of the list
going back to the first file again. Good for slideshows ;)

Title: Re: ASM source code
Post by: arnoldemu on 21:30, 20 July 10
Updated source:

http://www.cpctech.org.uk/source/overscan.asm

Updated overscan code so that it supports crtc type 2 (changed register 3 value).
Title: Re: ASM source code
Post by: Executioner on 01:05, 22 July 10
Quote from: arnoldemu on 21:30, 20 July 10
Updated overscan code so that it supports crtc type 2 (changed register 3 value).

Your link is wrong: try http://www.cpctech.org.uk/source/overscn.asm (http://www.cpctech.org.uk/source/overscn.asm)
Title: Re: ASM source code
Post by: arnoldemu on 09:46, 22 July 10
Quote from: Executioner on 01:05, 22 July 10
Your link is wrong: try http://www.cpctech.org.uk/source/overscn.asm (http://www.cpctech.org.uk/source/overscn.asm)
thanks :)
Title: Re: ASM source code
Post by: Axelay on 16:04, 23 July 10
Thought I'd have a go at some commented source of a variation of the sprite code from the 64k version of Star Sabre.  This example only uses one screen, runs with firmware and interrupts, and isn't well optimised.  The source has been tested under Winape.

This demonstrates using a look up table to generate an address list for all the sprites, then using that list when printing, then clearing the sprites.  The idea being that the more things the list is used for, the more useful it becomes to generate the addresses just the once as a separate process (for example, you might need to save & restore the background, or check for background collisions).  It also shows how the look up table can be used for easy 'sprite clipping' on the top and bottom edges of the screen.
Title: Re: ASM source code
Post by: Devilmarkus on 16:22, 23 July 10
Thanks for sharing.
To let JavaCPC compile this piece of code, I have a question:

.ScoreText
    text "Score:10000 Lives:3",0


when I replace it to:

.ScoreText
    db "Score:10000 Lives:3",0

it compiles.
So what's the difference between 'text' and 'db'?
Title: Re: ASM source code
Post by: Axelay on 03:01, 24 July 10
Quote from: Devilmarkus on 16:22, 23 July 10
So what's the difference between 'text' and 'db'?

Nothing at all, I guess 'text' must be specific to Maxam.
Title: Re: ASM source code
Post by: fano on 14:03, 24 July 10
http://www.grimware.org/doku.php/documentations/software/winape/start#defb.db.defm.byte.and.text (http://www.grimware.org/doku.php/documentations/software/winape/start#defb.db.defm.byte.and.text)
Title: Re: ASM source code
Post by: arnoldemu on 21:56, 17 September 10

http://www.cpctech.org.uk/source/sampplay.asm

New source:

- Shows how to play samples using digiblaster, amdrum and AY sound chip.
- All source sample data should be raw (e.g. no headers), 8-bit signed samples.
You can use Markus' tools to make this.
- shows how to create an RSX

Markus has been using similar code in his new productions.
Title: Re: ASM source code
Post by: Devilmarkus on 09:08, 18 September 10
Quote from: arnoldemu on 21:56, 17 September 10
Markus has been using similar code in his new productions.

Here's my tool I used to transform 8 bit mono WAV-files to RAW.

(http://cpc-live.com/rawtransformet.png)
How to use?
- Simple: Just keep the default settings. No changes needed here.
- Click "Transform" and select your WAV file.
- That's all.
- You will find up to 33 RAW files in your folder. (If WAV is larger, the rest is truncated)
- "Transform Folder" is not useful yet. It's just experimental.
- "Header" adds an AMSDOS header to each RAW file.
- "As ASM" also generates ASM source code for each RAW part.
- "Store sample" also saves the complete RAW file as 1 sample file (up to 524k). (My experimental JavaCPC can import this by drag & drop)
Title: Re: ASM source code
Post by: arnoldemu on 21:47, 20 September 10
http://www.cpctech.org.uk/source/mltmde2.asm (http://www.cpctech.org.uk/source/mltmde2.asm)

New/Updated source
- This example shows multiple modes using the firmware. It is based on the code here:
http://www.cpctech.org.uk/source/multmode.asm (http://www.cpctech.org.uk/source/multmode.asm)

- However, sometimes one of the mode changes will not occur exactly at the time we expect, but is delayed by 8 lines.
This delay is caused by the keyboard scan.

The firmware doesn't scan the firmware always at the same time in a frame. It does scan the keyboard every 6 interrupts so that it is once per frame.

This example shows how to sync with the vsync (using firmware), and then use KL SCAN NEEDED to reset the keyboard scan so that it occurs when we want it to. Now our mode splits are accurate.

EDIT: Only works on 664/6128 because it uses firmware v1.1 functions.
Source updated with comment.
Title: Re: ASM source code
Post by: arnoldemu on 21:20, 12 October 10
New source:

http://www.cpctech.org.uk/source/modesplt.asm

This shows how to do the most accurate mode-split with the firmware.

It uses an asynchronous express fast ticker event.

With this one, I can't even use MC SET MODE because the alternative register set is not setup for it, and also because it disables and then re-enables interrupts. So this time I had to look at the OS and work out where the information is stored.

Normally C' holds the byte we are interested in, but at this point A' actually stores it.
Also I must ensure the rom is paged in, but I mustn't remember this in A'.

Asynchronous express interrupts are the 2nd interrupt type to be processed. First is frame ticker (if vsync is active), otherwise these are the first interrupt type to be executed at other times. This function is about 8 or so scanlines ahead of the previous one and doesn't get altered by the keyboard scanning AND it works on 464, 664 and 6128.

But to make it work I have to hit the hardware direct and make sure I setup the alternative register set correct, otherwise the firmware will crash.

Enjoy my journey into the OS rom and the results ;)

Title: Re: ASM source code
Post by: arnoldemu on 13:08, 20 November 10
New source:

http://www.cpctech.org.uk/source/sixpixfirm.asm

This shows how to draw a 6x8 pixel font in mode 1 using the firmware.
It can be slow, but it works.
Title: Re: ASM source code
Post by: arnoldemu on 13:11, 20 November 10
Quote from: arnoldemu on 13:08, 20 November 10
New source:

http://www.cpctech.org.uk/source/sixpixfirm.asm (http://www.cpctech.org.uk/source/sixpixfirm.asm)

This shows how to draw a 6x8 pixel font in mode 1 using the firmware.
It can be slow, but it works.
And now the version without the firmware:

http://www.cpctech.org.uk/source/sixpix.asm

This does some manipulation of the screen pixels to draw and mask the chars.
This example also shows how you can write text to the screen *without* the firmware and using your own pixel data.
Title: Re: ASM source code
Post by: AMSDOS on 22:03, 20 November 10
arnoldemu wrote:

And now the version without the firmware:

http://www.cpctech.org.uk/source/sixpix.asm (http://www.cpctech.org.uk/source/sixpix.asm)

This does some manipulation of the screen pixels to draw and mask the chars.
This example also shows how you can write text to the screen *without* the firmware and using your own pixel data.


Just wondering if this version of the program is supposed to return the user back to BASIC?

EDIT: Oh I see you're looping "l1" onto itself!  ;)  Change it to ret and your back in BASIC!  :)  Only the non-firmware version and firmware versions vary quite significantly cause the Firmware version alters the text so it still active once the program exits!  I couldn't see a lot of difference speed wise between both of these program, though I presume it would become more apparent the more you throw more 'text' at these routines!
Title: Re: ASM source code
Post by: arnoldemu on 10:47, 22 November 10
Quote from: CP/M User on 22:03, 20 November 10
arnoldemu wrote:

And now the version without the firmware:

http://www.cpctech.org.uk/source/sixpix.asm (http://www.cpctech.org.uk/source/sixpix.asm)

This does some manipulation of the screen pixels to draw and mask the chars.
This example also shows how you can write text to the screen *without* the firmware and using your own pixel data.


Just wondering if this version of the program is supposed to return the user back to BASIC?

EDIT: Oh I see you're looping "l1" onto itself!  ;)  Change it to ret and your back in BASIC!  :)  Only the non-firmware version and firmware versions vary quite significantly cause the Firmware version alters the text so it still active once the program exits!  I couldn't see a lot of difference speed wise between both of these program, though I presume it would become more apparent the more you throw more 'text' at these routines!
Both pieces of code were actually made for another game which I am helping with.
Some other people are making it, but I offered some help. Not sure when this game will be released.
Title: Re: ASM source code
Post by: redbox on 10:50, 22 November 10
Quote from: arnoldemu on 10:47, 22 November 10
Both pieces of code were actually made for another game which I am helping with.
Some other people are making it, but I offered some help. Not sure when this game will be released.

A Spectrum conversion?

The font looks very Speccy and also you're converting 1-bit per pixel graphics  ;)
Title: Re: ASM source code
Post by: AMSDOS on 11:15, 22 November 10
arnoldemu wrote:

Both pieces of code were actually made for another game which I am helping with.
Some other people are making it, but I offered some help. Not sure when this game will be released.


Always good to have a different font when it comes to games!  ;D

This article on Screen Squashing (which is older than my 6128  ;) ) always comes to mind when I think of articles on Character Sets:

http://cpcwiki.eu/imgs/7/78/Amstrad_Computer_User8504_020.jpg (http://cpcwiki.eu/imgs/7/78/Amstrad_Computer_User8504_020.jpg)
http://cpcwiki.eu/imgs/3/3b/Amstrad_Computer_User8504_021.jpg (http://cpcwiki.eu/imgs/3/3b/Amstrad_Computer_User8504_021.jpg)
http://cpcwiki.eu/imgs/4/4b/Amstrad_Computer_User8504_022.jpg (http://cpcwiki.eu/imgs/4/4b/Amstrad_Computer_User8504_022.jpg)
http://cpcwiki.eu/imgs/5/5e/Amstrad_Computer_User8504_025.jpg (http://cpcwiki.eu/imgs/5/5e/Amstrad_Computer_User8504_025.jpg)
Title: Re: ASM source code
Post by: arnoldemu on 16:28, 05 December 10
Quote from: arnoldemu on 13:11, 20 November 10
And now the version without the firmware:

http://www.cpctech.org.uk/source/sixpix.asm (http://www.cpctech.org.uk/source/sixpix.asm)

This does some manipulation of the screen pixels to draw and mask the chars.
This example also shows how you can write text to the screen *without* the firmware and using your own pixel data.

The Y char position was not calculated correctly in this code. This has now been fixed.
Title: Re: ASM source code
Post by: arnoldemu on 16:31, 05 December 10
Updated source:

http://www.cpctech.org.uk/source/6pixpatch.asm (http://www.cpctech.org.uk/source/6pixpatch.asm)


I mostly fixed cursor position.
But still some bugs here.
Title: Re: ASM source code
Post by: Devilmarkus on 16:54, 05 December 10
Why not 2 RSX commands?
|LOCATE,<1-53>,<1-lines>
|PRINT,"HELLO WORLD"

+ these:
|PEN,x
|PAPER,y
Title: Re: ASM source code
Post by: AMSDOS on 08:52, 06 December 10
This is perhaps a bit beyond me, though I was playing around with txt_write_char and noticed you were only using "A" with the character byte, cause with that routine H contains the physical column number and L holds the physical line number. When I was trying it out as a standard writing routine with 65 in A it doesn't seem to obey writing outside the zone 0-39 and 0-24 seems to be it's range.

I didn't think it was possible to go beyond the bounds using text based Co-ordinates, hence the article from the early Amstrad CPC464 User (which became ACU) I posted was treating the text as graphically based characters. Interesting I "TAG"ged while your program was running and it wrote using the standard character set across the screen.

But there's a lot of stuff going on in that program that I don't know!  ??? 

I remember having this whole fastwriting routine for the IBM which allowed me to write wherever onscreen using Text based co-ordinates. I don't recall there being anything standard about it, though it came in very useful because I was converting some 80x50 Text Mode games in TP for CP/M-86. In CP/M-86 while you could tell it to go into 80x50 Mode, CP/M-86 simply didn't know anything about 80x50 text mode and needed a separate routine which would allow it to happen. I'm guessing this is the sort of thing your trying out here.
Title: Re: ASM source code
Post by: arnoldemu on 11:04, 06 December 10
Quote from: CP/M User on 08:52, 06 December 10
This is perhaps a bit beyond me, though I was playing around with txt_write_char and noticed you were only using "A" with the character byte, cause with that routine H contains the physical column number and L holds the physical line number. When I was trying it out as a standard writing routine with 65 in A it doesn't seem to obey writing outside the zone 0-39 and 0-24 seems to be it's range.

I didn't think it was possible to go beyond the bounds using text based Co-ordinates, hence the article from the early Amstrad CPC464 User (which became ACU) I posted was treating the text as graphically based characters. Interesting I "TAG"ged while your program was running and it wrote using the standard character set across the screen.

But there's a lot of stuff going on in that program that I don't know!  ??? 

I remember having this whole fastwriting routine for the IBM which allowed me to write wherever onscreen using Text based co-ordinates. I don't recall there being anything standard about it, though it came in very useful because I was converting some 80x50 Text Mode games in TP for CP/M-86. In CP/M-86 while you could tell it to go into 80x50 Mode, CP/M-86 simply didn't know anything about 80x50 text mode and needed a separate routine which would allow it to happen. I'm guessing this is the sort of thing your trying out here.
I think tag makes it use the graphics drawing functions?

I was thinking about the char ranges and thought that perhaps I needed to redefine the window size, or perhaps also "WIDTH" or similar. Then it may work.

Well, the aim of this initially was to draw a 6 pixel wide font. Then I wanted to extend it so it could be used from BASIC without using any | commands. So you could use normal BASIC commands to use it.

Also, the size of the screen could be changed and this new charset used if you wanted.
I was interested in how much work I would need to do with patching the firmware jumpblock for it to work.
Title: Re: ASM source code
Post by: AMSDOS on 11:31, 06 December 10
arnoldemu wrote:

I think tag makes it use the graphics drawing functions?

Yep, TAG allows the user to enter standard Text Character from a Graphic co-ordinates position.

I was thinking about the char ranges and thought that perhaps I needed to redefine the window size, or perhaps also "WIDTH" or similar. Then it may work.

I try some experimenting with WINDOW 1,53,1,25, perhaps the firmware equivalent may do something, though I dare say it's all based on that one WINDOW routine. WIDTH might do something though it appears to be. I had a look though the firmware guide which had some stuff re;ating to the cursor though didn't see anything relating to the size of the cursor, merely the ability of turning it on and switching it off and something relating to drawing and undrawing the cursor!  :-[   There seems to be a few routines relating to the position of the cursor, though it may have to restrict itself to those standard position guidelines.

Anyhow I'm suprised to see how far it's developed into what you've created!  :)


Title: Re: ASM source code
Post by: AMSDOS on 04:14, 19 December 10
I hope no-one minds me posting this old dinosaur of a routine in here!  ???

org &4000

    .setup 
     LD A,1   ;; My crude routine for setting up Scr_Mode
     CALL &BC0E
     LD A,240  ;; Setup Symbol Table - A Holds Character value
     LD HL,ship1  ;; HL points to Symbol Data to Define to
     CALL &BBA8  ;; Firmware routine to Redefine Symbol Table.
     LD A,241
     LD HL,ship2
     CALL &BBA8
     LD A,242
     LD HL,ship3
     CALL &BBA8
     LD A,243
     LD HL,ship4
     CALL &BBA8
    .init
     ld hl,&140C  ;; Initial Position
     LD A,0   ;; Initial Direction
    .loop
     PUSH HL   ;; Start of Main Loop
     PUSH AF
     CALL &BB75  ;; TXT SET CURSOR
     POP AF
     PUSH AF
     ADD A,240  ;; graphic code
     CALL &BB5D  ;; Print
     LD BC,&0C00  ;; Start Short Delay
    .shtdel
     DEC BC   
     LD A,B
     OR C
     JR NZ,shtdel  ;; loop back if Non Zero
     POP AF
     POP HL   ;; only HL actually wanted
     PUSH HL
     PUSH AF   ;; the next call corrupts AF & HL
     CALL &BB75  ;; TXT SET CURSOR
     LD A,32   ;; code for space
     CALL &BB5D  ;; Print
     LD A,0   ;; code for up arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,proa  ;; Jump if Key Up
     POP AF   ;; reclaim direction code
     POP HL   ;; ..and position
     CP 0   ;; Compare A with 0 - up?
     JR NZ,right  ;; Jump to check Right if Not
     DEC L   ;; Up a row
     JR newpos  ;; Jump to the next position
    .right
     CP 1   ;; Compare with 1 - right?
     JR NZ,down
     INC H   ;; Right one column
     JR newpos
    .down
     CP 2   ;; Down?
     JR NZ,left
     INC L   ;; Down a row
     JR newpos
    .left
     DEC H   ;; Left - no check needed here
    .newpos
     PUSH HL   ;; Save new position
     PUSH AF   ;; Protect A from the TEST KEY call
    .proa
     LD A,1   ;; key code for right arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,lftar  ;; Zero if not pressed
     POP AF   ;; old direction
     ADD A,1   ;; clockwise move
     CP 4   ;; check A value in range
     JR NZ,newdir2  ;; Jump if not 4
     LD A,0   ;; reset A to 0
    .newdir2
     PUSH AF   ;; new direction
     LD BC,&2000  ;; delay to separate keystrokes
    .dloop2
     DEC BC
     LD A,B
     OR C
     JR NZ,dloop2
    .lftar
     LD A,8   ;; key code for left arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,cesc  ;; jump if not pressed
     POP AF   ;; old direction
     SUB 1   ;; Subtract: A=A-1
     JR NC,newdir  ;; Jump if Carry bit not set **
     LD A,3   ;; Reset A to 3 if below 0
    .newdir
     PUSH AF   ;; New Direction
     LD BC,&2000  ;; delay loop
    .dloop
     DEC BC   
     LD A,B
     OR C
     JR NZ,dloop
    .cesc
     LD A,66   ;; key code for ESC
     CALL &BB1E  ;; KM TEST KEY
     JR Z,check
     POP AF   ;; clear stack before return
     POP HL
     RET   ;; Return to Basic
    .check
     POP AF
     POP HL   ;; only HL really wanted
     PUSH AF   ;; save direction code
     LD A,L   ;; routine to check L value
     CP 0   ;; off top of screen?
     JR NZ,botscr
     LD L,25   ;; wrap-round, top to bottom
     JR checkh  ;; Jump to H check
    .botscr
     CP 26   ;; bottom of screen?
     JR NZ,checkh
     LD L,1   ;; move to top
    .checkh
     LD A,H   ;; check H value
     CP 0   ;; off left?
     JR NZ,offright
     LD H,40   ;; move to right edge
     JR tidy   ;; jump to end
    .offright
     CP 41   ;; off right
     JR NZ,tidy
     LD H,1   ;; move to left edge
    .tidy
     POP AF   ;; tidy up the stack
     JP loop   ;; jump to start of main loop ***
    .ship1
     defb 16,56,56,56,124,124,198,130
    .ship2
     defb 192,112,62,31,62,112,192,0
    .ship3
     defb 130,198,124,124,56,56,56,16
    .ship4
     defb 0,3,14,124,248,124,14,3 ;; data for defining the ships.


This is one of those Left/Right, point the ship in this direction kind of routine and use the foward arrow to move it in the direction it's facing. The original program (which is mainly this) comes from Amstrad CPC464 User (before it became ACU) and the program appeared to only be CPC464 friendly. A good deal of modify it just to get it to compile in Maxam was required since the original routine was using direct addresses & bytes in the Jump & Jump Relative routine and no labels!  ???  So I've tried to label the program as best as I could, result the program works. The original code never included the matrix data either, where in it was included within the BASIC Loader program, but now it should act as the BASIC program does. But I reckon there could be considerable enhancements which could be done to it if anyone is looking for a routine like this.
Title: Re: ASM source code
Post by: Gryzor on 09:55, 24 December 10
Dear AA,

I typed the program that you printed in your last issue, again and again, but my Amstrad gives me an error on every line. Even if I add line numbers, when I try to run it I get errors again and I don't know how to correct them.

I noticed that you didn't print the checksums so I can check if I have typed it in correctly, but I am pretty sure I did. Also, you didn't print those dots that represent spaces, those are really useful...

Is my 464 broken?

Thank you,
Th.P.

Quote from: CP/M User on 04:14, 19 December 10
I hope no-one minds me posting this old dinosaur of a routine in here!  ???

org &4000

    .setup 
     LD A,1   ;; My crude routine for setting up Scr_Mode
     CALL &BC0E
     LD A,240  ;; Setup Symbol Table - A Holds Character value
     LD HL,ship1  ;; HL points to Symbol Data to Define to
     CALL &BBA8  ;; Firmware routine to Redefine Symbol Table.
     LD A,241
     LD HL,ship2
     CALL &BBA8
     LD A,242
     LD HL,ship3
     CALL &BBA8
     LD A,243
     LD HL,ship4
     CALL &BBA8
    .init
     ld hl,&140C  ;; Initial Position
     LD A,0   ;; Initial Direction
    .loop
     PUSH HL   ;; Start of Main Loop
     PUSH AF
     CALL &BB75  ;; TXT SET CURSOR
     POP AF
     PUSH AF
     ADD A,240  ;; graphic code
     CALL &BB5D  ;; Print
     LD BC,&0C00  ;; Start Short Delay
    .shtdel
     DEC BC   
     LD A,B
     OR C
     JR NZ,shtdel  ;; loop back if Non Zero
     POP AF
     POP HL   ;; only HL actually wanted
     PUSH HL
     PUSH AF   ;; the next call corrupts AF & HL
     CALL &BB75  ;; TXT SET CURSOR
     LD A,32   ;; code for space
     CALL &BB5D  ;; Print
     LD A,0   ;; code for up arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,proa  ;; Jump if Key Up
     POP AF   ;; reclaim direction code
     POP HL   ;; ..and position
     CP 0   ;; Compare A with 0 - up?
     JR NZ,right  ;; Jump to check Right if Not
     DEC L   ;; Up a row
     JR newpos  ;; Jump to the next position
    .right
     CP 1   ;; Compare with 1 - right?
     JR NZ,down
     INC H   ;; Right one column
     JR newpos
    .down
     CP 2   ;; Down?
     JR NZ,left
     INC L   ;; Down a row
     JR newpos
    .left
     DEC H   ;; Left - no check needed here
    .newpos
     PUSH HL   ;; Save new position
     PUSH AF   ;; Protect A from the TEST KEY call
    .proa
     LD A,1   ;; key code for right arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,lftar  ;; Zero if not pressed
     POP AF   ;; old direction
     ADD A,1   ;; clockwise move
     CP 4   ;; check A value in range
     JR NZ,newdir2  ;; Jump if not 4
     LD A,0   ;; reset A to 0
    .newdir2
     PUSH AF   ;; new direction
     LD BC,&2000  ;; delay to separate keystrokes
    .dloop2
     DEC BC
     LD A,B
     OR C
     JR NZ,dloop2
    .lftar
     LD A,8   ;; key code for left arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,cesc  ;; jump if not pressed
     POP AF   ;; old direction
     SUB 1   ;; Subtract: A=A-1
     JR NC,newdir  ;; Jump if Carry bit not set **
     LD A,3   ;; Reset A to 3 if below 0
    .newdir
     PUSH AF   ;; New Direction
     LD BC,&2000  ;; delay loop
    .dloop
     DEC BC   
     LD A,B
     OR C
     JR NZ,dloop
    .cesc
     LD A,66   ;; key code for ESC
     CALL &BB1E  ;; KM TEST KEY
     JR Z,check
     POP AF   ;; clear stack before return
     POP HL
     RET   ;; Return to Basic
    .check
     POP AF
     POP HL   ;; only HL really wanted
     PUSH AF   ;; save direction code
     LD A,L   ;; routine to check L value
     CP 0   ;; off top of screen?
     JR NZ,botscr
     LD L,25   ;; wrap-round, top to bottom
     JR checkh  ;; Jump to H check
    .botscr
     CP 26   ;; bottom of screen?
     JR NZ,checkh
     LD L,1   ;; move to top
    .checkh
     LD A,H   ;; check H value
     CP 0   ;; off left?
     JR NZ,offright
     LD H,40   ;; move to right edge
     JR tidy   ;; jump to end
    .offright
     CP 41   ;; off right
     JR NZ,tidy
     LD H,1   ;; move to left edge
    .tidy
     POP AF   ;; tidy up the stack
     JP loop   ;; jump to start of main loop ***
    .ship1
     defb 16,56,56,56,124,124,198,130
    .ship2
     defb 192,112,62,31,62,112,192,0
    .ship3
     defb 130,198,124,124,56,56,56,16
    .ship4
     defb 0,3,14,124,248,124,14,3 ;; data for defining the ships.


This is one of those Left/Right, point the ship in this direction kind of routine and use the foward arrow to move it in the direction it's facing. The original program (which is mainly this) comes from Amstrad CPC464 User (before it became ACU) and the program appeared to only be CPC464 friendly. A good deal of modify it just to get it to compile in Maxam was required since the original routine was using direct addresses & bytes in the Jump & Jump Relative routine and no labels!  ???  So I've tried to label the program as best as I could, result the program works. The original code never included the matrix data either, where in it was included within the BASIC Loader program, but now it should act as the BASIC program does. But I reckon there could be considerable enhancements which could be done to it if anyone is looking for a routine like this.
Title: Re: ASM source code
Post by: redbox on 10:00, 24 December 10
Quote from: Gryzor on 09:55, 24 December 10
Dear AA,
Is my 464 broken?

Brilliant  :)
Title: Re: ASM source code
Post by: fano on 10:11, 24 December 10
Quote from: Gryzor on 09:55, 24 December 10
Dear AA,

I typed the program that you printed in your last issue, again and again, but my Amstrad gives me an error on every line. Even if I add line numbers, when I try to run it I get errors again and I don't know how to correct them.

I noticed that you didn't print the checksums so I can check if I have typed it in correctly, but I am pretty sure I did. Also, you didn't print those dots that represent spaces, those are really useful...

Is my 464 broken?

Thank you,
Th.P.

:laugh:
Title: Re: ASM source code
Post by: Devilmarkus on 10:26, 24 December 10
mega-rofl  8)
Title: Re: ASM source code
Post by: AMSDOS on 12:01, 24 December 10
G. Kev is gonna be real mad to see what you've done to his thread!  :-[
Title: Re: ASM source code
Post by: redbox on 18:33, 29 December 10
Quote from: arnoldemu on 11:36, 30 April 10
I have a few more ideas (hardware scrolling a tilemap, software scrolling a tilemap, reducing/stopping flicker in sprites, double buffering) and then I will ask for suggestions.

Do you have the source code for this?

I am wrestling with it at the moment and would love to see how you've done it.
Title: Re: ASM source code
Post by: arnoldemu on 12:01, 01 January 11
New source:

  http://www.cpctech.org.uk/source/intpos.asm
 
  In relation to games:
 
  The example shows the position of each interrupt on the CPC.
  For games, it is much easier to change the mode or colours at the   position of an interrupt because it doesn't waste CPU time waiting for   an exact position on the screen.
 
  By changing the vsync position, you can change the relative position of   the visible part of the screen and also where the interrupts come. But   then you end up with a picture shifted within the monitor display. You   can get away with one char or so either up/down from the normal   position.
 
  CALL &8000

Posted by a Happy Kev.

 
 
Title: Re: ASM source code
Post by: arnoldemu on 12:01, 01 January 11
Quote from: redbox on 18:33, 29 December 10
Do you have the source code for this?

I am wrestling with it at the moment and would love to see how you've done it.
Yes, but nothing cleaned up.

P.M. me your e-mail address and I'll send it.
Title: Re: ASM source code
Post by: arnoldemu on 12:44, 01 January 11
New source:

http://www.cpctech.org.uk/source/scrdim.asm

This example shows:
1. position and time between CPC interrupts
2. how you can modify hsync/vsync/vdisp/hdisp to position the screen how you want (it's interactive!)
3. Then depending on vdisp/hdisp, the approx amount of ram used (really it depends on Register 9 and it's hardcoded here, and also the way the CPC screen is arranged means the calculation in this example is not perfect).
 
  In relation to games:

This example gives an idea about how the amount of ram used changes depending on the width/height of the displayed screen.
NOTE that if hardware scrolling was used, the amount of ram used would always be 16K (or 32k if overscan) because of the way the hardware scrolling is done.

  CALL &8000 to run it.
Title: Re: ASM source code
Post by: Devilmarkus on 17:08, 01 January 11
Quote from: arnoldemu on 12:01, 01 January 11
New source:

  http://www.cpctech.org.uk/source/intpos.asm (http://www.cpctech.org.uk/source/intpos.asm)
 

Freezes after using cursor keys?
Seem to work on 6128 only?!?
Title: Re: ASM source code
Post by: Devilmarkus on 17:09, 01 January 11
Quote from: arnoldemu on 12:44, 01 January 11
New source:

http://www.cpctech.org.uk/source/scrdim.asm (http://www.cpctech.org.uk/source/scrdim.asm)

Freezes, too?!?
Title: Re: ASM source code
Post by: arnoldemu on 22:00, 01 January 11
Quote from: Devilmarkus on 17:08, 01 January 11
Freezes after using cursor keys?
Seem to work on 6128 only?!?
hmmm.. I only tested in on Winape.
it doesn't use 6128 specific code.
You have to be careful you don't move the screen outside of the normal range or the monitor can't cope.
Also not sure it works on CRTC type 2.
Title: Re: ASM source code
Post by: arnoldemu on 22:01, 01 January 11
Quote from: Devilmarkus on 17:09, 01 January 11
Freezes, too?!?
Not on winape.. I will build it for another emu later and see if it works ok.
I do need to stop it flickering and also I need to slow down the keys ;)
Title: Re: ASM source code
Post by: Devilmarkus on 15:19, 30 January 11
Quote from: arnoldemu on 21:56, 17 September 10
http://www.cpctech.org.uk/source/sampplay.asm (http://www.cpctech.org.uk/source/sampplay.asm)

New source:

- Shows how to play samples using digiblaster, amdrum and AY sound chip.
- All source sample data should be raw (e.g. no headers), 8-bit signed samples.
You can use Markus' tools to make this.
- shows how to create an RSX

Markus has been using similar code in his new productions.

I re-assembled the code today.
Is it possible that there's something wrong with |DRIVER,0 ? (AY driver)
I just hear crap here... ?!?
Title: Re: ASM source code
Post by: arnoldemu on 10:59, 26 February 11
New source:

http://www.cpctech.org.uk/source/os_spr.asm
 
This example shows how to draw a sprite to an overscan screen. The important part here is the "scr_next_line" code.
There may be a better shorter way to do this, but this one works.

The screen is the "32k" overscan type, suitable for crtc type 2.

Control the sprite with cursors. Sprite can disapear when moving because of monitor drawing deleted version of sprite before drawing freshly drawn sprite, but the functionality is working.

Another method is used here to avoid flicker when sprite is not moving: I store previous coordinates of sprite, if these are updated I then delete and draw the sprite, otherwise I do nothing.

NOTE: I have also adjusted the screen start base so that the "problem" screen address is on the left side, meaning the code for "scr next byte" is just an inc hl. If I used a different base, then a special "scr next byte" case would be needed to cope with &07ff->&4000 case.


Title: Re: ASM source code
Post by: Sykobee (Briggsy) on 00:57, 27 February 11
Thanks for that code, I'm learning by example and that's great.
Title: Re: ASM source code
Post by: TFM on 23:29, 28 February 11
Flickering can be omitted by choosing the right time to start undraw/draw sprite. If the sprite is in the upper half of the screen, then start after interrupt 3 (occurt right in middle hight of the screen). If the sprite is in the lower half of the screen then start at interrupt 0 (frame flyback). Unclear?
Title: Re: ASM source code
Post by: arnoldemu on 10:26, 01 March 11
Quote from: TFM/FS on 23:29, 28 February 11
Flickering can be omitted by choosing the right time to start undraw/draw sprite. If the sprite is in the upper half of the screen, then start after interrupt 3 (occurt right in middle hight of the screen). If the sprite is in the lower half of the screen then start at interrupt 0 (frame flyback). Unclear?
Yes it can be done this way.
I have read of other ways too.
So, when I have a bit more time I will experiment with various ways to avoid flicker.

But methods include:

1. Sorting sprite by Y coordinate and then drawing them from top to bottom.
2. Sorting sprite by Y coordinate and then drawing them from bottom to top.
3. As you draw each sprite, erase 1 scanline, draw 1 scanline and repeat until all sprite is drawn. (this reduces flicker to a few pixels or one line).
4. double buffering.

The flicker comes because the sprite is erased completely and then drawn after.
At the top of the screen, the "monitor" has drawn the erased sprite, so that it never draws the sprite in it's new location.

When you move the sprite down the screen, there has been enough time to erase the sprite and draw it before the monitor then draws it correctly.

So although you can sort the sprites in Y and draw them this way, or choose to draw them at a different interrupt, you will still have to think where on the screen you need to erase the sprite.

So it's not exactly as simple as you say ;)

I am also talking about a general method that works with many sprites and not just 1.
Title: Re: ASM source code
Post by: TFM on 19:49, 01 March 11
Well, it like the simple solution, usually it's the most efficient and therefore best. In my progs if works all fine. But we must separate two things here. a) to omit flickering b) to reduce flickering.
And I can only warn to use too complex strategies, they usually make it too slow. As Kolumbus alrady sayd: To be genious means to keep it simple. And like my old dad sayd: Everybody can make it complex. I always keep this things in mind.
Finally there will be one perfect strategy for every kind of resolution (x, y) and way of using split screens / overscan or just 16 K V-RAM.


Edit: I implicate that sprites are erased directly before they are redrawn, anything else makes no sense. To use erase/draw scanline cycles again cost too much time IHMO.
Title: Re: ASM source code
Post by: arnoldemu on 10:27, 02 March 11
Quote from: TFM/FS on 19:49, 01 March 11
Well, it like the simple solution, usually it's the most efficient and therefore best. In my progs if works all fine. But we must separate two things here. a) to omit flickering b) to reduce flickering.
And I can only warn to use too complex strategies, they usually make it too slow. As Kolumbus alrady sayd: To be genious means to keep it simple. And like my old dad sayd: Everybody can make it complex. I always keep this things in mind.
Finally there will be one perfect strategy for every kind of resolution (x, y) and way of using split screens / overscan or just 16 K V-RAM.


Edit: I implicate that sprites are erased directly before they are redrawn, anything else makes no sense. To use erase/draw scanline cycles again cost too much time IHMO.
I agree that complex methods can make it slow.

Well let me be a student and learn ;)
Title: Re: ASM source code
Post by: arnoldemu on 10:30, 02 March 11
New sources:

http://www.cpctech.org.uk/source/plot1.asm (http://www.cpctech.org.uk/source/plot1.asm)
http://www.cpctech.org.uk/source/plot2.asm (http://www.cpctech.org.uk/source/plot2.asm)
  http://www.cpctech.org.uk/source/plot3.asm (http://www.cpctech.org.uk/source/plot3.asm)
  http://www.cpctech.org.uk/source/plot4.asm (http://www.cpctech.org.uk/source/plot4.asm)
 
These examples show how to plot a pixel.
Each gets more and more low level, so you can see how the firmware functions work and also how to access pixels on the screen.

plot1.asm uses graphics functions to plot a pixel and works in any mode and with upper rom enabled/disabled. (GRA PLOT ABSOLUTE)

plot2.asm uses screen functions to plot a pixel and also works in any mode with upper rom enabled/disabled. (SCR DOT POSITION, SCR PIXELS, SCR INK ENCODE)

plot3.asm uses less screen functions to plot a pixel, works in any mode, but not with upper rom enabled. (SCR DOT POSITION, SCR INK ENCODE)

plot4.asm uses less screen functions, is now for mode 0, and doesn't work with upper rom enabled.
(SCR DOT POSITION)


EDIT1: These examples are not complete. Complete examples will be uploaded later today.
EDIT2: Samples complete and uploaded.
EDIT3:

http://www.cpctech.org.uk/source/plot4m1.asm

plot4.asm example for mode 1.


  http://www.cpctech.org.uk/source/plot4m2.asm
 
  plot4.asm example for mode 2.
Title: Re: ASM source code
Post by: AMSDOS on 11:08, 03 March 11
Interesting the number of ways you can Plot onscreen!  :-[

:-[  Of course I've been doing some work with GRA PLOT ABSOLUTE and forgot about having this one huge routine.  ???

;; Tag Plot in Assembly

  ORG &4000

  ld a,1
  call &bc0e
  ld b,64              ;; Number of times to loop
  ld de,data_xpos      ;; Load Coordinate Position into DE
  ld hl,data_ypos      ;; Load Coordinate Position into HL
  ld (adrxpos),de
  ld (adrypos),hl      ;; Store address of data
  push hl
  ld hl,data_color
  ld (addrcolor),hl
  pop hl

.loop         ;; Begin of Loop
   push hl
   push af
   ld hl,(addrcolor)
   ld a,(hl)
   call do_color
   pop af
   pop hl
   
   ld de,(adrxpos)     ;; Get contents of address of Data
                       ;; into DE
   inc de
   inc de              ;; Increase this by 2 data is 2 bytes in size
   ld (adrxpos),de     ;; Put this new address into address of data
   ld hl,(adrypos)     ;; Put address of ypos into hl
   inc hl
   inc hl              ;; Increase this by 2 same as DE
   ld (adrypos),hl     ;; Put this new address into address of data
   push bc             
   call do_plot        ;; Call this routine
   pop bc
 
   djnz loop           ;; Go back if B is greater than 0
   ret                  ;; Otherwise Exit

.do_color
  call &bbde
  ld hl,(addrcolor)
  inc hl
  ld (addrcolor),hl
  ret

.do_plot

  ld b,(hl)            ;; Store Contents of Lower HL (YPOS Data) into B
  inc hl               ;; Increase address of HL
  ld c,(hl)            ;; Store Contents of Upper HL (YPOS Data) into C
  ld hl,ypos           ;; Get Lower address of HL
  ld (hl),b            ;; And put value of B into it
  inc hl               ;; Increase this by 1
  ld (hl),c            ;; Now put value of C into it

  ;; What this has effecively done is move the contents
  ;; of ypos in particular, from one memory location to
  ;; another fixed location, for where the data can go
  ;; into the registers & then do a call to Plot Absolute
  ;; (&BBEA). I used to try doing this while moving the
  ;; address (e.g. Get contents of first xpos & ypos,
  ;; then move onto the second), course it maybe possible,
  ;; but I found this much easier.

  ex de,hl        ;; Exchange Contents of DE & HL
  ld b,(hl)            ;; Put Contents of HL (which was DE) into B
  inc hl               ;; Increase HL by 1
  ld c,(hl)            ;; Put that into C
  ld hl,xpos           ;; Get address of xpos
  ld (hl),b           
  inc hl
  ld (hl),c            ;; Put contents into it

  ;; This is really just the same as above apart from getting the
  ;; address of xpos, I left it with this, instead of trying to
  ;; Poke my own program (by replacing YPOS address with XPOS). 
 
  ld de,(xpos)         ;; So with all the data being at XPOS &
  ld hl,(ypos)         ;; YPOS, I can do a call for Plot Absolute
  call &bbea
  ret

;; Data Areas

.xpos  defw 0          ;; Section where XPOS & YPOS goes
.ypos  defw 0
.adrxpos defw 0        ;; This is the address of the data for XPOS
.adrypos defw 0        ;; Same as Above except for YPOS

.data_xpos
defw 0                ;; Leave this line here
defw 0,2,4,6,8,10,12,14 ;; Sample Data (XPOS)
defw 0,2,4,6,8,10,12,14
defw 0,2,4,6,8,10,12,14
defw 0,2,4,6,8,10,12,14
defw 0,2,4,6,8,10,12,14
defw 0,2,4,6,8,10,12,14
defw 0,2,4,6,8,10,12,14
defw 0,2,4,6,8,10,12,14

.data_ypos
defw 0                ;; Leave this line alone
defw 0,0,0,0,0,0,0,0  ;; Sample Data (YPOS)
defw 2,2,2,2,2,2,2,2
defw 4,4,4,4,4,4,4,4
defw 6,6,6,6,6,6,6,6
defw 8,8,8,8,8,8,8,8
defw 10,10,10,10,10,10,10,10
defw 12,12,12,12,12,12,12,12
defw 14,14,14,14,14,14,14,14

.data_color
defb 1,1,0,1,0,1,1,0
defb 0,3,3,3,3,3,0,0
defb 0,0,2,2,2,0,0,0
defb 0,0,2,2,2,0,0,0
defb 0,0,2,2,2,0,0,0
defb 0,0,2,2,2,0,0,0
defb 0,0,2,2,2,0,0,0
defb 0,0,0,1,0,0,0,0

.addrcolor
defw 0


Purpose?  It's clearly not ideal for Sprite Handling, though it could be made to handle large fixed images without loading in 17k Screens perhaps. Maybe possible to reduce the size of this routine/program, by reducing the reoccuring xpos & ypos values. Otherwise it's simply another routine for the dust pile!  8)
Title: Re: ASM source code
Post by: arnoldemu on 11:40, 03 March 11
Quote from: CP/M User on 11:08, 03 March 11
Interesting the number of ways you can Plot onscreen!  :-[
Well each goes lower and lower level, so that the final one (not finished yet), calcs screen address of pixel, does all the masking and plotting itself.

Purpose?  It's clearly not ideal for Sprite Handling, though it could be made to handle large fixed images without loading in 17k Screens perhaps. Maybe possible to reduce the size of this routine/program, by reducing the reoccuring xpos & ypos values. Otherwise it's simply another routine for the dust pile!  8)

I see, drawing a sprite or image using GRA PLOT ABSOLUTE. Interesting idea, and I am sure this works well with cpm.

BTW, I am happy to host any routines on my website in the source section.
So you don't have to let them disapear ;)
Title: Re: ASM source code
Post by: AMSDOS on 10:08, 04 March 11
arnoldemu wrote:

Well each goes lower and lower level, so that the final one (not finished yet), calcs screen address of pixel, does all the masking and plotting itself.

The way the experts would make it!  ;D

QuotePurpose?  It's clearly not ideal for Sprite Handling, though it could be made to handle large fixed images without loading in 17k Screens perhaps. Maybe possible to reduce the size of this routine/program, by reducing the reoccuring xpos & ypos values. Otherwise it's simply another routine for the dust pile!  8)

I see, drawing a sprite or image using GRA PLOT ABSOLUTE. Interesting idea, and I am sure this works well with cpm.

Well it was only a part of another routine I had made ages ago (which I think I posted on this forum earlier - to see if it could be improved). Originally the idea was to see how this "Tag Plot" routine would perform as a sprite routine. Not really up to it - as demonstrated from my original Bouncing Ball program which is on my website. There would be some marginal improvement if all that code was in assembly, though I can still see some delay in it - obviously not really meant for plotting an image around the screen, it works (including in CP/M) great if you love slow motion!  ;D 
SCR HORIZONTAL on the other hand is look a bit more promising in terms of display rate time, won't really know how well it works moving things around til I get around to it, at the moment I'm studying the last program I made and writing in the what facts and figures I can code in to make an 8x8 move around. It probably won't ever be as fast as a true sprite routine, though if it's reasonible I may find something for it!

BTW, I am happy to host any routines on my website in the source section.
So you don't have to let them disapear ;)


These routines I come up with are usually work-in-progress. I don't mind whoever wants them can most certainally have them, it's Public Domain at best I reckon!  ;D  This one I just posted I can certainally make it better  by include a Double-byte Loop which would allow for larger images and make it work better that way. By only concern is allowing for larger images will blowout the number of co-ordinate positions, really needs to be written so the table would go:

x: 0,2,4,6,8,10,12,14
y: 0,2,4,6,8,10,12,14

Increment y from 0 to 2 when x has plotted out 14 and resetting x to 0 - thus producing the next line for x to plot the points along the y axis.
Title: Re: ASM source code
Post by: arnoldemu on 10:24, 07 March 11
Updated sources:

http://www.cpctech.org.uk/source/pscrlvrt.asm
http://www.cpctech.org.uk/source/pscrlhrz.asm
(Added some chars to screen so scroll effect is seen better over whole screen)

http://www.cpctech.org.uk/source/hardscrl.asm
(Now checks for lower case chars for keys and has chars over the screen so effect is better)

http://www.cpctech.org.uk/source/scrlhrz.asm
(Chars over the screen to see effect better, checks for lower case chars for keys, fixed R3 scrolling in both directions)

New source:

http://www.cpctech.org.uk/source/sprfirm.asm

Demonstrates a lot of the scr functions, including SCR NEXT BYTE, SCR PREV BYTE, SCR NEXT LINE, SCR PREV LINE, SCR GET LOCATION, RAM LAM.
This moves a sprite (flickering) over a background.
It uses the firmware functions to read/write the screen in a way that works with upper rom enabled.
You can activate 2 different read functions and 2 different write functions.

One read using indirections (but the lower rom must be enabled for this to work), and one using RAM LAM.
And 2 different write functions (one writing direct, another using scr pixels).

New test source:

http://www.cpctech.org.uk/source/plusscrl.asm
Mid-line screen scrolling on plus

I need to test on a real +, I am not sure full scrolling would be possible.
But may be useful for some effects.


Title: Re: ASM source code
Post by: arnoldemu on 21:32, 21 March 11
New source:

http://www.cpctech.org.uk/source/memcheck.asm

Memory check code used in Batman Forever demo.

To use:
1. call memcheck
2. call mem_check_contig_64_blocks
A register is the first configuration where there are 64k pages side by side that can be used. So you can access the ram with one base page.

mem_unique_configs is the list of page configurations that are valid and can be used.
Up to 512k dk'tronics compatible ram is supported by this code.

So for example, you can use the ram of a dk'tronics silicon disk on a 464 and the code will still detect as having enough ram. It will then give you the list of blocks (e.g. starting from cc).
Title: Re: ASM source code
Post by: arnoldemu on 10:31, 22 March 11
More source will come soon, including some test code, and with the musical loader I'll write up all the things I discovered and worked out in order to make it work.

Title: Re: ASM source code
Post by: arnoldemu on 17:25, 24 April 11
New source:

http://www.cpctech.org.uk/source/sftscrl.asm

Software scrolling the screen using the firmware and SCR SW ROLL.
This also demonstrates how you update a line of the screen, depending on the direction scrolling to maintain the scroll effect.
The scroll is in char sized increments (8 lines) and is only up and down.
Title: Re: ASM source code
Post by: arnoldemu on 17:38, 24 April 11
New source:

http://www.cpctech.org.uk/source/hrdscrl.asm


Hardware scrolling the screen using the firmware and SCR HW ROLL.
This also demonstrates how you update a line of the screen, depending on the direction scrolling to maintain the scroll effect.
The scroll is in char sized increments (8 lines) and is only up and down.

The effect is poor, clearing the line and drawing the chars takes a long time using firmware, so you can't see the power of hardware scrolling, but demonstrates this function.
Title: Re: ASM source code
Post by: arnoldemu on 21:34, 28 April 11
Two new sources:

http://www.cpctech.org.uk/source/expstr.asm (http://www.cpctech.org.uk/source/expstr.asm)

This example uses KM SET EXPAND and KM SET TRANSLATE to associate a string with a key. e.g. when you press F1 it could print "|DISC<CR>" in basic. Same kind of functionality as KEY DEF but in asm.

http://www.cpctech.org.uk/source/autotype.asm (http://www.cpctech.org.uk/source/autotype.asm)

This example autotypes a string in basic. It uses a frame flyback interrupt, it returns each char of a string using KM CHAR RETURN, it then monitors if that char has been read yet (so this locks it to firmware 1.1 at this time - CPC6128, Plus). Typing is not as fast as Markus has been able to do with his emu ;)

Both came about after discussion with somebody about autotyping strings in order to autoboot a program.
So here we go.

NOTE: KM CHAR RETURN is used to put 1 ASCII char into the keyboard buffer. However, when it's read, it is not decoded, so you can't assign it a string with KM SET EXPAND and expect it to display a whole string. Firmware just returns the char you gave it. ;)

Title: Re: ASM source code
Post by: arnoldemu on 21:29, 05 June 11
Arrgh. I did another edit. And I thought I had just quoted  :laugh:

EDIT: Is there a way for me to revert an  edit I made to my own message?

Title: Re: ASM source code
Post by: AMSDOS on 01:01, 06 June 11
Quote from: arnoldemu on 21:29, 05 June 11
Arrgh. I did another edit. And I thought I had just quoted  :laugh:

EDIT: Is there a way for me to revert an  edit I made to my own message?

Google Cache (http://webcache.googleusercontent.com/search?q=cache:Et0xNoKSUjUJ:cpcwiki.eu/forum/index.php%3Ftopic%3D668.75+%22CPC+Wiki+forum%22%2B%22ASM+Source+Code%22&cd=1&hl=en&ct=clnk&gl=au&source=www.google.com.au)?

I presume it's this post:

QuoteNew source:

http://www.cpctech.org.uk/source/fwdbuff.asm (http://www.cpctech.org.uk/source/fwdbuff.asm)

Double buffering using the firmware.
Demonstrates the firmware functions MC SCREEN OFFSET and SCR SET POSITION.
Yes, even with the firmware you can double buffer graphics to make them flicker free if you want.
Title: Re: ASM source code
Post by: arnoldemu on 09:12, 06 June 11
New source:

http://www.cpctech.org.uk/source/fwdbuff.asm (http://www.cpctech.org.uk/source/fwdbuff.asm)

Double buffering using the firmware.
Demonstrates the firmware functions MC SCREEN OFFSET and SCR SET POSITION.
Yes, even with the firmware you can double buffer graphics to make them flicker free if you want.

(Thanks it was this one)
Title: Re: ASM source code
Post by: redbox on 10:00, 06 June 11
Quote from: arnoldemu on 09:12, 06 June 11
Double buffering using the firmware.


Fantastic, thanks for this.
Title: Re: ASM source code
Post by: arnoldemu on 09:34, 05 July 12
Please can we sticky this topic?
Title: Re: ASM source code
Post by: Gryzor on 09:37, 05 July 12
Quote from: arnoldemu on 09:34, 05 July 12
Please can we sticky this topic?

Sure, but (since I haven't followed it), what is it about? The title isn't super-explanatory...
Title: Re: ASM source code
Post by: AMSDOS on 02:04, 08 September 12
Quote from: Gryzor on 09:37, 05 July 12

Sure, but (since I haven't followed it), what is it about? The title isn't super-explanatory...


ASM is shorthand for ASseMbly which usually reflects the 'asm' extension for the source code. Sometimes people might use a different extension (e.g. '.Z80'), if they want to emphasise which form of CPU their using (useful when you're dealing with a site which deals with several different platforms).


Normally if I want to look at something though I visit the 'Unofficial Amstrad WWW Resource' site though.  :D
Title: Re: ASM source code
Post by: TotO on 07:18, 08 September 12
I though that Gryzor did not ask about the mean of ASM but about the goal/content of the topic, to know how to "stick it". :)
Title: Re: ASM source code
Post by: arnoldemu on 09:30, 08 September 12
Quote from: Gryzor on 09:37, 05 July 12

Sure, but (since I haven't followed it), what is it about? The title isn't super-explanatory...
In this topic I, and others,  have posted links to various example programs written in z80 assembly language.
Some of these show how to use firmware functions, others to draw sprites.

I requested the sticky because I think others would be interested to look through the posts to help them learn coding on the cpc.

If you could change the topic title to "Example Z80 assembly programs" that would be great too.
Title: Re: ASM source code
Post by: Gryzor on 10:19, 13 September 12
@TotO, thanks, that's indeed what I was wondering about
@Arnoldemu, sure, will do it right away :)
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 10:29, 29 October 12

This is my most refined example I've made which is using GRA LINE ABSOLUTE to draw a series of lines (from the example provided) from a loop. I made an earlier example (which I might of posted elsewhere), though in this one I've setup 2 address pointers which points to the data I want to display in memory. My earlier example was taking the data from one spot, and moving it into another area and GRA LINE ABSOLUTE was accessing it from there. That method worked, though seemed to be a run around approach which I felt could be improved. This is the result.




;; Draw loop  in Assembly
;; CP/M User


ORG &4000 ;; This routine can go almost anywhere

;; Initialiation stuff


;; ld a,1
;; call &bc0e ;; SCR SET MODE, Routine will work in any mode which is set.


ld a,1
call &bbde ;; GRA SET PEN (PEN 1)


ld de,100 ;; xpos position to start at
ld hl,100 ;; ypos position to start at


;; Changing these values will change where and how image is to be drawn.


call &bbc0 ;; GRA MOVE ABSOLUTE


;; Setup size of the Loop with points to plot


ld b,4 ;; number of points to loop for image


.loop ;; The main loop


ld hl,(adrypos) ;; Address contents which points to image data for ypos goes into HL


ld e,(hl) ;; \
inc hl ;; - Contents of HL which is ypos data (16bit number) goes into DE
ld d,(hl) ;; /


ex de,hl ;; That information (ypos data) needs to go into HL register


push hl ;; But I need to protect that information so I can use HL.


ld hl,(adrxpos) ;; Address contents which points to image data for xpos goes into HL


ld e,(hl) ;; \
inc hl ;; - The same process now happens for xpos data (16bit number) going into DE
ld d,(hl) ;; /


pop hl ;; I can now restore that ypos data back into HL...


push bc ;; ...though I need to protect the loop counter.


call &bbf6 ;; GRA LINE ABSOLUTE, Entry: HL = y-coordinate, DE = x-coordinate
;; Exit: AF, BC, DE & HL corrupt.


pop bc ;; Restore loop counter.


ld hl,(adrxpos) ;; \
inc hl ;; - This moves address pointer for xpos to the following address & stores it.
inc hl ;; - Because 16bit data is being used, HL is incremented twice.
ld (adrxpos),hl ;; /


ld hl,(adrypos) ;; \
inc hl ;; - And the same thing applies for the address pointer for ypos data.
inc hl ;; - And again 16bit data is used.
ld (adrypos),hl ;; /


djnz loop ;; If loop counter hasn't being reached,
;; loop counter is decreased by 1 until B = 0.
;; The following address pointer will then be used.


ld hl,data_xpos ;; \
ld (adrxpos),hl ;; :
;; - Once loop is finished, the data points for xpos & ypos needs to be restored.
ld hl,data_ypos ;; :
ld (adrypos),hl ;; /


ret ;; Returns to BASIC (if called from there).


.adrxpos


defw data_xpos


.adrypos


defw data_ypos


.data_xpos


defw 100,200,200,100,0 ;; Standard graphic points to draw for xpos.


.data_ypos


defw 200,150,100,100,0 ;; Standard graphic points to draw for ypos.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: TotO on 13:14, 29 October 12
The pseudo random number generator from the cpcrslib for SDCC.
Look simple and efficient, as shown into the game named Totems (http://www.cpcwiki.eu/forum/news-events/totems-by-esp-soft/).


_cpc_Random::
   LD A,(#valor_previo)
   LD L,A
   LD A,R
   ADD L
   LD (#valor_previo),A
   LD L,A
   LD H,#0  ; value return in HL
   RET
valor_previo:
   .db #0xFF
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: SyX on 15:04, 03 November 12
A few years ago, i put a lot of snippets in this thread (http://www.amstrad.es/forum/viewtopic.php?f=6&t=1680) of the spanish forum, feel free to use them, and if somebody needs english comments, only ask :) 
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 17:36, 17 November 12
A new example:

http://www.cpctech.org.uk/source/colour_split.asm (http://www.cpctech.org.uk/source/colour_split.asm)

This example changes the whole palette at each interrupt. The screen is set to mode 1 and text is printed for each pen. (pen 1, pen 2, pen 3).
So here you can see how games change colours on the screen to give the illusion there are more colours than just 4 in mode 1.

This example uses the firmware.

If a sprite moves between the areas, then it's colours will automatically change, in this way we have our own kind of "colour clash".


Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 16:23, 26 December 12
A new example:

This shows how you can setup a double buffered overscan ("32k style") screen that fits within 64k.
It's a simple example that clears each screen and flips between them.

The screen is 46 wide and 32 tall.

The comments at the top show the free memory ranges that can be used and the size of ram if no scrolling is used.
This is not a "crossfire" example.

normal interrupt mode 1 interrupts are available.
biggest range is 1152 bytes. others are smaller.

if you wanted to, a simple game could fit into the memory ranges, with code organised all over the memory.

for a 64k machine it doesn't leave much room (20k total), but would be an interesting challenge.

For showing a double buffered overscan screen it's fine, although you would need to load the screens in a single block and reorganise them after loading. I can knock up an example that does just this another day, so opening up some nice graphical techniques for the "lowly poor 64k machines that get much hate" ;)

http://www.cpctech.org.uk/source/overdbf.asm (http://www.cpctech.org.uk/source/overdbf.asm)

NOTE: The locations of the screens have been carefully chosen so that the "problem" addresses appear on the right side (or perhaps left, can't remember, therefore making sprite routines easier and faster to make).
NOTE2: In addition the address has been chosen, so there is the potential for the firmware to be used to load all the data, then turn it off, and re-arrange it to get the final layout.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 11:25, 12 January 13
I had Kevin help me with this many years ago which shows the process of setting up a Table for Sprites along with the processes for moving a sprite around the screen. I made a couple of improvements to the code as well.




     org &4000


.conkey equ &bb1e
   
     ld a,0
     call &bc0e
     ld bc,&0101
     call &bc38
     call setcolors
     call initialise
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ex de,hl ;;  ld de,(scradr) <- ex de,hl is more efficent way to get something from HL to DE.
     ld hl,sprdata 
     ld b,8
     ld c,15
     call disspr
.mainloop
     call control
     ld a,66 ;; Check if ESC has been Pressed
     call conkey ;; Routine to Check for Key Pressed
     jr z,mainloop ;; Return to Mainloop if ESC has not been pressed
     call &bc02 ;; Otherwise Proceed to Exit, Reset Colours
     ld a,2 ;; And Return
     call &bc0e ;; To Mode 2.
     ret ;; Return to BASIC if called from there.
;; .conkey
;;     call &bb1e ;; Disabled cause there's no real need to have
;;     ret ;; as a routine plus save a byte :)
.setcolors
     ld hl,sprcolor ;; Address to INK Colours
     ld a,0 ;; PEN Number
.colloop
     ld c,(hl) ;; Contents of INKs is stored into C
     ld b,c ;; and B Registers.
     push af ;; Protect PEN Number Value
     push hl ;; And the Address to the INK Colours
     call &bc32 ;; SCR SET INK
     pop hl ;; Restore Address to the INK Colours
     pop af ;; Restore PEN Number Value
     inc hl ;; Point to next address for INKS
     inc a ;; Increase PEN Number
     cp 10 ;; Has PEN 15 been reached?
     jr c,colloop ;; Jump to Loop if value hasn't been reached.


  .control
     ld a,8 ;; Was Left Arrow Key Pressed?
     call conkey ;; KM TEST KEY
     jr nz,moveleft ;; Proceed to moveleft if it has
     ld a,1 ;; Was Right Arrow Key Pressed?
     call conkey ;; KM TEST KEY
     jr nz,moveright ;; Proceed to moveright if it has
     ld a,0 ;; Was Up Arrow Key Pressed?
     call conkey ;; KM TEST KEY
     jr nz,moveup ;; Proceed to moveup if it has
     ld a,2 ;; Was Down Arrow Key Pressed?
     call conkey ;; KM TEST KEY
     jp nz,movedown ;; Proceed To movedown if it has.
;;    ld a,66
;;    call conkey
;;    jr nz,exit
     ret
  .moveleft
     ld a,&0 ;; Does Accumulator = 0
     ld hl,(xpos)
     cp h ;; Check with XPOS
     jp nz,doleft ;; Only Move if possible.
  .showleft
     ld hl,(xpos) ;; New Position of XPOS
     call findcolumn ;; Convert XPOS into Screen Address
     ld (scradr),hl ;; Store New Screen Address
     ex de,hl ;;    ld de,(scradr) ;; Put this into DE
     ld hl,sprdata ;; Sprite address to HL
     ld b,8 ;; Length
     ld c,15 ;; Width
     call disspr ;; Display Sprite
     ret
  .doleft
     ld hl,(xpos) ;; Proceed to Decrease XPOS
     dec h
     ld (xpos),hl ;; Store new value to XPOS.
     jp showleft ;; And proceed to Display in New Position.
  .moveright
     ld a,&46
     ld hl,(xpos)
     cp h
     jp nz,doright
  .showright
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ex de,hl ;; ld de,(scradr)
     ld hl,sprdata
     ld b,8
     ld c,15
     call disspr
     ret
  .doright
     ld hl,(xpos)
     inc h
     ld (xpos),hl
     jp showright
  .moveup
     ld a,&0
     ld hl,(xpos)
     cp l
     jp nz,doup
  .showup
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ex de,hl ;;  ld de,(scradr)
     ld hl,sprdata 
     ld b,8
     ld c,15
     call disspr
     ret
  .doup
     ld hl,(xpos)
     dec l
     ld (xpos),hl
     jp showup
  .movedown
     ld a,&b6
     ld hl,(xpos)
     cp l
     jp nz,dodown
  .showdown
     ld hl,(xpos)
     call findcolumn
     ld (scradr),hl
     ex de,hl ;;  ld de,(scradr)
     ld hl,sprdata
     ld b,8
     ld c,15
     call disspr
     ret
  .dodown
     ld hl,(xpos)
     inc l
     ld (xpos),hl
     jp showdown


  .findcolumn
                                ;; H = x coordinate (0-79)
                                ;; L = y coordinate (0-199)
                                ;; HL = screen address (top-left of sprite)


     push bc                    ;; store BC because we are modifying it in this
                                ;; routine
     push de                    ;; store DE because we are modifying it in this
                                ;; routine
     ld c,h                     ;; store x coordinate in C register
     ld h,0                     ;; L = y coordinate, H = 0
     add hl,hl                  ;; double L. Now L is a byte offset from the
                                ;; start of the table pointing to the
                                ;; entry corresponding to screen Y
                                ;; coordinate. We double because each entry
                                ;; is two bytes.
     ld de,table                ;; base of table
     add hl,de                  ;; add offset to base to get actual address in
                                ;; memory of the table entry
     ld a,(hl)
     inc hl
     ld h,(hl)
     ld l,a                     ;; HL = value from table. it is the screen
                                ;; address for the start of this line
                                ;; corresponding to the Y coordinate
     ld b,0                     ;; BC = x coordinate as a 16-bit value. C = x
                                ;; coordinate
     add hl,bc                  ;; add on X coordinate
                                ;; HL = final screen coordinate for x,y position


     pop de                     ;; restore registers we used
     pop bc
     ret


.initialise ;; Routine to Setup Screen Addresses to Table.
     ld de,table
     ld hl,&c000
     ld b,&19
.next
     push bc
     push hl
     ld b,&8
.loop
     push bc
     ld a,l
     ld (de),a
     inc de
     ld a,h
     ld (de),a
     inc de
     ld bc,&800
     add hl,bc
     pop bc
     djnz loop
     pop hl
     ld bc,&50
     add hl,bc
     pop bc
     djnz next
     ret


.disspr
;; Entry Conditions:
;;
;; DE = Sprite Address to display sprite at
;; HL = Sprite Location
;; B = Sprite Width
;; C = Sprite Height


     LD A,B
     LD (p1+1),A
.loop1
     PUSH DE
.p1   
     LD B,&0
.loop2
     LDI
     INC C
     DJNZ loop2
     POP DE


     LD A,D        ;;
     ADD &8        ;;
     LD D,A        ;;
     JR NC,end     ;;     
     LD A,E        ;; Step down a line
     ADD &50       ;;
     LD E,A        ;;
     LD A,D        ;;
     ADC &C0       ;;
     LD D,A        ;;


.end 
     DEC C
     JR NZ,loop1
     RET


  .table
     defs 400 ;; 200 scanlines * 2 for the size of each entry.
  .scradr
     defw &c000
  .xpos
     defb &00
  .ypos
     defb &00
  .scrrow
     defb 0
  .sprcolor
     defb 0,26,0,6,3,15,18,1,2,20,0
  .sprdata
     defb 12,12,12,12,12,12,12,12
     defb 8,0,0,0,0,0,0,4
     defb 8,0,&54,&fc,0,0,0,4
     defb 8,0,&a9,3,&a8,0,0,4
     defb 8,0,&f0,&f0,&a0,0,0,4
     defb 8,&44,&f0,&a0,&a0,0,0,4
     defb 8,&44,&e4,&70,&a0,0,0,4
     defb 8,&44,&b0,&10,&20,0,0,4
     defb 8,&44,&b0,0,0,0,0,4
     defb 8,0,&e4,&30,&20,&68,0,4
     defb 8,0,&83,&e9,&83,&16,&80,4
     defb 8,&41,&d6,&fc,&a8,&68,0,4
     defb 8,0,&56,&56,2,0,0,4
     defb 8,0,&c3,&41,&82,0,0,4
     defb 8,0,0,0,0,0,0,4
     defb 12,12,12,12,12,12,12,12
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Devilmarkus on 14:09, 12 January 13
This routine is nice and fast.
Could you do the same with a sprite which doesnt destroy the background?
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 01:22, 13 January 13
Quote from: Devilmarkus on 14:09, 12 January 13
This routine is nice and fast.
Could you do the same with a sprite which doesnt destroy the background?


Not with the Sprite Driver I'm using because it wasn't designed for Pixel Accuracy (as explained in the article). The routine comes from AA53 Cracking the code p39-40. There is another example on p40 which I think is more about the accuracy, though more processes are involved within the routine.


I was looking at some other sprite routines Rob Buckley at in AA112 p16 & AA113 p16 as well, which relates more to drawing sprites with a Background or over other Sprites, though I'm a bit of a dunce when it comes to how they work because the articles were limited in space.  :'( 


Sean McManus had some interesting example ESD2 I think it's called which had some Pixel Accurate Sprites moving over one another which looks a little bit more in my league, not sure if that's his example from the AA112-113 issues.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 11:15, 05 February 13
I've had a look at this simple 8bit Random Number Generator which is on the Wiki and I've strapped a simple 8bit Unsigned Divide and I've loaded the Accumulator with 20 which produces some Random Like Results between 0 & 19:


;; 8 Bit Random Number Generator
org &4000


.rand8 ld a,(seed)
ld b,a
add a,a
add a,a
add a,b
inc a
ld (seed),a
ld a,20 ;; Divide Begins here
ld c,a
ld a,0
ld hl,(seed)
ld b,16
.divide add hl,hl
rla
cp c
jr c,end
sub c
inc l
.end djnz divide
ld (result),a
ret


.seed defb 0
defb 0
.result defb 0



Here's a little test program (in BASIC) :D


10 FOR a=1 TO 1000:CALL &4000:PRINT "Seed:";PEEK(&4022);"  ";"Result:";PEEK(&4024):NEXT a



Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AugustoRuiz on 16:09, 27 March 13
Any docs on how to read from disk, not using the firmware?

Thank you for this great thread!
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 18:43, 27 March 13
Quote from: AugustoRuiz on 16:09, 27 March 13
Any docs on how to read from disk, not using the firmware?

Thank you for this great thread!
I've got some example code already. I'll dig it out.

You want code that goes directly to the 765 disc controller?

Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AugustoRuiz on 22:49, 27 March 13
I'd like to read a big file in chunks, so I can process each chunk while reading the next one. For audio playing ;)
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 10:25, 28 March 13
Quote from: AugustoRuiz on 22:49, 27 March 13
I'd like to read a big file in chunks, so I can process each chunk while reading the next one. For audio playing ;)
a musical disc loader is different from a normal loader.

I do have a musical loader.

I will post the code to a normal loader first.


Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 12:15, 29 March 13
http://www.cpctech.org.uk/source/fdcload.asm (http://www.cpctech.org.uk/source/fdcload.asm)

Simple loader that reads whole sectors into memory.

I will update the comments for the source to explain more about what the code means.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 16:18, 30 March 13
Quote from: arnoldemu on 12:15, 29 March 13
http://www.cpctech.org.uk/source/fdcload.asm (http://www.cpctech.org.uk/source/fdcload.asm)

Simple loader that reads whole sectors into memory.

I will update the comments for the source to explain more about what the code means.
more comments added.

EDIT: And more added.

If you read the comments perhaps you will get ideas of how a musical loader is done ;)

I will post other code soon, building up to a release of my musical loader code.

I want people to understand how it is possible, and the theory behind it.

Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AugustoRuiz on 22:26, 01 April 13
Thank you so much!
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 13:40, 01 June 13
Example of how to make a multi-load game/program:

http://www.cpctech.org.uk/download/modasm.zip (http://www.cpctech.org.uk/download/modasm.zip)

In this asm example I use pasmo because it makes .lst files that can be included in other asm files.
main.s is built, it has the main functions and the main code. lst is generated that has it's labels.

Now I build level.s and include the labels from main. One label defines where level.s should be located, others are used so we can call functions in main.

main.s loads level.s and executes it, so we can see how we can have code and data in the levels.
So to load next level, we only need to call a function in main to load the level and execute it.

we could have level1.s level2.s level3.s all setup like level.s.

And there we have our multi-load game/program.

This shows how easy it is to do with pasmo and asm.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 11:21, 10 June 13

This is what I've come up with in Assembly today which is the Z80 equivalent of Chris Wootton Starscroller 10-Liner from October 1990 ACU.


Originally when I compiled what I'd written (in Winape Assembler), it was functioning with a "jr mainloop" jumping back to it, though it appeared to be exceeding the -126 bytes limit and yet it the program was still functioning.


My other quibble at the moment with the random number generator is to do with producing numbers between 0-640 for the random horizontal alignment, unfortunately I don't really quite understand why. I created a divider which kind of produces numbers within that range, but at the moment it's like I've put the largest as one part of my result (&FF) & my second part of the result is producing numbers between 0-7, I've only put it like that cause it seems to be the best random result. Earlier I had it setup so my first random result was between 0-80 & my second being 0-2 so it would look like it was somewhere between 0 & 280h which would give me my random 640, though the results were trending, not sure why.  :(



org &4000


.inkey equ &bb09
.mode equ &bc0e
.inks equ &bc32
.border equ &bc38
.print equ &bb5a
.matrix equ &bba8
.plot equ &bbea
.pen equ &bb90
.grapen equ &bbde
.scroll equ &bc4d
.locate equ &bb75
.frame equ &bd19
.colres equ &bc02


call setup
ld a,(xpos)
ld h,a
ld l,25
call locate
ld a,254
call print
ld a,255
call print
ld hl,direction
ld a,&3d ;; dec a
ld (hl),a
.mainloop


call inkey
cp &0d
jr z,exit
ld a,(xpos)
.direction
defb 0 ;; Decrement/Increment goes here.
ld (xpos),a
ld h,a
ld l,25
call locate


call frame


ld a,254
call print
ld a,255
call print

call frame


ld a,(xpos)
cp &1 ;; checks for xpos value and
call z,change_value1 ;; call appropriate routine if true

ld a,(xpos)
cp &13 ;; checks for xpos value and
call z,change_value2 ;; call appropriate routine if true




ld hl,divider
ld a,3 ;; get a value between 0..3
ld (hl),a


call rand8 ;; has to look random

inc a ;; has to be a value between 1 & 4
ld (result),a ;; not sure


ld a,(result) ;; why I'm doing this
call grapen

ld hl,divider
ld a,255 ;; first random number be a large as possible
ld (hl),a


call rand8


ld (result),a ;; store into result


ld hl,divider
ld a,7 ;; not sure why 7, seems to create random effect
ld (hl),a


call rand8


ld (result+1),a ;; a trick way of making a 16bit random from a 8bit
;; number generator. Not sure how effective it is.
;; Wanted to produce random numbers between 0 & 640.


ld de,(result)
ld hl,398
call plot


ld b,0
ld a,0
call scroll


jp mainloop ;; This was a jr maintop, but I think it would of been
;; illegal on a real cpc because it exceeded -126
;; bytes!!


.exit ret

.setup xor a
call mode
ld a,4
call pen
ld bc,0
call border
ld hl,colours
ld a,0
.setup_inks
ld c,(hl)
ld b,c
push af
push hl
call inks
pop hl
pop af
inc hl
inc a
cp &5
jr c,setup_inks
ld a,254
ld hl,pattern1
call matrix
ld a,255
ld hl,pattern2
call matrix
ret


.change_value1
ld hl,direction
ld a,&3c ;; inc a
ld (hl),a
ret


.change_value2
ld hl,direction
ld a,&3d ;; dec a
ld (hl),a
ret


.rand8 ld a,(seed)
ld b,a
add a,a
add a,a
add a,b
inc a
ld (seed),a
ld a,(divider)
ld c,a
ld a,0
ld hl,(seed)
ld b,16
.divide add hl,hl
rla
cp c
jr c,end
sub c
inc l
.end djnz divide
ret


.colours
defb 0,26,26,13,6
.pattern1
defb 1,1,65,67,71,127,67,1
.pattern2
defb 128,128,130,194,226,254,194,128
.xpos defb 10
.seed defb 7
.result defb 0,0
.divider
defb 3
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: redbox on 11:42, 10 June 13
Quote from: AMSDOS on 11:21, 10 June 13
My other quibble at the moment with the random number generator is to do with producing numbers between 0-640 for the random horizontal alignment

It's random enough for the routine, but actually not very random.  If you turn off the call to the firmware scroll you'll see it build up on the top line of the screen.

You could poke the "stars" directly to the screen memory instead.  This is &50 (80) bytes wide which would mean an easier 8-bit random routine.  There's also enough head room (bit 7, i.e. 128, on or off) to also include whether or not the "star" gets shown in the first or second pixel of the byte.

The inks in your routine are set to 0,26,26,13 and 6.  This is why you're requiring another call of the random routine between the ranges of 0-3 because this selects one of the INKs before drawing the star.  So the choices are 0 (black = no star), 26 (white), 26 (white) or 13 (grey).  The routine therefore should draw twice as many white stars as grey stars, and sometimes it draws a black star too.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: tastefulmrship on 13:23, 10 June 13
Quote from: AMSDOS on 11:21, 10 June 13
This is what I've come up with in Assembly today which is the Z80 equivalent of Chris Wootton Starscroller 10-Liner from October 1990 ACU.
Tenuously linked post ahead!

If you're interested, here's the horizontal star-scroller from the XOR cracktros...
Just assmeble in WinAPE/Maxam and CALL &A000 to see what it does. If you're using WinAPE, then it's best to keep the boot-screen up, so you can see that it doesn't affect the text on screen while it runs.

For better results, try changing the background colours to #00 (BLACK) and inks 1 & 3 to #26 (BRIGHT WHITE) and 13 (WHITE) respectively. It gives a slight impression of a star-trail as it moves across the screen.


org #a000

.inflp    call stars
    jp inflp

.stars    ld de,#0000
    ld hl,here2
    ld b,25
.loop1    ld a,(hl)
    ld e,a
    inc hl
    ld a,(hl)
    ld d,a
    dec hl
    ld a,(de)
    cp #fe
    jr nz,jump1
    xor a
    ld (de),a
.jump1    inc de
    ld a,d
    cp #00
    jr nz,jump2
    push hl
    ld hl,#c000
    add hl,de
    ex de,hl
    pop hl
.jump2    ld a,(de)
    cp #00
    jr nz,jump3
    ld a,#fe
    ld (de),a
.jump3    ld a,e
    ld (hl),a
    inc hl
    ld a,d
    ld (hl),a
    inc hl
    djnz loop1

    ld hl,here3
    ld b,25
.loop2    ld a,(hl)
    ld e,a
    inc hl
    ld a,(hl)
    ld d,a
    dec hl
    ld a,(de)
    cp #fe
    jr nz,jump4
    xor a
    ld (de),a
.jump4    inc de
    inc de
    ld a,d
    cp #00
    jr nz,jump5
    push hl
    ld hl,#c000
    add hl,de
    ex de,hl
    pop hl
.jump5    ld a,(de)
    cp #00
    jr nz,jump6
    ld a,#fe
    ld (de),a
.jump6    ld a,e
    ld (hl),a
    inc hl
    ld a,d
    ld (hl),a
    inc hl
    djnz loop2

    call #bd19
    ret

.here2
db #00,#c0,#55,#c0,#c0,#c0,#f4,#c0
db #68,#c1,#a9,#c1,#20,#c2,#55,#c2
db #82,#c2,#e0,#c2,#4a,#c3,#a0,#c3
db #d9,#c3,#49,#c4,#a0,#c4,#d9,#c4
db #48,#c5,#65,#c5,#c6,#c5,#fa,#c5
db #85,#c6,#d5,#c6,#20,#c7,#49,#c7
db #a0,#c7

.here3
db #30,#d0,#90,#d8,#a0,#f0,#10,#d1
db #7a,#e1,#a0,#e9,#00,#ca,#30,#d2
db #b0,#e2,#e0,#ea,#50,#d3,#75,#db
db #e0,#f3,#20,#d4,#a0,#cc,#e9,#dc
db #0a,#ed,#65,#dd,#a9,#d5,#15,#f6
db #85,#ee,#a5,#ee,#ff,#ce,#4a,#e7
db #b0,#ef


(P.S. The code isn't originally mine, so I'm not trying to steal the glory here or anything!)
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Devilmarkus on 19:23, 10 June 13
Nice stars!

When you change this:


.inflp    call stars
    jp inflp


to:


.inflp    call stars
    ret


you can call it from BASIC like:
10 CALL &A000:GOTO 10
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 13:04, 11 June 13
Quote from: redbox on 11:42, 10 June 13
It's random enough for the routine, but actually not very random.  If you turn off the call to the firmware scroll you'll see it build up on the top line of the screen.

You could poke the "stars" directly to the screen memory instead.  This is &50 (80) bytes wide which would mean an easier 8-bit random routine.  There's also enough head room (bit 7, i.e. 128, on or off) to also include whether or not the "star" gets shown in the first or second pixel of the byte.


This seems to be a good idea, I'm not quite sure if it would work, would rolling the screen change the offset, I was just wondering if using SCR Pixels would be better since it asks for a PEN mask, Pixel Mask & Screen Address.
I started off playing around with the random number routine to generate a random colour number, and then use a routine (I was familiar with from AA) to work out which byte to use in relation to that, though that wasn't quite working for me.  :(

QuoteThe inks in your routine are set to 0,26,26,13 and 6.  This is why you're requiring another call of the random routine between the ranges of 0-3 because this selects one of the INKs before drawing the star.  So the choices are 0 (black = no star), 26 (white), 26 (white) or 13 (grey).  The routine therefore should draw twice as many white stars as grey stars, and sometimes it draws a black star too.


That is correct (those are the original ink colours from the program I got it from), initially the Simple Random Number routine I'm using to get random number, I've stuck a divider on it (from another book  ;D  ), which returns numbers within the specified range, so in this case I made it ld a,3 which gives me numbers between 0..2 (not 0..3, which is a commented mistake  :o ), and after that process I've increased the value of A which should give values between 1 to 3 and not 1 to 4 as I've mistakingly written in. So there shouldn't be any Red stars which I haven't noticed and no black ones because the value will always be greater than 0.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: redbox on 13:10, 11 June 13
Quote from: AMSDOS on 13:04, 11 June 13
I'm not quite sure if it would work, would rolling the screen change the offset

Good point.

But I'm always looking at it from an optimisation point of view, which of course would mean completely removing use of the firmware which isn't the point of your project  ;)

Nice to see what you've done though and you've exposed some of the issues of translation between BASIC > Firmware > Assembler and vice versa.  The firmware (which in turn BASIC uses) has some excellent routines which don't have the confines of rigid "8/16-bit ness", but the caveat is that they're generally slow.

Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 11:05, 12 June 13

Quote from: redbox on 13:10, 11 June 13
Good point.

But I'm always looking at it from an optimisation point of view, which of course would mean completely removing use of the firmware which isn't the point of your project  ;) 

Initially when I started writing this Assembly version, I was looking for a way to write an assembly equivalent of "xpos:=xpos+xdir" with "xdir" either being 1 or -1, which I did by checking the values of the position and poking the appropriate "INC" or "DEC" to reverse the direction of the Space craft that way.


Though now it looks like I'll need to find a better random number generator if I'm to apply it in the 0-640 number range or use the screen to position the stars. With the current routine I'm using, I was think in terms of 640 as 280h, and was trying to apply numbers between 0-80 as my low byte and numbers between 0-2 as my high byte, though when I applied that, the program was generating a distinctive pattern and a trending pattern of Stars across the screen with areas appearing to be out of range.  :-X 
The program I posted sets up the low byte divider to be anything from 0-FFh & 0-7h (I think) for the high byte, which makes the stars appear more random, though because it's setup like that, there are numbers exceeding the 640 limit, which is why some stars won't even be shown, hence the gaps along the line numbers.

I figure that if a 16bit Random Number generator produces numbers between 0-65535, then to get it back close to the 0-640 range it only has to be divided by 102 times, though I'm not very good on these Shift and Rotating instructions if they are other little tricks or faster ways of calculating results within certain ranges.
QuoteNice to see what you've done though and you've exposed some of the issues of translation between BASIC > Firmware > Assembler and vice versa.  The firmware (which in turn BASIC uses) has some excellent routines which don't have the confines of rigid "8/16-bit ness", but the caveat is that they're generally slow.

BASIC might use the firmware, though Assembly or a Compiled Language can improve it by taking machine language immediately. Yeah it's not perfect, though for this program it's fine and can be improved.  :D
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: ralferoo on 12:11, 12 June 13
Quote from: AMSDOS on 11:05, 12 June 13
Though now it looks like I'll need to find a better random number generator if I'm to apply it in the 0-640 number range or use the screen to position the stars. With the current routine I'm using, I was think in terms of 640 as 280h, and was trying to apply numbers between 0-80 as my low byte and numbers between 0-2 as my high byte, though when I applied that, the program was generating a distinctive pattern and a trending pattern of Stars across the screen with areas appearing to be out of range.  :-X 
...
I figure that if a 16bit Random Number generator produces numbers between 0-65535, then to get it back close to the 0-640 range it only has to be divided by 102 times, though I'm not very good on these Shift and Rotating instructions if they are other little tricks or faster ways of calculating results within certain ranges.

If you have random numbers in the range 0..32767 (which IIRC you do, you can do this):

; entry HL = 15 bit random number
; exit HL = scaled to 0..639, A and BC corrupted, carry clear

ld b,h
ld c,l
xor a

add hl,hl   ; *2 (HL now 0..65534)
add hl,hl   ; *2 (HL now 0..65532)
adc a,a     ; carry into A (A:HL now 0..131068)
add hl,bc   ; *5
adc a,0     ; A:HL now 5*original or 0..163835

ld l,h
ld h,a      ; HL now in range 0..639 (163835/256)
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 13:53, 14 June 13
Thanks for that, it has made a difference and things appear a bit more random.  :)



org &4000


.inkey equ &bb09
.mode equ &bc0e
.inks equ &bc32
.border equ &bc38
.print equ &bb5a
.matrix equ &bba8
.plot equ &bbea
.pen equ &bb90
.grapen equ &bbde
.scroll equ &bc4d
.locate equ &bb75
.frame equ &bd19


call setup
ld a,(xpos)
ld h,a
ld l,25
call locate
ld a,254
call print
ld a,255
call print
ld hl,direction
ld a,&3d
ld (hl),a


.mainloop


call inkey
cp &0d
jr z,exit
ld a,(xpos)
.direction
defb 0
ld (xpos),a
ld h,a
ld l,25
call locate


call frame


ld a,254
call print
ld a,255
call print

call frame


ld a,(xpos)
cp 1
call z,change_value1

ld a,(xpos)
cp 19
call z,change_value2


call rand8


srl a
srl a
srl a
srl a
srl a
srl a
srl a


inc a
ld (result),a


ld a,(result)
call grapen

call rand8


ld (result),a


call rand8


srl a


ld (result+1),a


ld hl,(result)
call scale_number
ld (result),hl


ex hl,de


ld de,(result)
ld hl,398
call plot


ld b,0
ld a,0
call scroll


jp mainloop


.exit ret

.setup xor a
call mode
ld a,4
call pen
ld bc,0
call border
ld hl,colours
ld a,0
.setup_inks
ld c,(hl)
ld b,c
push af
push hl
call inks
pop hl
pop af
inc hl
inc a
cp &5
jr c,setup_inks
ld a,254
ld hl,pattern1
call matrix
ld a,255
ld hl,pattern2
call matrix
ret


.change_value1
ld hl,direction
ld a,&3c
ld (hl),a
ret


.change_value2
ld hl,direction
ld a,&3d
ld (hl),a
ret


.rand8 ld a,(seed)
ld b,a
add a,a
add a,a
add a,b
inc a
ld (seed),a
ret


.scale_number


;; entry HL = 15 bit random number
;; exit HL = scaled to 0..639,
;;      A & BC Corrupt, carry clear
ld b,h
ld c,l
xor a


add hl,hl ;; *2 (HL now 0..65534)
add hl,hl ;; *2 (HL now 0..65532)
adc a,a ;; carry into A (A:HL now 0..131068)
add hl,bc ;; *5
adc a,0 ;; A:HL now 5*original or 0..163835


ld l,h
ld h,a ;; HL now in range 0..639 (163835/256)


ret


.colours
defb 0,26,13,0,6
.pattern1
defb 1,1,65,67,71,127,67,1
.pattern2
defb 128,128,130,194,226,254,194,128
.xpos defb 10
.seed defb 127
.result defb 0,0



This is what I've come up with and have now implemented srl to shift the values into their appropriate places (instead of relying on a Divide).
For the coloured stars, I'm using "srl a" 7 times which gets me a value between 0 & 1 depending on what number seed comes out of the 8bit random number generator. Don't need 0 so I'm adding 1 which will get me either 1 or 2, which seems good enough, I wasn't sure if there was a better way of doing it instead of having 7 "srl a" though.  :) 
To get a number between 0..32767 though, it seems ideal to have a "srl" in there instead of a whole Divide and cuts down on the code.  :D
Title: Re: ASM source code
Post by: AMSDOS on 10:45, 04 July 13
Quote from: AMSDOS on 04:14, 19 December 10
I hope no-one minds me posting this old dinosaur of a routine in here! 

org &4000

    .setup 
     LD A,1   ;; My crude routine for setting up Scr_Mode
     CALL &BC0E
     LD A,240  ;; Setup Symbol Table - A Holds Character value
     LD HL,ship1  ;; HL points to Symbol Data to Define to
     CALL &BBA8  ;; Firmware routine to Redefine Symbol Table.
     LD A,241
     LD HL,ship2
     CALL &BBA8
     LD A,242
     LD HL,ship3
     CALL &BBA8
     LD A,243
     LD HL,ship4
     CALL &BBA8
    .init
     ld hl,&140C  ;; Initial Position
     LD A,0   ;; Initial Direction
    .loop
     PUSH HL   ;; Start of Main Loop
     PUSH AF
     CALL &BB75  ;; TXT SET CURSOR
     POP AF
     PUSH AF
     ADD A,240  ;; graphic code
     CALL &BB5D  ;; Print
     LD BC,&0C00  ;; Start Short Delay
    .shtdel
     DEC BC   
     LD A,B
     OR C
     JR NZ,shtdel  ;; loop back if Non Zero
     POP AF
     POP HL   ;; only HL actually wanted
     PUSH HL
     PUSH AF   ;; the next call corrupts AF & HL
     CALL &BB75  ;; TXT SET CURSOR
     LD A,32   ;; code for space
     CALL &BB5D  ;; Print
     LD A,0   ;; code for up arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,proa  ;; Jump if Key Up
     POP AF   ;; reclaim direction code
     POP HL   ;; ..and position
     CP 0   ;; Compare A with 0 - up?
     JR NZ,right  ;; Jump to check Right if Not
     DEC L   ;; Up a row
     JR newpos  ;; Jump to the next position
    .right
     CP 1   ;; Compare with 1 - right?
     JR NZ,down
     INC H   ;; Right one column
     JR newpos
    .down
     CP 2   ;; Down?
     JR NZ,left
     INC L   ;; Down a row
     JR newpos
    .left
     DEC H   ;; Left - no check needed here
    .newpos
     PUSH HL   ;; Save new position
     PUSH AF   ;; Protect A from the TEST KEY call
    .proa
     LD A,1   ;; key code for right arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,lftar  ;; Zero if not pressed
     POP AF   ;; old direction
     ADD A,1   ;; clockwise move
     CP 4   ;; check A value in range
     JR NZ,newdir2  ;; Jump if not 4
     LD A,0   ;; reset A to 0
    .newdir2
     PUSH AF   ;; new direction
     LD BC,&2000  ;; delay to separate keystrokes
    .dloop2
     DEC BC
     LD A,B
     OR C
     JR NZ,dloop2
    .lftar
     LD A,8   ;; key code for left arrow
     CALL &BB1E  ;; KM TEST KEY
     JR Z,cesc  ;; jump if not pressed
     POP AF   ;; old direction
     SUB 1   ;; Subtract: A=A-1
     JR NC,newdir  ;; Jump if Carry bit not set **
     LD A,3   ;; Reset A to 3 if below 0
    .newdir
     PUSH AF   ;; New Direction
     LD BC,&2000  ;; delay loop
    .dloop
     DEC BC   
     LD A,B
     OR C
     JR NZ,dloop
    .cesc
     LD A,66   ;; key code for ESC
     CALL &BB1E  ;; KM TEST KEY
     JR Z,check
     POP AF   ;; clear stack before return
     POP HL
     RET   ;; Return to Basic
    .check
     POP AF
     POP HL   ;; only HL really wanted
     PUSH AF   ;; save direction code
     LD A,L   ;; routine to check L value
     CP 0   ;; off top of screen?
     JR NZ,botscr
     LD L,25   ;; wrap-round, top to bottom
     JR checkh  ;; Jump to H check
    .botscr
     CP 26   ;; bottom of screen?
     JR NZ,checkh
     LD L,1   ;; move to top
    .checkh
     LD A,H   ;; check H value
     CP 0   ;; off left?
     JR NZ,offright
     LD H,40   ;; move to right edge
     JR tidy   ;; jump to end
    .offright
     CP 41   ;; off right
     JR NZ,tidy
     LD H,1   ;; move to left edge
    .tidy
     POP AF   ;; tidy up the stack
     JP loop   ;; jump to start of main loop ***
    .ship1
     defb 16,56,56,56,124,124,198,130
    .ship2
     defb 192,112,62,31,62,112,192,0
    .ship3
     defb 130,198,124,124,56,56,56,16
    .ship4
     defb 0,3,14,124,248,124,14,3 ;; data for defining the ships.


This is one of those Left/Right, point the ship in this direction kind of routine and use the foward arrow to move it in the direction it's facing. The original program (which is mainly this) comes from Amstrad CPC464 User (before it became ACU) and the program appeared to only be CPC464 friendly. A good deal of modify it just to get it to compile in Maxam was required since the original routine was using direct addresses & bytes in the Jump & Jump Relative routine and no labels!   So I've tried to label the program as best as I could, result the program works. The original code never included the matrix data either, where in it was included within the BASIC Loader program, but now it should act as the BASIC program does. But I reckon there could be considerable enhancements which could be done to it if anyone is looking for a routine like this.

Quote from: Gryzor on 09:55, 24 December 10
Dear AA,

I typed the program that you printed in your last issue, again and again, but my Amstrad gives me an error on every line. Even if I add line numbers, when I try to run it I get errors again and I don't know how to correct them.

I noticed that you didn't print the checksums so I can check if I have typed it in correctly, but I am pretty sure I did. Also, you didn't print those dots that represent spaces, those are really useful...

Is my 464 broken?

Thank you,
Th.P.

I don't understand, does this mean that routine above doesn't work? I would of done it in Winape Assembler which is just a matter of  compiling it to memory @ &4000 and "CALL &4000" should have it working with redefined character and all.  :'( I was lazy in setting up a Matrix Table (BASIC equivalent to SYMBOL AFTER 240), which seems to become more important if you generate a Binary File with an Executable Address as that defines an area of memory to put your redefined SYMBOLs - as I have done in that routine using &BBA8.
Title: Re: ASM source code
Post by: arnoldemu on 09:32, 29 August 13
New example:

http://www.cpctech.org.uk/source/spec_spr.asm (http://www.cpctech.org.uk/source/spec_spr.asm)

Shows how to draw a sprite on a Spectrum sized screen.

It explains some benefits of using a spectrum sized screen.

Somebody will be a long soon to say "don't use a spectrum sized screen"  :laugh:
Title: Re: ASM source code
Post by: arnoldemu on 10:10, 29 August 13
New example:

http://www.cpctech.org.uk/source/comp_spr.asm (http://www.cpctech.org.uk/source/comp_spr.asm)

This example shows what I call "compressed sprites".

I have a "large" sprite which has many areas that are fully transparent. Normally we would waste time masking these areas if a standard masking sprite routine was used for the whole sprite. (e.g. we don't split it into smaller sprites and just draw those).

In the code there are 2 draw functions. One shows the sprite itself (I am no graphics artist ;). It moves and you can see it masked over the screen. The other draws pixels for the control codes so that you can see where it recognises fully transparent, masked, fully opaque and end of line conditions.

Turn it on to see the difference.

There are other ways to compress sprites, this is one example.
The code is not optimised, and this method may not be the fastest but it shows how to draw large sprites in this way.
Title: Re: ASM source code
Post by: arnoldemu on 09:43, 30 August 13
New example:

http://www.cpctech.org.uk/source/cpl_spr.asm (http://www.cpctech.org.uk/source/cpl_spr.asm)

This example shows what I call "compiled sprites".

In the code there are 3 sprites. For each of these there is 1 drawing function. Within the function you will see the instructions for masking, writing opaque pixels and for skipping fully transparent pixels and for moving to the next line. The code is not optimised - I also think there is a bug in the code generation meaning the pixels are not correct but it's enough for this example so you can see what a sprite of this type looks like.

NOTE: If I wanted to have pre-shifted sprites, I would need more functions. If I want more sprites I also need more functions. The advantage of this method is that it's faster to draw a sprite but at the expense of needing more ram to store the drawing routines. - More useful if you are making a game for cpcay cartridge OR mixing hard and software sprites in a plus game.

Title: Re: ASM source code
Post by: arnoldemu on 09:46, 30 August 13
I think now I have shown the methods to draw sprites on a cpc:

I have covered:
- preshifted sprites
- compiled sprites
- compressed sprites
- masked sprites
- xor sprites
- "mode 3 sprites"/bitplanes sprites. (I think I did an example of this???) hmmm.. not sure now ;)

I haven't show enough  methods for erasing sprites yet.
So far shown:
- storing background to restore it back
- using XOR to redraw the sprite to erase it in addition to drawing it.

Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: redbox on 15:15, 22 October 13
Here's a "sprite" routine I've just written to add to the mix...

The problem I was having is that if you compress "big" sprites (e.g. logos, status bars etc - mainly the type of thing you want to draw to the screen once and drawing it isn't time critical) with Exomizer or similar then you have to decompress them to RAM first before drawing them on the screen (due to the CPC's video addressing format) which is kind of self-defeating.

Therefore, I wrote a routine that only compresses data within a set boundary, i.e. one horizontal screen line of the sprite.  Then on decompression we can draw it directly to the screen without using any kind of buffer whatsoever.

It works nicely and in the example provided the saving is 17% over the original.  The routines demonstrate simple repetition based compression and are descriptive (i.e. not optimised) so feel free to adapt to your purpose/speed requirements.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Devilmarkus on 13:15, 24 October 13
I typed in a tape turboload and turbosave routine. (It's not soooo turboish, but provides colour striped border)

This program originally comes from the Spanish CPC mag. "Amstrad Personal" no. 09.

        ;;    TURBOSAVE - TURBOLOAD for tapes
        ;;    Typed-in and slightly modified
        ;;    by Devilmarkus
        ;;    Found in "Amstrad Personal" no. 09
        ;;    Original author: Pedro M. Cuenca
        ;;    To SAVE a file to tape:
        ;;    |TURBOSAVE,<start>,<length>
        ;;    To LOAD a file from tape:
        ;;    |TURBOLOAD,<start>,<length>

color2    equ 85
color1    equ 80

org        &8000

        ld        bc, table
        ld        hl, space
        jp        &bcd1

table:
        defw        name
        JP        rsave
        JP        rload

name:
        db        "TURBOSAV","E"+&80
        db        "TURBOLOA","D"+&80
        db        0

space:
        defs        4

rsave:
        cp        2
        ret        nz
        ld        l,(ix+0)
        ld        h,(ix+1)
        inc        hl
        ld        (length),hl
        ld        l,(ix+2)
        ld        h,(ix+3)
        ld        (address),hl
        jp        saveroutine

rload:
        cp        2
        ret        nz
        ld        l,(ix+0)
        ld        h,(ix+1)
        ;inc        hl
        ld        (length),hl
        ld        l,(ix+2)
        ld        h,(ix+3)
        ld        (address),hl
        jp        loadroutine

saveroutine:
        di
        ex        af,af'
        push        af
        ex        af,af'
        exx
        push        bc
        ld        bc,&f610
        out        (c),c
        exx
        ld        b,3

retar:
        ld        hl, 0

buc1:
        dec        hl
        ld        a,h
        or        l
        jr        nz,buc1
        djnz        retar
        ld        bc,&7f10
        ld        a,color2
        out        (c),c
        out        (c),a
        call        savecab
        ld        hl,(address)
        ld        de,(length)
        call        save
        exx
        ld        c,0
        out        (c),c
        pop        bc
        exx
        ex        af,af'
        pop        af
        ex        af,af'
        ei
        ret

save:
        ld        a,(hl)
        call        sbyte
        inc        hl
        dec        de
        ld        a,d
        or        e
        jr        nz,save
        ret

sbyte:
        ld        b,8

sbuc:
        exx
        rra
        jr        c,bit1

bit0:
        ld        hl,100
        ld        (stime1),hl
        ld        (stime2),hl
        jr        sig

bit1:
        ld        hl,25
        ld        (stime1),hl
        ld        (stime2),hl
        jr        sig

sig:
        ex        af,af'
        ld        a,%00110000
        out        (c),a
        ld        a,&10
        out        (&7f),a
        ld        a,color1
        out        (&7f),a
        defb        &21

stime1:
        defw        0

        reto1:
        dec        hl
        ld        a,h
        or        l
        jr        nz, reto1
        ld        a,%00010000
        out        (c),a
        ld        a,&10
        out        (&7f),a
        ld        a,color2
        out        (&7f),a
        defb        &21

stime2:
        defw        0

        reto2:
        dec        hl
        ld        a,h
        or        l
        jr        nz, reto2
        ex        af,af'
        exx
        djnz        sbuc
        ret

savecab:
        ld        b,128
cabuc:
        push        bc
        ld        a, &aa
        call        sbyte
        pop        bc
        djnz        cabuc
        ld        b,1
        exx
        jp        bit0
        ret

loadroutine:
        di
        ex        af,af'
        push        af
        ex        af,af'
        exx
        push        bc
        ld        bc,&f610
        out        (c),c
        ld        b,&f5
        exx

fallo:
        ld        b,3
        retarl
        ld        hl,0
buc1l:
        dec        hl
        ld        a,h
        or        l
        jr        nz, buc1l
        djnz        retarl
        ld        bc,&7f10
        ld        a,color2
        out        (c),c
        out        (c),a
        call        loadcab
        ld        hl,(address)
        ld        de,(length)
        call        load
        jr        c,fallo
        exx
        ld        bc, &f600
        out        (c),c
        pop        bc
        exx
        ex        af,af'
        pop        af
        ex        af,af'
        ei
        ret

loadcab:
        ld        b,128

loopcab:
        call        lbyte
        jr        c, loadcab
        cp        &aa
        jr        nz,loadcab
        djnz        loopcab
        call        w_bajo
        jp        w_alto

load:
        call        lbyte
        ret        c
        ld        (hl),a
        inc        hl
        dec        de
        ld        a,d
        or        e
        jr        nz,load
        ret

lbyte:
        push        bc
        ld        b,8

lbuc:
        ex        af,af'
        call        w_bajo
        jr        c,error
        call        w_alto
        jr        c,error
        ld        a,(talto)
        cp        40
        jr        c,es1

es0:
        ld        a,(tbajo)
        cp        40
        jr        c,error
        ex        af,af'
        or        a
        jr        salida

es1:
        ld        a,(tbajo)
        cp        40
        jr        nc, error
        ex        af,af'
        scf

salida:
        rra
        djnz        lbuc
        or        a
        pop        bc
        ret

error:
        ex        af,af'
        scf
        pop        bc
        ret

w_bajo:
        ld        a,&10
        out        (&7f),a
        ld        a,color2
        out        (&7f),a
        exx
        ld        hl, talto
        ld        (hl),1
bucalto:
        in        a,(c)
        rla
        jr        c,s1
        inc        (hl)
        jr        z,n0
        jr        bucalto

w_alto:
        ld        a,&10
        out        (&7f),a
        ld        a,color1
        out        (&7f),a
        exx
        ld        hl, tbajo
        ld        (hl),1

bucbajo:
        in        a,(c)
        rla
        jr        nc, s1
        inc        (hl)
        jr        z, n0
        jr        bucbajo

s1:
        or        a
        exx
        ret

n0:
        scf
        exx
        ret

address:        defs 2
length:        defs 2
talto:        defs 1
tbajo:        defs 1


For the non-ASM coders (BASIC only):
10 AD=&8000:L=&01C7
20 READ a:POKE AD+P,a
30 P=P+1:IF P=L THEN END
40 GOTO 20
50 DATA &01,&09,&80,&21,&24,&80,&C3,&D1,&BC,&11,&80,&C3,&28,&80,&C3,&41
60 DATA &80,&54,&55,&52,&42,&4F,&53,&41,&56,&C5,&54,&55,&52,&42,&4F,&4C
70 DATA &4F,&41,&C4,&00,&00,&00,&00,&00,&FE,&02,&C0,&DD,&6E,&00,&DD,&66
80 DATA &01,&23,&22,&C3,&81,&DD,&6E,&02,&DD,&66,&03,&22,&C1,&81,&C3,&59
90 DATA &80,&FE,&02,&C0,&DD,&6E,&00,&DD,&66,&01,&22,&C3,&81,&DD,&6E,&02
100 DATA &DD,&66,&03,&22,&C1,&81,&C3,&FA,&80,&F3,&08,&F5,&08,&D9,&C5,&01
110 DATA &10,&F6,&ED,&49,&D9,&06,&03,&21,&00,&00,&2B,&7C,&B5,&20,&FB,&10
120 DATA &F6,&01,&10,&7F,&3E,&55,&ED,&49,&ED,&79,&CD,&E8,&80,&2A,&C1,&81
130 DATA &ED,&5B,&C3,&81,&CD,&93,&80,&D9,&0E,&00,&ED,&49,&C1,&D9,&08,&F1
140 DATA &08,&FB,&C9,&7E,&CD,&9E,&80,&23,&1B,&7A,&B3,&20,&F6,&C9,&06,&08
150 DATA &D9,&1F,&38,&0B,&21,&64,&00,&22,&C8,&80,&22,&DC,&80,&18,&0B,&21
160 DATA &19,&00,&22,&C8,&80,&22,&DC,&80,&18,&00,&08,&3E,&30,&ED,&79,&3E
170 DATA &10,&D3,&7F,&3E,&50,&D3,&7F,&21,&00,&00,&2B,&7C,&B5,&20,&FB,&3E
180 DATA &10,&ED,&79,&3E,&10,&D3,&7F,&3E,&55,&D3,&7F,&21,&00,&00,&2B,&7C
190 DATA &B5,&20,&FB,&08,&D9,&10,&B9,&C9,&06,&80,&C5,&3E,&AA,&CD,&9E,&80
200 DATA &C1,&10,&F7,&06,&01,&D9,&C3,&A4,&80,&C9,&F3,&08,&F5,&08,&D9,&C5
210 DATA &01,&10,&F6,&ED,&49,&06,&F5,&D9,&06,&03,&21,&00,&00,&2B,&7C,&B5
220 DATA &20,&FB,&10,&F6,&01,&10,&7F,&3E,&55,&ED,&49,&ED,&79,&CD,&39,&81
230 DATA &2A,&C1,&81,&ED,&5B,&C3,&81,&CD,&4C,&81,&38,&DC,&D9,&01,&00,&F6
240 DATA &ED,&49,&C1,&D9,&08,&F1,&08,&FB,&C9,&06,&80,&CD,&58,&81,&38,&F9
250 DATA &FE,&AA,&20,&F5,&10,&F5,&CD,&8B,&81,&C3,&A3,&81,&CD,&58,&81,&D8
260 DATA &77,&23,&1B,&7A,&B3,&20,&F5,&C9,&C5,&06,&08,&08,&CD,&8B,&81,&38
270 DATA &26,&CD,&A3,&81,&38,&21,&3A,&C5,&81,&FE,&28,&38,&0B,&3A,&C6,&81
280 DATA &FE,&28,&38,&13,&08,&B7,&18,&09,&3A,&C6,&81,&FE,&28,&30,&08,&08
290 DATA &37,&1F,&10,&D7,&B7,&C1,&C9,&08,&37,&C1,&C9,&3E,&10,&D3,&7F,&3E
300 DATA &55,&D3,&7F,&D9,&21,&C5,&81,&36,&01,&ED,&78,&17,&38,&1D,&34,&28
310 DATA &1D,&18,&F6,&3E,&10,&D3,&7F,&3E,&50,&D3,&7F,&D9,&21,&C6,&81,&36
320 DATA &01,&ED,&78,&17,&30,&05,&34,&28,&05,&18,&F6,&B7,&D9,&C9,&37,&D9
330 DATA &C9,&00,&00,&00,&00,&00,&00


Have fun with it!

Attachment: Original listing. Thanks to SyX for sharing it!
Title: Re: ASM source code
Post by: arnoldemu on 22:49, 06 January 14
New Asm examples:

Showing different ways to handle the cpc's interrupts in interrupt mode 1. These show how to hit the hardware directly.

http://www.cpctech.org.uk/source/hwint.asm (http://www.cpctech.org.uk/source/hwint.asm)
http://www.cpctech.org.uk/source/hwint2.asm (http://www.cpctech.org.uk/source/hwint2.asm)
http://www.cpctech.org.uk/source/hwint3.asm (http://www.cpctech.org.uk/source/hwint3.asm)
http://www.cpctech.org.uk/source/hwint4.asm (http://www.cpctech.org.uk/source/hwint4.asm)
http://www.cpctech.org.uk/source/hwint5.asm (http://www.cpctech.org.uk/source/hwint5.asm)
http://www.cpctech.org.uk/source/hwintdelay.asm (http://www.cpctech.org.uk/source/hwintdelay.asm)

Title: Re: ASM source code
Post by: AMSDOS on 09:19, 07 January 14
Quote from: arnoldemu on 09:46, 30 August 13
I think now I have shown the methods to draw sprites on a cpc:

I have covered:
- preshifted sprites
- compiled sprites
- compressed sprites
- masked sprites
- xor sprites
- "mode 3 sprites"/bitplanes sprites. (I think I did an example of this???) hmmm.. not sure now ;)

I haven't show enough  methods for erasing sprites yet.
So far shown:
- storing background to restore it back
- using XOR to redraw the sprite to erase it in addition to drawing it.

Not directly relating to Sprites, though I noticed the article on Collision Detection (http://www.cpctech.org.uk/docs/colldet.html) looks in need of a tune up. ACU had an article on this in it's early days along with example, though the example (as lengthy as it is), relies on using the character set in conjunction with it's graphical position, I'm not sure how difficult it would be to upgrade it to graphical sprite for the collision detection.
Title: Re: ASM source code
Post by: arnoldemu on 10:02, 07 January 14
Quote from: AMSDOS on 09:19, 07 January 14
Not directly relating to Sprites, though I noticed the article on Collision Detection (http://www.cpctech.org.uk/docs/colldet.html) looks in need of a tune up. ACU had an article on this in it's early days along with example, though the example (as lengthy as it is), relies on using the character set in conjunction with it's graphical position, I'm not sure how difficult it would be to upgrade it to graphical sprite for the collision detection.
I used exact collision on Balloonacy using a mask.

I do plan to write up box based collision which is most commonly used. LOL, I laughed when I read that link of mine.

Busy with other projects for the moment.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 10:56, 13 January 14
Quote from: arnoldemu on 10:02, 07 January 14
I used exact collision on Balloonacy using a mask.

I do plan to write up box based collision which is most commonly used. LOL, I laughed when I read that link of mine.

Busy with other projects for the moment.

I'm having a look at the bits and pieces I've made for putting together for a game, though I'm having issues with the collision detection. For the main character I'm using a routine to draw a triangular shape on screen using a series of Lines and wasn't sure if a test for colour check would be sufficient enough to provide an accurate collision detection given the angled nature of the character doesn't have square edges facing what it needs to attack.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 10:56, 03 May 14
Quote from: Jonah (Tasteful Mr) Ship on 13:23, 10 June 13
Tenuously linked post ahead!

If you're interested, here's the horizontal star-scroller from the XOR cracktros...
Just assmeble in WinAPE/Maxam and CALL &A000 to see what it does. If you're using WinAPE, then it's best to keep the boot-screen up, so you can see that it doesn't affect the text on screen while it runs.

For better results, try changing the background colours to #00 (BLACK) and inks 1 & 3 to #26 (BRIGHT WHITE) and 13 (WHITE) respectively. It gives a slight impression of a star-trail as it moves across the screen.


org #a000

.inflp    call stars
    jp inflp

.stars    ld de,#0000
    ld hl,here2
    ld b,25
.loop1    ld a,(hl)
    ld e,a
    inc hl
    ld a,(hl)
    ld d,a
    dec hl
    ld a,(de)
    cp #fe
    jr nz,jump1
    xor a
    ld (de),a
.jump1    inc de
    ld a,d
    cp #00
    jr nz,jump2
    push hl
    ld hl,#c000
    add hl,de
    ex de,hl
    pop hl
.jump2    ld a,(de)
    cp #00
    jr nz,jump3
    ld a,#fe
    ld (de),a
.jump3    ld a,e
    ld (hl),a
    inc hl
    ld a,d
    ld (hl),a
    inc hl
    djnz loop1

    ld hl,here3
    ld b,25
.loop2    ld a,(hl)
    ld e,a
    inc hl
    ld a,(hl)
    ld d,a
    dec hl
    ld a,(de)
    cp #fe
    jr nz,jump4
    xor a
    ld (de),a
.jump4    inc de
    inc de
    ld a,d
    cp #00
    jr nz,jump5
    push hl
    ld hl,#c000
    add hl,de
    ex de,hl
    pop hl
.jump5    ld a,(de)
    cp #00
    jr nz,jump6
    ld a,#fe
    ld (de),a
.jump6    ld a,e
    ld (hl),a
    inc hl
    ld a,d
    ld (hl),a
    inc hl
    djnz loop2

    call #bd19
    ret

.here2
db #00,#c0,#55,#c0,#c0,#c0,#f4,#c0
db #68,#c1,#a9,#c1,#20,#c2,#55,#c2
db #82,#c2,#e0,#c2,#4a,#c3,#a0,#c3
db #d9,#c3,#49,#c4,#a0,#c4,#d9,#c4
db #48,#c5,#65,#c5,#c6,#c5,#fa,#c5
db #85,#c6,#d5,#c6,#20,#c7,#49,#c7
db #a0,#c7

.here3
db #30,#d0,#90,#d8,#a0,#f0,#10,#d1
db #7a,#e1,#a0,#e9,#00,#ca,#30,#d2
db #b0,#e2,#e0,#ea,#50,#d3,#75,#db
db #e0,#f3,#20,#d4,#a0,#cc,#e9,#dc
db #0a,#ed,#65,#dd,#a9,#d5,#15,#f6
db #85,#ee,#a5,#ee,#ff,#ce,#4a,#e7
db #b0,#ef


(P.S. The code isn't originally mine, so I'm not trying to steal the glory here or anything!)


This is pretty much the kind of thing I want to eventually implement in the other thread I made which deals with 16 bit numbers, though this approach seems more simplified compared to what I'm trying to do in the other thread.
I cut this program down by removing the second loop that points to here3 which gives me something closer to what I'm looking for, though the stars move left->right across the screen and I'm after right->left instead. I was able to do that by changing the inc de to dec de at the loop1 label, though the program only goes so far and then it crashes, looks like the program is writing to sensitive memory locations.
It looks like this routine is designed to simply move pixels across an entire screen, I was thinking of implementing different size playing fields which made become an issue for this, otherwise would anyone know what's happening with this routine?  :'(
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Xifos on 18:19, 03 May 14
Hi,

:)

if you look at that :

inc de
ld a,d
cp #0
jr nz,jump2

The test is on de=&0000 (when reaching the end of video memory (&C000 to &FFFF), so &FFFF+1.
If you change to dec de to have stars going the other direction, it cannot work anymore.
You should check if de=&BFFF (d=&BF), and set it to FFFF, maybe...
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: TFM on 00:37, 04 May 14
Quote from: Xifos on 18:19, 03 May 14inc deld a,dcp #0jr nz,jump2



inc de
ld a,d
or a,a
jr nz,jump2



Makes it 1 us more quick :)
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Executioner on 12:54, 04 May 14
Quote from: Xifos on 18:19, 03 May 14
if you look at that :

inc de
ld a,d
cp #0
jr nz,jump2

The test is on de=&0000 (when reaching the end of video memory (&C000 to &FFFF), so &FFFF+1.
If you change to dec de to have stars going the other direction, it cannot work anymore.
You should check if de=&BFFF (d=&BF), and set it to FFFF, maybe...

Except that doesn't check DE for 0, only D. To check DE for 0, simply change to:

dec de
ld a,d
or e
jr nz,jump2

If you want to check when DE goes to #FFFF, use:

ld a,d
or e
dec de
jr nz,jump2
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Xifos on 16:51, 04 May 14
Sorry, i did not make it clear, i was refering to the stars routine AMSDOS was wondering about...
This routine plots stars by setting bytes into video memory, increasing addresses, and testing when addresses go to &FFFF+1 (0) to set them to &c000.
AMSDOS changed it to decrease addresses (but it went crashing), so the test has to be done on DE going to &BFFF...
And the routine he posted is only testing D rather than DE...
;)
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Executioner on 06:37, 05 May 14
Quote from: Xifos on 16:51, 04 May 14
so the test has to be done on DE going to &BFFF...

Sorry, my mistake. The test for zero works only if you're incrementing past #ffff. ie. D becomes 0 next.

To test going the other way, simply use:

dec de
bit 6,d
jr nz,jump2

(ie. DE goes from #c000 to #bfff, this is the point when D drops below %11000000 to %10111111, all other high memory screen addresses have bit 6 set).
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 01:11, 07 May 14
Thanks for the antidotes guys  :)  The end result appears to be the same, though it's good to see some refined code.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 14:51, 24 May 14
New example code:

http://www.cpctech.org.uk/source/backbuff.asm (http://www.cpctech.org.uk/source/backbuff.asm)

&4000-&7fff contains a copy of the screen from &c000-&ffff but without the sprites.
This shows how you can erase sprites using this back buffer.

another way to erase sprites.

http://www.cpctech.org.uk/source/scrlchk.asm (http://www.cpctech.org.uk/source/scrlchk.asm)

This example performs continuous chunky scroll using hardware. If we had a pixel by pixel scroll it would run at a rate of 1 pixel per frame in mode 1, but because we don't on cpc, it delays for 8 frames then scrolls.

In addition it shows how to convert from our sprite coordinates to a screen address on a hardware scrolling screen, and the draws a striped rectangle for a sprite. Also, it highlights the problem area in red so you can see where it is and how it moves with a horizontal scroll.

http://www.cpctech.org.uk/source/scrlvrt.asm (http://www.cpctech.org.uk/source/scrlvrt.asm)

Smoother vertical hardware scrolling using R5 of the CRTC but without rupture/splitting. Same method used in Legend of Kage.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 17:21, 24 May 14
New example code:

http://www.cpctech.org.uk/source/scrlv1.asm (http://www.cpctech.org.uk/source/scrlv1.asm)

This shows how to avoid the problem area when hardware vertical scrolling. The problem area is highlighted. A screen width of 32 is chosen because &400/32 gives no remainder. See how the problem area remains on the right side of the screen.

Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 18:21, 24 May 14
New example code

http://www.cpctech.org.uk/source/scrlh1.asm (http://www.cpctech.org.uk/source/scrlh1.asm)

This example shows how to avoid the problem area when scrolling horizontally.

For a screen of width 40, and if we want to scroll 3 screens in width, then the maximum height the screen can be is 22
lines.

We must choose our screen dimensions carefully to both have horizontal scrolling AND to avoid the problem area. in addition the scroll can't be continuous there is a minimum and maximum range.

This method is used by Action Force.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 16:23, 25 May 14
New example code:

http://www.cpctech.org.uk/source/scrltile.asm (http://www.cpctech.org.uk/source/scrltile.asm)

This example shows how to scroll a tile map horizontally.

The scroll is in a single direction and continuous.

It is meant to be simple so you can see how to setup a tile map, setup the tiles, how the tile map is queried for the tiles, how the tiles are drawn.

Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 23:00, 31 May 14
Quote from: arnoldemu on 16:23, 25 May 14
New example code:

http://www.cpctech.org.uk/source/scrltile.asm (http://www.cpctech.org.uk/source/scrltile.asm)

This example shows how to scroll a tile map horizontally.

The scroll is in a single direction and continuous.

It is meant to be simple so you can see how to setup a tile map, setup the tiles, how the tile map is queried for the tiles, how the tiles are drawn.


This code seems to be a bit beyond me and the Winape Assembler.  :(
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: arnoldemu on 09:13, 01 June 14
Quote from: AMSDOS on 23:00, 31 May 14

This code seems to be a bit beyond me and the Winape Assembler.  :(
I use pasmo assembler. Build using amsdos command line option and put into a dsk file. Or use binary and load into winape debugger and call from basic.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 10:00, 01 June 14
Quote from: arnoldemu on 09:13, 01 June 14
I use pasmo assembler. Build using amsdos command line option and put into a dsk file. Or use binary and load into winape debugger and call from basic.


Ok I see that Assembler is included with the CPC BASIC 3 distribution.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 10:27, 31 January 15
I've been having a look at this routine for running BASIC programs through Assembly:


http://cpctech.cpc-live.com/source/runbas.asm (http://cpctech.cpc-live.com/source/runbas.asm)


but I'm unable to get it to work, even with the address for KL ROM SELECT. Probably because I didn't have the variables setup.


Questions:


1) Could it be made to work in Winape Assembler?


2) Could a BASIC program be included with it? Something with Variables (not 10 PRINT"HELLO WORLD", 20 GOTO 10), doesn't have to be big.


3) I was looking at a 12Kb BASIC Game, but was studying what those Addresses did in Memory, not sure if it's recommended due to the nature of the program?


4) I though this method could be used to load a BASIC program using Headerless loader and then execute this using this method, but only really makes sense to apply it for a larger program. Any thoughts?
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 15:52, 24 March 18
Hi @AMSDOS (http://www.cpcwiki.eu/forum/index.php?action=profile;u=330)

This question has been a long time, but if you want I can try to help you.
Send me that basic program and we take a look, if you still need to solve the problem.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 23:23, 24 March 18
Hi @Urusergi (http://www.cpcwiki.eu/forum/index.php?action=profile;u=923)

Unfortunately I'm unable to remember what that BASIC program was, had a feeling it might of been a program which had BASIC code as well as a binary file, but I don't know that for sure. Back in 2015 I was typing in a few large programs from various magazines like Your Computer. I checked out programs which I might have considered for it, but they weren't 12kb. The only thing I could think of which came close is the early AMSOFT game Quack-A-Jack, which has a 12kb binary file & 14kb BASIC file.

It maybe better though to use one of my BASIC programs, rather than invite trouble. At the moment I've been working on this program (http://www.cpcwiki.eu/forum/general-discussion/not-been-here-long/msg157930/#msg157930), and made some progress with it yesterday after adding enemy tank (with the help I had from an AA Type-in), I also improved the shooting sequence, so the tanks can move after shots have been fired. I probably might just add some colourful sprites to the program before handing it to you if you wanted to test that.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 00:41, 25 March 18
Quote from: AMSDOS on 10:27, 31 January 15
4) I though this method could be used to load a BASIC program using Headerless loader and then execute this using this method, but only really makes sense to apply it for a larger program. Any thoughts
Do you know "2cdt" x86 program?. I think that is what you need. You can create 2 unique blocks whatever the size of the basic game. The first block can be as small as 1 byte, and the second with the rest of bytes (and you can adjust the speed too). Obviously the biggest problem is when you get a "read error b" and you have to start charging again from the beginning  :doh:

Quote from: AMSDOS on 23:23, 24 March 18
I probably might just add some colourful sprites to the program before handing it to you if you wanted to test that.
Ok, pass it to me when you finish ;)
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 11:12, 25 March 18
Quote from: Urusergi on 00:41, 25 March 18
Do you know "2cdt" x86 program?. I think that is what you need. You can create 2 unique blocks whatever the size of the basic game. The first block can be as small as 1 byte, and the second with the rest of bytes (and you can adjust the speed too). Obviously the biggest problem is when you get a "read error b" and you have to start charging again from the beginning  :doh: 


It's not a problem producing a Headerless file with 2cdt, but I thought the problem is loading a headerless file over another BASIC program which is trying to load it, hence write Assembly program to load file from another location, then use Assembly routine to run the BASIC program.


Quote
Ok, pass it to me when you finish ;)


Are you sure? Winking emoji usually means do the opposite.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 16:39, 25 March 18
Quote from: AMSDOS on 11:12, 25 March 18It's not a problem producing a Headerless file with 2cdt, but I thought the problem is loading a headerless file over another BASIC program which is trying to load it, hence write Assembly program to load file from another location, then use Assembly routine to run the BASIC program.
No, I mean create 2 turbo blocks with header that are still firmware compatible. It's almost as fast as a headerless file and can be executed with run ""

Quote from: AMSDOS on 11:12, 25 March 18Are you sure? Winking emoji usually means do the opposite.
??? At least in my country I think it means that I am willing to help or I agree to help you. Let's see if other Spaniards corroborate me or I'm wrong.
In this forum I've always helped in everything I could, maybe that's the reason I 've more likes than posts.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: adolfo.pa on 20:21, 25 March 18
Quote from: Urusergi on 16:39, 25 March 18
??? At least in my country I think it means that I am willing to help or I agree to help you. Let's see if other Spaniards corroborate me or I'm wrong.

Sorry @Urusergi (http://www.cpcwiki.eu/forum/index.php?action=profile;u=923) , I think you're wrong about the emoji  :) Northern spaniard here, and I've always used it as a "just joking" indicator.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 21:19, 25 March 18
Quote from: adolfo.pa on 20:21, 25 March 18
Sorry @Urusergi (http://www.cpcwiki.eu/forum/index.php?action=profile;u=923) , I think you're wrong about the emoji  :) Northern spaniard here, and I've always used it as a "just joking" indicator.

Then I'm going to have to erase a few thousand of smiles that I put in ~15 years that I've been writing in forums and, interestingly, nobody told me anything about my mistake (in fact, they always reacted positively).

For example, someone sends me this message recently:
"Is it possible to have a version without the crosshair fix, we will have the option of on or off then.  ;) "

What should I understand? Is it a joke? and he doesn't really want me to do that version?
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: adolfo.pa on 22:24, 25 March 18
Quote from: Urusergi on 21:19, 25 March 18
Then I'm going to have to erase a few thousand of smiles that I put in ~15 years that I've been writing in forums and, interestingly, nobody told me anything about my mistake (in fact, they always reacted positively).

For example, someone sends me this message recently:
"Is it possible to have a version without the crosshair fix, we will have the option of on or off then.  ;) "

What should I understand? Is it a joke? and he doesn't really want me to do that version?

It is definitely a friendly emoji, so it is natural for people to react to it in a positive way. Also, most of the time the meaning will be obvious given the context; in your response it is pretty clear you used it with the meaning of a regular smiley (friendlyness).

I use it to make sure people know I'm joking. For example, the other day I posted this as a response to Duke:
QuotePlease stop making so many cool stuff! You make the rest of us look like lazy couch potatos (which we aren't, of course  ;) )

If you remove the wink smiley the meaning changes quite a lot  :)

Not exactly an authoritative source of information, but here is the entry in the Emojipedia (https://emojipedia.org/winking-face/).
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 23:03, 25 March 18
@adolfo.pa (http://www.cpcwiki.eu/forum/index.php?action=profile;u=2309) I think you're not understanding the approach.

AMSDOS thinks I'm not going to help him with the problem if I tell him in this way:
"Ok, pass it to me when you finish  ;) "

Recently someone (foreign) asked me for help in this way:
"Is it possible to have a version without the crosshair fix, we will have the option of on or off then.  (http://www.cpcwiki.eu/forum/Smileys/SoLoSMiLeYS1/wink.gif) "

Of course I made that version he asked me and I didn't think he was kidding

That's why I think that depending on the country we may understand the emoticons in different ways.

What do you think in this case?
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 23:24, 25 March 18
@AMSDOS (http://www.cpcwiki.eu/forum/index.php?action=profile;u=330) as you haven't finished your game yet, I've created two examples with a spanish game (Star Sordium):

- Original is 10 Blocks at 2000 baud and loads in 2 minutes and 11 seconds.

- 2 Blocks at 2000 baud loads in 1 minute and 23 seconds.

- 2 Blocks at 2500 baud loads in 1 minute and 6 seconds.


look at the attachments (here I used to put a wink emoticon, but better not)
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: adolfo.pa on 23:33, 25 March 18
Quote from: Urusergi on 23:03, 25 March 18
What do you think in this case?

Well, I think you're giving too much importance to this  ;)

I don't think there's any country specific thing going on here, and AFAIK, the meaning of the winky smiley is the same on all western/european countries. In my job I chat regularly with people from western europe, USA, and Brazil, and all of them seem to use it in that sense. Proof of that is that I haven't been fired yet :D

Cheers!
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 23:47, 25 March 18
Quote from: adolfo.pa on 23:33, 25 March 18
Well, I think you're giving too much importance to this  ;)
I don't give importance, it's just curiosity but I see that you don't want to answer (Lo entiendo  ;) )

Let's leave it that way....
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: adolfo.pa on 23:55, 25 March 18
Quote from: Urusergi on 23:47, 25 March 18
I don't give importance, it's just curiosity but I see that you don't want to answer (Lo entiendo  ;) )

Now I'm confused, because I though I had answered you  ???

Anyway, this is waaay off-topic, so yep, let's forget about it.

Cheers!
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 09:45, 26 March 18
Quote from: Urusergi on 16:39, 25 March 18
No, I mean create 2 turbo blocks with header that are still firmware compatible. It's almost as fast as a headerless file and can be executed with run ""


I'm familiar with that approach as I used to do that with all my AMSOFT games with JL-Copy, but that's not taking my BASIC program and using and Assembly routine to execute that BASIC from Assembly. I think the size of my BASIC code and number of variables it uses throws me in the deep end when it comes to that routine, I think it just needs a short program with a couple of variables just to show it's function properly, but as it is I'm having trouble following it.


Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 15:22, 26 March 18
Ok, I see that you want to use exclusively the machine code routine for load, and then run the basic file.

Tonight I'll try with a little example.

Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 09:01, 27 March 18
It doesn't have to load, but I would like to see it in an Assembler format with the BASIC embedded in as defb statements. I think something simple like this should be fine:


10 a%=1000
20 b%=256
30 PRINT a%+b%
40 PRINT"8)"
50 END



Thanks
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 16:24, 27 March 18
Sorry but I've already created a headerless file with my prime number generator in basic.

Machine code:

kl_rom_select equ &B90F

org &A000

ld hl,&0170  ; load basic start
ld de,&00E9 ; basic length
ld a,&16  ; sync file char
call &bca1

ld hl,(length)
ld c,0
call kl_rom_select
ld a,(&c002)
cp 0
jp z,cpc464
ld (&ae66),hl
ld (&ae68),hl
ld (&ae6a),hl
ld (&ae6c),hl
cp 1
jp z,cpc664
jp &ea78        ;; run BASIC CPC6128
.cpc664
jp &ea7d        ;; run BASIC CPC664
.cpc464
ld (&ae83),hl
ld (&ae85),hl
ld (&ae87),hl
ld (&ae89),hl
jp &e9bd        ;; run BASIC CPC464


length dw &025A ; Address of start of variables (&AE66-67 in cpc6128-664, &AE83-84 in cpc464)


If you don't understand something, don't hesitate to ask me, but I think it's pretty simple to follow.


Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 21:10, 27 March 18
@AMSDOS (http://www.cpcwiki.eu/forum/index.php?action=profile;u=330) Here is your Basic example  8)

kl_rom_select equ &B90F

ORG &A000

LD HL,Data
LD DE,&0170  ; Basic start
LD BC,EndData-Data
LDIR

ld hl,(length)
ld c,0
call kl_rom_select
ld a,(&c002)
cp 0
jp z,cpc464
ld (&ae66),hl
ld (&ae68),hl
ld (&ae6a),hl
ld (&ae6c),hl
cp 1
jp z,cpc664
jp &ea78        ;; run BASIC CPC6128
.cpc664
jp &ea7d        ;; run BASIC CPC664
.cpc464
ld (&ae83),hl
ld (&ae85),hl
ld (&ae87),hl
ld (&ae89),hl
jp &e9bd        ;; run BASIC CPC464


;PRINT HEX$(PEEK(&AE67))
;PRINT HEX$(PEEK(&AE66))
length dw &01AC ; Address of start of variables (&AE66-67 in cpc6128-664, &AE83-84 in cpc464)

.Data
DB &0D,&00,&0A,&00,&02,&00,&00,&E1
DB &EF,&1A,&E8,&03,&00,&0D,&00,&14
DB &00,&02,&00,&00,&E2,&EF,&1A,&00
DB &01,&00,&10,&00,&1E,&00,&BF,&20
DB &02,&00,&00,&E1,&F4,&02,&00,&00
DB &E2,&00,&0A,&00,&28,&00,&BF,&22
DB &38,&29,&22,&00,&06,&00,&32,&00
DB &98,&00,&00,&00
.EndData
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: ikonsgr on 09:39, 01 July 18
You might want to add this code (http://www.cpcwiki.eu/forum/programming/how-to-readwrite-a-file-'byte-by-byte'-using-firmware-but-much-faster!/msg162099/#msg162099) to Source codes too.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: AMSDOS on 08:38, 07 July 18
Quote from: ikonsgr on 09:39, 01 July 18
You might want to add this code (http://www.cpcwiki.eu/forum/programming/how-to-readwrite-a-file-'byte-by-byte'-using-firmware-but-much-faster!/msg162099/#msg162099) to Source codes too.


I've added a page (http://www.cpcwiki.eu/index.php/Programming:Read/Write_a_file_quickly_byte-by-byte), please inspect it though. Registration to the CPCWiki is seperate from the forum, so feel free to register and amend where necessary.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: ikonsgr on 08:55, 07 July 18
Ok, thanks!
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: issalig on 15:58, 08 June 21
Hi  @Urusergi (https://www.cpcwiki.eu/forum/index.php?action=profile;u=923) , I have a question about the code, why 170+code_size is copied 4 times?

Quote from: Urusergi on 21:10, 27 March 18@AMSDOS (http://www.cpcwiki.eu/forum/index.php?action=profile;u=330) Here is your Basic example  8)

kl_rom_select equ &B90F

ORG &A000

LD HL,Data
LD DE,&0170  ; Basic start
LD BC,EndData-Data
LDIR

ld hl,(length)
ld c,0
call kl_rom_select
ld a,(&c002)
cp 0
jp z,cpc464
ld (&ae66),hl
ld (&ae68),hl
ld (&ae6a),hl
ld (&ae6c),hl
cp 1
jp z,cpc664
jp &ea78        ;; run BASIC CPC6128
.cpc664
jp &ea7d        ;; run BASIC CPC664
.cpc464
ld (&ae83),hl
ld (&ae85),hl
ld (&ae87),hl
ld (&ae89),hl
jp &e9bd        ;; run BASIC CPC464


;PRINT HEX$(PEEK(&AE67))
;PRINT HEX$(PEEK(&AE66))
length dw &01AC ; Address of start of variables (&AE66-67 in cpc6128-664, &AE83-84 in cpc464)

.Data
DB &0D,&00,&0A,&00,&02,&00,&00,&E1
DB &EF,&1A,&E8,&03,&00,&0D,&00,&14
DB &00,&02,&00,&00,&E2,&EF,&1A,&00
DB &01,&00,&10,&00,&1E,&00,&BF,&20
DB &02,&00,&00,&E1,&F4,&02,&00,&00
DB &E2,&00,&0A,&00,&28,&00,&BF,&22
DB &38,&29,&22,&00,&06,&00,&32,&00
DB &98,&00,&00,&00
.EndData

Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: Urusergi on 23:22, 08 June 21
Quote from: issalig on 15:58, 08 June 21
Hi  @Urusergi (https://www.cpcwiki.eu/forum/index.php?action=profile;u=923) , I have a question about the code, why 170+code_size is copied 4 times?


Hi, those four memory locations must have the same data. You can find out what they mean in this web page:

http://www.cantrell.org.uk/david/tech/cpc/cpc-firmware/mem-use.htm


Look at &AE66, &AE68, &AE6A, &AE6C



Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: NicolasCanadea on 11:51, 28 August 22
Hello, i'm learning about assembler z80. First i created a asm code with CPCTelera. When i read the default code i see for example the lines :

.area _DATA
----
---
.area _CODE

what mean these? for example i imagine _DATA is a macro define. DATA and CODE are areas of data programme (256bytes) and CODE is code programme. But the compiler start with $4000 address, how set this address? 
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: asertus on 15:42, 28 August 22
Quote from: NicolasCanadea on 11:51, 28 August 22Hello, i'm learning about assembler z80. First i created a asm code with CPCTelera. When i read the default code i see for example the lines :

.area _DATA
----
---
.area _CODE

what mean these? for example i imagine _DATA is a macro define. DATA and CODE are areas of data programme (256bytes) and CODE is code programme. But the compiler start with $4000 address, how set this address?

Actually those areas are required due to the assembler version that it uses.

You may write everything after your .area _CODE line.

In cpctelera, there is a configuration file for make,

./cfg/build_config.mk and there you can find that configuration,

# Name of the project (without spaces, as it will be used as filename)
#   and Z80 memory location where code will start in the generated binary
PROJNAME   := menace
Z80CODELOC := 0x4000

there you have default code location. You may update it if required.







Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: reidrac on 15:54, 28 August 22
I would give a go to a different assembler.

CPCTelera uses the SDCC compiler suite that comes with an assembler that is powerful but has a few weird things in its syntax. On top of that, it uses a linker, and that's where the code and data sections kick in.

Is not impossible, but if you aren't using C, it adds a lot of complexity that may not play in your favour if you're learning.

Some people use pasmo, rasm, or the winape integrated assembler. IMHO those are better options.
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: funkheld on 17:15, 15 February 24
FutureOS ASM , a nice quick thing :

Use the Q/W/E/S keys to move the "A" over the graphic.
Every time you move the "A" the image is updated very quickly without flickering.
It stops at the edges.

Use the "a" key to exit the program.

greeting

------------------------------------------
ORG &8000

; mode 1
LD  A,(RAMCHAR)
SET 0,A
RES 1,A
LD  (RAMCHAR),A
LD  B,&7F
OUT (C),A

LD IX,LESC
CALL ROM_A2C
                                 
LD  HL,S80X25
CALL ROM_A

LD  BC,&7F10 ;border
OUT (C),C
LD  A,&55   
OUT (C),A   
LD  (BORDER),A  ;border color &40-&5F

LD  BC,&7F00 ;INK 0
OUT (C),C
LD  A,&54     
OUT (C),A
LD  (INK_0),A ;paper color &40-&5F

LD  BC,&7F01 ;INK 1
OUT (C),C
LD  A,&52   
OUT (C),A
LD  (INK_1),A ;INK 1 color &40-&5F

LD  BC,&7F02 ;INK 2
OUT (C),C
LD  A,&4f   
OUT (C),A
LD  (INK_2),A ;INK 2 color &40-&5F

LD  BC,&7F03 ;INK 3
OUT (C),C
LD  A,&4c     
OUT (C),A
LD  (INK_3),A ;INK 3 color &40-&5F

LD A,(REG_PC+1)
ld a,0
LD (MEDIUM),A

;Lade Bild in E-RAM
LD BC,&7fc4 
LD (AKT_RAM),BC
LD  DE,LBI
CALL LABIER

anfang:

schleife:
call H_ALLET
jr z,schleife

ld (hl),a
cp "q"
jp nz,weiter1

ld  a,(TXT+4)
dec a
cp &ff
jr nz,mache
jr gehe

mache:
ld (TXT+4),a
call posxy

gehe:
jp anfang

weiter1:
ld (hl),a
cp "e"
jr nz,weiter2

ld  a,(TXT+4)
inc a
cp 40
jr nz,mache1
jr gehe1

mache1:
ld (TXT+4),a
call posxy

gehe1:
jp anfang

weiter2:
ld (hl),a
cp "w"
jr nz,weiter3

ld  a,(TXT+3)
dec a
cp &ff
jr nz,mache2
jr gehe2

mache2:
ld (TXT+3),a
call posxy

gehe2:
jp anfang

weiter3:
ld (hl),a
cp "s"
jr nz,weiter4

ld  a,(TXT+3)
inc a
cp 25
jr nz,mache3
jr gehe3

mache3:
ld (TXT+3),a
call posxy
jr gehe3

gehe3:
jp anfang

weiter4:
  ld (hl),a
  cp "a"
  jp nz,anfang
  call ende

TXT DB &02,&10, &1F,10,10,"A",&00

LBI DB &00,"BILDF001SCR"
MEDIUM DB &00

ende:
LD HL,TUR_E
JP ROM_D 
ret

posxy:
LD  BC,&7fc4
OUT (C),C
LD  HL,&4000 
LD  DE,&C000 
LD  BC,&4000 
LD  IX,F_MOVE
CALL ROM_A2C 

LD  HL,TXT 
CALL TER_BB
call FRAME
ret

FRAME:
  LD B,&F5
FRA_L
  IN A,(C)
  RRCA     

  JR NC,FRA_L
RET 

LABIER
LD A,&03
LD (REG08_4),A ;Laden in E-RAM

LD HL,&4000
LD (REG16_3),HL ;Ziel-Adresse ist &4000 im E-RAM bei 16 KB Bildern

LD A,(MEDIUM) ;Quell-Medium

LD IX,LADE_N
CALL ROM_A2C ;Lade Bild

INC A
JR NZ,LB_ERR ;A<>&FF --> Fehler beim Laden!

LD BC,&FA7E
LD A,(MO_ST)
OUT (C),A ;Laufwerks-Motoren ausschalten

LD BC,&7FC0
OUT (C),C ;Bank in Main RAM

LD A,&FF
RET ;A = &FF --> Bild wurde erfolgreich geladen!

;Fehler beim Laden
LB_ERR
LD BC,&FA7E
LD A,(MO_ST)
OUT (C),A
LD BC,&7FC0
OUT (C),C
XOR A
RET

;Switch ROM char set on = lower RAM on
romchar:
LD  A,(RAMCHAR) ;actual RAM/ROM state
RES 2,A
LD  (RAMCHAR),A ;set L-RAM on
LD  B,&7F
OUT (C),A
ret

;Switch ROM char set off = lower ROM off
ramchar:
LD  A,(RAMCHAR) ;actual RAM/ROM state
SET 2,A
LD  (RAMCHAR),A ;set L-ROM off
LD  B,&7F
OUT (C),A
ret

H_ALLET EQU &C02F
TER_GB EQU &CDF6
TER_BB EQU &CD4C
TER_GG EQU &CE80
TER_RR EQU &CF2A
AKT_RAM EQU &B84C
F_MOVE EQU &C0C8
LADE_N EQU &FD5C
REG_PC  EQU &B8DA ;RAM
REG08_4 EQU &B8E0
REG16_3 EQU &B8EA
MO_ST  EQU &B97F
STR_BB EQU &CA1C
C_POS  EQU &B848
WATA  EQU &FD38
TUR_E EQU &FE9D
RAMCHAR EQU &B847
LESC EQU &C017
ROM_A2C EQU &FF2A
OSRON_A EQU &FF22
OSRON_B EQU &FF58
OSRON_C EQU &FF8E
OSRON_D EQU &FFD6
ROM_A  EQU &FF00
ROM_C  EQU &FF0C
ROM_D  EQU &FF12
ROM_D2A EQU &FFBA

S64X32 EQU &D5A8
S80X25 EQU &D60E

BORDER EQU &BB91
INK_0  EQU &BB92
INK_1  EQU &BB93
INK_2  EQU &BB94
INK_3  EQU &BB95

TERM_2  EQU &D48C
TERM_2D EQU &D2F7
TERM_2I EQU &D358
TERM_2K EQU &D3C0
TERM_2U EQU &D42
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: GUNHED on 17:38, 16 February 24
Please put it on disc, the picture to be loaded is missing. Also there is a missing letter in the source code: TERM_2U EQU &D42C
Title: Re: Example Z80 assembly programs (was:ASM source code)
Post by: funkheld on 21:00, 16 February 24
This Picture is in the BILDF001.ZIP 1,33kb

"C" is been stolen...

greeting.

Powered by SMFPacks Menu Editor Mod