├── Compress
└── LZ77Decode
│ ├── GFX
│ ├── Lenna.lz
│ ├── Lenna.png
│ ├── Lenna.scr
│ └── compress.bat
│ ├── LIB
│ ├── Z80_HEADER.ASM
│ └── ZXSPECTRUM.INC
│ ├── LZ77Decode.asm
│ ├── LZ77Decode.png
│ ├── LZ77Decode.z80
│ └── Make.bat
├── HelloWorld
├── Font8x8.asm
├── HelloWorld.asm
├── HelloWorld.png
├── HelloWorld.z80
├── LIB
│ ├── Z80_HEADER.ASM
│ └── ZXSPECTRUM.INC
└── Make.bat
├── Input
├── Joystick
│ ├── Cursor
│ │ ├── Font8x8.asm
│ │ ├── JoystickCursor.asm
│ │ ├── JoystickCursor.png
│ │ ├── JoystickCursor.z80
│ │ ├── LIB
│ │ │ ├── Z80_HEADER.ASM
│ │ │ └── ZXSPECTRUM.INC
│ │ └── Make.bat
│ ├── FullerBox
│ │ ├── Font8x8.asm
│ │ ├── JoystickFullerBox.asm
│ │ ├── JoystickFullerBox.png
│ │ ├── JoystickFullerBox.z80
│ │ ├── LIB
│ │ │ ├── Z80_HEADER.ASM
│ │ │ └── ZXSPECTRUM.INC
│ │ └── Make.bat
│ ├── Kempston
│ │ ├── Font8x8.asm
│ │ ├── JoystickKempston.asm
│ │ ├── JoystickKempston.png
│ │ ├── JoystickKempston.z80
│ │ ├── LIB
│ │ │ ├── Z80_HEADER.ASM
│ │ │ └── ZXSPECTRUM.INC
│ │ └── Make.bat
│ └── Sinclair
│ │ ├── Font8x8.asm
│ │ ├── JoystickSinclair.asm
│ │ ├── JoystickSinclair.png
│ │ ├── JoystickSinclair.z80
│ │ ├── LIB
│ │ ├── Z80_HEADER.ASM
│ │ └── ZXSPECTRUM.INC
│ │ └── Make.bat
├── Keyboard
│ ├── Font8x8.asm
│ ├── Keyboard.asm
│ ├── Keyboard.png
│ ├── Keyboard.z80
│ ├── LIB
│ │ ├── Z80_HEADER.ASM
│ │ └── ZXSPECTRUM.INC
│ └── Make.bat
└── Mouse
│ └── Kempston
│ ├── Font8x8.asm
│ ├── LIB
│ ├── Z80_HEADER.ASM
│ └── ZXSPECTRUM.INC
│ ├── Make.bat
│ ├── MouseKempston.asm
│ ├── MouseKempston.png
│ └── MouseKempston.z80
├── LIB
├── Z80_HEADER.ASM
├── ZXSPECTRUM.INC
└── ZXSPECTRUM_PSG.INC
├── README.md
├── Screen
├── FillPixel
│ ├── FillPixel.asm
│ ├── FillPixel.png
│ ├── FillPixel.z80
│ ├── LIB
│ │ ├── Z80_HEADER.ASM
│ │ └── ZXSPECTRUM.INC
│ └── Make.bat
├── FillScreen
│ ├── FillScreen.asm
│ ├── FillScreen.png
│ ├── FillScreen.z80
│ ├── GFX
│ │ ├── Lenna.png
│ │ └── Lenna.scr
│ ├── LIB
│ │ ├── Z80_HEADER.ASM
│ │ └── ZXSPECTRUM.INC
│ └── Make.bat
├── Fractal
│ └── Mandelbrot
│ │ ├── LIB
│ │ ├── Z80_HEADER.ASM
│ │ └── ZXSPECTRUM.INC
│ │ ├── Make.bat
│ │ ├── Mandelbrot.asm
│ │ ├── Mandelbrot.png
│ │ └── Mandelbrot.z80
├── PlotLine
│ ├── LIB
│ │ ├── Z80_HEADER.ASM
│ │ └── ZXSPECTRUM.INC
│ ├── Make.bat
│ ├── PlotLine.asm
│ ├── PlotLine.png
│ └── PlotLine.z80
├── PlotPixel
│ ├── LIB
│ │ ├── Z80_HEADER.ASM
│ │ └── ZXSPECTRUM.INC
│ ├── Make.bat
│ ├── PlotPixel.asm
│ ├── PlotPixel.png
│ └── PlotPixel.z80
└── PlotSprite
│ ├── LIB
│ ├── Z80_HEADER.ASM
│ └── ZXSPECTRUM.INC
│ ├── Make.bat
│ ├── PlotSprite.asm
│ ├── PlotSprite.png
│ └── PlotSprite.z80
└── Sound
├── Beeper
├── PlayNote
│ ├── BeeperPlayNote.asm
│ ├── BeeperPlayNote.z80
│ ├── LIB
│ │ ├── Z80_HEADER.ASM
│ │ └── ZXSPECTRUM.INC
│ └── Make.bat
└── PlaySample
│ ├── 8tosigmadelta.c
│ ├── BeeperPlaySample.asm
│ ├── BeeperPlaySample.z80
│ ├── LIB
│ ├── Z80_HEADER.ASM
│ └── ZXSPECTRUM.INC
│ ├── Make.bat
│ └── sample.bin
└── PSG
├── Axel-F
├── LIB
│ ├── Z80_HEADER.ASM
│ ├── ZXSPECTRUM.INC
│ └── ZXSPECTRUM_PSG.INC
├── Make.bat
├── PSGAxel-F.asm
└── PSGAxel-F.z80
├── FFPrelude
├── LIB
│ ├── Z80_HEADER.ASM
│ ├── ZXSPECTRUM.INC
│ └── ZXSPECTRUM_PSG.INC
├── Make.bat
├── PSGFFPrelude.asm
└── PSGFFPrelude.z80
├── PlayNote
├── LIB
│ ├── Z80_HEADER.ASM
│ ├── ZXSPECTRUM.INC
│ └── ZXSPECTRUM_PSG.INC
├── Make.bat
├── PSGPlayNote.asm
└── PSGPlayNote.z80
├── Twinkle
├── LIB
│ ├── Z80_HEADER.ASM
│ ├── ZXSPECTRUM.INC
│ └── ZXSPECTRUM_PSG.INC
├── Make.bat
├── PSGTwinkle.asm
└── PSGTwinkle.z80
├── Twinkle2Channel
├── LIB
│ ├── Z80_HEADER.ASM
│ ├── ZXSPECTRUM.INC
│ └── ZXSPECTRUM_PSG.INC
├── Make.bat
├── PSGTwinkle2Channel.asm
└── PSGTwinkle2Channel.z80
└── Twinkle3Channel
├── LIB
├── Z80_HEADER.ASM
├── ZXSPECTRUM.INC
└── ZXSPECTRUM_PSG.INC
├── Make.bat
├── PSGTwinkle3Channel.asm
└── PSGTwinkle3Channel.z80
/Compress/LZ77Decode/GFX/Lenna.lz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Compress/LZ77Decode/GFX/Lenna.lz
--------------------------------------------------------------------------------
/Compress/LZ77Decode/GFX/Lenna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Compress/LZ77Decode/GFX/Lenna.png
--------------------------------------------------------------------------------
/Compress/LZ77Decode/GFX/Lenna.scr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Compress/LZ77Decode/GFX/Lenna.scr
--------------------------------------------------------------------------------
/Compress/LZ77Decode/GFX/compress.bat:
--------------------------------------------------------------------------------
1 | gbacrushercl -L Lenna.scr -O Lenna.lz
2 |
--------------------------------------------------------------------------------
/Compress/LZ77Decode/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Compress/LZ77Decode/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Compress/LZ77Decode/LZ77Decode.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum LZ77 Decode demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "LZ77Decode.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($5CCB) ; Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | // Decode LZ77/LZSS Data To Screen Bitmap & Color Area
16 | ld hl,Screen+4 // HL = LZ Source Offset (Skip LZ Header)
17 | ld de,SCR_BMP // DE = Destination Address
18 | LZLoop:
19 | ld a,(hl) // A = Flag Data For Next 8 Blocks (0 = Uncompressed Byte, 1 = Compressed Bytes)
20 | inc hl // HL++
21 | ld b,a // B = A
22 | ld c,%10000000 // C = Flag Data Block Type Shifter
23 | LZBlockLoop:
24 | ld a,(Screen+2) // A = Data Length Hi Byte
25 | add a,SCR_COL+767>>8 // A = Destination End Offset Hi Byte
26 | cp d // Compare Destination End Offset Hi Byte With Destination Address Hi Byte
27 | jr nz,LZContinue
28 | ld a,(Screen+1) // A = Destination End Offset Lo Byte
29 | cp e // Compare Destination End Offset Lo Byte With Destination Address Lo Byte
30 | jr z,LZEnd // IF (Destination Address == Destination End Offset) LZ End
31 | LZContinue:
32 | xor a // A = 0
33 | cp c // IF (Flag Data Block Type Shifter == 0) LZ Loop
34 | jr z,LZLoop
35 | ld a,b // A = Flag Data For Next 8 Blocks (0 = Uncompressed Byte, 1 = Compressed Bytes)
36 | and c // Test Block Type
37 | jr nz,LZDecode // IF (Block Type != 0) LZ Decode Bytes
38 | srl c // Shift C To Next Flag Data Block Type
39 | ld a,(hl) // ELSE Copy Uncompressed Byte
40 | inc hl // HL++
41 | ld (de),a // Store Uncompressed Byte To Destination Address
42 | inc de // Destination Address++
43 | jr LZBlockLoop
44 | LZDecode:
45 | srl c // Shift C To Next Flag Data Block Type
46 | push bc // Push BC To Stack
47 | ld a,(hl) // A = Number Of Bytes To Copy & Disp MSB's
48 | inc hl // HL++
49 | ld b,a // B = A
50 | ld a,(hl) // A = Disp LSB's
51 | inc hl // HL++
52 | push hl // Push HL To Stack
53 | cpl // Complement A
54 | ld l,a // L = A
55 | ld a,b // A = B
56 | and $0F // A &= $0F
57 | cpl // Complement A
58 | ld h,a // H = A (HL = -Disp - 1)
59 | add hl,de // HL = Destination - Disp - 1
60 | srl b
61 | srl b
62 | srl b
63 | srl b // B = Number Of Bytes To Copy (Minus 3)
64 | inc b
65 | inc b
66 | inc b // B = Number Of Bytes To Copy
67 | LZCopy:
68 | ld a,(hl) // A = Byte To Copy
69 | inc hl // HL++
70 | ld (de),a // Store Uncompressed Byte To Destination Address
71 | inc de // Destination Address++
72 | dec b // Number Of Bytes To Copy--
73 | jr nz,LZCopy // IF (Number Of Bytes To Copy != 0) LZ Copy Bytes
74 | pop hl // Pop HL Off Stack
75 | pop bc // Pop BC Off Stack
76 | jr LZBlockLoop
77 | LZEnd:
78 |
79 | Loop:
80 | jr Loop
81 |
82 | insert Screen, "GFX/Lenna.lz" // Include LZ Compressed Screen Data (???? Bytes)
--------------------------------------------------------------------------------
/Compress/LZ77Decode/LZ77Decode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Compress/LZ77Decode/LZ77Decode.png
--------------------------------------------------------------------------------
/Compress/LZ77Decode/LZ77Decode.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Compress/LZ77Decode/LZ77Decode.z80
--------------------------------------------------------------------------------
/Compress/LZ77Decode/Make.bat:
--------------------------------------------------------------------------------
1 | bass LZ77Decode.asm
--------------------------------------------------------------------------------
/HelloWorld/HelloWorld.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Hello World Text Printing demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "HelloWorld.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($5CCB) ; Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
16 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
17 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
18 | FillCOL:
19 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
20 | dec hl // Decrement Screen Color Address (HL--)
21 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
22 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
23 |
24 | // Print Text Characters To Screen Bitmap Area
25 | ld c,13*8 // C = Byte Copy Count (13 Characters * 8 Bytes)
26 | ld de,SCR_BMP+9+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 9, ROW = 3, SCREEN BLOCK = 1)
27 | ld ix,Text // IX = Text Offset
28 |
29 | LoopText:
30 | ld h,0 // H = 0
31 | ld l,(ix+$00) // L = Next Text Character (L = IX[0])
32 | add hl,hl // HL *= 8
33 | add hl,hl
34 | add hl,hl // HL = Text Character Address
35 |
36 | ld a,c // A = Byte Copy Count (C)
37 | ld bc,Font8x8-($20*8) // BC = Font Address
38 | add hl,bc // Text Character Address (HL) += Font Address (BC)
39 | ld c,a // C = Byte Copy Count (A)
40 |
41 | ld b,7 // B = Count (7)
42 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
43 | LoopTextByte:
44 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
45 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
46 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
47 | djnz LoopTextByte // Decrement Count (B--), IF (Count != 0) Loop Text Byte
48 |
49 | xor a // A = 0
50 | cp c // Compare C To A
51 | jr z,TextEnd // IF (Z Flag Set) Text End
52 |
53 | ld a,-7 // A = -7
54 | add a,d // Subtract 7 From Screen Bitmap Area Address MSB (D -= 7) (7 Scanlines Up)
55 | ld d,a // D = A
56 | inc ix // Increment Text Offset (IX++)
57 | jr LoopText
58 | TextEnd:
59 |
60 | Loop:
61 | jr Loop
62 |
63 | Text:
64 | db "Hello, World!" // Hello World Text (13 Bytes)
65 |
66 | Font8x8:
67 | include "Font8x8.asm" // Include 8x8 Font
--------------------------------------------------------------------------------
/HelloWorld/HelloWorld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/HelloWorld/HelloWorld.png
--------------------------------------------------------------------------------
/HelloWorld/HelloWorld.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/HelloWorld/HelloWorld.z80
--------------------------------------------------------------------------------
/HelloWorld/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/HelloWorld/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/HelloWorld/Make.bat:
--------------------------------------------------------------------------------
1 | bass HelloWorld.asm
--------------------------------------------------------------------------------
/Input/Joystick/Cursor/JoystickCursor.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Joystick Cursor Input demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "JoystickCursor.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($5CCB) ; Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
16 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
17 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
18 | FillCOL:
19 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
20 | dec hl // Decrement Screen Color Address (HL--)
21 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
22 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
23 |
24 | // Print Text Characters To Screen Bitmap Area
25 | ld c,27*8 // C = Byte Copy Count (27 Characters * 8 Bytes)
26 | ld de,SCR_BMP+2+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 2, ROW = 3, SCREEN BLOCK = 1)
27 | ld ix,Text // IX = Text Offset
28 |
29 | LoopText:
30 | ld h,0 // H = 0
31 | ld l,(ix+$00) // L = Next Text Character (L = IX[0])
32 | add hl,hl // HL *= 8
33 | add hl,hl
34 | add hl,hl // HL = Text Character Address
35 |
36 | ld a,c // A = Byte Copy Count (C)
37 | ld bc,Font8x8-($20*8) // BC = Font Address
38 | add hl,bc // Text Character Address (HL) += Font Address (BC)
39 | ld c,a // C = Byte Copy Count (A)
40 |
41 | ld b,7 // B = Count (7)
42 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
43 | LoopTextByte:
44 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
45 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
46 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
47 | djnz LoopTextByte // Decrement Count (B--), IF (Count != 0) Loop Text Byte
48 |
49 | xor a // A = 0
50 | cp c // Compare C To A
51 | jr z,TextEnd // IF (Z Flag Set) Text End
52 |
53 | ld a,-7 // A = -7
54 | add a,d // Subtract 7 From Screen Bitmap Area Address MSB (D -= 7) (7 Scanlines Up)
55 | ld d,a // D = A
56 | inc ix // Increment Text Offset (IX++)
57 | jr LoopText
58 | TextEnd:
59 |
60 | Loop:
61 | // Print Joystick Cursor Text Character To Screen Bitmap Area
62 | call ReadJoystickCursor // A = Character Byte Code From Pressed Button
63 | cp 0 // Compare A To 0
64 | jr z,Skip // IF (A = 0) Skip
65 |
66 | ld de,SCR_BMP+27+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 27, ROW = 3, SCREEN BLOCK = 1)
67 | ld h,0 // H = 0
68 | ld l,a // L = Text Character (A)
69 | add hl,hl // HL *= 8
70 | add hl,hl
71 | add hl,hl // HL = Text Character Address
72 |
73 | ld bc,Font8x8-($20*8) // BC = Font Address
74 | add hl,bc // Text Character Address (HL) += Font Address (BC)
75 |
76 | ld b,7 // B = Count (7)
77 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
78 | LoopButtonTextByte:
79 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
80 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
81 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
82 | djnz LoopButtonTextByte // Decrement Count (B--), IF (Count != 0) Loop Button Text Byte
83 |
84 | Skip:
85 | jr Loop
86 |
87 | ReadJoystickCursor: // Read Joystick Cursor (A = Character Byte Code From Pressed Button)
88 | ld hl,CursorMap // HL = Cursor Map Address
89 | ld bc,$F7FE // BC = Cursor Address A ($F7FE)
90 | in a,(c) // A = Buttons From Cursor Address A (BC)
91 | and $10 // A &= $10 (Mask Bit 4)
92 | srl a // A >>= 3
93 | srl a
94 | srl a
95 | ld d,a // D = A
96 | ld b,$EF // BC = Cursor Address B ($EFFE)
97 | in a,(c) // A = Buttons From Cursor Address B (BC)
98 | and $1D // A &= $1D (Mask Bits 0,2,3,4)
99 | or d // A |= D
100 | ld b,5 // B = Button Count (Number Of Buttons = 5)
101 | ReadButton:
102 | srl a // Logical Shift A Right, Carry Flag = Bit 0
103 | jr nc,ButtonFound // IF (Carry Flag = 0) Button Found
104 | inc hl // ELSE: Increment Cursor Map Address (HL++) For Next Table Address
105 | djnz ReadButton // Decrement Button Count (B--), IF (Button Count != 0) Read Button
106 | ret // Button Not Found: A = 0
107 | ButtonFound:
108 | ld a,(hl) // Button Found: A = Character Byte Code
109 | ret
110 | CursorMap:
111 | db "F","L","R","U","D" // Character 0..4
112 |
113 | Text:
114 | db "Joystick Cursor Input = \d \d" // Joystick Cursor Input Text (27 Bytes)
115 |
116 | Font8x8:
117 | include "Font8x8.asm" // Include 8x8 Font
--------------------------------------------------------------------------------
/Input/Joystick/Cursor/JoystickCursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Joystick/Cursor/JoystickCursor.png
--------------------------------------------------------------------------------
/Input/Joystick/Cursor/JoystickCursor.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Joystick/Cursor/JoystickCursor.z80
--------------------------------------------------------------------------------
/Input/Joystick/Cursor/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Input/Joystick/Cursor/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Input/Joystick/Cursor/Make.bat:
--------------------------------------------------------------------------------
1 | bass JoystickCursor.asm
--------------------------------------------------------------------------------
/Input/Joystick/FullerBox/JoystickFullerBox.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Joystick Fuller Box Input demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "JoystickFullerBox.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($5CCB) ; Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
16 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
17 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
18 | FillCOL:
19 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
20 | dec hl // Decrement Screen Color Address (HL--)
21 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
22 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
23 |
24 | // Print Text Characters To Screen Bitmap Area
25 | ld c,31*8 // C = Byte Copy Count (31 Characters * 8 Bytes)
26 | ld de,SCR_BMP+0+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 0, ROW = 3, SCREEN BLOCK = 1)
27 | ld ix,Text // IX = Text Offset
28 |
29 | LoopText:
30 | ld h,0 // H = 0
31 | ld l,(ix+$00) // L = Next Text Character (L = IX[0])
32 | add hl,hl // HL *= 8
33 | add hl,hl
34 | add hl,hl // HL = Text Character Address
35 |
36 | ld a,c // A = Byte Copy Count (C)
37 | ld bc,Font8x8-($20*8) // BC = Font Address
38 | add hl,bc // Text Character Address (HL) += Font Address (BC)
39 | ld c,a // C = Byte Copy Count (A)
40 |
41 | ld b,7 // B = Count (7)
42 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
43 | LoopTextByte:
44 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
45 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
46 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
47 | djnz LoopTextByte // Decrement Count (B--), IF (Count != 0) Loop Text Byte
48 |
49 | xor a // A = 0
50 | cp c // Compare C To A
51 | jr z,TextEnd // IF (Z Flag Set) Text End
52 |
53 | ld a,-7 // A = -7
54 | add a,d // Subtract 7 From Screen Bitmap Area Address MSB (D -= 7) (7 Scanlines Up)
55 | ld d,a // D = A
56 | inc ix // Increment Text Offset (IX++)
57 | jr LoopText
58 | TextEnd:
59 |
60 | Loop:
61 | // Print Joystick Fuller Box Text Character To Screen Bitmap Area
62 | call ReadJoystickFullerBox // A = Character Byte Code From Pressed Button
63 | cp 0 // Compare A To 0
64 | jr z,Skip // IF (A = 0) Skip
65 |
66 | ld de,SCR_BMP+29+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 29, ROW = 3, SCREEN BLOCK = 1)
67 | ld h,0 // H = 0
68 | ld l,a // L = Text Character (A)
69 | add hl,hl // HL *= 8
70 | add hl,hl
71 | add hl,hl // HL = Text Character Address
72 |
73 | ld bc,Font8x8-($20*8) // BC = Font Address
74 | add hl,bc // Text Character Address (HL) += Font Address (BC)
75 |
76 | ld b,7 // B = Count (7)
77 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
78 | LoopButtonTextByte:
79 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
80 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
81 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
82 | djnz LoopButtonTextByte // Decrement Count (B--), IF (Count != 0) Loop Button Text Byte
83 |
84 | Skip:
85 | jr Loop
86 |
87 | ReadJoystickFullerBox: // Read Joystick Fuller Box (A = Character Byte Code From Pressed Button)
88 | ld hl,FullerBoxMap // HL = Fuller Box Map Address
89 | in a,($7F) // A = Buttons From Fuller Box Port ($7F)
90 | rlca // Rotate A Left Through Carry Flag
91 | and $1F // A &= $1F (Mask 1st 5 Bits)
92 | ld b,5 // B = Button Count (Number Of Buttons = 5)
93 | ReadButton:
94 | srl a // Logical Shift A Right, Carry Flag = Bit 0
95 | jr nc,ButtonFound // IF (Carry Flag = 0) Button Found
96 | inc hl // ELSE: Increment Fuller Box Map Address (HL++) For Next Table Address
97 | djnz ReadButton // Decrement Button Count (B--), IF (Button Count != 0) Read Button
98 | ret // Button Not Found: A = 0
99 | ButtonFound:
100 | ld a,(hl) // Button Found: A = Character Byte Code
101 | ret
102 | FullerBoxMap:
103 | db "F","U","D","L","R" // Character 0..4
104 |
105 | Text:
106 | db "Joystick Fuller Box Input = \d \d" // Joystick Fuller Box Input Text (31 Bytes)
107 |
108 | Font8x8:
109 | include "Font8x8.asm" // Include 8x8 Font
--------------------------------------------------------------------------------
/Input/Joystick/FullerBox/JoystickFullerBox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Joystick/FullerBox/JoystickFullerBox.png
--------------------------------------------------------------------------------
/Input/Joystick/FullerBox/JoystickFullerBox.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Joystick/FullerBox/JoystickFullerBox.z80
--------------------------------------------------------------------------------
/Input/Joystick/FullerBox/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Input/Joystick/FullerBox/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Input/Joystick/FullerBox/Make.bat:
--------------------------------------------------------------------------------
1 | bass JoystickFullerBox.asm
--------------------------------------------------------------------------------
/Input/Joystick/Kempston/JoystickKempston.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Joystick Kempston Input demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "JoystickKempston.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($5CCB) ; Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
16 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
17 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
18 | FillCOL:
19 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
20 | dec hl // Decrement Screen Color Address (HL--)
21 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
22 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
23 |
24 | // Print Text Characters To Screen Bitmap Area
25 | ld c,29*8 // C = Byte Copy Count (29 Characters * 8 Bytes)
26 | ld de,SCR_BMP+1+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 1, ROW = 3, SCREEN BLOCK = 1)
27 | ld ix,Text // IX = Text Offset
28 |
29 | LoopText:
30 | ld h,0 // H = 0
31 | ld l,(ix+$00) // L = Next Text Character (L = IX[0])
32 | add hl,hl // HL *= 8
33 | add hl,hl
34 | add hl,hl // HL = Text Character Address
35 |
36 | ld a,c // A = Byte Copy Count (C)
37 | ld bc,Font8x8-($20*8) // BC = Font Address
38 | add hl,bc // Text Character Address (HL) += Font Address (BC)
39 | ld c,a // C = Byte Copy Count (A)
40 |
41 | ld b,7 // B = Count (7)
42 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
43 | LoopTextByte:
44 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
45 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
46 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
47 | djnz LoopTextByte // Decrement Count (B--), IF (Count != 0) Loop Text Byte
48 |
49 | xor a // A = 0
50 | cp c // Compare C To A
51 | jr z,TextEnd // IF (Z Flag Set) Text End
52 |
53 | ld a,-7 // A = -7
54 | add a,d // Subtract 7 From Screen Bitmap Area Address MSB (D -= 7) (7 Scanlines Up)
55 | ld d,a // D = A
56 | inc ix // Increment Text Offset (IX++)
57 | jr LoopText
58 | TextEnd:
59 |
60 | Loop:
61 | // Print Joystick Kempston Text Character To Screen Bitmap Area
62 | call ReadJoystickKempston // A = Character Byte Code From Pressed Button
63 | cp 0 // Compare A To 0
64 | jr z,Skip // IF (A = 0) Skip
65 |
66 | ld de,SCR_BMP+28+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 28, ROW = 3, SCREEN BLOCK = 1)
67 | ld h,0 // H = 0
68 | ld l,a // L = Text Character (A)
69 | add hl,hl // HL *= 8
70 | add hl,hl
71 | add hl,hl // HL = Text Character Address
72 |
73 | ld bc,Font8x8-($20*8) // BC = Font Address
74 | add hl,bc // Text Character Address (HL) += Font Address (BC)
75 |
76 | ld b,7 // B = Count (7)
77 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
78 | LoopButtonTextByte:
79 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
80 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
81 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
82 | djnz LoopButtonTextByte // Decrement Count (B--), IF (Count != 0) Loop Button Text Byte
83 |
84 | Skip:
85 | jr Loop
86 |
87 | ReadJoystickKempston: // Read Joystick Kempston (A = Character Byte Code From Pressed Button)
88 | ld hl,KempstonMap // HL = Kempston Map Address
89 | in a,($1F) // A = Buttons From Kempston Port ($1F)
90 | and $1F // A &= $1F (Mask 1st 5 Bits)
91 | ld b,5 // B = Button Count (Number Of Buttons = 5)
92 | ReadButton:
93 | srl a // Logical Shift A Right, Carry Flag = Bit 0
94 | jr c,ButtonFound // IF (Carry Flag = 1) Button Found
95 | inc hl // ELSE: Increment Kempston Map Address (HL++) For Next Table Address
96 | djnz ReadButton // Decrement Button Count (B--), IF (Button Count != 0) Read Button
97 | ret // Button Not Found: A = 0
98 | ButtonFound:
99 | ld a,(hl) // Button Found: A = Character Byte Code
100 | ret
101 | KempstonMap:
102 | db "R","L","D","U","F" // Character 0..4
103 |
104 | Text:
105 | db "Joystick Kempston Input = \d \d" // Joystick Kempston Input Text (29 Bytes)
106 |
107 | Font8x8:
108 | include "Font8x8.asm" // Include 8x8 Font
--------------------------------------------------------------------------------
/Input/Joystick/Kempston/JoystickKempston.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Joystick/Kempston/JoystickKempston.png
--------------------------------------------------------------------------------
/Input/Joystick/Kempston/JoystickKempston.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Joystick/Kempston/JoystickKempston.z80
--------------------------------------------------------------------------------
/Input/Joystick/Kempston/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Input/Joystick/Kempston/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Input/Joystick/Kempston/Make.bat:
--------------------------------------------------------------------------------
1 | bass JoystickKempston.asm
--------------------------------------------------------------------------------
/Input/Joystick/Sinclair/JoystickSinclair.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Joystick Sinclair P@ort 1 & 2 Input demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "JoystickSinclair.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($5CCB) ; Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
16 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
17 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
18 | FillCOL:
19 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
20 | dec hl // Decrement Screen Color Address (HL--)
21 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
22 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
23 |
24 | // Print Text 1 Characters To Screen Bitmap Area
25 | ld c,30*8 // C = Byte Copy Count (30 Characters * 8 Bytes)
26 | ld de,SCR_BMP+1+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 1, ROW = 3, SCREEN BLOCK = 1)
27 | ld ix,Text1 // IX = Text 1 Offset
28 |
29 | LoopText1:
30 | ld h,0 // H = 0
31 | ld l,(ix+$00) // L = Next Text Character (L = IX[0])
32 | add hl,hl // HL *= 8
33 | add hl,hl
34 | add hl,hl // HL = Text Character Address
35 |
36 | ld a,c // A = Byte Copy Count (C)
37 | ld bc,Font8x8-($20*8) // BC = Font Address
38 | add hl,bc // Text Character Address (HL) += Font Address (BC)
39 | ld c,a // C = Byte Copy Count (A)
40 |
41 | ld b,7 // B = Count (7)
42 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
43 | LoopText1Byte:
44 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
45 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
46 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
47 | djnz LoopText1Byte // Decrement Count (B--), IF (Count != 0) Loop Text 1 Byte
48 |
49 | xor a // A = 0
50 | cp c // Compare C To A
51 | jr z,Text1End // IF (Z Flag Set) Text 1 End
52 |
53 | ld a,-7 // A = -7
54 | add a,d // Subtract 7 From Screen Bitmap Area Address MSB (D -= 7) (7 Scanlines Up)
55 | ld d,a // D = A
56 | inc ix // Increment Text 1 Offset (IX++)
57 | jr LoopText1
58 | Text1End:
59 |
60 | // Print Text 2 Characters To Screen Bitmap Area
61 | ld c,30*8 // C = Byte Copy Count (30 Characters * 8 Bytes)
62 | ld de,SCR_BMP+1+(32*4)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 1, ROW = 4, SCREEN BLOCK = 1)
63 | ld ix,Text2 // IX = Text 2 Offset
64 |
65 | LoopText2:
66 | ld h,0 // H = 0
67 | ld l,(ix+$00) // L = Next Text Character (L = IX[0])
68 | add hl,hl // HL *= 8
69 | add hl,hl
70 | add hl,hl // HL = Text Character Address
71 |
72 | ld a,c // A = Byte Copy Count (C)
73 | ld bc,Font8x8-($20*8) // BC = Font Address
74 | add hl,bc // Text Character Address (HL) += Font Address (BC)
75 | ld c,a // C = Byte Copy Count (A)
76 |
77 | ld b,7 // B = Count (7)
78 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
79 | LoopText2Byte:
80 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
81 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
82 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
83 | djnz LoopText2Byte // Decrement Count (B--), IF (Count != 0) Loop Text 2 Byte
84 |
85 | xor a // A = 0
86 | cp c // Compare C To A
87 | jr z,Text2End // IF (Z Flag Set) Text 2 End
88 |
89 | ld a,-7 // A = -7
90 | add a,d // Subtract 7 From Screen Bitmap Area Address MSB (D -= 7) (7 Scanlines Up)
91 | ld d,a // D = A
92 | inc ix // Increment Text 2 Offset (IX++)
93 | jr LoopText2
94 | Text2End:
95 |
96 | Loop:
97 | // Print Joystick Sinclair Port 1 Text Character To Screen Bitmap Area
98 | call ReadJoystickSinclair1 // A = Character Byte Code From Pressed Button
99 | cp 0 // Compare A To 0
100 | jr z,Skip1 // IF (A = 0) Skip 1
101 |
102 | ld de,SCR_BMP+29+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 29, ROW = 3, SCREEN BLOCK = 1)
103 | ld h,0 // H = 0
104 | ld l,a // L = Text Character (A)
105 | add hl,hl // HL *= 8
106 | add hl,hl
107 | add hl,hl // HL = Text Character Address
108 |
109 | ld bc,Font8x8-($20*8) // BC = Font Address
110 | add hl,bc // Text Character Address (HL) += Font Address (BC)
111 |
112 | ld b,7 // B = Count (7)
113 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
114 | LoopButtonTextByte1:
115 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
116 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
117 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
118 | djnz LoopButtonTextByte1 // Decrement Count (B--), IF (Count != 0) Loop Button Text Byte 1
119 |
120 | Skip1:
121 |
122 | // Print Joystick Sinclair Port 2 Text Character To Screen Bitmap Area
123 | call ReadJoystickSinclair2 // A = Character Byte Code From Pressed Button
124 | cp 0 // Compare A To 0
125 | jr z,Skip2 // IF (A = 0) Skip 2
126 |
127 | ld de,SCR_BMP+29+(32*4)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 29, ROW = 4, SCREEN BLOCK = 1)
128 | ld h,0 // H = 0
129 | ld l,a // L = Text Character (A)
130 | add hl,hl // HL *= 8
131 | add hl,hl
132 | add hl,hl // HL = Text Character Address
133 |
134 | ld bc,Font8x8-($20*8) // BC = Font Address
135 | add hl,bc // Text Character Address (HL) += Font Address (BC)
136 |
137 | ld b,7 // B = Count (7)
138 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
139 | LoopButtonTextByte2:
140 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
141 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
142 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
143 | djnz LoopButtonTextByte2 // Decrement Count (B--), IF (Count != 0) Loop Button Text Byte 2
144 |
145 | Skip2:
146 | jr Loop
147 |
148 | ReadJoystickSinclair1: // Read Joystick Sinclair Port 1 (A = Character Byte Code From Pressed Button)
149 | ld hl,Sinclair1Map // HL = Sinclair Map Address
150 | ld bc,$EFFE // BC = Sinclair Port 1 ($EFFE)
151 | in a,(c) // A = Buttons From Sinclair Port 1 (BC)
152 | and $1F // A &= $1F (Mask 1st 5 Bits)
153 | ld b,5 // B = Button Count (Number Of Buttons = 5)
154 | ReadButton1:
155 | srl a // Logical Shift A Right, Carry Flag = Bit 0
156 | jr nc,ButtonFound1 // IF (Carry Flag = 0) Button Found 1
157 | inc hl // ELSE: Increment Sinclair Map Address (HL++) For Next Table Address
158 | djnz ReadButton1 // Decrement Button Count (B--), IF (Button Count != 0) Read Button 1
159 | ret // Button Not Found: A = 0
160 | ButtonFound1:
161 | ld a,(hl) // Button Found: A = Character Byte Code
162 | ret
163 | Sinclair1Map:
164 | db "F","U","D","R","L" // Character 0..4
165 |
166 | ReadJoystickSinclair2: // Read Joystick Sinclair Port 2 (A = Character Byte Code From Pressed Button)
167 | ld hl,Sinclair2Map // HL = Sinclair Map Address
168 | ld bc,$F7FE // BC = Sinclair Port 2 ($F7FE)
169 | in a,(c) // A = Buttons From Sinclair Port 2 (BC)
170 | and $1F // A &= $1F (Mask 1st 5 Bits)
171 | ld b,5 // B = Button Count (Number Of Buttons = 5)
172 | ReadButton2:
173 | srl a // Logical Shift A Right, Carry Flag = Bit 0
174 | jr nc,ButtonFound2 // IF (Carry Flag = 0) Button Found 2
175 | inc hl // ELSE: Increment Sinclair Map Address (HL++) For Next Table Address
176 | djnz ReadButton2 // Decrement Button Count (B--), IF (Button Count != 0) Read Button 2
177 | ret // Button Not Found: A = 0
178 | ButtonFound2:
179 | ld a,(hl) // Button Found: A = Character Byte Code
180 | ret
181 | Sinclair2Map:
182 | db "L","R","D","U","F" // Character 0..4
183 |
184 | Text1:
185 | db "Joystick Sinclair Port 1 = \d \d" // Joystick Sinclair Port 1 Input Text (30 Bytes)
186 | Text2:
187 | db "Joystick Sinclair Port 2 = \d \d" // Joystick Sinclair Port 2 Input Text (30 Bytes)
188 |
189 | Font8x8:
190 | include "Font8x8.asm" // Include 8x8 Font
--------------------------------------------------------------------------------
/Input/Joystick/Sinclair/JoystickSinclair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Joystick/Sinclair/JoystickSinclair.png
--------------------------------------------------------------------------------
/Input/Joystick/Sinclair/JoystickSinclair.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Joystick/Sinclair/JoystickSinclair.z80
--------------------------------------------------------------------------------
/Input/Joystick/Sinclair/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Input/Joystick/Sinclair/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Input/Joystick/Sinclair/Make.bat:
--------------------------------------------------------------------------------
1 | bass JoystickSinclair.asm
--------------------------------------------------------------------------------
/Input/Keyboard/Keyboard.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Keyboard Input demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "Keyboard.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($5CCB) ; Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
16 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
17 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
18 | FillCOL:
19 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
20 | dec hl // Decrement Screen Color Address (HL--)
21 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
22 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
23 |
24 | // Print Text Characters To Screen Bitmap Area
25 | ld c,20*8 // C = Byte Copy Count (20 Characters * 8 Bytes)
26 | ld de,SCR_BMP+6+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 6, ROW = 3, SCREEN BLOCK = 1)
27 | ld ix,Text // IX = Text Offset
28 |
29 | LoopText:
30 | ld h,0 // H = 0
31 | ld l,(ix+$00) // L = Next Text Character (L = IX[0])
32 | add hl,hl // HL *= 8
33 | add hl,hl
34 | add hl,hl // HL = Text Character Address
35 |
36 | ld a,c // A = Byte Copy Count (C)
37 | ld bc,Font8x8-($20*8) // BC = Font Address
38 | add hl,bc // Text Character Address (HL) += Font Address (BC)
39 | ld c,a // C = Byte Copy Count (A)
40 |
41 | ld b,7 // B = Count (7)
42 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
43 | LoopTextByte:
44 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
45 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
46 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
47 | djnz LoopTextByte // Decrement Count (B--), IF (Count != 0) Loop Text Byte
48 |
49 | xor a // A = 0
50 | cp c // Compare C To A
51 | jr z,TextEnd // IF (Z Flag Set) Text End
52 |
53 | ld a,-7 // A = -7
54 | add a,d // Subtract 7 From Screen Bitmap Area Address MSB (D -= 7) (7 Scanlines Up)
55 | ld d,a // D = A
56 | inc ix // Increment Text Offset (IX++)
57 | jr LoopText
58 | TextEnd:
59 |
60 | Loop:
61 | // Print Keyboard Text Character To Screen Bitmap Area
62 | call ReadKeyboard // A = Character Byte Code From Pressed Key
63 | cp 0 // Compare A To 0
64 | jr z,Skip // IF (A = 0) Skip
65 |
66 | ld de,SCR_BMP+24+(32*3)+($800*1) // DE = Screen Bitmap Area Address ($4000..$57FF) (Starting Position Of Text: COLUMN = 24, ROW = 3, SCREEN BLOCK = 1)
67 | ld h,0 // H = 0
68 | ld l,a // L = Text Character (A)
69 | add hl,hl // HL *= 8
70 | add hl,hl
71 | add hl,hl // HL = Text Character Address
72 |
73 | ld bc,Font8x8-($20*8) // BC = Font Address
74 | add hl,bc // Text Character Address (HL) += Font Address (BC)
75 |
76 | ld b,7 // B = Count (7)
77 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
78 | LoopKeyTextByte:
79 | dec de // Decrement Screen Bitmap Area Address (DE--) (8 Pixels Back)
80 | inc d // Increment Screen Bitmap Area Address MSB (D++) (1 Scanline Down)
81 | ldi // Copy Text Character Data To Screen Bitmap Area (LD (DE),(HL), DE++, HL++, BC--)
82 | djnz LoopKeyTextByte // Decrement Count (B--), IF (Count != 0) Loop Key Text Byte
83 |
84 | Skip:
85 | jr Loop
86 |
87 | ReadKeyboard: // Read Keyboard (A = Character Byte Code From Pressed Key)
88 | ld hl,KeyboardMap // HL = Keyboard Map Address
89 | ld d,8 // D = Keyboard ROW Count (Number Of Keyboard Ports To Check = 8)
90 | ld c,$FE // C = Keyboard Port LSB Address (Always $FE For Reading Keyboard Ports)
91 | ReadPort:
92 | ld b,(hl) // B = Keyboard Port MSB Address From Table (BC = Keyboard Port)
93 | inc hl // Increment Keyboard Map Address (HL++) To Get Key List
94 | in a,(c) // A = Row Of Keys From Keyboard Port (BC)
95 | and $1F // A &= $1F (Mask 1st 5 Bits)
96 | ld b,5 // B = Key Count (Number Of Keys In Row = 5)
97 | ReadKey:
98 | srl a // Logical Shift A Right, Carry Flag = Bit 0
99 | jr nc,KeyFound // IF (Carry Flag = 0) Key Found
100 | inc hl // ELSE: Increment Keyboard Map Address (HL++) For Next Table Address
101 | djnz ReadKey // Decrement Key Count (B--), IF (Key Count != 0) Read Key
102 | dec d // Decrement Keyboard ROW Count (D--)
103 | jr nz,ReadPort // IF (Keyboard ROW Count != 0) Read Port
104 | ret // Key Not Found: A = 0
105 | KeyFound:
106 | ld a,(hl) // Key Found: A = Character Byte Code
107 | ret
108 | KeyboardMap:
109 | db $FE, "#","Z","X","C","V" // ROW 0: Keyboard Port MSB, Character 0..4
110 | db $FD, "A","S","D","F","G" // ROW 1: Keyboard Port MSB, Character 0..4
111 | db $FB, "Q","W","E","R","T" // ROW 2: Keyboard Port MSB, Character 0..4
112 | db $F7, "1","2","3","4","5" // ROW 3: Keyboard Port MSB, Character 0..4
113 | db $EF, "0","9","8","7","6" // ROW 4: Keyboard Port MSB, Character 0..4
114 | db $DF, "P","O","I","U","Y" // ROW 5: Keyboard Port MSB, Character 0..4
115 | db $BF, "#","L","K","J","H" // ROW 6: Keyboard Port MSB, Character 0..4
116 | db $7F, " ","#","M","N","B" // ROW 7: Keyboard Port MSB, Character 0..4
117 |
118 | Text:
119 | db "Keyboard Input = \d \d" // Keyboard Input Text (20 Bytes)
120 |
121 | Font8x8:
122 | include "Font8x8.asm" // Include 8x8 Font
--------------------------------------------------------------------------------
/Input/Keyboard/Keyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Keyboard/Keyboard.png
--------------------------------------------------------------------------------
/Input/Keyboard/Keyboard.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Keyboard/Keyboard.z80
--------------------------------------------------------------------------------
/Input/Keyboard/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Input/Keyboard/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Input/Keyboard/Make.bat:
--------------------------------------------------------------------------------
1 | bass Keyboard.asm
--------------------------------------------------------------------------------
/Input/Mouse/Kempston/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Input/Mouse/Kempston/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Input/Mouse/Kempston/Make.bat:
--------------------------------------------------------------------------------
1 | bass MouseKempston.asm
--------------------------------------------------------------------------------
/Input/Mouse/Kempston/MouseKempston.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Mouse/Kempston/MouseKempston.png
--------------------------------------------------------------------------------
/Input/Mouse/Kempston/MouseKempston.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Input/Mouse/Kempston/MouseKempston.z80
--------------------------------------------------------------------------------
/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/LIB/ZXSPECTRUM_PSG.INC:
--------------------------------------------------------------------------------
1 | //===================================== (Key: RW = Read/Write)
2 | // ZX Spectrum 128K AY8912 PSG Include
3 | //=====================================
4 | //---------------------
5 | // I/O Map (Z80 Ports)
6 | //---------------------
7 | //--------
8 | // AY8912
9 | //--------
10 | constant AY8912_ADDR($FFFD) // $FFFD: AY8912 - Address W
11 |
12 | // AY8912 - Read (Write Address Port $FFFD, Read Data Port $FFFD)
13 | constant AY8912_READ($FFFD) // $FFFD: AY8912 - Read Data R
14 |
15 | // AY8912 - Write (Write Address Port $FFFD, Write Data Port $BFFD)
16 | constant AY8912_WRITE($BFFD) // $BFFD: AY8912 - Write Data W
17 |
18 | //------------
19 | // AY8912 PSG
20 | //------------
21 | constant PSG_FINE_TUNE_A($00) // $00: AY8912 PSG - Channel A Fine Tune (Bits 0..7) RW
22 | constant PSG_COARSE_TUNE_A($01) // $01: AY8912 PSG - Channel A Coarse Tune (Bits 0..3) RW
23 | constant PSG_FINE_TUNE_B($02) // $02: AY8912 PSG - Channel B Fine Tune (Bits 0..7) RW
24 | constant PSG_COARSE_TUNE_B($03) // $03: AY8912 PSG - Channel B Coarse Tune (Bits 0..3) RW
25 | constant PSG_FINE_TUNE_C($04) // $04: AY8912 PSG - Channel C Fine Tune (Bits 0..7) RW
26 | constant PSG_COARSE_TUNE_C($05) // $05: AY8912 PSG - Channel C Coarse Tune (Bits 0..3) RW
27 | constant PSG_NOISE_TUNE($06) // $06: AY8912 PSG - Channel Noise Tune (Bits 0..4) RW
28 |
29 | constant PSG_KEY($07) // $07: AY8912 PSG - Port A/B Mode (Bits 6..7), Channel Enable Noise (Bits 3..5), Tone (Bits 0..2) RW
30 |
31 | constant PSG_MODE_VOL_A($08) // $08: AY8912 PSG - Channel A Mode (Bit 4), Volume (Bits 0..3) RW
32 | constant PSG_MODE_VOL_B($09) // $09: AY8912 PSG - Channel B Mode (Bit 4), Volume (Bits 0..3) RW
33 | constant PSG_MODE_VOL_C($0A) // $0A: AY8912 PSG - Channel C Mode (Bit 4), Volume (Bits 0..3) RW
34 |
35 | constant PSG_ENV_FINE_TUNE($0B) // $0B: AY8912 PSG - Volume Envelope Period Fine Tune (Bits 0..7) RW
36 | constant PSG_ENV_COARSE_TUNE($0C) // $0C: AY8912 PSG - Volume Envelope Period Coarse Tune (Bits 0..7) RW
37 |
38 | // AY8912 PSG - Volume Envelope Shape (8 = |\|\|\|\, 9 = |\____, 10 = |\/\/, 11 = |\/''', 12= /|/|/|/|, 13 = /''', 14 = /\/\, 15 = /|___)
39 | constant PSG_ENV_SHAPE($0D) // $0D: AY8912 PSG - Volume Envelope Shape (Bits 0..3) RW
40 |
41 | constant PSG_PORT_A($0E) // $0E: AY8912 PSG - Port A (With External Pinouts On AY8910 & AY8912) RW
42 | constant PSG_PORT_B($0F) // $0F: AY8910 PSG - Port B (With External Pinouts On AY8910 Only) RW
43 |
44 | // Frequency WORD Offsets For Period Table
45 | constant A0($00)
46 | constant A0s($02)
47 | constant B0b($02)
48 | constant B0($04)
49 | constant C1($06)
50 | constant C1s($08)
51 | constant D1b($08)
52 | constant D1($0A)
53 | constant D1s($0C)
54 | constant E1b($0C)
55 | constant E1($0E)
56 | constant F1($10)
57 | constant F1s($12)
58 | constant G1b($12)
59 | constant G1($14)
60 | constant G1s($16)
61 | constant A1b($16)
62 |
63 | constant A1($18)
64 | constant A1s($1A)
65 | constant B1b($1A)
66 | constant B1($1C)
67 | constant C2($1E)
68 | constant C2s($20)
69 | constant D2b($20)
70 | constant D2($22)
71 | constant D2s($24)
72 | constant E2b($24)
73 | constant E2($26)
74 | constant F2($28)
75 | constant F2s($2A)
76 | constant G2b($2A)
77 | constant G2($2C)
78 | constant G2s($2E)
79 | constant A2b($2E)
80 |
81 | constant A2($30)
82 | constant A2s($32)
83 | constant B2b($32)
84 | constant B2($34)
85 | constant C3($36)
86 | constant C3s($38)
87 | constant D3b($38)
88 | constant D3($3A)
89 | constant D3s($3C)
90 | constant E3b($3C)
91 | constant E3($3E)
92 | constant F3($40)
93 | constant F3s($42)
94 | constant G3b($42)
95 | constant G3($44)
96 | constant G3s($46)
97 | constant A3b($46)
98 |
99 | constant A3($48)
100 | constant A3s($4A)
101 | constant B3b($4A)
102 | constant B3($4C)
103 | constant C4($4E)
104 | constant C4s($50)
105 | constant D4b($50)
106 | constant D4($52)
107 | constant D4s($54)
108 | constant E4b($54)
109 | constant E4($56)
110 | constant F4($58)
111 | constant F4s($5A)
112 | constant G4b($5A)
113 | constant G4($5C)
114 | constant G4s($5E)
115 | constant A4b($5E)
116 |
117 | constant A4($60)
118 | constant A4s($62)
119 | constant B4b($62)
120 | constant B4($64)
121 | constant C5($66)
122 | constant C5s($68)
123 | constant D5b($68)
124 | constant D5($6A)
125 | constant D5s($6C)
126 | constant E5b($6C)
127 | constant E5($6E)
128 | constant F5($70)
129 | constant F5s($72)
130 | constant G5b($72)
131 | constant G5($74)
132 | constant G5s($76)
133 | constant A5b($76)
134 |
135 | constant A5($78)
136 | constant A5s($7A)
137 | constant B5b($7A)
138 | constant B5($7C)
139 | constant C6($7E)
140 | constant C6s($80)
141 | constant D6b($80)
142 | constant D6($82)
143 | constant D6s($84)
144 | constant E6b($84)
145 | constant E6($86)
146 | constant F6($88)
147 | constant F6s($8A)
148 | constant G6b($8A)
149 | constant G6($8C)
150 | constant G6s($8E)
151 | constant A6b($8E)
152 |
153 | constant A6($90)
154 | constant A6s($92)
155 | constant B6b($92)
156 | constant B6($94)
157 | constant C7($96)
158 | constant C7s($98)
159 | constant D7b($98)
160 | constant D7($9A)
161 | constant D7s($9C)
162 | constant E7b($9C)
163 | constant E7($9E)
164 | constant F7($A0)
165 | constant F7s($A2)
166 | constant G7b($A2)
167 | constant G7($A4)
168 | constant G7s($A6)
169 | constant A7b($A6)
170 |
171 | constant A7($A8)
172 | constant A7s($AA)
173 | constant B7b($AA)
174 | constant B7($AC)
175 | constant C8($AE)
176 | constant C8s($B0)
177 | constant D8b($B0)
178 | constant D8($B2)
179 | constant D8s($B4)
180 | constant E8b($B4)
181 | constant E8($B6)
182 | constant F8($B8)
183 | constant F8s($BA)
184 | constant G8b($BA)
185 | constant G8($BC)
186 | constant G8s($BE)
187 | constant A8b($BE)
188 |
189 | constant A8($B0)
190 | constant A8s($B2)
191 | constant B8b($B2)
192 | constant B8($B4)
193 | constant C9($B6)
194 | constant C9s($B8)
195 | constant D9b($B8)
196 | constant D9($BA)
197 | constant D9s($BC)
198 | constant E9b($BC)
199 | constant E9($BE)
200 | constant F9($C0)
201 | constant F9s($C2)
202 | constant G9b($C2)
203 | constant G9($C4)
204 | constant G9s($C6)
205 | constant A9b($C6)
206 |
207 | constant SUST($FE)
208 | constant REST($FF)
209 |
210 | macro PeriodTable() { // Timing, 9 Octaves: A0..G9# (108 Words)
211 | dw $FE4,$F00,$E28,$D5D,$C9D,$BE7,$B3D,$A9B,$A03,$973,$8EB,$86B // A0..G1#
212 | dw $7F2,$780,$714,$6AE,$64E,$5F3,$59E,$54D,$501,$4B9,$475,$435 // A1..G2#
213 | dw $3F9,$3C0,$38A,$357,$327,$2F9,$2CF,$2A6,$280,$25C,$23A,$21A // A2..G3#
214 | dw $1FC,$1E0,$1C5,$1AB,$193,$17C,$167,$153,$140,$12E,$11D,$10D // A3..G4#
215 | dw $0FE,$0F0,$0E2,$0D5,$0C9,$0BE,$0B3,$0A9,$0A0,$097,$08E,$086 // A4..G5#
216 | dw $07F,$078,$071,$06A,$064,$05F,$059,$054,$050,$04B,$047,$043 // A5..G6#
217 | dw $03F,$03C,$038,$035,$032,$02F,$02C,$02A,$028,$025,$023,$021 // A6..G7#
218 | dw $01F,$01E,$01C,$01A,$019,$017,$016,$015,$014,$012,$011,$010 // A7..G8#
219 | dw $00F,$00F,$00E,$00D,$00C,$00B,$00B,$00A,$00A,$009,$008,$008 // A8..G9#
220 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ZXSpectrum
2 | ==========
3 |
4 | ZX Spectrum Bare Metal Code by krom (Peter Lemon).
5 |
6 | All code compiles out of box with the bass assembler by byuu.
7 | I use a special version of bass by ARM9 which has been updated with ZX Spectrum Z80 output:
8 | https://github.com/ARM9/bass
9 | I have included binaries of all the demos.
10 |
11 | I also use a tool called Image Spectrumizer, which I use to convert GFX to the ZX Spectrum screen:
12 | https://github.com/jarikomppa/img2spec
13 |
14 | Special thanks to Dobo/spec-chum, who has helped me get into ZX Spectrum Coding =D
15 | Check out his github here: https://github.com/spec-chum
16 |
17 | Check out Retro Programming for useful tips on Z80 Coding here: http://www.retroprogramming.com
18 | Also check out World of Spectrum here: https://www.worldofspectrum.org
19 |
20 | Please check out Speccy by Marat Fayzullin, an accurate ZX Spectrum emulator with debugger:
21 | https://fms.komkon.org/Speccy
22 |
23 | Howto Compile:
24 | All the code compiles into a single binary (TAPENAME.Z80) file.
25 | Using bass Run: make.bat
26 |
27 | Howto Run:
28 | I only test with a real ZX Spectrum 128+3 using the fast disk upload tool Project OTLA:
29 | https://code.google.com/archive/p/otla
30 |
31 | You can also use ZX Spectrum emulators like Speccy & the MAME ZX Spectrum Driver.
--------------------------------------------------------------------------------
/Screen/FillPixel/FillPixel.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Fill Pixel demo by krom (Peter Lemon):
2 | // Original Code by Introspec
3 | arch zxs.cpu
4 | output "FillPixel.z80", create
5 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
6 | fill $C000 // Fill 48KB Program Code With Zero Bytes
7 |
8 | macro seek(variable offset) {
9 | origin (offset-$4000)+30
10 | base offset
11 | }
12 |
13 | seek($5CCB) ; Start: // Entry Point Of Code
14 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
15 |
16 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
17 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
18 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
19 | FillCOL:
20 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
21 | dec hl // Decrement Screen Color Address (HL--)
22 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
23 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
24 |
25 | // Fill Screen Bitmap Area With Alternating Pixels Each Scanline
26 | ld hl,SCR_BMP+6143 // HL = Screen Bitmap Area End Address ($4000+6143)
27 | FillBMP:
28 | ld a,h
29 | rra
30 | sbc a,a
31 | xor %01010101
32 | ld (hl),a
33 | dec hl
34 | bit 6,h
35 | jr nz,FillBMP
36 |
37 | Loop:
38 | jr Loop
--------------------------------------------------------------------------------
/Screen/FillPixel/FillPixel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/FillPixel/FillPixel.png
--------------------------------------------------------------------------------
/Screen/FillPixel/FillPixel.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/FillPixel/FillPixel.z80
--------------------------------------------------------------------------------
/Screen/FillPixel/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Screen/FillPixel/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Screen/FillPixel/Make.bat:
--------------------------------------------------------------------------------
1 | bass FillPixel.asm
--------------------------------------------------------------------------------
/Screen/FillScreen/FillScreen.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Fill Screen demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "FillScreen.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($5CCB) ; Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | // Fill Screen Bitmap & Color Area With Screen Data
16 | ld bc,Screen.size // BC = Screen Data Size Count (6912 Bytes)
17 | ld de,SCR_BMP // DE = Screen Bitmap Area Start Address ($4000)
18 | ld hl,Screen // HL = Screen Data Start Address
19 | ldir // Copy Screen Data To Screen Bitmap/Color Area (WHILE BC > 0 (LD (DE),(HL), DE++, HL++, BC--))
20 |
21 | Loop:
22 | jr Loop
23 |
24 | insert Screen, "GFX/Lenna.scr" // Include Screen Data (6912 Bytes)
--------------------------------------------------------------------------------
/Screen/FillScreen/FillScreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/FillScreen/FillScreen.png
--------------------------------------------------------------------------------
/Screen/FillScreen/FillScreen.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/FillScreen/FillScreen.z80
--------------------------------------------------------------------------------
/Screen/FillScreen/GFX/Lenna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/FillScreen/GFX/Lenna.png
--------------------------------------------------------------------------------
/Screen/FillScreen/GFX/Lenna.scr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/FillScreen/GFX/Lenna.scr
--------------------------------------------------------------------------------
/Screen/FillScreen/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Screen/FillScreen/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Screen/FillScreen/Make.bat:
--------------------------------------------------------------------------------
1 | bass FillScreen.asm
--------------------------------------------------------------------------------
/Screen/Fractal/Mandelbrot/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Screen/Fractal/Mandelbrot/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Screen/Fractal/Mandelbrot/Make.bat:
--------------------------------------------------------------------------------
1 | bass Mandelbrot.asm
--------------------------------------------------------------------------------
/Screen/Fractal/Mandelbrot/Mandelbrot.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Mandelbrot Fractal demo by krom (Peter Lemon):
2 | // Original Code by John Metcalf
3 | arch zxs.cpu
4 | output "Mandelbrot.z80", create
5 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
6 | fill $C000 // Fill 48KB Program Code With Zero Bytes
7 |
8 | macro seek(variable offset) {
9 | origin (offset-$4000)+30
10 | base offset
11 | }
12 |
13 | seek($5CCB) ; Start: // Entry Point Of Code
14 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
15 |
16 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
17 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
18 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
19 | FillCOL:
20 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
21 | dec hl // Decrement Screen Color Address (HL--)
22 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
23 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
24 |
25 | // Plot Mandelbrot Fractal
26 | ld de,255*256+191
27 | XLOOP:
28 | push de
29 | ld hl,-180 // X Coordinate
30 | ld e,d
31 | call SCALE
32 | ld (XPOS),bc
33 | pop de
34 | YLOOP:
35 | push de
36 | ld hl,-96 // Y Coordinate
37 | call SCALE
38 | ld (YPOS),bc
39 | ld hl,0
40 | ld (IMAG),hl
41 | ld (REAL),hl
42 | ld b,15 // Iterations
43 | ITER:
44 | push bc
45 | ld bc,(IMAG)
46 | ld hl,(REAL)
47 | or a
48 | sbc hl,bc
49 | ld d,h
50 | ld e,l
51 | add hl,bc
52 | add hl,bc
53 | call FIXMUL
54 | ld de,(XPOS)
55 | add hl,de
56 | ld de,(REAL)
57 | ld (REAL),hl
58 | ld hl,(IMAG)
59 | call FIXMUL
60 | rla
61 | adc hl,hl
62 | ld de,(YPOS)
63 | add hl,de
64 | ld (IMAG),hl
65 | call ABSVAL
66 | ex de,hl
67 | ld hl,(REAL)
68 | call ABSVAL
69 | add hl,de
70 | ld a,h
71 | cp 46 // 46 ~= 2 * V 2 << 4
72 | pop bc
73 | jr nc,ESCAPE
74 | djnz ITER
75 | pop de
76 | call PLOT
77 | db 254 // Trick To Skip Next Instruction ("cp $D1" Instruction On Return From CALL)
78 | ESCAPE:
79 | pop de
80 | dec e
81 | jr nz,YLOOP
82 | dec d
83 | jr nz,XLOOP
84 | ret
85 |
86 | FIXMUL: // HL = HL * DE >> 24
87 | call MULT16BY16
88 | ld a,b
89 | ld b,4
90 | FMSHIFT:
91 | rla
92 | adc hl,hl
93 | djnz FMSHIFT
94 | ret
95 |
96 | SCALE: // BC = (HL + E) * Zoom
97 | ld d,0
98 | add hl,de
99 | ld de,48 // Zoom
100 |
101 | MULT16BY16: // HL:BC (Signed 32-Bit) = HL * DE
102 | xor a
103 | call ABSVAL
104 | ex de,hl
105 | call ABSVAL
106 | push af
107 | ld c,h
108 | ld a,l
109 | call MULT8BY16
110 | ld b,a
111 | ld a,c
112 | ld c,h
113 | push bc
114 | ld c,l
115 | call MULT8BY16
116 | pop de
117 | add hl,de
118 | adc a,b
119 | ld b,l
120 | ld l,h
121 | ld h,a
122 | pop af
123 | rra
124 | ret nc
125 | ex de,hl
126 | xor a
127 | ld h,a
128 | ld l,a
129 | sbc hl,bc
130 | ld b,h
131 | ld c,l
132 | ld h,a
133 | ld l,a
134 | sbc hl,de
135 | ret
136 |
137 | MULT8BY16: // Return A:HL (24-Bit) = A * DE
138 | ld hl,0
139 | ld b,8
140 | M816LOOP:
141 | add hl,hl
142 | rla
143 | jr nc,M816SKIP
144 | add hl,de
145 | adc a,0
146 | M816SKIP:
147 | djnz M816LOOP
148 | ret
149 |
150 | PLOT: // Plot Pixel (D = X Position, E = Y Position)
151 | ld a,7
152 | and d
153 | ld b,a
154 | inc b
155 | ld a,e
156 | rra
157 | scf
158 | rra
159 | or a
160 | rra
161 | ld l,a
162 | xor e
163 | and 248
164 | xor e
165 | ld h,a
166 | ld a,d
167 | xor l
168 | and 7
169 | xor d
170 | rrca
171 | rrca
172 | rrca
173 | ld l,a
174 | ld a,1
175 | PLOTBIT:
176 | rrca
177 | djnz PLOTBIT
178 | or (hl)
179 | ld (hl),a
180 | ret
181 |
182 | ABSVAL: // Returns HL = |HL|, Increments A IF Sign Bit Has Changed
183 | bit 7,h
184 | ret z
185 | ld b,h
186 | ld c,l
187 | ld hl,0
188 | or a
189 | sbc hl,bc
190 | inc a
191 | ret
192 |
193 | XPOS:
194 | dw 0
195 | YPOS:
196 | dw 0
197 | REAL:
198 | dw 0
199 | IMAG:
200 | dw 0
--------------------------------------------------------------------------------
/Screen/Fractal/Mandelbrot/Mandelbrot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/Fractal/Mandelbrot/Mandelbrot.png
--------------------------------------------------------------------------------
/Screen/Fractal/Mandelbrot/Mandelbrot.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/Fractal/Mandelbrot/Mandelbrot.z80
--------------------------------------------------------------------------------
/Screen/PlotLine/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Screen/PlotLine/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Screen/PlotLine/Make.bat:
--------------------------------------------------------------------------------
1 | bass PlotLine.asm
--------------------------------------------------------------------------------
/Screen/PlotLine/PlotLine.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Plot Line demo by krom (Peter Lemon):
2 | // Original Code by John Metcalf
3 | arch zxs.cpu
4 | output "PlotLine.z80", create
5 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
6 | fill $C000 // Fill 48KB Program Code With Zero Bytes
7 |
8 | macro seek(variable offset) {
9 | origin (offset-$4000)+30
10 | base offset
11 | }
12 |
13 | seek($5CCB) ; Start: // Entry Point Of Code
14 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
15 |
16 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
17 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
18 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
19 | FillCOL:
20 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
21 | dec hl // Decrement Screen Color Address (HL--)
22 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
23 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
24 |
25 | // Plot Line Using Recursive Divide & Conquer Over Screen Bitmap Area
26 | ld de,$0000 // DE = Line End1 (D = X Position, E = Y Position)
27 | ld hl,$FFBF // HL = Line End2 (H = X Position, L = Y Position)
28 | call DRAWLINE
29 |
30 | Loop:
31 | jr Loop
32 |
33 | DRAWLINE:
34 | call PLOT
35 | push hl
36 |
37 | // Calculate Centre Pixel (HL)
38 | ld a,l
39 | add a,e
40 | rra
41 | ld l,a
42 | ld a,h
43 | add a,d
44 | rra
45 | ld h,a
46 |
47 | or a
48 | sbc hl,de
49 | jr z,EXIT // IF (DE (End1) = HL (Centre)) Exit
50 | add hl,de
51 |
52 | ex de,hl
53 | call DRAWLINE // DE = Centre, HL = End1
54 | ex (sp),hl
55 | ex de,hl
56 | call DRAWLINE // DE = End2, HL = Centre
57 |
58 | ex de,hl
59 | pop de
60 | ret
61 |
62 | EXIT:
63 | pop hl
64 | ret
65 |
66 | PLOT: // Plot Pixel (D = X Position, E = Y Position)
67 | push hl
68 | ld a,d
69 | and 7
70 | ld b,a
71 | inc b
72 | ld a,e
73 | rra
74 | scf
75 | rra
76 | or a
77 | rra
78 | ld l,a
79 | xor e
80 | and 248
81 | xor e
82 | ld h,a
83 | ld a,l
84 | xor d
85 | and 7
86 | xor d
87 | rrca
88 | rrca
89 | rrca
90 | ld l,a
91 | ld a,1
92 | PLOTBIT:
93 | rrca
94 | djnz PLOTBIT
95 | or (hl)
96 | ld (hl),a
97 | pop hl
98 | ret
--------------------------------------------------------------------------------
/Screen/PlotLine/PlotLine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/PlotLine/PlotLine.png
--------------------------------------------------------------------------------
/Screen/PlotLine/PlotLine.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/PlotLine/PlotLine.z80
--------------------------------------------------------------------------------
/Screen/PlotPixel/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Screen/PlotPixel/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Screen/PlotPixel/Make.bat:
--------------------------------------------------------------------------------
1 | bass PlotPixel.asm
--------------------------------------------------------------------------------
/Screen/PlotPixel/PlotPixel.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Plot Pixel demo by krom (Peter Lemon):
2 | // Original Code by John Metcalf
3 | arch zxs.cpu
4 | output "PlotPixel.z80", create
5 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
6 | fill $C000 // Fill 48KB Program Code With Zero Bytes
7 |
8 | macro seek(variable offset) {
9 | origin (offset-$4000)+30
10 | base offset
11 | }
12 |
13 | seek($5CCB) ; Start: // Entry Point Of Code
14 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
15 |
16 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
17 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
18 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
19 | FillCOL:
20 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
21 | dec hl // Decrement Screen Color Address (HL--)
22 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
23 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
24 |
25 | // Plot Pixel In Screen Bitmap Area
26 | ld de,$8060 // DE = XY Position (X = 128, Y = 96)
27 |
28 | PLOT: // Plot Pixel (D = X Position, E = Y Position)
29 | ld a,7
30 | and d
31 | ld b,a
32 | inc b
33 | ld a,e
34 | rra
35 | scf
36 | rra
37 | or a
38 | rra
39 | ld l,a
40 | xor e
41 | and 248
42 | xor e
43 | ld h,a
44 | ld a,d
45 | xor l
46 | and 7
47 | xor d
48 | rrca
49 | rrca
50 | rrca
51 | ld l,a
52 | ld a,1
53 | PLOTBIT:
54 | rrca
55 | djnz PLOTBIT
56 | or (hl)
57 | ld (hl),a
58 |
59 | Loop:
60 | jr Loop
--------------------------------------------------------------------------------
/Screen/PlotPixel/PlotPixel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/PlotPixel/PlotPixel.png
--------------------------------------------------------------------------------
/Screen/PlotPixel/PlotPixel.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/PlotPixel/PlotPixel.z80
--------------------------------------------------------------------------------
/Screen/PlotSprite/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Screen/PlotSprite/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Screen/PlotSprite/Make.bat:
--------------------------------------------------------------------------------
1 | bass PlotSprite.asm
--------------------------------------------------------------------------------
/Screen/PlotSprite/PlotSprite.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Plot Sprite demo by krom (Peter Lemon):
2 | // Original Code by John Metcalf
3 | arch zxs.cpu
4 | output "PlotSprite.z80", create
5 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
6 | fill $C000 // Fill 48KB Program Code With Zero Bytes
7 |
8 | macro seek(variable offset) {
9 | origin (offset-$4000)+30
10 | base offset
11 | }
12 |
13 | seek($5CCB) ; Start: // Entry Point Of Code
14 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
15 |
16 | // Fill Screen Color Area With Full Brightness, White Paper Color, Black Ink Color
17 | ld hl,SCR_COL+767 // HL = Screen Color Area End Address ($5800+767)
18 | ld a,BRIGHT+P_WHITE+I_BLACK // A = Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
19 | FillCOL:
20 | ld (hl),a // Store Color Attributes (A) To Screen Color Area Address (HL)
21 | dec hl // Decrement Screen Color Address (HL--)
22 | bit 3,h // Test Bit 3 Of Screen Color Address MSB (H)
23 | jr nz,FillCOL // IF (Bit 3 Of Screen Color Address MSB != 0) Fill Color
24 |
25 | // Fill Screen Bitmap Area With Alternating Pixels Each Scanline
26 | ld hl,SCR_BMP+6143 // HL = Screen Bitmap Area End Address ($4000+6143)
27 | FillBMP:
28 | ld a,h
29 | rra
30 | sbc a,a
31 | xor %01010101
32 | ld (hl),a
33 | dec hl
34 | bit 6,h
35 | jr nz,FillBMP
36 |
37 | // Plot Sprite Over Screen Bitmap Area
38 | ld hl,Sprite // HL = Sprite Address
39 | ld de,$8050 // DE = Sprite Position On Screen (D = X Position, E = Y Position)
40 |
41 | PutSprite:
42 | ld a,e // A = Sprite Y Position (E)
43 | and $C0 // A &= $C0 (Bits 6 & 7)
44 | cp $C0 // Compare A To $C0
45 | jp z,PutSpriteEnd // IF (Sprite Y Position >= 192) Put Sprite End (Sprite Fully Off Screen)
46 | ld c,16 // C = Sprite Scanlines To Draw
47 | ld a,e // A = Sprite Y Position (E)
48 | and $B0 // A &= $B0 (Bits 4,5 & 7)
49 | cp $B0 // Compare A To $B0
50 | jp nz,NextLine // IF (Sprite Y Position < 176) Next Line
51 | ld c,e // C = Sprite Y Position (E)
52 | ld a,192 // A = 192
53 | sub c // A -= C
54 | ld c,a // C = Sprite Scanlines To Draw (Y Clip)
55 | NextLine:
56 | ld a,d
57 | and 7
58 | inc a
59 | ld b,a
60 | ld a,e
61 | rra
62 | cp 96
63 | ret nc
64 | rra
65 | or a
66 | rra
67 | push de
68 | push hl
69 | ld l,a
70 | xor e
71 | and 248
72 | xor e
73 | ld h,a
74 | ld a,l
75 | xor d
76 | and 7
77 | xor d
78 | rrca
79 | rrca
80 | rrca
81 | ld l,a
82 |
83 | ld e,255
84 | SPD:
85 | ex (sp),hl
86 | ld a,(hl)
87 | inc hl
88 | ld d,(hl)
89 | inc hl
90 | ex (sp),hl
91 |
92 | push bc
93 | rrc e
94 | jr NoShift
95 | ShiftSPR:
96 | rra
97 | rr d
98 | rr e
99 | NoShift:
100 | djnz ShiftSPR
101 |
102 | push hl
103 | ld b,3
104 | Mask:
105 | bit 0,e
106 | jr z,BM1
107 | and (hl)
108 | db 254 // jr BM2
109 | BM1:
110 | xor (hl)
111 | BM2:
112 | ld (hl),a
113 | inc l
114 | ld a,l
115 | and 31
116 | ld a,d
117 | ld d,e
118 | jr z,Clip
119 | djnz Mask
120 | Clip:
121 | bit 0,e
122 | ld e,0
123 | pop hl
124 | pop bc
125 | jr nz,SPD
126 | pop hl
127 | pop de
128 | inc e
129 | dec c
130 | jr nz,NextLine
131 | PutSpriteEnd:
132 |
133 | Loop:
134 | jr Loop
135 |
136 | Sprite:
137 | db %11111100,%00111111, %00000000,%00000000
138 | db %11110000,%00001111, %00000011,%11000000
139 | db %11100000,%00000111, %00001100,%00110000
140 | db %11000000,%00000011, %00010000,%00001000
141 | db %10000000,%00000001, %00100010,%00000100
142 | db %10000000,%00000001, %00100111,%00000100
143 | db %00000000,%00000000, %01000010,%00010010
144 | db %00000000,%00000000, %01000000,%00001010
145 | db %00000000,%00000000, %01000000,%00010010
146 | db %00000000,%00000000, %01000000,%00101010
147 | db %10000000,%00000001, %00100000,%01010100
148 | db %10000000,%00000001, %00100010,%10100100
149 | db %11000000,%00000011, %00010001,%01001000
150 | db %11100000,%00000111, %00001100,%00110000
151 | db %11110000,%00001111, %00000011,%11000000
152 | db %11111100,%00111111, %00000000,%00000000
--------------------------------------------------------------------------------
/Screen/PlotSprite/PlotSprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/PlotSprite/PlotSprite.png
--------------------------------------------------------------------------------
/Screen/PlotSprite/PlotSprite.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Screen/PlotSprite/PlotSprite.z80
--------------------------------------------------------------------------------
/Sound/Beeper/PlayNote/BeeperPlayNote.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Beeper Play Note demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "BeeperPlayNote.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($8000); Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 |
15 | xor a // A = 0
16 | LoopNote:
17 | xor %00010111 // A = Beeper Attributes (---S-BBB: S = BEEPER Sound, B = BORDER Color)
18 | out (SND_BCOL),a // Write Beeper Attributes To Beeper Register Port ($FE)
19 | ld bc,1000 // BC = Pitch (Lower Number = Higher Pitch)
20 | Wait:
21 | dec c // Decrement Pitch LSB (C--)
22 | jr nz,Wait // IF (Pitch LSB != 0) Wait
23 | dec b // Decrement Pitch MSB (B--)
24 | jr nz,Wait // IF (Pitch MSB != 0) Wait
25 | jr LoopNote // ELSE Loop Note
--------------------------------------------------------------------------------
/Sound/Beeper/PlayNote/BeeperPlayNote.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/Beeper/PlayNote/BeeperPlayNote.z80
--------------------------------------------------------------------------------
/Sound/Beeper/PlayNote/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Sound/Beeper/PlayNote/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Sound/Beeper/PlayNote/Make.bat:
--------------------------------------------------------------------------------
1 | bass BeeperPlayNote.asm
--------------------------------------------------------------------------------
/Sound/Beeper/PlaySample/8tosigmadelta.c:
--------------------------------------------------------------------------------
1 | /*
2 | Offline conversion of 8-bit sample files (RAW format, no header) to
3 | 1-bit sigma-delta encoded stream files.
4 |
5 | (C)2012 Miguel Angel Rodriguez Jodar (mcleod_ideafix)
6 | Dept. Architecture and Computer Technology. University of Seville, Spain
7 | Licensed under the terms of GPL.
8 |
9 | Change input and output files to suit your needs.
10 | TO-DO: process input file in chunks, rather than completely load it in memory
11 | */
12 |
13 | #define INPUTFILE "sample.raw"
14 | #define OUTPUTFILE "sample.bin"
15 |
16 | #include
17 | #include
18 |
19 | void main (void)
20 | {
21 | FILE *f;
22 | int leido;
23 | int i,sample,integrador,salida,filesize;
24 | unsigned char *buffer; /* remove "unsigned" if using signed samples */
25 | unsigned char *buffout;
26 |
27 | f=fopen (INPUTFILE, "rb");
28 | fseek (f, 0, SEEK_END);
29 | filesize = ftell (f);
30 | fseek (f, 0, SEEK_SET);
31 | buffer=malloc(filesize);
32 | buffout=malloc(filesize/4);
33 | filesize = fread (buffer, 1, filesize, f);
34 | fclose(f);
35 |
36 | integrador = 0;
37 | salida = 0;
38 | memset (buffout, 0, filesize/4);
39 |
40 | for (i=0;i0)
45 | {
46 | salida=127;
47 | buffout[i/4] = buffout[i/4] | (1<<(7-(i*2)%8));
48 | }
49 | else
50 | {
51 | salida=-128;
52 | }
53 |
54 | /* repeat once (2x oversampling) */
55 | integrador += (sample-salida);
56 | if (integrador>0)
57 | {
58 | salida=127;
59 | buffout[i/4] = buffout[i/4] | (1<<(7-(i*2+1)%8));
60 | }
61 | else
62 | {
63 | salida=-128;
64 | }
65 | }
66 |
67 | f=fopen (OUTPUTFILE, "wb");
68 | fwrite (buffout, 1, filesize/4, f);
69 | fclose(f);
70 |
71 | free(buffer);
72 | free(buffout);
73 | }
--------------------------------------------------------------------------------
/Sound/Beeper/PlaySample/BeeperPlaySample.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum Beeper Play Sample demo by krom (Peter Lemon):
2 | // Original Code by Miguel Angel Rodriguez Jodar. (mcleod_ideafix)
3 | // Simple player for 1-bit samples. See file 8tosigmadelta.c for sigma-delta
4 | // offline conversion of RAW 8-bit PCM sample files to 1-bit sample files.
5 |
6 | arch zxs.cpu
7 | output "BeeperPlaySample.z80", create
8 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
9 | fill $C000 // Fill 48KB Program Code With Zero Bytes
10 |
11 | macro seek(variable offset) {
12 | origin (offset-$4000)+30
13 | base offset
14 | }
15 |
16 | seek($8000); Start: // Entry Point Of Code
17 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
18 |
19 | di // Disable Interrupts
20 | Loop:
21 | ld hl,Sample
22 | ld de,Sample.size
23 | call PlaySample
24 | jr Loop
25 |
26 | PlaySample: // Play Sigma-Delta Sample On Beeper (DE = Sample Length, HL = Sample Address) (Requires Disabled Interrupts)
27 | ld a,(hl) // Load 8 Samples
28 | ld b,8 // B = Count (8)
29 | LoopSample:
30 | ld c,a // Backup To C
31 | and $80 // Isolate High Bit
32 | sra a // A >>= 3 (Shift To Beeper Sound Bit)
33 | sra a
34 | sra a
35 | or I_BLACK // Apply Desired Border Color
36 | out (SND_BCOL),a // Write Beeper Attributes To Beeper Register Port ($FE)
37 | ld a,c // Restore From C
38 | rla // Next Sample Now In High Bit
39 | // nop // Place NOPs Here To Slow Down Playback Rate
40 | djnz LoopSample // Decrement Count (B--), IF (Count != 0) Process Next Sample
41 | inc hl
42 | dec de
43 | ld a,d
44 | or e
45 | jp nz,PlaySample // Process Next 8 Samples
46 | ret
47 |
48 | insert Sample, "sample.bin" // Include 22050Hz 4-Bit Sigma-Delta Sample Data (8856 Bytes)
--------------------------------------------------------------------------------
/Sound/Beeper/PlaySample/BeeperPlaySample.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/Beeper/PlaySample/BeeperPlaySample.z80
--------------------------------------------------------------------------------
/Sound/Beeper/PlaySample/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Sound/Beeper/PlaySample/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Sound/Beeper/PlaySample/Make.bat:
--------------------------------------------------------------------------------
1 | bass BeeperPlaySample.asm
--------------------------------------------------------------------------------
/Sound/Beeper/PlaySample/sample.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/Beeper/PlaySample/sample.bin
--------------------------------------------------------------------------------
/Sound/PSG/Axel-F/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Sound/PSG/Axel-F/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Sound/PSG/Axel-F/LIB/ZXSPECTRUM_PSG.INC:
--------------------------------------------------------------------------------
1 | //===================================== (Key: RW = Read/Write)
2 | // ZX Spectrum 128K AY8912 PSG Include
3 | //=====================================
4 | //---------------------
5 | // I/O Map (Z80 Ports)
6 | //---------------------
7 | //--------
8 | // AY8912
9 | //--------
10 | constant AY8912_ADDR($FFFD) // $FFFD: AY8912 - Address W
11 |
12 | // AY8912 - Read (Write Address Port $FFFD, Read Data Port $FFFD)
13 | constant AY8912_READ($FFFD) // $FFFD: AY8912 - Read Data R
14 |
15 | // AY8912 - Write (Write Address Port $FFFD, Write Data Port $BFFD)
16 | constant AY8912_WRITE($BFFD) // $BFFD: AY8912 - Write Data W
17 |
18 | //------------
19 | // AY8912 PSG
20 | //------------
21 | constant PSG_FINE_TUNE_A($00) // $00: AY8912 PSG - Channel A Fine Tune (Bits 0..7) RW
22 | constant PSG_COARSE_TUNE_A($01) // $01: AY8912 PSG - Channel A Coarse Tune (Bits 0..3) RW
23 | constant PSG_FINE_TUNE_B($02) // $02: AY8912 PSG - Channel B Fine Tune (Bits 0..7) RW
24 | constant PSG_COARSE_TUNE_B($03) // $03: AY8912 PSG - Channel B Coarse Tune (Bits 0..3) RW
25 | constant PSG_FINE_TUNE_C($04) // $04: AY8912 PSG - Channel C Fine Tune (Bits 0..7) RW
26 | constant PSG_COARSE_TUNE_C($05) // $05: AY8912 PSG - Channel C Coarse Tune (Bits 0..3) RW
27 | constant PSG_NOISE_TUNE($06) // $06: AY8912 PSG - Channel Noise Tune (Bits 0..4) RW
28 |
29 | constant PSG_KEY($07) // $07: AY8912 PSG - Port A/B Mode (Bits 6..7), Channel Enable Noise (Bits 3..5), Tone (Bits 0..2) RW
30 |
31 | constant PSG_MODE_VOL_A($08) // $08: AY8912 PSG - Channel A Mode (Bit 4), Volume (Bits 0..3) RW
32 | constant PSG_MODE_VOL_B($09) // $09: AY8912 PSG - Channel B Mode (Bit 4), Volume (Bits 0..3) RW
33 | constant PSG_MODE_VOL_C($0A) // $0A: AY8912 PSG - Channel C Mode (Bit 4), Volume (Bits 0..3) RW
34 |
35 | constant PSG_ENV_FINE_TUNE($0B) // $0B: AY8912 PSG - Volume Envelope Period Fine Tune (Bits 0..7) RW
36 | constant PSG_ENV_COARSE_TUNE($0C) // $0C: AY8912 PSG - Volume Envelope Period Coarse Tune (Bits 0..7) RW
37 |
38 | // AY8912 PSG - Volume Envelope Shape (8 = |\|\|\|\, 9 = |\____, 10 = |\/\/, 11 = |\/''', 12= /|/|/|/|, 13 = /''', 14 = /\/\, 15 = /|___)
39 | constant PSG_ENV_SHAPE($0D) // $0D: AY8912 PSG - Volume Envelope Shape (Bits 0..3) RW
40 |
41 | constant PSG_PORT_A($0E) // $0E: AY8912 PSG - Port A (With External Pinouts On AY8910 & AY8912) RW
42 | constant PSG_PORT_B($0F) // $0F: AY8910 PSG - Port B (With External Pinouts On AY8910 Only) RW
43 |
44 | // Frequency WORD Offsets For Period Table
45 | constant A0($00)
46 | constant A0s($02)
47 | constant B0b($02)
48 | constant B0($04)
49 | constant C1($06)
50 | constant C1s($08)
51 | constant D1b($08)
52 | constant D1($0A)
53 | constant D1s($0C)
54 | constant E1b($0C)
55 | constant E1($0E)
56 | constant F1($10)
57 | constant F1s($12)
58 | constant G1b($12)
59 | constant G1($14)
60 | constant G1s($16)
61 | constant A1b($16)
62 |
63 | constant A1($18)
64 | constant A1s($1A)
65 | constant B1b($1A)
66 | constant B1($1C)
67 | constant C2($1E)
68 | constant C2s($20)
69 | constant D2b($20)
70 | constant D2($22)
71 | constant D2s($24)
72 | constant E2b($24)
73 | constant E2($26)
74 | constant F2($28)
75 | constant F2s($2A)
76 | constant G2b($2A)
77 | constant G2($2C)
78 | constant G2s($2E)
79 | constant A2b($2E)
80 |
81 | constant A2($30)
82 | constant A2s($32)
83 | constant B2b($32)
84 | constant B2($34)
85 | constant C3($36)
86 | constant C3s($38)
87 | constant D3b($38)
88 | constant D3($3A)
89 | constant D3s($3C)
90 | constant E3b($3C)
91 | constant E3($3E)
92 | constant F3($40)
93 | constant F3s($42)
94 | constant G3b($42)
95 | constant G3($44)
96 | constant G3s($46)
97 | constant A3b($46)
98 |
99 | constant A3($48)
100 | constant A3s($4A)
101 | constant B3b($4A)
102 | constant B3($4C)
103 | constant C4($4E)
104 | constant C4s($50)
105 | constant D4b($50)
106 | constant D4($52)
107 | constant D4s($54)
108 | constant E4b($54)
109 | constant E4($56)
110 | constant F4($58)
111 | constant F4s($5A)
112 | constant G4b($5A)
113 | constant G4($5C)
114 | constant G4s($5E)
115 | constant A4b($5E)
116 |
117 | constant A4($60)
118 | constant A4s($62)
119 | constant B4b($62)
120 | constant B4($64)
121 | constant C5($66)
122 | constant C5s($68)
123 | constant D5b($68)
124 | constant D5($6A)
125 | constant D5s($6C)
126 | constant E5b($6C)
127 | constant E5($6E)
128 | constant F5($70)
129 | constant F5s($72)
130 | constant G5b($72)
131 | constant G5($74)
132 | constant G5s($76)
133 | constant A5b($76)
134 |
135 | constant A5($78)
136 | constant A5s($7A)
137 | constant B5b($7A)
138 | constant B5($7C)
139 | constant C6($7E)
140 | constant C6s($80)
141 | constant D6b($80)
142 | constant D6($82)
143 | constant D6s($84)
144 | constant E6b($84)
145 | constant E6($86)
146 | constant F6($88)
147 | constant F6s($8A)
148 | constant G6b($8A)
149 | constant G6($8C)
150 | constant G6s($8E)
151 | constant A6b($8E)
152 |
153 | constant A6($90)
154 | constant A6s($92)
155 | constant B6b($92)
156 | constant B6($94)
157 | constant C7($96)
158 | constant C7s($98)
159 | constant D7b($98)
160 | constant D7($9A)
161 | constant D7s($9C)
162 | constant E7b($9C)
163 | constant E7($9E)
164 | constant F7($A0)
165 | constant F7s($A2)
166 | constant G7b($A2)
167 | constant G7($A4)
168 | constant G7s($A6)
169 | constant A7b($A6)
170 |
171 | constant A7($A8)
172 | constant A7s($AA)
173 | constant B7b($AA)
174 | constant B7($AC)
175 | constant C8($AE)
176 | constant C8s($B0)
177 | constant D8b($B0)
178 | constant D8($B2)
179 | constant D8s($B4)
180 | constant E8b($B4)
181 | constant E8($B6)
182 | constant F8($B8)
183 | constant F8s($BA)
184 | constant G8b($BA)
185 | constant G8($BC)
186 | constant G8s($BE)
187 | constant A8b($BE)
188 |
189 | constant A8($B0)
190 | constant A8s($B2)
191 | constant B8b($B2)
192 | constant B8($B4)
193 | constant C9($B6)
194 | constant C9s($B8)
195 | constant D9b($B8)
196 | constant D9($BA)
197 | constant D9s($BC)
198 | constant E9b($BC)
199 | constant E9($BE)
200 | constant F9($C0)
201 | constant F9s($C2)
202 | constant G9b($C2)
203 | constant G9($C4)
204 | constant G9s($C6)
205 | constant A9b($C6)
206 |
207 | constant SUST($FE)
208 | constant REST($FF)
209 |
210 | macro PeriodTable() { // Timing, 9 Octaves: A0..G9# (108 Words)
211 | dw $FE4,$F00,$E28,$D5D,$C9D,$BE7,$B3D,$A9B,$A03,$973,$8EB,$86B // A0..G1#
212 | dw $7F2,$780,$714,$6AE,$64E,$5F3,$59E,$54D,$501,$4B9,$475,$435 // A1..G2#
213 | dw $3F9,$3C0,$38A,$357,$327,$2F9,$2CF,$2A6,$280,$25C,$23A,$21A // A2..G3#
214 | dw $1FC,$1E0,$1C5,$1AB,$193,$17C,$167,$153,$140,$12E,$11D,$10D // A3..G4#
215 | dw $0FE,$0F0,$0E2,$0D5,$0C9,$0BE,$0B3,$0A9,$0A0,$097,$08E,$086 // A4..G5#
216 | dw $07F,$078,$071,$06A,$064,$05F,$059,$054,$050,$04B,$047,$043 // A5..G6#
217 | dw $03F,$03C,$038,$035,$032,$02F,$02C,$02A,$028,$025,$023,$021 // A6..G7#
218 | dw $01F,$01E,$01C,$01A,$019,$017,$016,$015,$014,$012,$011,$010 // A7..G8#
219 | dw $00F,$00F,$00E,$00D,$00C,$00B,$00B,$00A,$00A,$009,$008,$008 // A8..G9#
220 | }
--------------------------------------------------------------------------------
/Sound/PSG/Axel-F/Make.bat:
--------------------------------------------------------------------------------
1 | bass PSGAxel-F.asm
--------------------------------------------------------------------------------
/Sound/PSG/Axel-F/PSGAxel-F.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/PSG/Axel-F/PSGAxel-F.z80
--------------------------------------------------------------------------------
/Sound/PSG/FFPrelude/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Sound/PSG/FFPrelude/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Sound/PSG/FFPrelude/LIB/ZXSPECTRUM_PSG.INC:
--------------------------------------------------------------------------------
1 | //===================================== (Key: RW = Read/Write)
2 | // ZX Spectrum 128K AY8912 PSG Include
3 | //=====================================
4 | //---------------------
5 | // I/O Map (Z80 Ports)
6 | //---------------------
7 | //--------
8 | // AY8912
9 | //--------
10 | constant AY8912_ADDR($FFFD) // $FFFD: AY8912 - Address W
11 |
12 | // AY8912 - Read (Write Address Port $FFFD, Read Data Port $FFFD)
13 | constant AY8912_READ($FFFD) // $FFFD: AY8912 - Read Data R
14 |
15 | // AY8912 - Write (Write Address Port $FFFD, Write Data Port $BFFD)
16 | constant AY8912_WRITE($BFFD) // $BFFD: AY8912 - Write Data W
17 |
18 | //------------
19 | // AY8912 PSG
20 | //------------
21 | constant PSG_FINE_TUNE_A($00) // $00: AY8912 PSG - Channel A Fine Tune (Bits 0..7) RW
22 | constant PSG_COARSE_TUNE_A($01) // $01: AY8912 PSG - Channel A Coarse Tune (Bits 0..3) RW
23 | constant PSG_FINE_TUNE_B($02) // $02: AY8912 PSG - Channel B Fine Tune (Bits 0..7) RW
24 | constant PSG_COARSE_TUNE_B($03) // $03: AY8912 PSG - Channel B Coarse Tune (Bits 0..3) RW
25 | constant PSG_FINE_TUNE_C($04) // $04: AY8912 PSG - Channel C Fine Tune (Bits 0..7) RW
26 | constant PSG_COARSE_TUNE_C($05) // $05: AY8912 PSG - Channel C Coarse Tune (Bits 0..3) RW
27 | constant PSG_NOISE_TUNE($06) // $06: AY8912 PSG - Channel Noise Tune (Bits 0..4) RW
28 |
29 | constant PSG_KEY($07) // $07: AY8912 PSG - Port A/B Mode (Bits 6..7), Channel Enable Noise (Bits 3..5), Tone (Bits 0..2) RW
30 |
31 | constant PSG_MODE_VOL_A($08) // $08: AY8912 PSG - Channel A Mode (Bit 4), Volume (Bits 0..3) RW
32 | constant PSG_MODE_VOL_B($09) // $09: AY8912 PSG - Channel B Mode (Bit 4), Volume (Bits 0..3) RW
33 | constant PSG_MODE_VOL_C($0A) // $0A: AY8912 PSG - Channel C Mode (Bit 4), Volume (Bits 0..3) RW
34 |
35 | constant PSG_ENV_FINE_TUNE($0B) // $0B: AY8912 PSG - Volume Envelope Period Fine Tune (Bits 0..7) RW
36 | constant PSG_ENV_COARSE_TUNE($0C) // $0C: AY8912 PSG - Volume Envelope Period Coarse Tune (Bits 0..7) RW
37 |
38 | // AY8912 PSG - Volume Envelope Shape (8 = |\|\|\|\, 9 = |\____, 10 = |\/\/, 11 = |\/''', 12= /|/|/|/|, 13 = /''', 14 = /\/\, 15 = /|___)
39 | constant PSG_ENV_SHAPE($0D) // $0D: AY8912 PSG - Volume Envelope Shape (Bits 0..3) RW
40 |
41 | constant PSG_PORT_A($0E) // $0E: AY8912 PSG - Port A (With External Pinouts On AY8910 & AY8912) RW
42 | constant PSG_PORT_B($0F) // $0F: AY8910 PSG - Port B (With External Pinouts On AY8910 Only) RW
43 |
44 | // Frequency WORD Offsets For Period Table
45 | constant A0($00)
46 | constant A0s($02)
47 | constant B0b($02)
48 | constant B0($04)
49 | constant C1($06)
50 | constant C1s($08)
51 | constant D1b($08)
52 | constant D1($0A)
53 | constant D1s($0C)
54 | constant E1b($0C)
55 | constant E1($0E)
56 | constant F1($10)
57 | constant F1s($12)
58 | constant G1b($12)
59 | constant G1($14)
60 | constant G1s($16)
61 | constant A1b($16)
62 |
63 | constant A1($18)
64 | constant A1s($1A)
65 | constant B1b($1A)
66 | constant B1($1C)
67 | constant C2($1E)
68 | constant C2s($20)
69 | constant D2b($20)
70 | constant D2($22)
71 | constant D2s($24)
72 | constant E2b($24)
73 | constant E2($26)
74 | constant F2($28)
75 | constant F2s($2A)
76 | constant G2b($2A)
77 | constant G2($2C)
78 | constant G2s($2E)
79 | constant A2b($2E)
80 |
81 | constant A2($30)
82 | constant A2s($32)
83 | constant B2b($32)
84 | constant B2($34)
85 | constant C3($36)
86 | constant C3s($38)
87 | constant D3b($38)
88 | constant D3($3A)
89 | constant D3s($3C)
90 | constant E3b($3C)
91 | constant E3($3E)
92 | constant F3($40)
93 | constant F3s($42)
94 | constant G3b($42)
95 | constant G3($44)
96 | constant G3s($46)
97 | constant A3b($46)
98 |
99 | constant A3($48)
100 | constant A3s($4A)
101 | constant B3b($4A)
102 | constant B3($4C)
103 | constant C4($4E)
104 | constant C4s($50)
105 | constant D4b($50)
106 | constant D4($52)
107 | constant D4s($54)
108 | constant E4b($54)
109 | constant E4($56)
110 | constant F4($58)
111 | constant F4s($5A)
112 | constant G4b($5A)
113 | constant G4($5C)
114 | constant G4s($5E)
115 | constant A4b($5E)
116 |
117 | constant A4($60)
118 | constant A4s($62)
119 | constant B4b($62)
120 | constant B4($64)
121 | constant C5($66)
122 | constant C5s($68)
123 | constant D5b($68)
124 | constant D5($6A)
125 | constant D5s($6C)
126 | constant E5b($6C)
127 | constant E5($6E)
128 | constant F5($70)
129 | constant F5s($72)
130 | constant G5b($72)
131 | constant G5($74)
132 | constant G5s($76)
133 | constant A5b($76)
134 |
135 | constant A5($78)
136 | constant A5s($7A)
137 | constant B5b($7A)
138 | constant B5($7C)
139 | constant C6($7E)
140 | constant C6s($80)
141 | constant D6b($80)
142 | constant D6($82)
143 | constant D6s($84)
144 | constant E6b($84)
145 | constant E6($86)
146 | constant F6($88)
147 | constant F6s($8A)
148 | constant G6b($8A)
149 | constant G6($8C)
150 | constant G6s($8E)
151 | constant A6b($8E)
152 |
153 | constant A6($90)
154 | constant A6s($92)
155 | constant B6b($92)
156 | constant B6($94)
157 | constant C7($96)
158 | constant C7s($98)
159 | constant D7b($98)
160 | constant D7($9A)
161 | constant D7s($9C)
162 | constant E7b($9C)
163 | constant E7($9E)
164 | constant F7($A0)
165 | constant F7s($A2)
166 | constant G7b($A2)
167 | constant G7($A4)
168 | constant G7s($A6)
169 | constant A7b($A6)
170 |
171 | constant A7($A8)
172 | constant A7s($AA)
173 | constant B7b($AA)
174 | constant B7($AC)
175 | constant C8($AE)
176 | constant C8s($B0)
177 | constant D8b($B0)
178 | constant D8($B2)
179 | constant D8s($B4)
180 | constant E8b($B4)
181 | constant E8($B6)
182 | constant F8($B8)
183 | constant F8s($BA)
184 | constant G8b($BA)
185 | constant G8($BC)
186 | constant G8s($BE)
187 | constant A8b($BE)
188 |
189 | constant A8($B0)
190 | constant A8s($B2)
191 | constant B8b($B2)
192 | constant B8($B4)
193 | constant C9($B6)
194 | constant C9s($B8)
195 | constant D9b($B8)
196 | constant D9($BA)
197 | constant D9s($BC)
198 | constant E9b($BC)
199 | constant E9($BE)
200 | constant F9($C0)
201 | constant F9s($C2)
202 | constant G9b($C2)
203 | constant G9($C4)
204 | constant G9s($C6)
205 | constant A9b($C6)
206 |
207 | constant SUST($FE)
208 | constant REST($FF)
209 |
210 | macro PeriodTable() { // Timing, 9 Octaves: A0..G9# (108 Words)
211 | dw $FE4,$F00,$E28,$D5D,$C9D,$BE7,$B3D,$A9B,$A03,$973,$8EB,$86B // A0..G1#
212 | dw $7F2,$780,$714,$6AE,$64E,$5F3,$59E,$54D,$501,$4B9,$475,$435 // A1..G2#
213 | dw $3F9,$3C0,$38A,$357,$327,$2F9,$2CF,$2A6,$280,$25C,$23A,$21A // A2..G3#
214 | dw $1FC,$1E0,$1C5,$1AB,$193,$17C,$167,$153,$140,$12E,$11D,$10D // A3..G4#
215 | dw $0FE,$0F0,$0E2,$0D5,$0C9,$0BE,$0B3,$0A9,$0A0,$097,$08E,$086 // A4..G5#
216 | dw $07F,$078,$071,$06A,$064,$05F,$059,$054,$050,$04B,$047,$043 // A5..G6#
217 | dw $03F,$03C,$038,$035,$032,$02F,$02C,$02A,$028,$025,$023,$021 // A6..G7#
218 | dw $01F,$01E,$01C,$01A,$019,$017,$016,$015,$014,$012,$011,$010 // A7..G8#
219 | dw $00F,$00F,$00E,$00D,$00C,$00B,$00B,$00A,$00A,$009,$008,$008 // A8..G9#
220 | }
--------------------------------------------------------------------------------
/Sound/PSG/FFPrelude/Make.bat:
--------------------------------------------------------------------------------
1 | bass PSGFFPrelude.asm
--------------------------------------------------------------------------------
/Sound/PSG/FFPrelude/PSGFFPrelude.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/PSG/FFPrelude/PSGFFPrelude.z80
--------------------------------------------------------------------------------
/Sound/PSG/PlayNote/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Sound/PSG/PlayNote/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Sound/PSG/PlayNote/LIB/ZXSPECTRUM_PSG.INC:
--------------------------------------------------------------------------------
1 | //===================================== (Key: RW = Read/Write)
2 | // ZX Spectrum 128K AY8912 PSG Include
3 | //=====================================
4 | //---------------------
5 | // I/O Map (Z80 Ports)
6 | //---------------------
7 | //--------
8 | // AY8912
9 | //--------
10 | constant AY8912_ADDR($FFFD) // $FFFD: AY8912 - Address W
11 |
12 | // AY8912 - Read (Write Address Port $FFFD, Read Data Port $FFFD)
13 | constant AY8912_READ($FFFD) // $FFFD: AY8912 - Read Data R
14 |
15 | // AY8912 - Write (Write Address Port $FFFD, Write Data Port $BFFD)
16 | constant AY8912_WRITE($BFFD) // $BFFD: AY8912 - Write Data W
17 |
18 | //------------
19 | // AY8912 PSG
20 | //------------
21 | constant PSG_FINE_TUNE_A($00) // $00: AY8912 PSG - Channel A Fine Tune (Bits 0..7) RW
22 | constant PSG_COARSE_TUNE_A($01) // $01: AY8912 PSG - Channel A Coarse Tune (Bits 0..3) RW
23 | constant PSG_FINE_TUNE_B($02) // $02: AY8912 PSG - Channel B Fine Tune (Bits 0..7) RW
24 | constant PSG_COARSE_TUNE_B($03) // $03: AY8912 PSG - Channel B Coarse Tune (Bits 0..3) RW
25 | constant PSG_FINE_TUNE_C($04) // $04: AY8912 PSG - Channel C Fine Tune (Bits 0..7) RW
26 | constant PSG_COARSE_TUNE_C($05) // $05: AY8912 PSG - Channel C Coarse Tune (Bits 0..3) RW
27 | constant PSG_NOISE_TUNE($06) // $06: AY8912 PSG - Channel Noise Tune (Bits 0..4) RW
28 |
29 | constant PSG_KEY($07) // $07: AY8912 PSG - Port A/B Mode (Bits 6..7), Channel Enable Noise (Bits 3..5), Tone (Bits 0..2) RW
30 |
31 | constant PSG_MODE_VOL_A($08) // $08: AY8912 PSG - Channel A Mode (Bit 4), Volume (Bits 0..3) RW
32 | constant PSG_MODE_VOL_B($09) // $09: AY8912 PSG - Channel B Mode (Bit 4), Volume (Bits 0..3) RW
33 | constant PSG_MODE_VOL_C($0A) // $0A: AY8912 PSG - Channel C Mode (Bit 4), Volume (Bits 0..3) RW
34 |
35 | constant PSG_ENV_FINE_TUNE($0B) // $0B: AY8912 PSG - Volume Envelope Period Fine Tune (Bits 0..7) RW
36 | constant PSG_ENV_COARSE_TUNE($0C) // $0C: AY8912 PSG - Volume Envelope Period Coarse Tune (Bits 0..7) RW
37 |
38 | // AY8912 PSG - Volume Envelope Shape (8 = |\|\|\|\, 9 = |\____, 10 = |\/\/, 11 = |\/''', 12= /|/|/|/|, 13 = /''', 14 = /\/\, 15 = /|___)
39 | constant PSG_ENV_SHAPE($0D) // $0D: AY8912 PSG - Volume Envelope Shape (Bits 0..3) RW
40 |
41 | constant PSG_PORT_A($0E) // $0E: AY8912 PSG - Port A (With External Pinouts On AY8910 & AY8912) RW
42 | constant PSG_PORT_B($0F) // $0F: AY8910 PSG - Port B (With External Pinouts On AY8910 Only) RW
43 |
44 | // Frequency WORD Offsets For Period Table
45 | constant A0($00)
46 | constant A0s($02)
47 | constant B0b($02)
48 | constant B0($04)
49 | constant C1($06)
50 | constant C1s($08)
51 | constant D1b($08)
52 | constant D1($0A)
53 | constant D1s($0C)
54 | constant E1b($0C)
55 | constant E1($0E)
56 | constant F1($10)
57 | constant F1s($12)
58 | constant G1b($12)
59 | constant G1($14)
60 | constant G1s($16)
61 | constant A1b($16)
62 |
63 | constant A1($18)
64 | constant A1s($1A)
65 | constant B1b($1A)
66 | constant B1($1C)
67 | constant C2($1E)
68 | constant C2s($20)
69 | constant D2b($20)
70 | constant D2($22)
71 | constant D2s($24)
72 | constant E2b($24)
73 | constant E2($26)
74 | constant F2($28)
75 | constant F2s($2A)
76 | constant G2b($2A)
77 | constant G2($2C)
78 | constant G2s($2E)
79 | constant A2b($2E)
80 |
81 | constant A2($30)
82 | constant A2s($32)
83 | constant B2b($32)
84 | constant B2($34)
85 | constant C3($36)
86 | constant C3s($38)
87 | constant D3b($38)
88 | constant D3($3A)
89 | constant D3s($3C)
90 | constant E3b($3C)
91 | constant E3($3E)
92 | constant F3($40)
93 | constant F3s($42)
94 | constant G3b($42)
95 | constant G3($44)
96 | constant G3s($46)
97 | constant A3b($46)
98 |
99 | constant A3($48)
100 | constant A3s($4A)
101 | constant B3b($4A)
102 | constant B3($4C)
103 | constant C4($4E)
104 | constant C4s($50)
105 | constant D4b($50)
106 | constant D4($52)
107 | constant D4s($54)
108 | constant E4b($54)
109 | constant E4($56)
110 | constant F4($58)
111 | constant F4s($5A)
112 | constant G4b($5A)
113 | constant G4($5C)
114 | constant G4s($5E)
115 | constant A4b($5E)
116 |
117 | constant A4($60)
118 | constant A4s($62)
119 | constant B4b($62)
120 | constant B4($64)
121 | constant C5($66)
122 | constant C5s($68)
123 | constant D5b($68)
124 | constant D5($6A)
125 | constant D5s($6C)
126 | constant E5b($6C)
127 | constant E5($6E)
128 | constant F5($70)
129 | constant F5s($72)
130 | constant G5b($72)
131 | constant G5($74)
132 | constant G5s($76)
133 | constant A5b($76)
134 |
135 | constant A5($78)
136 | constant A5s($7A)
137 | constant B5b($7A)
138 | constant B5($7C)
139 | constant C6($7E)
140 | constant C6s($80)
141 | constant D6b($80)
142 | constant D6($82)
143 | constant D6s($84)
144 | constant E6b($84)
145 | constant E6($86)
146 | constant F6($88)
147 | constant F6s($8A)
148 | constant G6b($8A)
149 | constant G6($8C)
150 | constant G6s($8E)
151 | constant A6b($8E)
152 |
153 | constant A6($90)
154 | constant A6s($92)
155 | constant B6b($92)
156 | constant B6($94)
157 | constant C7($96)
158 | constant C7s($98)
159 | constant D7b($98)
160 | constant D7($9A)
161 | constant D7s($9C)
162 | constant E7b($9C)
163 | constant E7($9E)
164 | constant F7($A0)
165 | constant F7s($A2)
166 | constant G7b($A2)
167 | constant G7($A4)
168 | constant G7s($A6)
169 | constant A7b($A6)
170 |
171 | constant A7($A8)
172 | constant A7s($AA)
173 | constant B7b($AA)
174 | constant B7($AC)
175 | constant C8($AE)
176 | constant C8s($B0)
177 | constant D8b($B0)
178 | constant D8($B2)
179 | constant D8s($B4)
180 | constant E8b($B4)
181 | constant E8($B6)
182 | constant F8($B8)
183 | constant F8s($BA)
184 | constant G8b($BA)
185 | constant G8($BC)
186 | constant G8s($BE)
187 | constant A8b($BE)
188 |
189 | constant A8($B0)
190 | constant A8s($B2)
191 | constant B8b($B2)
192 | constant B8($B4)
193 | constant C9($B6)
194 | constant C9s($B8)
195 | constant D9b($B8)
196 | constant D9($BA)
197 | constant D9s($BC)
198 | constant E9b($BC)
199 | constant E9($BE)
200 | constant F9($C0)
201 | constant F9s($C2)
202 | constant G9b($C2)
203 | constant G9($C4)
204 | constant G9s($C6)
205 | constant A9b($C6)
206 |
207 | constant SUST($FE)
208 | constant REST($FF)
209 |
210 | macro PeriodTable() { // Timing, 9 Octaves: A0..G9# (108 Words)
211 | dw $FE4,$F00,$E28,$D5D,$C9D,$BE7,$B3D,$A9B,$A03,$973,$8EB,$86B // A0..G1#
212 | dw $7F2,$780,$714,$6AE,$64E,$5F3,$59E,$54D,$501,$4B9,$475,$435 // A1..G2#
213 | dw $3F9,$3C0,$38A,$357,$327,$2F9,$2CF,$2A6,$280,$25C,$23A,$21A // A2..G3#
214 | dw $1FC,$1E0,$1C5,$1AB,$193,$17C,$167,$153,$140,$12E,$11D,$10D // A3..G4#
215 | dw $0FE,$0F0,$0E2,$0D5,$0C9,$0BE,$0B3,$0A9,$0A0,$097,$08E,$086 // A4..G5#
216 | dw $07F,$078,$071,$06A,$064,$05F,$059,$054,$050,$04B,$047,$043 // A5..G6#
217 | dw $03F,$03C,$038,$035,$032,$02F,$02C,$02A,$028,$025,$023,$021 // A6..G7#
218 | dw $01F,$01E,$01C,$01A,$019,$017,$016,$015,$014,$012,$011,$010 // A7..G8#
219 | dw $00F,$00F,$00E,$00D,$00C,$00B,$00B,$00A,$00A,$009,$008,$008 // A8..G9#
220 | }
--------------------------------------------------------------------------------
/Sound/PSG/PlayNote/Make.bat:
--------------------------------------------------------------------------------
1 | bass PSGPlayNote.asm
--------------------------------------------------------------------------------
/Sound/PSG/PlayNote/PSGPlayNote.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum 128K AY8912 PSG Play Note demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "PSGPlayNote.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($8000); Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 | include "LIB/ZXSPECTRUM_PSG.INC" // Include ZX Spectrum PSG Definitions
15 |
16 | // Play Note On Tone Channel A
17 | ld d,PSG_FINE_TUNE_A // D = PSG Channel A Fine Tune Address ($00)
18 | ld e,0 // E = PSG Channel A Fine Tune (Bits 0..7 Fine Tune = 0)
19 | call PSGWrite // PSG Write Data (D = PSG Address, E = PSG Data)
20 |
21 | ld d,PSG_COARSE_TUNE_A // D = PSG Channel A Course Tune Address ($01)
22 | ld e,1 // E = PSG Channel A Coarse Tune (Bits 0..3 Course Tune = 1)
23 | call PSGWrite // PSG Write Data (D = PSG Address, E = PSG Data)
24 |
25 | ld d,PSG_MODE_VOL_A // D = PSG Channel A Mode/Volume Address ($08)
26 | ld e,15 // E = PSG Channel A Mode/Volume (Bit 4 Mode = 0, Bits 0..3 Volume = 15)
27 | call PSGWrite // PSG Write Data (D = PSG Address, E = PSG Data)
28 |
29 | ld d,PSG_KEY // D = PSG Channel Enable Address ($07)
30 | ld e,%00111110 // E = PSG Channel A Tone Enable (Bits 6..7 Port A/B Mode, Bits 3..5 Channel A..C Enable Noise, Bits 0..2 Channel A..C Enable Tone)
31 | call PSGWrite // PSG Write Data (D = PSG Address, E = PSG Data)
32 |
33 | Loop:
34 | jr Loop
35 |
36 | PSGRead: // PSG Read Data (A = PSG Address, Return A = PSG Data)
37 | ld bc,AY8912_ADDR // BC = AY8912 Address/Read Data Port ($FFFD)
38 | out (c),a // Write PSG Address (A) To AY8912 Address Port (BC)
39 | in a,(c) // Read PSG Data (A) From AY8912 Read Data Port (BC)
40 | ret
41 |
42 | PSGWrite: // PSG Write Data (D = PSG Address, E = PSG Data)
43 | ld bc,AY8912_ADDR // BC = AY8912 Address Port ($FFFD)
44 | out (c),d // Write PSG Address (D) To AY8912 Address Port (BC)
45 | ld b,AY8912_WRITE>>8 // BC = AY8912 Write Data Port ($BFFD)
46 | out (c),e // Write PSG Data (E) To AY8912 Write Data Port (BC)
47 | ret
--------------------------------------------------------------------------------
/Sound/PSG/PlayNote/PSGPlayNote.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/PSG/PlayNote/PSGPlayNote.z80
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle/LIB/ZXSPECTRUM_PSG.INC:
--------------------------------------------------------------------------------
1 | //===================================== (Key: RW = Read/Write)
2 | // ZX Spectrum 128K AY8912 PSG Include
3 | //=====================================
4 | //---------------------
5 | // I/O Map (Z80 Ports)
6 | //---------------------
7 | //--------
8 | // AY8912
9 | //--------
10 | constant AY8912_ADDR($FFFD) // $FFFD: AY8912 - Address W
11 |
12 | // AY8912 - Read (Write Address Port $FFFD, Read Data Port $FFFD)
13 | constant AY8912_READ($FFFD) // $FFFD: AY8912 - Read Data R
14 |
15 | // AY8912 - Write (Write Address Port $FFFD, Write Data Port $BFFD)
16 | constant AY8912_WRITE($BFFD) // $BFFD: AY8912 - Write Data W
17 |
18 | //------------
19 | // AY8912 PSG
20 | //------------
21 | constant PSG_FINE_TUNE_A($00) // $00: AY8912 PSG - Channel A Fine Tune (Bits 0..7) RW
22 | constant PSG_COARSE_TUNE_A($01) // $01: AY8912 PSG - Channel A Coarse Tune (Bits 0..3) RW
23 | constant PSG_FINE_TUNE_B($02) // $02: AY8912 PSG - Channel B Fine Tune (Bits 0..7) RW
24 | constant PSG_COARSE_TUNE_B($03) // $03: AY8912 PSG - Channel B Coarse Tune (Bits 0..3) RW
25 | constant PSG_FINE_TUNE_C($04) // $04: AY8912 PSG - Channel C Fine Tune (Bits 0..7) RW
26 | constant PSG_COARSE_TUNE_C($05) // $05: AY8912 PSG - Channel C Coarse Tune (Bits 0..3) RW
27 | constant PSG_NOISE_TUNE($06) // $06: AY8912 PSG - Channel Noise Tune (Bits 0..4) RW
28 |
29 | constant PSG_KEY($07) // $07: AY8912 PSG - Port A/B Mode (Bits 6..7), Channel Enable Noise (Bits 3..5), Tone (Bits 0..2) RW
30 |
31 | constant PSG_MODE_VOL_A($08) // $08: AY8912 PSG - Channel A Mode (Bit 4), Volume (Bits 0..3) RW
32 | constant PSG_MODE_VOL_B($09) // $09: AY8912 PSG - Channel B Mode (Bit 4), Volume (Bits 0..3) RW
33 | constant PSG_MODE_VOL_C($0A) // $0A: AY8912 PSG - Channel C Mode (Bit 4), Volume (Bits 0..3) RW
34 |
35 | constant PSG_ENV_FINE_TUNE($0B) // $0B: AY8912 PSG - Volume Envelope Period Fine Tune (Bits 0..7) RW
36 | constant PSG_ENV_COARSE_TUNE($0C) // $0C: AY8912 PSG - Volume Envelope Period Coarse Tune (Bits 0..7) RW
37 |
38 | // AY8912 PSG - Volume Envelope Shape (8 = |\|\|\|\, 9 = |\____, 10 = |\/\/, 11 = |\/''', 12= /|/|/|/|, 13 = /''', 14 = /\/\, 15 = /|___)
39 | constant PSG_ENV_SHAPE($0D) // $0D: AY8912 PSG - Volume Envelope Shape (Bits 0..3) RW
40 |
41 | constant PSG_PORT_A($0E) // $0E: AY8912 PSG - Port A (With External Pinouts On AY8910 & AY8912) RW
42 | constant PSG_PORT_B($0F) // $0F: AY8910 PSG - Port B (With External Pinouts On AY8910 Only) RW
43 |
44 | // Frequency WORD Offsets For Period Table
45 | constant A0($00)
46 | constant A0s($02)
47 | constant B0b($02)
48 | constant B0($04)
49 | constant C1($06)
50 | constant C1s($08)
51 | constant D1b($08)
52 | constant D1($0A)
53 | constant D1s($0C)
54 | constant E1b($0C)
55 | constant E1($0E)
56 | constant F1($10)
57 | constant F1s($12)
58 | constant G1b($12)
59 | constant G1($14)
60 | constant G1s($16)
61 | constant A1b($16)
62 |
63 | constant A1($18)
64 | constant A1s($1A)
65 | constant B1b($1A)
66 | constant B1($1C)
67 | constant C2($1E)
68 | constant C2s($20)
69 | constant D2b($20)
70 | constant D2($22)
71 | constant D2s($24)
72 | constant E2b($24)
73 | constant E2($26)
74 | constant F2($28)
75 | constant F2s($2A)
76 | constant G2b($2A)
77 | constant G2($2C)
78 | constant G2s($2E)
79 | constant A2b($2E)
80 |
81 | constant A2($30)
82 | constant A2s($32)
83 | constant B2b($32)
84 | constant B2($34)
85 | constant C3($36)
86 | constant C3s($38)
87 | constant D3b($38)
88 | constant D3($3A)
89 | constant D3s($3C)
90 | constant E3b($3C)
91 | constant E3($3E)
92 | constant F3($40)
93 | constant F3s($42)
94 | constant G3b($42)
95 | constant G3($44)
96 | constant G3s($46)
97 | constant A3b($46)
98 |
99 | constant A3($48)
100 | constant A3s($4A)
101 | constant B3b($4A)
102 | constant B3($4C)
103 | constant C4($4E)
104 | constant C4s($50)
105 | constant D4b($50)
106 | constant D4($52)
107 | constant D4s($54)
108 | constant E4b($54)
109 | constant E4($56)
110 | constant F4($58)
111 | constant F4s($5A)
112 | constant G4b($5A)
113 | constant G4($5C)
114 | constant G4s($5E)
115 | constant A4b($5E)
116 |
117 | constant A4($60)
118 | constant A4s($62)
119 | constant B4b($62)
120 | constant B4($64)
121 | constant C5($66)
122 | constant C5s($68)
123 | constant D5b($68)
124 | constant D5($6A)
125 | constant D5s($6C)
126 | constant E5b($6C)
127 | constant E5($6E)
128 | constant F5($70)
129 | constant F5s($72)
130 | constant G5b($72)
131 | constant G5($74)
132 | constant G5s($76)
133 | constant A5b($76)
134 |
135 | constant A5($78)
136 | constant A5s($7A)
137 | constant B5b($7A)
138 | constant B5($7C)
139 | constant C6($7E)
140 | constant C6s($80)
141 | constant D6b($80)
142 | constant D6($82)
143 | constant D6s($84)
144 | constant E6b($84)
145 | constant E6($86)
146 | constant F6($88)
147 | constant F6s($8A)
148 | constant G6b($8A)
149 | constant G6($8C)
150 | constant G6s($8E)
151 | constant A6b($8E)
152 |
153 | constant A6($90)
154 | constant A6s($92)
155 | constant B6b($92)
156 | constant B6($94)
157 | constant C7($96)
158 | constant C7s($98)
159 | constant D7b($98)
160 | constant D7($9A)
161 | constant D7s($9C)
162 | constant E7b($9C)
163 | constant E7($9E)
164 | constant F7($A0)
165 | constant F7s($A2)
166 | constant G7b($A2)
167 | constant G7($A4)
168 | constant G7s($A6)
169 | constant A7b($A6)
170 |
171 | constant A7($A8)
172 | constant A7s($AA)
173 | constant B7b($AA)
174 | constant B7($AC)
175 | constant C8($AE)
176 | constant C8s($B0)
177 | constant D8b($B0)
178 | constant D8($B2)
179 | constant D8s($B4)
180 | constant E8b($B4)
181 | constant E8($B6)
182 | constant F8($B8)
183 | constant F8s($BA)
184 | constant G8b($BA)
185 | constant G8($BC)
186 | constant G8s($BE)
187 | constant A8b($BE)
188 |
189 | constant A8($B0)
190 | constant A8s($B2)
191 | constant B8b($B2)
192 | constant B8($B4)
193 | constant C9($B6)
194 | constant C9s($B8)
195 | constant D9b($B8)
196 | constant D9($BA)
197 | constant D9s($BC)
198 | constant E9b($BC)
199 | constant E9($BE)
200 | constant F9($C0)
201 | constant F9s($C2)
202 | constant G9b($C2)
203 | constant G9($C4)
204 | constant G9s($C6)
205 | constant A9b($C6)
206 |
207 | constant SUST($FE)
208 | constant REST($FF)
209 |
210 | macro PeriodTable() { // Timing, 9 Octaves: A0..G9# (108 Words)
211 | dw $FE4,$F00,$E28,$D5D,$C9D,$BE7,$B3D,$A9B,$A03,$973,$8EB,$86B // A0..G1#
212 | dw $7F2,$780,$714,$6AE,$64E,$5F3,$59E,$54D,$501,$4B9,$475,$435 // A1..G2#
213 | dw $3F9,$3C0,$38A,$357,$327,$2F9,$2CF,$2A6,$280,$25C,$23A,$21A // A2..G3#
214 | dw $1FC,$1E0,$1C5,$1AB,$193,$17C,$167,$153,$140,$12E,$11D,$10D // A3..G4#
215 | dw $0FE,$0F0,$0E2,$0D5,$0C9,$0BE,$0B3,$0A9,$0A0,$097,$08E,$086 // A4..G5#
216 | dw $07F,$078,$071,$06A,$064,$05F,$059,$054,$050,$04B,$047,$043 // A5..G6#
217 | dw $03F,$03C,$038,$035,$032,$02F,$02C,$02A,$028,$025,$023,$021 // A6..G7#
218 | dw $01F,$01E,$01C,$01A,$019,$017,$016,$015,$014,$012,$011,$010 // A7..G8#
219 | dw $00F,$00F,$00E,$00D,$00C,$00B,$00B,$00A,$00A,$009,$008,$008 // A8..G9#
220 | }
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle/Make.bat:
--------------------------------------------------------------------------------
1 | bass PSGTwinkle.asm
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle/PSGTwinkle.asm:
--------------------------------------------------------------------------------
1 | // ZX Spectrum 128K AY8912 PSG Twinkle Song demo by krom (Peter Lemon):
2 | arch zxs.cpu
3 | output "PSGTwinkle.z80", create
4 | include "LIB/Z80_HEADER.ASM" // Include .Z80 Header (30 Bytes)
5 | fill $C000 // Fill 48KB Program Code With Zero Bytes
6 |
7 | macro seek(variable offset) {
8 | origin (offset-$4000)+30
9 | base offset
10 | }
11 |
12 | seek($8000); Start: // Entry Point Of Code
13 | include "LIB/ZXSPECTRUM.INC" // Include ZX Spectrum Definitions
14 | include "LIB/ZXSPECTRUM_PSG.INC" // Include ZX Spectrum PSG Definitions
15 |
16 | di // Disable Interrupts
17 | im 1 // Set Interrupt Mode 1
18 | ei // Enable Interrupts
19 |
20 | // Disable All Channels
21 | ld d,PSG_KEY // D = PSG Channel Enable Address ($07)
22 | ld e,%00111111 // E = PSG Channel Tone Enable (Bits 6..7 Port A/B Mode, Bits 3..5 Channel A..C Enable Noise, Bits 0..2 Channel A..C Enable Tone)
23 | call PSGWrite // PSG Write Data (D = PSG Address, E = PSG Data)
24 |
25 | // Setup Channel A Tone
26 | ld d,PSG_MODE_VOL_A // D = PSG Channel A Mode/Volume Address ($08)
27 | ld e,$0F // E = PSG Channel A Mode/Volume (Bit 4 Mode = 0, Bits 0..3 Volume = 15)
28 | call PSGWrite // PSG Write Data (D = PSG Address, E = PSG Data)
29 |
30 | LoopSong:
31 | ld de,SONGCHANA // DE = SONGCHANA 16-Bit Address
32 |
33 | PSGCHANA: // PSG Channel A
34 | ld a,(de) // A = Channel A: Period Table Offset
35 | cp SUST // Compare A To SUST Character ($FE)
36 | jr z,PSGCHANAEnd // IF (A == SUST) Channel A: PSGCHANA End
37 |
38 | // Key OFF
39 | ld a,PSG_KEY // A = PSG Channel Enable Address ($07)
40 | ld bc,AY8912_ADDR // BC = AY8912 Address Port ($FFFD)
41 | out (c),a // Write PSG Address (A) To AY8912 Address Port (BC)
42 | in a,(c) // A = PSG Channel Enable (Bits 6..7 Port A/B Mode, Bits 3..5 Channel A..C Enable Noise, Bits 0..2 Channel A..C Enable Tone)
43 | set 0,a // A = PSG Channel A Tone Disable (Bits 6..7 Port A/B Mode, Bits 3..5 Channel A..C Enable Noise, Bits 0..2 Channel A..C Enable Tone)
44 | ld b,AY8912_WRITE>>8 // BC = AY8912 Write Data Port ($BFFD)
45 | out (c),a // Write PSG Data (A) To AY8912 Write Data Port (BC)
46 |
47 | ld a,(de) // A = Channel A: Period Table Offset
48 | cp REST // Compare A To REST Character ($FF)
49 | jr z,PSGCHANAEnd // IF (A == REST) Channel A: PSGCHANA End
50 |
51 | // ELSE Channel A: Key ON
52 | ld b,$00 // B = $00
53 | ld c,a // C = Period Table Offset (A)
54 | ld hl,PeriodTable // HL = PeriodTable 16-Bit Address
55 | add hl,bc // HL += BC
56 |
57 | ld a,PSG_FINE_TUNE_A // A = PSG Channel A Fine Tune Address ($00)
58 | ld bc,AY8912_ADDR // BC = AY8912 Address Port ($FFFD)
59 | out (c),a // Write PSG Address (A) To AY8912 Address Port (BC)
60 | ld a,(hl) // A = PSG Channel A Fine Tune
61 | inc hl // Increment Period Table Offset (HL++)
62 | ld b,AY8912_WRITE>>8 // BC = AY8912 Write Data Port ($BFFD)
63 | out (c),a // Write PSG Data (A) To AY8912 Write Data Port (BC)
64 |
65 | ld a,PSG_COARSE_TUNE_A // A = PSG Channel A Course Tune Address ($01)
66 | ld b,AY8912_ADDR>>8 // BC = AY8912 Address Port ($FFFD)
67 | out (c),a // Write PSG Address (A) To AY8912 Address Port (BC)
68 | ld a,(hl) // A = Channel A Course Tune
69 | ld b,AY8912_WRITE>>8 // BC = AY8912 Write Data Port ($BFFD)
70 | out (c),a // Write PSG Data (A) To AY8912 Write Data Port (BC)
71 |
72 | // Key ON
73 | ld a,PSG_KEY // A = PSG Channel Enable Address ($07)
74 | ld b,AY8912_ADDR>>8 // BC = AY8912 Address Port ($FFFD)
75 | out (c),a // Write PSG Address (A) To AY8912 Address Port (BC)
76 | in a,(c) // A = PSG Channel Enable (Bits 6..7 Port A/B Mode, Bits 3..5 Channel A..C Enable Noise, Bits 0..2 Channel A..C Enable Tone)
77 | res 0,a // A = PSG Channel A Tone Enable (Bits 6..7 Port A/B Mode, Bits 3..5 Channel A..C Enable Noise, Bits 0..2 Channel A..C Enable Tone)
78 | ld b,AY8912_WRITE>>8 // BC = AY8912 Write Data Port ($BFFD)
79 | out (c),a // Write PSG Data (A) To AY8912 Write Data Port (BC)
80 | PSGCHANAEnd:
81 |
82 | // 250 MS Delay (15 VSYNCS)
83 | ld b,15 // B = Count
84 | Wait:
85 | halt // Power Down CPU Until An Interrupt Occurs
86 | djnz Wait // Decrement Count (B--), IF (Count != 0) Wait
87 |
88 | inc de // DE++ (Increment Song Offset)
89 |
90 | ld a,SongEnd>>8 // IF (Song Offset != Song End) PSG Channel A
91 | cp d
92 | jp nz,PSGCHANA
93 | ld a,SongEnd
94 | cp e
95 | jp nz,PSGCHANA
96 |
97 | jp LoopSong // Loop Song
98 |
99 | PSGRead: // PSG Read Data (A = PSG Address, Return A = PSG Data)
100 | ld bc,AY8912_ADDR // BC = AY8912 Address/Read Data Port ($FFFD)
101 | out (c),a // Write PSG Address (A) To AY8912 Address Port (BC)
102 | in a,(c) // Read PSG Data (A) From AY8912 Read Data Port (BC)
103 | ret
104 |
105 | PSGWrite: // PSG Write Data (D = PSG Address, E = PSG Data)
106 | ld bc,AY8912_ADDR // BC = AY8912 Address Port ($FFFD)
107 | out (c),d // Write PSG Address (D) To AY8912 Address Port (BC)
108 | ld b,AY8912_WRITE>>8 // BC = AY8912 Write Data Port ($BFFD)
109 | out (c),e // Write PSG Data (E) To AY8912 Write Data Port (BC)
110 | ret
111 |
112 | PeriodTable: // Period Table Used For PSG Tone Freqencies
113 | PeriodTable() // Timing, 9 Octaves: A0..G9# (108 Words)
114 |
115 | SongStart:
116 | SONGCHANA: // PSG Channel A Tone Song Data At 250ms (15 VSYNCS)
117 | db C5, REST, C5, REST, G5, REST, G5, REST, A5, REST, A5, REST, G5, SUST, SUST, REST // 1. Twinkle Twinkle Little Star...
118 | db F5, REST, F5, REST, E5, REST, E5, REST, D5, REST, D5, REST, C5, SUST, SUST, REST // 2. How I Wonder What You Are...
119 | db G5, REST, G5, REST, F5, REST, F5, REST, E5, REST, E5, REST, D5, SUST, SUST, REST // 3. Up Above The World So High...
120 | db G5, REST, G5, REST, F5, REST, F5, REST, E5, REST, E5, REST, D5, SUST, SUST, REST // 4. Like A Diamond In The Sky...
121 | db C5, REST, C5, REST, G5, REST, G5, REST, A5, REST, A5, REST, G5, SUST, SUST, REST // 5. Twinkle Twinkle Little Star...
122 | db F5, REST, F5, REST, E5, REST, E5, REST, D5, REST, D5, REST, C5, SUST, SUST, REST // 6. How I Wonder What You Are...
123 | SongEnd:
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle/PSGTwinkle.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/PSG/Twinkle/PSGTwinkle.z80
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle2Channel/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle2Channel/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle2Channel/LIB/ZXSPECTRUM_PSG.INC:
--------------------------------------------------------------------------------
1 | //===================================== (Key: RW = Read/Write)
2 | // ZX Spectrum 128K AY8912 PSG Include
3 | //=====================================
4 | //---------------------
5 | // I/O Map (Z80 Ports)
6 | //---------------------
7 | //--------
8 | // AY8912
9 | //--------
10 | constant AY8912_ADDR($FFFD) // $FFFD: AY8912 - Address W
11 |
12 | // AY8912 - Read (Write Address Port $FFFD, Read Data Port $FFFD)
13 | constant AY8912_READ($FFFD) // $FFFD: AY8912 - Read Data R
14 |
15 | // AY8912 - Write (Write Address Port $FFFD, Write Data Port $BFFD)
16 | constant AY8912_WRITE($BFFD) // $BFFD: AY8912 - Write Data W
17 |
18 | //------------
19 | // AY8912 PSG
20 | //------------
21 | constant PSG_FINE_TUNE_A($00) // $00: AY8912 PSG - Channel A Fine Tune (Bits 0..7) RW
22 | constant PSG_COARSE_TUNE_A($01) // $01: AY8912 PSG - Channel A Coarse Tune (Bits 0..3) RW
23 | constant PSG_FINE_TUNE_B($02) // $02: AY8912 PSG - Channel B Fine Tune (Bits 0..7) RW
24 | constant PSG_COARSE_TUNE_B($03) // $03: AY8912 PSG - Channel B Coarse Tune (Bits 0..3) RW
25 | constant PSG_FINE_TUNE_C($04) // $04: AY8912 PSG - Channel C Fine Tune (Bits 0..7) RW
26 | constant PSG_COARSE_TUNE_C($05) // $05: AY8912 PSG - Channel C Coarse Tune (Bits 0..3) RW
27 | constant PSG_NOISE_TUNE($06) // $06: AY8912 PSG - Channel Noise Tune (Bits 0..4) RW
28 |
29 | constant PSG_KEY($07) // $07: AY8912 PSG - Port A/B Mode (Bits 6..7), Channel Enable Noise (Bits 3..5), Tone (Bits 0..2) RW
30 |
31 | constant PSG_MODE_VOL_A($08) // $08: AY8912 PSG - Channel A Mode (Bit 4), Volume (Bits 0..3) RW
32 | constant PSG_MODE_VOL_B($09) // $09: AY8912 PSG - Channel B Mode (Bit 4), Volume (Bits 0..3) RW
33 | constant PSG_MODE_VOL_C($0A) // $0A: AY8912 PSG - Channel C Mode (Bit 4), Volume (Bits 0..3) RW
34 |
35 | constant PSG_ENV_FINE_TUNE($0B) // $0B: AY8912 PSG - Volume Envelope Period Fine Tune (Bits 0..7) RW
36 | constant PSG_ENV_COARSE_TUNE($0C) // $0C: AY8912 PSG - Volume Envelope Period Coarse Tune (Bits 0..7) RW
37 |
38 | // AY8912 PSG - Volume Envelope Shape (8 = |\|\|\|\, 9 = |\____, 10 = |\/\/, 11 = |\/''', 12= /|/|/|/|, 13 = /''', 14 = /\/\, 15 = /|___)
39 | constant PSG_ENV_SHAPE($0D) // $0D: AY8912 PSG - Volume Envelope Shape (Bits 0..3) RW
40 |
41 | constant PSG_PORT_A($0E) // $0E: AY8912 PSG - Port A (With External Pinouts On AY8910 & AY8912) RW
42 | constant PSG_PORT_B($0F) // $0F: AY8910 PSG - Port B (With External Pinouts On AY8910 Only) RW
43 |
44 | // Frequency WORD Offsets For Period Table
45 | constant A0($00)
46 | constant A0s($02)
47 | constant B0b($02)
48 | constant B0($04)
49 | constant C1($06)
50 | constant C1s($08)
51 | constant D1b($08)
52 | constant D1($0A)
53 | constant D1s($0C)
54 | constant E1b($0C)
55 | constant E1($0E)
56 | constant F1($10)
57 | constant F1s($12)
58 | constant G1b($12)
59 | constant G1($14)
60 | constant G1s($16)
61 | constant A1b($16)
62 |
63 | constant A1($18)
64 | constant A1s($1A)
65 | constant B1b($1A)
66 | constant B1($1C)
67 | constant C2($1E)
68 | constant C2s($20)
69 | constant D2b($20)
70 | constant D2($22)
71 | constant D2s($24)
72 | constant E2b($24)
73 | constant E2($26)
74 | constant F2($28)
75 | constant F2s($2A)
76 | constant G2b($2A)
77 | constant G2($2C)
78 | constant G2s($2E)
79 | constant A2b($2E)
80 |
81 | constant A2($30)
82 | constant A2s($32)
83 | constant B2b($32)
84 | constant B2($34)
85 | constant C3($36)
86 | constant C3s($38)
87 | constant D3b($38)
88 | constant D3($3A)
89 | constant D3s($3C)
90 | constant E3b($3C)
91 | constant E3($3E)
92 | constant F3($40)
93 | constant F3s($42)
94 | constant G3b($42)
95 | constant G3($44)
96 | constant G3s($46)
97 | constant A3b($46)
98 |
99 | constant A3($48)
100 | constant A3s($4A)
101 | constant B3b($4A)
102 | constant B3($4C)
103 | constant C4($4E)
104 | constant C4s($50)
105 | constant D4b($50)
106 | constant D4($52)
107 | constant D4s($54)
108 | constant E4b($54)
109 | constant E4($56)
110 | constant F4($58)
111 | constant F4s($5A)
112 | constant G4b($5A)
113 | constant G4($5C)
114 | constant G4s($5E)
115 | constant A4b($5E)
116 |
117 | constant A4($60)
118 | constant A4s($62)
119 | constant B4b($62)
120 | constant B4($64)
121 | constant C5($66)
122 | constant C5s($68)
123 | constant D5b($68)
124 | constant D5($6A)
125 | constant D5s($6C)
126 | constant E5b($6C)
127 | constant E5($6E)
128 | constant F5($70)
129 | constant F5s($72)
130 | constant G5b($72)
131 | constant G5($74)
132 | constant G5s($76)
133 | constant A5b($76)
134 |
135 | constant A5($78)
136 | constant A5s($7A)
137 | constant B5b($7A)
138 | constant B5($7C)
139 | constant C6($7E)
140 | constant C6s($80)
141 | constant D6b($80)
142 | constant D6($82)
143 | constant D6s($84)
144 | constant E6b($84)
145 | constant E6($86)
146 | constant F6($88)
147 | constant F6s($8A)
148 | constant G6b($8A)
149 | constant G6($8C)
150 | constant G6s($8E)
151 | constant A6b($8E)
152 |
153 | constant A6($90)
154 | constant A6s($92)
155 | constant B6b($92)
156 | constant B6($94)
157 | constant C7($96)
158 | constant C7s($98)
159 | constant D7b($98)
160 | constant D7($9A)
161 | constant D7s($9C)
162 | constant E7b($9C)
163 | constant E7($9E)
164 | constant F7($A0)
165 | constant F7s($A2)
166 | constant G7b($A2)
167 | constant G7($A4)
168 | constant G7s($A6)
169 | constant A7b($A6)
170 |
171 | constant A7($A8)
172 | constant A7s($AA)
173 | constant B7b($AA)
174 | constant B7($AC)
175 | constant C8($AE)
176 | constant C8s($B0)
177 | constant D8b($B0)
178 | constant D8($B2)
179 | constant D8s($B4)
180 | constant E8b($B4)
181 | constant E8($B6)
182 | constant F8($B8)
183 | constant F8s($BA)
184 | constant G8b($BA)
185 | constant G8($BC)
186 | constant G8s($BE)
187 | constant A8b($BE)
188 |
189 | constant A8($B0)
190 | constant A8s($B2)
191 | constant B8b($B2)
192 | constant B8($B4)
193 | constant C9($B6)
194 | constant C9s($B8)
195 | constant D9b($B8)
196 | constant D9($BA)
197 | constant D9s($BC)
198 | constant E9b($BC)
199 | constant E9($BE)
200 | constant F9($C0)
201 | constant F9s($C2)
202 | constant G9b($C2)
203 | constant G9($C4)
204 | constant G9s($C6)
205 | constant A9b($C6)
206 |
207 | constant SUST($FE)
208 | constant REST($FF)
209 |
210 | macro PeriodTable() { // Timing, 9 Octaves: A0..G9# (108 Words)
211 | dw $FE4,$F00,$E28,$D5D,$C9D,$BE7,$B3D,$A9B,$A03,$973,$8EB,$86B // A0..G1#
212 | dw $7F2,$780,$714,$6AE,$64E,$5F3,$59E,$54D,$501,$4B9,$475,$435 // A1..G2#
213 | dw $3F9,$3C0,$38A,$357,$327,$2F9,$2CF,$2A6,$280,$25C,$23A,$21A // A2..G3#
214 | dw $1FC,$1E0,$1C5,$1AB,$193,$17C,$167,$153,$140,$12E,$11D,$10D // A3..G4#
215 | dw $0FE,$0F0,$0E2,$0D5,$0C9,$0BE,$0B3,$0A9,$0A0,$097,$08E,$086 // A4..G5#
216 | dw $07F,$078,$071,$06A,$064,$05F,$059,$054,$050,$04B,$047,$043 // A5..G6#
217 | dw $03F,$03C,$038,$035,$032,$02F,$02C,$02A,$028,$025,$023,$021 // A6..G7#
218 | dw $01F,$01E,$01C,$01A,$019,$017,$016,$015,$014,$012,$011,$010 // A7..G8#
219 | dw $00F,$00F,$00E,$00D,$00C,$00B,$00B,$00A,$00A,$009,$008,$008 // A8..G9#
220 | }
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle2Channel/Make.bat:
--------------------------------------------------------------------------------
1 | bass PSGTwinkle2Channel.asm
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle2Channel/PSGTwinkle2Channel.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/PSG/Twinkle2Channel/PSGTwinkle2Channel.z80
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle3Channel/LIB/Z80_HEADER.ASM:
--------------------------------------------------------------------------------
1 | //=========================
2 | // ZX Spectrum .Z80 Header
3 | //=========================
4 | db $00 // A Register
5 | db $00 // F Register
6 | db $00 // C Register
7 | db $00 // B Register
8 | db $00 // L Register
9 | db $00 // H Register
10 | dw Start // Program Counter
11 | dw $0000 // Stack Pointer
12 | db $00 // Interrupt Register
13 | db $00 // Refresh Register (Bit 7 Not Used)
14 | db $00 // Bit 0 : Bit 7 Of Refresh Register
15 | // Bit 1..3: Border Color
16 | // Bit 4 : 1 = Basic SamRom Switched In
17 | // Bit 5 : 0 = Block Data Uncompressed, 1 = Block Data Compressed
18 | // Bit 6..7: Unused
19 | db $00 // E Register
20 | db $00 // D Register
21 | db $00 // C' Register
22 | db $00 // B' Register
23 | db $00 // E' Register
24 | db $00 // D' Register
25 | db $00 // L' Register
26 | db $00 // H' Register
27 | db $00 // A' Register
28 | db $00 // F' Register
29 | dw $0000 // IY Register
30 | dw $0000 // IX Register
31 | db $00 // Interrupt Flipflop, 0 = DI, 1..255 = EI
32 | db $00 // IFF2
33 | db $01 // Bit 0..1: Interrupt Mode (0, 1, 2)
34 | // Bit 2 : 1 = Issue 2 Emulation
35 | // Bit 3 : 1 = Double Interrupt Frequency
36 | // Bit 4..5: 0 = Normal, 1 = High Video Synchronisation, 2 = Normal, 3 = Low Video Synchronisation
37 | // Bit 6..7: 0 = Cursor/Protek/AGF, 1 = Kempston, 2 = Sinclair 2 Left, 3 = Sinclair 2 Right Joystick
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle3Channel/LIB/ZXSPECTRUM.INC:
--------------------------------------------------------------------------------
1 | //=====================
2 | // ZX Spectrum Include
3 | //=====================
4 | // Memory Map (1st 16KB Is Read Only ROM, Rest Of Memory Map Is Read/Write RAM)
5 | constant SYS_ROM($0000) // $0000..$3FFF: System ROM (16KB)
6 | constant SCR_BMP($4000) // $4000..$57FF: Screen Memory - Bitmap Data (6KB)
7 | constant SCR_COL($5800) // $5800..$5AFF: Screen Memory - Color Data (768 Bytes)
8 | constant PRN_BUF($5B00) // $5B00..$5BFF: Printer Buffer (256 Bytes)
9 | constant SYS_VAR($5C00) // $5C00..$5CBF: System Variables (192 Bytes)
10 | // $5CC0..$5CCA: Reserved (10 Bytes)
11 | constant SYS_RAM($5CCB) // $5CCB..$FF57: System RAM (Program) (40KB)
12 | constant RAM_TOP($FF58) // $FF58..$FFFF: Reserved (168 Bytes)
13 |
14 | // Screen Bitmap Color Attributes (%FBPPPIII: F = FLASH Mode, B = BRIGHTNESS Mode, P = PAPER Color, I = INK Color)
15 | constant I_BLACK(%00000000) // Ink Color 0: Black
16 | constant I_BLUE(%00000001) // Ink Color 1: Blue
17 | constant I_RED(%00000010) // Ink Color 2: Red
18 | constant I_MAGENTA(%00000011) // Ink Color 3: Magenta
19 | constant I_GREEN(%00000100) // Ink Color 4: Green
20 | constant I_CYAN(%00000101) // Ink Color 5: Cyan
21 | constant I_YELLOW(%00000110) // Ink Color 6: Yellow
22 | constant I_WHITE(%00000111) // Ink Color 7: White
23 |
24 | constant P_BLACK(%00000000) // Paper Color 0: Black
25 | constant P_BLUE(%00001000) // Paper Color 1: Blue
26 | constant P_RED(%00010000) // Paper Color 2: Red
27 | constant P_MAGENTA(%00011000) // Paper Color 3: Magenta
28 | constant P_GREEN(%00100000) // Paper Color 4: Green
29 | constant P_CYAN(%00101000) // Paper Color 5: Cyan
30 | constant P_YELLOW(%00110000) // Paper Color 6: Yellow
31 | constant P_WHITE(%00111000) // Paper Color 7: White
32 |
33 | constant BRIGHT(%01000000) // Britness Mode: 0 = Dark, 1 = Bright
34 | constant FLASH(%10000000) // Flashing Mode: 0 = Non Flashing, 1 = Flashing
35 |
36 | // I/O Map (Z80 Ports)
37 | constant SND_BCOL($FE) // $FE: Beeper Sound & Border Color (---S-BBB: S = BEEPER Sound, B = BORDER Color)
38 |
39 | macro align(size) { // Align Byte Amount
40 | while (pc() % {size}) {
41 | db 0
42 | }
43 | }
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle3Channel/LIB/ZXSPECTRUM_PSG.INC:
--------------------------------------------------------------------------------
1 | //===================================== (Key: RW = Read/Write)
2 | // ZX Spectrum 128K AY8912 PSG Include
3 | //=====================================
4 | //---------------------
5 | // I/O Map (Z80 Ports)
6 | //---------------------
7 | //--------
8 | // AY8912
9 | //--------
10 | constant AY8912_ADDR($FFFD) // $FFFD: AY8912 - Address W
11 |
12 | // AY8912 - Read (Write Address Port $FFFD, Read Data Port $FFFD)
13 | constant AY8912_READ($FFFD) // $FFFD: AY8912 - Read Data R
14 |
15 | // AY8912 - Write (Write Address Port $FFFD, Write Data Port $BFFD)
16 | constant AY8912_WRITE($BFFD) // $BFFD: AY8912 - Write Data W
17 |
18 | //------------
19 | // AY8912 PSG
20 | //------------
21 | constant PSG_FINE_TUNE_A($00) // $00: AY8912 PSG - Channel A Fine Tune (Bits 0..7) RW
22 | constant PSG_COARSE_TUNE_A($01) // $01: AY8912 PSG - Channel A Coarse Tune (Bits 0..3) RW
23 | constant PSG_FINE_TUNE_B($02) // $02: AY8912 PSG - Channel B Fine Tune (Bits 0..7) RW
24 | constant PSG_COARSE_TUNE_B($03) // $03: AY8912 PSG - Channel B Coarse Tune (Bits 0..3) RW
25 | constant PSG_FINE_TUNE_C($04) // $04: AY8912 PSG - Channel C Fine Tune (Bits 0..7) RW
26 | constant PSG_COARSE_TUNE_C($05) // $05: AY8912 PSG - Channel C Coarse Tune (Bits 0..3) RW
27 | constant PSG_NOISE_TUNE($06) // $06: AY8912 PSG - Channel Noise Tune (Bits 0..4) RW
28 |
29 | constant PSG_KEY($07) // $07: AY8912 PSG - Port A/B Mode (Bits 6..7), Channel Enable Noise (Bits 3..5), Tone (Bits 0..2) RW
30 |
31 | constant PSG_MODE_VOL_A($08) // $08: AY8912 PSG - Channel A Mode (Bit 4), Volume (Bits 0..3) RW
32 | constant PSG_MODE_VOL_B($09) // $09: AY8912 PSG - Channel B Mode (Bit 4), Volume (Bits 0..3) RW
33 | constant PSG_MODE_VOL_C($0A) // $0A: AY8912 PSG - Channel C Mode (Bit 4), Volume (Bits 0..3) RW
34 |
35 | constant PSG_ENV_FINE_TUNE($0B) // $0B: AY8912 PSG - Volume Envelope Period Fine Tune (Bits 0..7) RW
36 | constant PSG_ENV_COARSE_TUNE($0C) // $0C: AY8912 PSG - Volume Envelope Period Coarse Tune (Bits 0..7) RW
37 |
38 | // AY8912 PSG - Volume Envelope Shape (8 = |\|\|\|\, 9 = |\____, 10 = |\/\/, 11 = |\/''', 12= /|/|/|/|, 13 = /''', 14 = /\/\, 15 = /|___)
39 | constant PSG_ENV_SHAPE($0D) // $0D: AY8912 PSG - Volume Envelope Shape (Bits 0..3) RW
40 |
41 | constant PSG_PORT_A($0E) // $0E: AY8912 PSG - Port A (With External Pinouts On AY8910 & AY8912) RW
42 | constant PSG_PORT_B($0F) // $0F: AY8910 PSG - Port B (With External Pinouts On AY8910 Only) RW
43 |
44 | // Frequency WORD Offsets For Period Table
45 | constant A0($00)
46 | constant A0s($02)
47 | constant B0b($02)
48 | constant B0($04)
49 | constant C1($06)
50 | constant C1s($08)
51 | constant D1b($08)
52 | constant D1($0A)
53 | constant D1s($0C)
54 | constant E1b($0C)
55 | constant E1($0E)
56 | constant F1($10)
57 | constant F1s($12)
58 | constant G1b($12)
59 | constant G1($14)
60 | constant G1s($16)
61 | constant A1b($16)
62 |
63 | constant A1($18)
64 | constant A1s($1A)
65 | constant B1b($1A)
66 | constant B1($1C)
67 | constant C2($1E)
68 | constant C2s($20)
69 | constant D2b($20)
70 | constant D2($22)
71 | constant D2s($24)
72 | constant E2b($24)
73 | constant E2($26)
74 | constant F2($28)
75 | constant F2s($2A)
76 | constant G2b($2A)
77 | constant G2($2C)
78 | constant G2s($2E)
79 | constant A2b($2E)
80 |
81 | constant A2($30)
82 | constant A2s($32)
83 | constant B2b($32)
84 | constant B2($34)
85 | constant C3($36)
86 | constant C3s($38)
87 | constant D3b($38)
88 | constant D3($3A)
89 | constant D3s($3C)
90 | constant E3b($3C)
91 | constant E3($3E)
92 | constant F3($40)
93 | constant F3s($42)
94 | constant G3b($42)
95 | constant G3($44)
96 | constant G3s($46)
97 | constant A3b($46)
98 |
99 | constant A3($48)
100 | constant A3s($4A)
101 | constant B3b($4A)
102 | constant B3($4C)
103 | constant C4($4E)
104 | constant C4s($50)
105 | constant D4b($50)
106 | constant D4($52)
107 | constant D4s($54)
108 | constant E4b($54)
109 | constant E4($56)
110 | constant F4($58)
111 | constant F4s($5A)
112 | constant G4b($5A)
113 | constant G4($5C)
114 | constant G4s($5E)
115 | constant A4b($5E)
116 |
117 | constant A4($60)
118 | constant A4s($62)
119 | constant B4b($62)
120 | constant B4($64)
121 | constant C5($66)
122 | constant C5s($68)
123 | constant D5b($68)
124 | constant D5($6A)
125 | constant D5s($6C)
126 | constant E5b($6C)
127 | constant E5($6E)
128 | constant F5($70)
129 | constant F5s($72)
130 | constant G5b($72)
131 | constant G5($74)
132 | constant G5s($76)
133 | constant A5b($76)
134 |
135 | constant A5($78)
136 | constant A5s($7A)
137 | constant B5b($7A)
138 | constant B5($7C)
139 | constant C6($7E)
140 | constant C6s($80)
141 | constant D6b($80)
142 | constant D6($82)
143 | constant D6s($84)
144 | constant E6b($84)
145 | constant E6($86)
146 | constant F6($88)
147 | constant F6s($8A)
148 | constant G6b($8A)
149 | constant G6($8C)
150 | constant G6s($8E)
151 | constant A6b($8E)
152 |
153 | constant A6($90)
154 | constant A6s($92)
155 | constant B6b($92)
156 | constant B6($94)
157 | constant C7($96)
158 | constant C7s($98)
159 | constant D7b($98)
160 | constant D7($9A)
161 | constant D7s($9C)
162 | constant E7b($9C)
163 | constant E7($9E)
164 | constant F7($A0)
165 | constant F7s($A2)
166 | constant G7b($A2)
167 | constant G7($A4)
168 | constant G7s($A6)
169 | constant A7b($A6)
170 |
171 | constant A7($A8)
172 | constant A7s($AA)
173 | constant B7b($AA)
174 | constant B7($AC)
175 | constant C8($AE)
176 | constant C8s($B0)
177 | constant D8b($B0)
178 | constant D8($B2)
179 | constant D8s($B4)
180 | constant E8b($B4)
181 | constant E8($B6)
182 | constant F8($B8)
183 | constant F8s($BA)
184 | constant G8b($BA)
185 | constant G8($BC)
186 | constant G8s($BE)
187 | constant A8b($BE)
188 |
189 | constant A8($B0)
190 | constant A8s($B2)
191 | constant B8b($B2)
192 | constant B8($B4)
193 | constant C9($B6)
194 | constant C9s($B8)
195 | constant D9b($B8)
196 | constant D9($BA)
197 | constant D9s($BC)
198 | constant E9b($BC)
199 | constant E9($BE)
200 | constant F9($C0)
201 | constant F9s($C2)
202 | constant G9b($C2)
203 | constant G9($C4)
204 | constant G9s($C6)
205 | constant A9b($C6)
206 |
207 | constant SUST($FE)
208 | constant REST($FF)
209 |
210 | macro PeriodTable() { // Timing, 9 Octaves: A0..G9# (108 Words)
211 | dw $FE4,$F00,$E28,$D5D,$C9D,$BE7,$B3D,$A9B,$A03,$973,$8EB,$86B // A0..G1#
212 | dw $7F2,$780,$714,$6AE,$64E,$5F3,$59E,$54D,$501,$4B9,$475,$435 // A1..G2#
213 | dw $3F9,$3C0,$38A,$357,$327,$2F9,$2CF,$2A6,$280,$25C,$23A,$21A // A2..G3#
214 | dw $1FC,$1E0,$1C5,$1AB,$193,$17C,$167,$153,$140,$12E,$11D,$10D // A3..G4#
215 | dw $0FE,$0F0,$0E2,$0D5,$0C9,$0BE,$0B3,$0A9,$0A0,$097,$08E,$086 // A4..G5#
216 | dw $07F,$078,$071,$06A,$064,$05F,$059,$054,$050,$04B,$047,$043 // A5..G6#
217 | dw $03F,$03C,$038,$035,$032,$02F,$02C,$02A,$028,$025,$023,$021 // A6..G7#
218 | dw $01F,$01E,$01C,$01A,$019,$017,$016,$015,$014,$012,$011,$010 // A7..G8#
219 | dw $00F,$00F,$00E,$00D,$00C,$00B,$00B,$00A,$00A,$009,$008,$008 // A8..G9#
220 | }
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle3Channel/Make.bat:
--------------------------------------------------------------------------------
1 | bass PSGTwinkle3Channel.asm
--------------------------------------------------------------------------------
/Sound/PSG/Twinkle3Channel/PSGTwinkle3Channel.z80:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PeterLemon/ZXSpectrum/cc2db6c3088b6fcb5a42f62d7e55e4c779a31267/Sound/PSG/Twinkle3Channel/PSGTwinkle3Channel.z80
--------------------------------------------------------------------------------