Z80 Assembly programming for the Sam Coupe (Sam Coup�)

Download my Sam Coupe Sourcecode and Notes!

As part of my ongoing Z80 tutorials, I've been looking for technically impressive Z80 based computers that I was not familiar with, but demanded more attention than the market gave them... after a tip off from a Youtube viewer, I started looking at the Sam Coupe, and it represents an impressive Z80 based 8 bit system, that I had only barely heard of (In fact I incorrecty thougt it was 16 bit!)

What makes the Sam Coupe Special?
The Sam Coupe came late in the Z80's life - released in 1989, and discontinued in 1992... they were presumably going after the 16 bit market, and targeted their system with specs to really compete!
The machine was povided with a 3.5 inch disk drive by default, and came with a minimum of 256k... what's more, it used a 6mhz Z80... nearly twice what other systems had... and its screen display is capable of 256x192 at 16 colors... the same as the MSX, however as the Sam Coupe screen is part of system memory, it is MUCH faster than the MSX!

according to my testing, Despite having a 24k screen the Sam Coupe beats the Amstrad (16k screen, 3.57mhz) for speed doing fill commands... only the Enterprise is faster (again 16k, but a 4mhz processor)

The Enterprise 128 is an 8 bit Z80 system, it's comparable to the Amstrad CPC,however it has more advanced Memory Mapping which allows more flexible bank switching, and more advanced graphics

So what's not to like? well the only 'problem' with the system is the huge 24k screen seems to have caused some design limitations, unlike the CPC/Spectrum and Enterprise which bank swap in 16k chunks, the Sam Coupe swaps in 32k blocks... which would make porting my ChibiAkumas game pretty time consuming... that said, I hope to release new games for it in the future, build from the ground up to work with this limitation!

Unfortunately, the Sam Coupe only sold 12,000 units, so they're pretty rare now, and I don't own one! fortunately there's a great free emulator called SimCoupe
The sam Coupe
Image taken from Wikipedia

ChibiAkumas Tutorials

    Lesson H4 - Hello World on the Sam Coupe

Lesson S4 - Easy Sprites on the Sam Coupe

Lesson P2 - More Text Functions, Improvements... and the Sam Coupe!

Lesson P4 - Bitmap graphics on the ZX Spectrum and Sam Coupe

Lesson P6 - Keyreading on the Amstrad CPC, ZX Spectrum and Sam Coupe

Lesson P14 - Palette definitions on the Enterprise and Sam Coupe

Lesson P20 - Sound on the Sam Coupe

Lesson P28 - Bankswitching and hardware detection on the Sam Coupe

Lesson P37 - Playing Digital Sound with WAV on the Sam Coupe, Camputers Lynx and ZX Spectrum



Useful documents

User Manual - Basic usage guide
Technical Manual - You'll want this for programming
SAA1099 - Sound chip manual

Problems I've come across!

Sam Coupe disks are 3.5 inch, but they don't use standard dos format, this means you need to build disk images with Sam Coupe tools, there's some great ones, such as the "Sam Coupe Advanced Disk Manager" and "Sam Coupe Diskimage Manager", but the one I use most is a modified copy of "Andrew Colliers Simcoupe DSK manager"

I needed a program that could build a disk image from a script, and I found I was struggling to get disk images built with the correct "Start address" (execute address)... Andrews program built disk images from dos, but unfortunately did not put the code address in, My C++ skills are pretty rusty, but I managed to build a modified version that puts in a start address of &8000, and can read the keypresses from a text file, so can be scripted in the way I wanted... I'll include the source, build and other useful stuff in the download linked at the top of this page

Bankswitching theory on the Sam Coupe

Controling bank switching on the SAM is done with two ports, one controls the first 32k of the memory map, the other controls the second 32k, there's also a port that controls the bank pair that controls the visible screen (the screen uses 24k so two banks)

The SAM splits its 256/512k into 16k chunks, with the first bank is 0...

Port Name Description Bits Bit Meaning
&FA - 250 LMPR Low Memory Page Register WHLBBBBB    B=Bank &0000-&7FFF... L=Low rom off (1=off)... H=High rom on (1=on)� W=Write protect &0000-&3FFF
&FB - 251 HMPR High Memory Page Register MCCBBBBB B=Bank &8000-&FFFF... C=mode 3 color lookup... M=use externalmemory expansion
&FC - 252 VMPR Video Memory Page Register OMMBBBBB B=Video Bank... M=Mode... O=midi Io

