moe-bius/tsfm_speccy_player/main.asm
2025-08-14 19:33:16 +07:00

204 lines
5.8 KiB
NASM

; moe-bius - zx/tsfm player
; --atemka 14.o8.2o25
device zxspectrum128
ivt equ 0x8000
isr equ 0x8181
codestart equ 0x8080
reg_buffer equ 0x5B00 ; basic variables :meatjob:
EMPTYTAP "player.tap"
; IM2 vector table - all 257 values for floating bus condition
org ivt
block 257, (isr >> 8) ; isr at 0x8181
; dummy ISR (vblank synchronization is done by HALT)
org isr
stack_top:
ei
ret
; entrypoint
start:
di
ld sp, stack_top
; set IM2 vector table to 0x80
ld a, high ivt
ld i, a
im 2
; prefill register buffer to prevent crashes
ld hl, reg_buffer
ldi [hl], 0x2F : ldi [hl], 0xFF
ldi [hl], 0x2D : ldi [hl], 0xFF
ld [hl], -1
; enable interrupts
ei
.loop:
halt
ld a, 1 : out (0xfe), a
ld bc, 0xFFFD
ld de, 0x00C0
ld a, 0b11111000
out (c), a
ld hl, reg_buffer
call player.reg_out
ld a, 2 : out (0xfe), a
ld a, 0b11111001
ld b, 0xFF
out (c), a
inc hl
call player.reg_out
ld a, 3 : out (0xfe), a
ld iy, reg_buffer
call player.play_tick
xor a : out (0xfe), a
; and jump to next frame
xor a : ld bc, 0x7FFD : out (c), a ; map fast page to fix 128k AY ports contention
jp .loop
; ----------------------------------------------------
; vu meters
; orig by natt, rewritten by me
vumeter:
ld a, 0
call .get_address
ld [start.vu0], hl
ld a, 1
call .get_address
ld [start.vu1], hl
ld a, 2
call .get_address
ld [start.vu2], hl
ld a, 3
call .get_address
ld [start.vu3], hl
ld a, 4
call .get_address
ld [start.vu4], hl
ld a, 5
call .get_address
ld [start.vu5], hl
ret
; DE - screen pos, A - register value
.get_address:
bit 4, a
jp nz, .get_e
and 0x0E
ld h, high .calltab
ld l, a
ld e, [hl] : inc l
ld d, [hl]
exd
ret
.get_e:
ld hl, .draw_e
ret
; ------------------
; drawing routines
; DE - dst
.draw_e:
ld a, 0b00000000 : ld [bc], a : inc b ; 18
ld a, 0b11111111 : ld [bc], a : inc b ; 18
ld a, 0b11000011 : ld [bc], a : inc b ; 18
ld a, 0b11011111 : ld [bc], a : inc b ; 18
ld a, 0b11000111 : ld [bc], a : inc b ; 18
ld a, 0b11011111 : ld [bc], a : inc b ; 18
ld a, 0b11000011 : ld [bc], a : inc b ; 18
ld a, 0b11111111 : ld [bc], a : ret ; 24 = 150t per char
.draw_0:
.draw_1:
dup 7 : ld a, 0x00 : ld [bc], a : inc b : edup ; 18*7
dup 1 : ld a, 0x00 : ld [bc], a : ret : edup ; 24*1
.draw_2:
dup 6 : ld a, 0x00 : ld [bc], a : inc b : edup ; 18*6
dup 1 : ld a, 0xFF : ld [bc], a : inc b : edup ; 18*1
dup 1 : ld a, 0xFF : ld [bc], a : ret : edup ; 24
.draw_3:
dup 5 : ld a, 0x00 : ld [bc], a : inc b : edup ; 18*5
dup 2 : ld a, 0xFF : ld [bc], a : inc b : edup ; 18*2
dup 1 : ld a, 0xFF : ld [bc], a : ret : edup ; 24
.draw_4:
dup 4 : ld a, 0x00 : ld [bc], a : inc b : edup ; 18*4
dup 3 : ld a, 0xFF : ld [bc], a : inc b : edup ; 18*3
dup 1 : ld a, 0xFF : ld [bc], a : ret : edup ; 24
.draw_5:
dup 3 : ld a, 0x00 : ld [bc], a : inc b : edup ; 18*3
dup 4 : ld a, 0xFF : ld [bc], a : inc b : edup ; 18*4
dup 1 : ld a, 0xFF : ld [bc], a : ret : edup ; 24
.draw_6:
dup 2 : ld a, 0x00 : ld [bc], a : inc b : edup ; 18*2
dup 5 : ld a, 0xFF : ld [bc], a : inc b : edup ; 18*5
dup 1 : ld a, 0xFF : ld [bc], a : ret : edup ; 24
.draw_7:
dup 1 : ld a, 0x00 : ld [bc], a : inc b : edup ; 18*1
dup 6 : ld a, 0xFF : ld [bc], a : inc b : edup ; 18*6
dup 1 : ld a, 0xFF : ld [bc], a : ret : edup ; 24
align 256
.calltab:
dw .draw_0, .draw_1, .draw_2, .draw_3, .draw_4, .draw_5, .draw_6, .draw_7
; player include
include "player.asm"
; music include
music_p0_ch4:
incbin "ay_env/ay_env_ch4.bin"
music_p0_ch5:
incbin "ay_env/ay_env_ch5.bin"
music_p0_ch6:
incbin "ay_env/ay_env_ch6.bin"
music_p0_ch7:
incbin "ay_env/ay_env_ch7.bin"
music_p0_ch12:
incbin "ay_env/ay_env_ch12.bin"
music_p0_ch13:
incbin "ay_env/ay_env_ch13.bin"
music_p0_ch14:
incbin "ay_env/ay_env_ch14.bin"
music_p0_ch15:
incbin "ay_env/ay_env_ch15.bin"
code_end
; -------------------------------------------------
; music pages
page 0
emptytap "page0.tap"
org 0xC000
align 256
savetap "page0.tap",CODE,"page0",0xC000,$-0xC000
; splash screen
emptytap "splash.tap"
org 0x4000
splash:
block 6144, 0
block 768, (0<<3)|(7<<0)
;incbin "200a.scr"
savetap "splash.tap",CODE,"splash",0x4000,$-0x4000
endmodule
; ----------------------------------------------------
total_codelength equ code_end-codestart
display "total: ", /a, total_codelength, " bytes"
savesna "moebius.sna", start
savetap "player.tap",CODE,"moebius",codestart,total_codelength