Как оказалось для меня было достаточно сложно написать даже не сами эффекты (они могут быть и совсем простыми, че уж там), а именно сделать удобную систему по их компоновке и очередности переключения в зависимости от музыки. Повозившись несколько вечеров пришел к некоему начальному варианту своего демокернеля. Не идеально, но как точка отсчета пойдет. Итак что мне надо было
1 переключатель банков и экранов. Да да как не странно делать это просто из кода опасно ибо музыка на прерываниях в банке, иногда без этого никуда но в общем случае только через кернель.
2 обработчик прерываний, да он тоже в кернеле, из него вызывается плеер и эффекты висящие на прерывании, а также таймер
3 загрузка с диска: банк, адрес, число секторов. Тут все ясно, читаю сектора подряд, в 99% этого достаточно.
4 копирование из банка в банк. Кросс банк распаковщик я не делал поэтому нужно.
5 собственно депакер. Я пользовался великолепным mhmt, вроде сейчас буржуи придумали что то помоднее, посмотрю как нить
6 таймер, очень важная часть. У меня было 4 отдельных таймера, в 0 всегда фреймы от начала проигрывания музыки, остальные по обстоятельствам, пригодился пока только 0 и 1. Тут еще надо многое обдумать. У меня было только сохранить таймер, и ждать энный таймер +пауза. Для моей поделки этого было достаточно.
7 Различные запускалки эффектов, повесить на прерывание,просто вызвать, сменить обработчик прерываний (тут осторожно таймер сам себя тикать не будет)
8 Небольшая обвязка для работы с музыкой
9 Ну и вспомогательные поке в переменные эффектов
Все компилилось батником в несколько стадий.
Сначала кернель, из него экспорт нужных меток, которые потом инклюдились в эффекты.
Сами эффекты, из них экспортом собирались важные метки, которые потом использовались в конечной сборке.
Эффекты паковались
Сборка основного цикла и формирование образа, тут использовались все экспорты из эффектов и собственно делалась вся синхронизация когда и музыки.
В принципе получилось достаточно удобно, сборка одним батником, независимые части, отлаживать можно отдельно. Сам кернель занимал 512 байт, а основная управлялка сидела в отдельной банке. Как делают другие я не знаю, поискал по ничего путевого не нашел, либо как обычно плохо искал, либо правда это секреты для узкого круга и все приходит с опытом. Собственно любые предложения велком.
Самое сложное для меня в демо
1.
callbyHL: jp (hl)
;--------------int--------
INTVEC PUSH AF,BC,DE,HL,IX
EXX:PUSH AF,BC,DE,HL
EXA:PUSH AF
ld hl,(callb4)
ld a,h:or l:call nz,callbyHL
ld a,(curpage):and #18:or 1
ld bc,#7FFD:out (c),a
call PLAY
ld a,(CurPos)
ld (notecnt),a
ld a,(curpage)
ld bc,#7FFD:out (c),a
v1:ld hl,0:inc hl:ld (v1+1),hl,(intcnt),hl
POP AF:EXA
POP HL,DE,BC,AF:EXX
POP IX,HL,DE,BC,AF
EI:RETI
bank01:halt
bank02:push bc
ld bc,#7FFD:out (c),a
ld (curpage),a
pop bc:ret
curpage:db 0
notecnt:db 0
intcnt:dw 0
callb4:dw 0
Значения меток curpage и bank02 можно вынести в .inc Я использовал для простоты
ei:halt
ld a,$10
ld (curpage),a
или вызывал bank01
Синхронизация по notecnt или intcnt - intcnt удобнее при привязке к музыке.
3. омг лол. нахера тебе считать?
macrosectors datab,datae
IF low (datae-datab)=0
db 1,5,high (datae-datab)
ELSE
db 1,5,(1+high (datae-datab))
ENDIF
endm
MODULE boot
Basic:
db #00,#01;номер строки
DW EndLine1 - Line1
Line1:
db #EA;REM
ld sp,#5FFE
di
ld de,(#5CF4)
ld hl, #6000
ld a,#10,bc,#7FFD:out (c),a
sectors begin,end
call #3d13
макрос sectors перепишешь как тебе больше нравятся. Все части демо раскиданы по пагам, отсюда:
di
ld de,(#5CF4)
ld hl, #C500
ld a,#11,bc,#7FFD:out (c),a
sectors page1b,page1e
call #3d13
di
ld de,(#5CF4)
ld hl, #C000
ld a,#13,bc,#7FFD:out (c),a
sectors page3b,page3e
call #3d13
...
PAGE 3
ORG $C000
page3b:
part5b:
incbin "04chess\chess.code"
part5e:
part6b:
incbin "05sdots\sdots.code"
part6e:
part7b:
incbin "06heart\heart.code"
part7e:
part8b:
incbin "07interf\interf.code"
part8e:
part9b:
incbin "08colch\colch.code"
part9e:
part10b:
incbin "09stars\stars.code"
part10e:
page3e:
4. А зачем два банка щелкать?
5. zx7 пошустрее и жмет не хуже. Исключение - части кода распаковывает медленне.
6. Не понял зачем это?
7. переменная callb4 - пишешь адрес процедуры, главное условие, чтоб уложилась во фрем. По идее можно задействовать мультиколор.
Я использовал прием, чтобы избежать сечения луча - плазма в Reality, вспыхивание экрана в 4squares.
8. Непонятно, какая обвязка. пихаешь музон и плеер в страничку, вызов в векторе.
callbyHL: jp (hl)
;--------------int--------
INTVEC PUSH AF,BC,DE,HL,IX
EXX:PUSH AF,BC,DE,HL
EXA:PUSH AF
ld hl,(callb4)
ld a,h:or l:call nz,callbyHL
ld a,(curpage):and #18:or 1
ld bc,#7FFD:out (c),a
call PLAY
ld a,(CurPos)
ld (notecnt),a
ld a,(curpage)
ld bc,#7FFD:out (c),a
v1:ld hl,0:inc hl:ld (v1+1),hl,(intcnt),hl
POP AF:EXA
POP HL,DE,BC,AF:EXX
POP IX,HL,DE,BC,AF
EI:RETI
bank01:halt
bank02:push bc
ld bc,#7FFD:out (c),a
ld (curpage),a
pop bc:ret
curpage:db 0
notecnt:db 0
intcnt:dw 0
callb4:dw 0
Значения меток curpage и bank02 можно вынести в .inc Я использовал для простоты
ei:halt
ld a,$10
ld (curpage),a
или вызывал bank01
Синхронизация по notecnt или intcnt - intcnt удобнее при привязке к музыке.
3. омг лол. нахера тебе считать?
macrosectors datab,datae
IF low (datae-datab)=0
db 1,5,high (datae-datab)
ELSE
db 1,5,(1+high (datae-datab))
ENDIF
endm
MODULE boot
Basic:
db #00,#01;номер строки
DW EndLine1 - Line1
Line1:
db #EA;REM
ld sp,#5FFE
di
ld de,(#5CF4)
ld hl, #6000
ld a,#10,bc,#7FFD:out (c),a
sectors begin,end
call #3d13
макрос sectors перепишешь как тебе больше нравятся. Все части демо раскиданы по пагам, отсюда:
di
ld de,(#5CF4)
ld hl, #C500
ld a,#11,bc,#7FFD:out (c),a
sectors page1b,page1e
call #3d13
di
ld de,(#5CF4)
ld hl, #C000
ld a,#13,bc,#7FFD:out (c),a
sectors page3b,page3e
call #3d13
...
PAGE 3
ORG $C000
page3b:
part5b:
incbin "04chess\chess.code"
part5e:
part6b:
incbin "05sdots\sdots.code"
part6e:
part7b:
incbin "06heart\heart.code"
part7e:
part8b:
incbin "07interf\interf.code"
part8e:
part9b:
incbin "08colch\colch.code"
part9e:
part10b:
incbin "09stars\stars.code"
part10e:
page3e:
4. А зачем два банка щелкать?
5. zx7 пошустрее и жмет не хуже. Исключение - части кода распаковывает медленне.
6. Не понял зачем это?
7. переменная callb4 - пишешь адрес процедуры, главное условие, чтоб уложилась во фрем. По идее можно задействовать мультиколор.
Я использовал прием, чтобы избежать сечения луча - плазма в Reality, вспыхивание экрана в 4squares.
8. Непонятно, какая обвязка. пихаешь музон и плеер в страничку, вызов в векторе.
Ненависть- это подарок