You'll notice we only have two bank switching ports... this is because we switch the memory range in 32k chunks!
even though memory banks are split in 16k.... if we set port 250 to use bank 0... then the memory range &0000-&3FFF will point to bank 0... but the next bank (&4000-&7FFF) will use the following bank - bank 1!... The fact we have to work in 32k chunks makes bank switching on the SAM rather limited compared to other systems where we work in 16k chunks

Also notice bit 7 of port 251... this allows us to access external memory upgrades in the range &8000-&FFFF for many megabytes of memory - we won't be cover them in these tutorials!

Range
Page Addr Example
&0000 (&250) 0
&4000 (&250)+1 1
&8000 (&251) 10
&C000 (&251)+1 11

Because we need to swap banks in 32k chunks it makes it harder to uses memory efficiently on the SAM... if we page in the screen into one bank, and our sprites into the other... we have nowhere left for our code!

We will have to work out another way to organize our memory... for example storing a copy of our sprite handling code in the spare memory of the screen bank (the screen uses 24k of the 32k bank)

Keyreading on the Sam Coupe

The Sam Coupe keyboard matrix is based on the Spectrum... just with an extra 3 lines added to each row.. the extra 3 lines are read from port &F9
Our reading procedure is basically  the same as the Spectrum, but we have to add in the extra 3 bits from port &F9
The joystick ports on the sam coupe map to the keyboard matrix too, Joy 1 maps to number keys 6-0, Joy 2 maps to 1-5

The Sam Coupe KeyMatrix: (keys in Red are same as Speccy - BLUE are joystick keys... Magenta are Sam extras)

Load BC with the address of the required row and keys, and use "IN A,(C)"

Bit-> C= &F9 C= &FE
B=... 7 6 5 4 3 2 1 0
%11111110 F3 F2 F1 V C X Z SHIFT
%11111101 F6 F5 F4 G F D S A
%11111011 F9 F8 F7 T R E W Q
%11110111 CAPS TAB ESC 5 JOY2-L 4 JOY2-R 3 JOY2-D 2 JOY2-U 1 JOY2-F
%11101111 DEL + - 6 JOY1-L 7 JOY1-R 8 JOY1-D 9 JOY1-U 0 JOY1-F
%11011111 F0 " = Y U I O P
%10111111 EDIT : ; H J K L ENTR
%01111111 INV . , B N M DEL SPC
%11111111                               RIGHT LEFT DOWN    UP    CTRL

Sam Coupe sound registers
The Sam Coupe has 32 registers - though some have no purpose... write a RegNum to port 511, then a value to port 255 to set one.

Reg Purpose Bits Bit Meaning
&00 Amplitude generator 0 RRRRLLLL
Left / Right ... 15=Max volume
&01 Amplitude generator 1 RRRRLLLL Left / Right ... 15=Max volume
&02 Amplitude generator 2 RRRRLLLL Left / Right ... 15=Max volume
&03 Amplitude generator 3 RRRRLLLL Left / Right ... 15=Max volume
&04 Amplitude generator 4 RRRRLLLL Left / Right ... 15=Max volume
&05 Amplitude generator 5 RRRRLLLL Left / Right ... 15=Max volume
&08 Tone Generator 0 Frequency FFFFFFFF Higher number = higher tone
&09 Tone Generator 1 Frequency FFFFFFFF Higher number = higher tone
&0A Tone Generator 2 Frequency FFFFFFFF Higher number = higher tone
&0B Tone Generator 3 Frequency FFFFFFFF Higher number = higher tone
&0C Tone Generator 4 Frequency FFFFFFFF Higher number = higher tone
&0D Tone Generator 5 Frequency FFFFFFFF Higher number = higher ton41
&10 Octave register -111-000 Set tone register octaves
&11 Octave register -333-222 Set tone register octaves
&12 Octave register -555-444 Set tone register octaves
&14 Frequency enable --543210 Tone Channel enable 0=off
&15 Noise enable --543210 Noise Channel enable 0=off
&16 Noise Generator --11--00 00=31k 01=15k 10=7k 11= freq gen 0 (Chn0) / 1 (Chn3)
&18 Envelope Generator 0 (CH2) O-GREEEM envelope controller On / 0= use CH 1 1=timed / Resolution / Envelope shape / Mirror other channel
&19 Envelope Generator 1 (CH5) O-GREEEM envelope controller On / 0= use CH 4 1=timed / Resolution / Envelope shape / Mirror other channel
&1C Reset and Enable ------RE Reset frequency / Enable sound


