News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Please help a newbie

Started by litwr, 20:27, 04 January 14

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

litwr

I worked with Amstrad CPC 6128 at 1988-89.  Later I used PCW8256 and finally (1991) PCW9512.  I want to convert a program from 8-bit Commodore to CPC 6128.  It is assembler level conversion.  I have problem with understanding of CPC hardware.  It is easy to use several screen modes with Commodore but it is very difficult or even impossible for CPC.  :(   I want to have 192 upper screen lines at 160 pixels mode and 8 bottom lines at 320 pixels mode.   Could somebody give me links or information about my problem?  Please.

arnoldemu

Please look at the source section of my website
cpctech.org.uk

Also look in the and sources part of the programming part of this forum.

Both have examples.

Generally the amstrad has fixed interrupts, six per frame spaced 52 lines apart.

One of my examples shows the positions. You can adjust them by moving the screen up or down or waiting with nops until you reach the positions ok n you want.

There are two ways to do what you want. Use the firmware (the Rom functions) or do the work yourself.

If you need more examples let me know - I can code some more.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Look in my website, look for modes example.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

I would really appreciate how I could make the information more easy to understand so I can help you and others to understand the amstrad. For Rom functions look at the firmware guide and soft 968 in the docs section of my website. For hardware look for gate array.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

MacDeath

 attribute system enable to even assign the different video modes per attribute.


On the CPC you need to perform a raster interrupt (don't know the exact scientific name) which involves some limitations as well, but stays a common and well known trick.


You may also need to re-dimension the screen if you want more than  lines vertically.


I guess you wil find useful informations and helpfull dudes here.

litwr

Many thanks for help and support.  :)  I began to refresh my memory with CPC data about two months ago and http://www.cpctech.org.uk is my main source of information.  However I'm a bit lost at these arrays of data.  I tried to run the example named `multmdeh'  (http://www.cpctech.org.uk/source/multmdeh.html) and failed - this stopped me.  I can't understand JP 0 command which finishes the interrupt - is it a typo?
I was lucky today - I found and successfully ran `multmode' (http://www.cpctech.org.uk/source/multmode.html) and `modesplt' (http://www.cpctech.org.uk/source/modesplt.html)!  :o  The `modesplt' code almost does the required trick.  However it gives the first area one line bigger than it need to be, 193 lines instead of 192.  How to shift the interrupt positions by 1 line?  I am going to work with register 30 but I expect it will not be too easy...  Will firmware restore its value?
BTW I'd found a typo at CPC Firmware guide: the math function MOVE REAL is at &bd61. ;)

arnoldemu

Quote from: litwr on 20:07, 05 January 14
Many thanks for help and support.  :)  I began to refresh my memory with CPC data about two months ago and http://www.cpctech.org.uk is my main source of information.  However I'm a bit lost at these arrays of data.  I tried to run the example named `multmdeh'  (http://www.cpctech.org.uk/source/multmdeh.html) and failed - this stopped me.  I can't understand JP 0 command which finishes the interrupt - is it a typo?
I was lucky today - I found and successfully ran `multmode' (http://www.cpctech.org.uk/source/multmode.html) and `modesplt' (http://www.cpctech.org.uk/source/modesplt.html)!  :o  The `modesplt' code almost does the required trick.  However it gives the first area one line bigger than it need to be, 193 lines instead of 192.  How to shift the interrupt positions by 1 line?  I am going to work with register 30 but I expect it will not be too easy...  Will firmware restore its value?
BTW I'd found a typo at CPC Firmware guide: the math function MOVE REAL is at &bd61. ;)

jp 0 is not a typo. The code is self modified. I poke the address to change the jump.

It is possible to move the interrupt, but we don't often do this.

Normal method is to use the normal interrupt position, but then we add a delay until we are ready to change mode/colours.

Example:


halt
defs 32 ;; this will insert 32 NOP instructions (1 NOP = 00 byte).


;; the following uses a loop

halt
ld b,8                     
delay: djnz delay


If the time is long, use registers and a loop to make it. Look at the timings for the instructions.


halt
ld bc,20 ;; [3]
delay: dec bc ;; [2]
ld a,b ;;[1]
or c ;;[1]
jp nz,delay ;; [3]


jp is good, because it always takes 3 regardless of condition.
So, 1 time around the loop takes 2+1+1+3. We repeat the loop 20 times.
But don't forget the ld bc,20 this takes 3 too so we must account for this in our timing calculations.

Each line is 64 nops. (e.g. 64 * NOP). CPC timings are more easy because all instructions are a multiple of a NOP in timing. e.g. LD BC,3 is takes the same time as 3 NOPs.

Interrupts occur at the end of HSYNC. It's not the end of the line. So normally we wait some cycles after the int to move to the start of the next line, then we wait x lines.

With normal sized screen you need something like this:


halt
defs 16 ;; move to start of next line
defs 64*3 ;; wait 3 lines.


I will do another code example that will show how you can delay the

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Firmware restores colours and mode using an interrupt.
You must use firmware functions so it knows which mode and colours you want or it will put them back to the ones it remembers.

Firmware will also call the rom, so can restore the rom settings, so use firmware functions to tell it which roms are active or not.

