Showing posts with label ZX Spectrum. Show all posts
Showing posts with label ZX Spectrum. Show all posts

Sunday, 10 October 2021

ZX Spectrum Next z88dk banking example

The Spectrum Next's z80 processor can only directly address 64k of memory but the ZX Spectrum 128 and ZX Spectrun Next models are equipped with far more physical memory than this. 

Bank switching is used to access this extra memory.

This example explains how to implement bank switching in C code using z88DK compiler. 

https://github.com/pdj102/bankingExample

Monday, 6 September 2021

z88dk adt p_forward_list demo

 Demo of how to use the z88dk adt p_forward_list

#include <stdio.h> 
#include <stdint.h>     // standard names for ints with no ambiguity 
#include <adt/p_forward_list.h>

static p_forward_list_t src;

typedef struct
{
    void *next;

    uint8_t v;
item_t;

int main()
{
    uint8_t l;

    item_t item1;
    item_t item2;
    item_t item3;

    item1.v = 1;
    item2.v = 2;
    item3.v = 3;

    item_t *item_ptr;

    p_forward_list_init(&src);

    printf("Push 1, 2, 3 to front\n");
    p_forward_list_push_front(&src,&item1);
    p_forward_list_push_front(&src,&item2);
    p_forward_list_push_front(&src,&item3);        

    l = p_forward_list_size(&src);
    printf("List length = %d\n"l);
    printf("Read items from list\n");

    for (item_ptr = p_forward_list_front(&src); item_ptritem_ptr = p_forward_list_next(item_ptr))
    {
        printf("Item = %d\n"item_ptr->v);
    }

    printf("Clear list\n"); 
    p_forward_list_clear(&src);
    l = p_forward_list_size(&src);
    printf("List length = %d\n"l);     

    printf("Push 1, 2, 3 to back\n");
    p_forward_list_push_back(&src,&item1);
    p_forward_list_push_back(&src,&item2);
    p_forward_list_push_back(&src,&item3);    

    for (item_ptr = p_forward_list_front(&src); item_ptritem_ptr = p_forward_list_next(item_ptr))
    {
        printf("Item = %d\n"item_ptr->v);
    }

    printf("Remove 2\n");
    p_forward_list_remove(&src,&item2);

    l = p_forward_list_size(&src);
    printf("List length = %d\n"l);
    printf("Read items from list\n");
    for (item_ptr = p_forward_list_front(&src); item_ptritem_ptr = p_forward_list_next(item_ptr))
    {
        printf("Item = %d\n"item_ptr->v);
    }

    while(1)
    {

    }

    return 0;
}

 

Sunday, 5 September 2021

ZX Spectrum Next Hello World C program using z88dk

Hello World C program for the ZX Spectrum Next using the z88dk compiler.

Z88DK

Z88DK is a collection of software development tools that targets the 8080 and z80 family of machines. It allows development of programs in C, assembly language or any mixture of the two. What makes z88dk unique is its ease of use, built-in support for many z80 machines, including ZX Spectrum Next, and its extensive set of assembly language library subroutines implementing the C standard and extensions.

The Z88DK offers several C Run Times (CRT) that can be selected using -startup at compile time. These CRTs provide the initialisation code that is called before main(). Some of them provide a simple tty device which supports controls codes such as \x16nn move cursor to X,Y.

NB when installing z88dk on Windows you need to set up the environment variables

  1. create a environment variable to point to the z88dk root folder e.g. called z88dk
  2. include z88dk\bin in your PATH 
  3. set Z80_OZFILES to point to \lib e.g. $Env:Z80_OZFILES=$Env:z88dk+"\Lib\"
  4. ZCCCFG to point to the config folder e.g. $Env:ZCCCFG=$Env:z88dk+"\Lib\Config"

Hello World C program

The following program prints "Hello World" near the middle of the screen and then loops forever changing the border between red and yellow. 

The resultant .nex file can be loaded by a ZX Spectrum emulator such as CSpect or copied over and run on real ZX Spectrum Next hardware.

/* =========================================================================
    ZX Spectrum Next Hello World C program
    Compile using z88dk
    zcc +zxn -vn -SO3 -clib=sdcc_iy -startup=1 --max-allocs-per-node200000 .\helloworldSpectumNext.c -create-app -subtype=nex

    +zxn            target ZX Spectrum Next
    -vn             no verbose
    -SO3            set optimisation level 3
    -clib           use sdcc_iy library (and use the recommended zsdcc compiler which produces smaller code)
    -start          set the C Run Time. 1 is standard 32 column display tty_z88dk terminal
    --max-allocs-per-node   controls how deeply zsdcc looks at code alternatives
    -create-app     run the program to create an executable that can be run by an emulator
    -subtype=nex    Create a nex file executable
*/

#include <arch/zxn.h>   // ZX Spectrum Next architecture specfic functions
#include <stdio.h>      

// Define some macros to make use of tty_z88dk control codes
// Program must be compiled with a CRT that supports tty_z88dk e.g. -startup=1
#define printInk(k)          printf("\x10%c"'0'+(k))
#define printPaper(k)        printf("\x11%c"'0'+(k))
#define printAt(rowcol)    printf("\x16%c%c", (col)+1, (row)+1)

int main()
{
    printAt(10,10);                 // move cursor 
    puts("Hello World!");       

    while(1) {                      // loop for ever
            zx_border(INK_RED);     // set border red
            zx_border(INK_YELLOW);  // set border yellow
    };
    
    return 0;
}
 

Sunday, 16 February 2020

ZX Spectrum Hello World! Assembler on Windows


1. Download the PASMO Z80 cross assembler.

2. Download and install the FUSE ZX Spectrum emulator

2. Save the following hello world! program to 'helloworld.txt'

; hello-world.z80
CHAN_OPEN   equ  5633
PRINT       equ  8252

            org  32512

            ld   a, 2                ; 3E 02
            call CHAN_OPEN           ; CD 01 16
            ld   de, text            ; 11 0E 7F
            ld   bc, textend-text    ; 01 0E 00
            jp   PRINT               ; C3 3C 20

text        defb 'Hello, World!'     ; 48 65 6C 6C 6F 2C 20 57
                                     ; 6F 72 6C 64 21
            defb 13                  ; 0D

textend     equ  $


3.  Compile the programme into a TAP file with basic loader
.\pasmo -1 --tapbas '..\Zx Spectrum\helloworld.txt' prog.tap >> debug.txt

-1 (digit 'one') Show debug info during both passes of assembly.

With the --tapbas option a tap file is generated with two parts: a Basic loader and a code block with the object code. The Basic loader does a CLEAR before the initial address of the code, loads the code, and executes it if a entry point is defined (see the END directive). That way you can directly launch the code in a emulator, or transfer it to a tape for use in a real Spectrum. 

4.  Open the prog.tap file in Fuse

Fuse will load the first part of the TAP file which is the basic loader programme

The Basic loader program
5. Run the assembler program by issuing the the command

RANDOMIZE  USR 32512

To type this on a spectrum 48K keyboard

type T to enter the RANDOMIZE command then
press Shift+Ctrl (to enter Extended keyboard mode - flashing E cursor) and type 'L' for USR
then type 32512 and press return to execute




* alternatively add the directive END 32512 to the end of the helloworld program and PASMO will include the basic command to run the assembly code automatically.

 

Sunday, 3 June 2018

ZX Spectrum +2 memory map

The ZX Spectrum +2 has 131,072 bytes of RAM and 32,768 bytes of ROM making a total of 163,840 bytes (160K) in all.

The processor hardware can only address 65,536 bytes therefore paging is used to move pages of memory in and out of the processor address space. The processor always 'sees' the memory as 16K of ROM and 48K of RAM.

The ZX Spectrum +2 memory map is shown below. The first 16K is ROM which can have either ROM 0 or ROM 1 paged in to position. RAMs 2 and 5 are fixed in position and any RAM page can be paged into position RAM 0 - 7 (16 KB in size).

Memory banks 1,3,5 and 7 are contended, which reduces the speed of memory access in these banks.

The +2 memory map

  • ROM 0 - 128k editor and menu system
  • ROM 1 -  48K BASIC
  • RAM 5 - the normal screen
  • RAM 7 - shadow screen 

Screen memory layout

The RAM 5 normal screen memory layout is as follows

RAM 5 bank screen memory layout

 Paging


Paging is controlled by performing I/O writes to ports 0x7ffd. The paging logic decodes the address bus partially (uses A15 and A1 lines only), so the exact port is 0xxx xxxx  xxxx xx0x. The bits are described in the table below:

Port 0x7ffd


An example of a typical bank switch on the 128 is:
     LD      A,(0x5b5c)      ;Previous value of port held somewhere convinient
     AND     0xf8
     OR      4               ;Select bank 4
     LD      BC,0x7ffd
     DI
     LD      (0x5b5c),A
     OUT     (C),A
     EI
The principle is the same for all bank switching: change only the bits you need to.


Clear command


If you do wish to reserve memory for machine code so that it is not used by BASIC, then issue the command CLEAR n, where n is the last byte you wish to be available to BASIC. So, if you want your machine code to sit at address &8000 in the memory map, then issue the command:

CLEAR 32767
We want the last byte of memory available to basic to be just before our code, so (&8000 – 1) is 32767 in decimal. Assemble and load your code into address 32768 and run.

Sunday, 11 September 2016

Repairing a ZX Spectrum 128K +2 (serial no U-043583) - Part 5

In part 4, I re-checked the onboard power supply voltages and made some adjustments to the +12V supply which was measuring a low 10.98V but even with +12V on the 12V line the ghost image still remained.

The final fix was found when someone on world of spectrum suggested the TV might be displaying both the composite video and the RGB video signal resulting in the two images on the screen. Initially, I thought the  cable I had bought was only wired for composite but on rechecking (this time measuring for resistance rather than continuity, oops!) it turns out the RGB pins are also wired.

The SCART to HDMI converter that I am using has no means of forcing selection of RGB or composite video in on the SCART input so as an experiment I connected an alkaline battery to the SCART "blanking" pin 16 to force RGB selection and the ghost image was gone.

Finally, it is now fixed and the display looks amazing!

Fixed display with no ghost image




Saturday, 10 September 2016

Repairing a ZX Spectrum 128K +2 (serial no U-043583) - Part 4

In part 3, I checked the inputs to the TEA2000 composite video chip and could not see any obvious issues other than the low voltage on the 12V input.

I decided to check and replace some components on the onboard powersupply to see if they were causing the low 10V voltage measured on the +12V supply.

The onboard powersupply uses a ZTX650 transistor TR9 which looked okay but I decided to replace it with a ZTX651 which is an acceptable replacement for the 650 and I also replaced electrolytic caps C41 (100uF) and C23 (22uF) in case they were starting to fail.

Measuring the voltages I still get similar results so TR9 and the caps do not seem to be the cause of the low voltage on the 12V supply.

I measured
  • -12.34 (-12V)
  •  10.98 (+12V)
  • -5.03 (-5V)
  • 4.96V (+5V)
I posted on world of spectrum and it was suggested I check resistors R54(1K) and R55(1K8) which form the sense/feedback resistor network that drives TR8. Both resistors checked out okay and I noticed that the two resistors form a voltage divider so I decided to experiment. Replacing R55 with a 2K2 resistor results in 12.3V on the +12V supply. This does not fix the display problem but I have decided to leave it in for now.

Finally, I have decided to order a replacement TEA2000 to see if the IC is faulty. 

Saturday, 3 September 2016

Repairing a ZX Spectrum 128K +2 (serial no U-043583) - Part 2


In part 1 I fixed the manufacturing fault which resulted in no output on the composite video but the resultant image was terrible.

Spectrum composite video on LG 32LB650V
The screen is covered in dots which do not move and seem to only appear on alternate lines. I do not think these dots are caused by a fault reading from memory as they also appear on the spectrum's border which is not read from memory.

I tried a SCART to HDMI convertor and the dots are gone so it turns out my LG TV (model 32LB650V) does not like the composite video from the spectrum. Maybe it is confused by the progressive PAL signal?



SCART to HDMI adapter ghost image
The dots and lines are gone but now there is a ghost image on the composite video.


Composite to SCART adapte

At this point, I tried another spectrum +2 using the SCART to HDMI adapter and got a perfect image so this ghost image must be due to a fault with the spectrum.

I lashed up a temporary RGB cable and tried that via the SCART to HDMI adapter and the ghost image was not present to I think the problem is something to do with the composite video circutry. Part 3....





Sunday, 21 August 2016

Repairing a ZX Spectrum 128K +2 (serial no U-043583) - Part 1

I bought a ZX spectrum 128K +2* from ebay (serial no U-043583) which whilst it seemed to be mostly working had a terrible picture on the UHF output and no output on the composite video. So I set about trying to repair it.

Issue 3 of the ZX Spectrum 128K +2 had a number of transistors fitted the wrong way around during manufacture. So let's check those out.

* Not the black amstrad ZX spectrum +2A and +2B

Incorrectly fitted TR4


TR4 is often fitted incorrectly which prevents a composite video signal being present on pin 1 of the RGB connector. Sure enough the TR4 on this +2 is fitted the wrong way round. Note the silk screen is incorrect for this transistor.

TR4 fitted the wrong way round



TR4 is a TN3904 transistor. The collector should be connected to 12V, the base to diode D7 and the emitter to composite video out. If the transistor is fitted the right way round then testing for continuity with a multi-meter will show the collector connected to pin 11 of the TEA2000 IC (12V).

2N3094

If the transistor is fitted the wrong way round it is very easily corrected by unsoldering the part and putting it back the right way round.

TR9

TR9 forms part of the circuitry which generates the 12V required by the TEA2000 composite video IC. The TR9 is a ZTX650 NPN transistor and when fitted the right way round the emitter should be connected to ground. I have read reports of this being often fitted the wrong way round but on this +2 it is fitted correctly.


ZTX650
TR9 fitted right way round

Spectrum 2+ TR8 and TR9 schematic from service manual


Incorrectly fitted TR8 

TR8 also forms part of the circuitry which generates the 12V required by the TEA2000 composite video IC. TR8 is a 2TX213 PNP transistor and when fitted the right way round the emitter should be connected to +5V and the collector to resistor R29.

TR8 was fitted the wrong way round in this spectrum and this was corrected by unsoldering the transistor and fitting it back the right way round. Again, the silk screen is incorrect and indicates the wrong way round for the part.
TR8 fitted wrong way round



Incorrectly fitted TR5 

TR5 forms part of the circuitry for generating the Vsync signal which is required when using an RGB output. TR5 is a TN3904 transistor and when fitted the right way round the collector is connected to 5V and emitter to resister R57.

TR5 is fitted the wrong way round in this spectrum and can be corrected by turning it around but given this problem should not affect the composite video signal I have left it as is for now and will fix it later when I want to use the RGB output.

TR5 fitted wrong way round

 

 
TR5 Spectrum 2+ schematic from service manual

 

How to check a transistor is not faulty

The diode test mode on a multi-meter can be used to check a transistor. The transistor should be unsoldered from the circuit prior to testing.

A good diode should display a voltage drop ranging between 0.5 to 0.8 volts when forward biased and OL when reversed biased.

Composite video 

With the transistors swapped round I now get a picture on the composite video output but it is rather poor! Part two.....