SamDos
I had a lot of trouble getting SamDos to work (mostly my own fault) but was quite frustrated by the fact it seems there is no usable example of how to use it,
As I now have a working sample, I'm uploading it here to try to help others!

Call SAVE and LOADDIRECT with HL pointing to a filename (see the example at the top) and DE pointing to a memory destination... A should point to a Bank!

BC must be bytes to save with the SAVE command!

I will be covering this code in disk ops in detail  in my tutorials very soon!



LoadFileName:         db "-"
LoadFileNameTrack:    db "0000"
             db "."
LoadFileNameCompressed:    db "D"
LoadFileNameDisk:     db "0      "


DBASIC    EQU &F37D
FOPEN    EQU &0F
FCLOSE    EQU &10
CREATE    EQU &16
BLWRITE    EQU &26
BLREAD    EQU &27
SETDMA    EQU &1A ;Disk transfer address (Destination/source)
BDOS_INIT        EQU &1B
BDOS_RESET        EQU &00
BDOS_DiskRESET        EQU &0D
BDOS_DefaultDrive     EQU &0E
BDOS_GetDefaultDrive     EQU &19

;defw &0000 DiscDestRelocateCall_Plus2;not implemented yet!





DiskDriver_Save:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;        Create a new file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ld (FileErrorSpRestore_Plus2-2),sp

    push af
        push bc
        push de
            ld de,diskerr    ;Error handler
            ld (&5BC0),de    ;This is called EVERY return from a Dos call (if error occured or not!)

            ld de,&4B00
            ld a,19
            ld (de),a
            inc de
            ld bc,14
            ldir
        pop de
        pop bc

        ld ix,&4B00
;    ld a,d
;    and %110000
    pop af
    ld (ix+31),a    ;31      16K PACE NUMBER START

    ld (ix+32),e    ;32-33  PAGE OFFSET (8000-BFFFH) LSB/MSB
    ld a,d
    and %00111111
    or  %10000000
    ld (ix+33),a

    xor a        ;34      NUMBER OF PAGES IN LENGTH
    ld (ix+34),a

    ld (ix+35),c    ;35-36  MODULO 0 TO 16383 LENGTH ie file length MOD 16384.
    ld (ix+36),b

    ld (ix+37),a    ;37      EXECUTE PAGE NUMBER if applicable

    ld (ix+38),a    ;38-39  EXECUTE OFFSET (8000-BFFFH) LSB/MSB if applicable
    ld (ix+39),a

    xor a        ;Before using this hook poke &5BB9  with 0 to overite existing file.
    ld (&5BB9),a   

    ld ix,&4B00
    rst 1
    db 132    ;HSAVE - Save file using IX pointed UIFA
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



DiskDriver_LoadDirect:
    push hl
        ld hl,null                    ;Disable the relocate
        ld (DiscDestRelocateCall_Plus2-2),hl
    pop hl
