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 |
![]() Image taken from Wikipedia |
ChibiAkumas Tutorials
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"Bankswitching theory on the Sam Coupe
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 |
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 |
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 |
|