├── 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 --------------------------------------------------------------------------------