DiskDriver_Load:


    ld (FileErrorSpRestore_Plus2-2),sp

    push de
        ld de,diskerr    ;Error handler
        ld (&5BC0),de    ;This is called EVERY return from a Dos call (if error occured or not!)
                ;note - we're not setting this on WRITE command, we're assuming one read command will happen first!

        ld de,&4B00    ;This points to the UIFA in ram bank 00 - SAMDOS doesn't seem to work right if it's anywhere else!
        ld a,19        ;This means CODE FILE
        ld (de),a
        inc de
        ld bc,14    ;copy the 14 char file name from HL - must be padded with spaces!
        ldir
   
         ld ix,&4B00
        rst 1
        db 129         ; HGTHD - Get the file header (loads to IX+80

        ld bc,(&4B00+80+35)    ;Get the file size

        ld a,%00111111        ;For some reason the file sizes seems to be too high, it should be a less than 16384
        and b            ;It may be my mistake!
        ld b,a
    pop hl


    ;This is used when the file is compressed.
;    ex hl,de   
    call null:DiscDestRelocateCall_Plus2
;    ex hl,de
    push hl
    push bc

        ld bc,251    ;HMPR - High Memory Page Register (251 dec)
        in a,(c)
        ld (DiskRestoreBank_Plus1-1),a
        push bc
            ld de,&4F00
            ld hl,DoActualLoad
            ld bc,DoActualLoad_BlockEnd-DoActualLoad
            ldir
           
            ld de,diskerrSpec-DoActualLoad+&4F00    ;Error handler
            ld (&5BC0),de    ;This is called EVERY return from a Dos call (if error occured or not!)
        pop bc
    pop de
    pop hl
    jp &4F00
DoActualLoad:
    and %11100000
    or 0:DiskLoadBank_Plus1
    out (c),a
    ld c,0
    ld ix,&4B00
    rst 1               
    db 130                ;HLOAD - Load the file
LoadDone:
        scf        ; OK! set carry flag
LoadDone2:
        ret
DoLoadFromBankB:   
diskerrSpec:
        push af
            ld bc,251    ;HMPR - High Memory Page Register (251 dec)
            ld a,0    :DiskRestoreBank_Plus1
            out (c),a
        pop af
diskerr:
       
        or a    ;Clear the carry frlag
        ret z     ; no error
        ld sp,&0000:FileErrorSpRestore_Plus2
        jr LoadDone2

DoActualLoad_BlockEnd:
;UIFA
;db 19
;db "music.bin                        "
;
;ds 80+48
;DIFA
;ds 48
;5BC0H - REPLACE THIS WITH MY OWN ERROR HANDLER!

;UIFA and DIFA have the same format,
;UIFA is provided by user at IX, DIFA is returned by the disk at IX+80

;0      STATUS/FILE TYPE.
;1-14      FILENAME. 14 characters are allocated to allow for device
;    identification, for example D1;filenamexx. SAMDOS will strip
;    off the device identifier, so the maximum length of a filename
;    is still ten characters.Sa
;15      FLAGS
;16-26  If the file type is 17 or 18 then these bytes contain the
;    type/length byte and the name.
;16      If the file type is 20 then this byte contains the screen
;    mode.
;16-18  If the file type is 16 then these bytes contain the program
;    length excluding variables.
;19-21  If the file type is 16 then these bytes contain the program
;    length plus the numeric variables.
;22-24  If the file type is 16 then these bytes contain the program
;    length plus the numeric variables and the gap length before
;    the character variables.
;27-30  SPARE 4 BYTES (Reserved)
;31      16K PACE NUMBER START
;32-33  PAGE OFFSET (8000-BFFFH) LSB/MSB
;34      NUMBER OF PAGES IN LENGTH
;35-36  MODULO 0 TO 16383 LENGTH ie file length MOD 16384.
;37      EXECUTE PAGE NUMBER if applicable
;38-39  EXECUTE OFFSET (8000-BFFFH) LSB/MSB if applicable
;40-47  SPARE 8 BYTES (Comment Field





Links
SimCoupe - Great Sam Coupe Emulator!
Sam.Speccy.cz - Great site with tons of technical info






Visit www.ChibiAkumas.com to get my games and their source code! | Support me on patreon


** Yes I've called it "Sam Coupe" not "Sam Coup�" - If I don't know how to type the � symbol no-one searching for it will either!
 

View Options
Default Dark
Simple (Hide this menu)
Print Mode (white background)

Top Menu
***Main Menu***
Youtube channel
Patreon
Introduction to Assembly (Basics for absolute beginners)
Amazon Affiliate Link
AkuSprite Editor
ChibiTracker
Dec/Bin/Hex/Oct/Ascii Table

Alt Tech
Archive.org
Bitchute
Odysee
Rumble
DailyMotion
Please note: I wlll upload more content to these alt platforms based on the views they bring in

Z80 Content
***Z80 Tutorial List***
Learn Z80 Assembly (2021)
Learn Z80 Assembly (old)
Hello World
Simple Samples
Advanced Series
Multiplatform Series
Platform Specific Series
ChibiAkumas Series
Grime Z80
Z80 Downloads
Z80 Cheatsheet
Sources.7z
DevTools kit
Z80 Platforms
Amstrad CPC
Elan Enterprise
Gameboy & Gameboy Color
Master System & GameGear
MSX & MSX2
Sam Coupe
TI-83
ZX Spectrum
Spectrum NEXT
Camputers Lynx

6502 Content
***6502 Tutorial List***
Learn 6502 Assembly
Advanced Series
Platform Specific Series
Hello World Series
Simple Samples
Grime 6502
6502 Downloads
6502 Cheatsheet
Sources.7z
DevTools kit
6502 Platforms
Apple IIe
Atari 800 and 5200
Atari Lynx
BBC Micro
Commodore 64
Commodore PET
Commander x16
Super Nintendo (SNES)
Nintendo NES / Famicom
PC Engine (Turbografx-16)
Vic 20

68000 Content
***68000 Tutorial List***
Learn 68000 Assembly
Hello World Series
Platform Specific Series
Simple Samples
Grime 68000
68000 Downloads
68000 Cheatsheet
Sources.7z
DevTools kit
68000 Platforms
Amiga 500
Atari ST
Neo Geo
Sega Genesis / Mega Drive
Sinclair QL
X68000 (Sharp x68k)

8086 Content
Learn 8086 Assembly
Platform Specific Series
Hello World Series
Simple Samples
8086 Downloads
8086 Cheatsheet
Sources.7z
DevTools kit
8086 Platforms
Wonderswan
MsDos

ARM Content
Learn ARM Assembly
Learn ARM Thumb Assembly
Platform Specific Series
Hello World
Simple Samples
ARM Downloads
ARM Cheatsheet
Sources.7z
DevTools kit
ARM Platforms
Gameboy Advance
Nintendo DS
Risc Os

Risc-V Content
Learn Risc-V Assembly
Risc-V Downloads
Risc-V Cheatsheet
Sources.7z
DevTools kit

MIPS Content
Learn Risc-V Assembly
Platform Specific Series
Hello World
Simple Samples
MIPS Downloads
MIPS Cheatsheet
Sources.7z
DevTools kit
MIPS Platforms
Playstation
N64

PDP-11 Content
Learn PDP-11 Assembly
Platform Specific Series
Simple Samples
PDP-11 Downloads
PDP-11 Cheatsheet
Sources.7z
DevTools kit
PDP-11 Platforms
PDP-11
UKNC

TMS9900 Content
Learn TMS9900 Assembly
Platform Specific Series
Hello World
TMS9900 Downloads
TMS9900 Cheatsheet
Sources.7z
DevTools kit
TMS9900 Platforms
Ti 99

6809 Content
Learn 6809 Assembly
Learn 6309 Assembly
Platform Specific Series
Hello World Series
Simple Samples
6809 Downloads
6809/6309 Cheatsheet
Sources.7z
DevTools kit
6809 Platforms
Dragon 32/Tandy Coco
Fujitsu FM7
TRS-80 Coco 3
Vectrex

65816 Content
Learn 65816 Assembly
Hello World
Simple Samples
65816 Downloads
65816 Cheatsheet
Sources.7z
DevTools kit
65816 Platforms
SNES

eZ80 Content
Learn eZ80 Assembly
Platform Specific Series
eZ80 Downloads
eZ80 Cheatsheet
Sources.7z
DevTools kit
eZ80 Platforms
Ti84 PCE

IBM370 Content
Learn IBM370 Assembly
Simple Samples
IBM370 Downloads
IBM370 Cheatsheet
Sources.7z
DevTools kit

Super-H Content
Learn SH2 Assembly
Hello World Series
Simple Samples
SH2 Downloads
SH2 Cheatsheet
Sources.7z
DevTools kit
SH2 Platforms
32x
Saturn

PowerPC Content
Learn PowerPC Assembly
Hello World Series
Simple Samples
PowerPC Downloads
PowerPC Cheatsheet
Sources.7z
DevTools kit
PowerPC Platforms
Gamecube

Work in Progress
ChibiAndroids

Misc bits
Ruby programming









Buy my Assembly programming book
on Amazon in Print or Kindle!


Buy my Assembly programming book





Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!



































































































Buy my Assembly programming book
on Amazon in Print or Kindle!


Buy my Assembly programming book





Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!



































































































Buy my Assembly programming book
on Amazon in Print or Kindle!


Buy my Assembly programming book





Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!