Firmware doesn't restore CRTC state (except screen start when the screen is scrolled by the firmware) so you can change the other registers. Use register 7 to move the screen up/down, this will also shift the position of all the interrupts by 8 lines at a time.

I will do an update to my site soon, so that the links to all the new code examples are visible.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

My bad, you are correct. the jp 0 is a typo.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource


litwr

#10
I've just made it!  :)  I used the following code
split_on ld bc,&bc07            ;; select CRTC register 7
         out (c),c
         inc b
         ld a,29
         out (c),a
         ld a,6
         ld (ticker_counter),a
         call MC_WAIT_FLYBACK
         halt
         halt
         call MC_WAIT_FLYBACK
      ...
to install the interrupt and the code ticker_function
         push af
         push bc
         ld a,(ticker_counter)
         dec a
         jr nz,cont1
         ld b,$66
wait     djnz wait
         ld a,6
cont1    ld (ticker_counter),a
         ex af,af'
         ld c,a
         ex af,af'
         cp 6
         ld a,1
         jr z,cont2
         dec a
cont2    res 1,c
         res 0,c
    ...
for the interrupt.  Arnoldemu, could you explain HALT-HALT magic?
I am only a bit disappointed by the fact that CPU will do nothing during 384 cycles (the waiting loop), I assume that DJNZ gets 4 cycles.  How many cycles does CPC6128 give for z80 per one screen (1/50 second for PAL)?  I'd made such calculations for Commodore 64 and plus/4 - http://www.lemon64.com/forum/viewtopic.php?t=44377 ;) 
Thank you very much arnoldemu - your information helps me very much.  :)  MacDeatch, thanks for the links.  Sorry, my French is very poor but we have google which may help in these cases.  ;)
BTW I am using pasmo 6 cross-assembler under Linux.  Is there something else?  The pasmo's listings are a bit not right.  :-[ It also generates numbers to the symbol table.  :(

arnoldemu

I use pasmo under linux too. I think it's great.

I generate a header with pasmo --amsdos.

And I can put that directly into a disk image with cpcxfs.


Halt instruction waits until the next interrupt and then continues execution.
Each interrupt is 52 lines apart. Interrupts are synchronised with the VSYNC.

MC_WAIT_FLYBACK will return when VSYNC is active.
If you call it when VSYNC is active, it will return immediately.
If you call it when VSYNC is not active, it will wait until VSYNC has started.

In this code: MC_WAIT_FLYBACK may return immediate, or it may wait until the start of VSYNC. No way to know what has happened.
First HALT will be triggered by the interrupt that happens 2 HSYNCs after VSYNC OR if it has passed this point the interrupt after the VSYNC.

We then do a second HALT (52 lines later) which will definitely be after the VSYNC has finished. VSYNC is max 16 lines. Interrupts are 52 lines apart.

The next MC_WAIT_FLYBACK will now definitely trigger at the start of the VSYNC because no VSYNC is active and it will wait until it is.
We are now synchronised with the start of the VSYNC.

The CRTC register 7 will move the vsync position, and because interrupts are synchronised with VSYNC, this will also move the interrupts positions.
The display will move, and now the interrupt will trigger in a different place on the display than it did before.

It is ok to change the vsync position because you still have 50hz screen with 312 lines.

With the delay: You can replace the delay with some code, but it must take the same time to execute as the delay would.
The document on my website, and on cpcwiki tells how much time each instruction takes to execute.

CPC has 64 NOPs per line. 312 lines per screen giving 19968 NOPs for a 50hz screen.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Unofficial Amstrad WWW Resource

this is the document with the timings. Some may not be up to date, but most are.

It shows here that an INC HL instruction. It's 1 byte, but takes 2 NOP cycles. This means it's execution takes the same time as 2xNOP instruction.

The DJNZ instruction:
b-1=0 : 3, b-1<>0 : 4

DJNZ decrements B register then makes a decision. If B!=0 then it jumps and does the loop again, otherwise execution continues after it.


Your loop:
ld b,$66
wait     djnz wait

It takes:
101*4 + 3.

101 loops where B!=0, then final where B=0. Making 66 loops total.
Including the LD B.

101*4 + 3 + 2 = 409 NOPs.

This works out at about 6 scanlines.




My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

NOTE:
1. There are some details about interrupts which I have not talked about because it can be confusing for somebody who is learning the cpc.

If you delay an interrupt (e.g. disable interrupts for some time with DI), you can cause the next interrupt to move, and you may also have less than 6 interrupts.

What happens is that as soon as interrupts are re-enabled, the interrupt will happen. It is delayed by the hardware. The hardware then stops the next interrupt after it from being closer than 32 lines.

This will causes the next interrupt to move (if your delay is more than 32 lines).

If this happens near the end of the frame, the interrupt that would normally trigger after the start of VSYNC doesn't happen (it's too close).

I will write an example to show this so you can see how it works.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

TFM

Pasmo? Get MAXAM and work on a real CPC!  8)   :)  if you like  ;)
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

litwr

QuoteHere I posted some examples. I will post some more.
Thank you very much but it is beyond my current scope.  Maybe later.  :D

Powered by SMFPacks Menu Editor Mod