Код:
; Пример программы супер-микро-мини демка ...
EQU $ASAM.PASS.ERROR=1 ;Количество пустых компиляций, для
;устронения вложенных меток в дважды
;запаковынном блоке или больше.
INCLUDE "speccy.az8" ;Маленький набор утилит.
.LoadPack ,_ ;Загрузка ранее запакованных кусков из
@.1.P EQU $PAGE ;файлов, в данном случае это нужно
@.1.S INCBIN @.0 ;для LOADER'а, который подгрузит
@.1.E EQU $-1 ;картинку загрузки ... =)
@.1.L EQU $ASAM.LOAD.SIZE+2
DW $ASAM.LOAD.SIZE
..
.PackerXP _ ;Запаковка блока для 128 страниц
ORG @.0
@.0.P EQU $PAGE
DSQ.Pack @.-@.0
@.0.E EQU $-1
@.0.S EQU $-@.0
..
.RunXP _ ;Автоматическая распаковка и запуск
LD A,@.0.P
LD HL,@.0.E
LD DE,FREEBLOCK
CALL DEPACKXP
..
PAGE 17 ;Какая-то часть компилится в страницу
ORG 49152
EFFx1 PHASE FREEBLOCK ;Адрес свободной памяти
EFFx1_S CALL WaitINCER ;Ожидаем окончания секундного интервала
LD A,1*8+7
CALL Clearuchik ;Стираем экран
CALL Printik ;Печать текста
DW 20480
DB "Spectrum Is The Best ..."+128
RET ;Прощай жизнь, конец части =)
UNPHASE
PackerXP EFFx1 ;Запаковываем кусок
B17.S EQU $-49152 ;Размер страницы #17, который в будущем
;запакуется в LOADER, я понимаю, что
;в этой странице уже и так всё запаковано,
;но это всё просто пример
PAGE 19 ;То же, что и сверху ... =)
ORG 49152
EFFx2 PHASE FREEBLOCK
EFFx2_S CALL WaitINCER
LD A,2*8+6
CALL Clearuchik
CALL Printik
DW 18432
DB "Hello To Aprisobal ..."+128
RET
UNPHASE
PackerXP EFFx2
CLR_P19: ;Процедура, стирания экрана, которая
PUSH AF ;распологается сразу после запакованной
LD A,R ;части
AND 00000111B
LD B,A
RLCA
RLCA
RLCA
OR B
CALL CLR_M0
POP AF
LD HL,16384
LD DE,16385
LD BC,6143
LD (HL),L
LDIR
CLR_M0: LD DE,22529
LD B,A
RRA
RRA
AND A
RRA
LD HL,ICLR+1
LD (HL),A
CLR_M1 BIT 7,(HL)
JZ CLR_M1
LD A,B
LD HL,22528
LD (HL),A
LD BC,767
LDIR
RET
EFFx3 PHASE FREEBLOCK ;Ещё один блок части, в котором
EFFx3_S JMP EFFx3_START ;используется метка на метку !
ORG 49152-(EFFx3_END-EFFx3_START) ;Откомпилит дальнейший код с адреса
EFFx3_START ;в самый конец свободной части памяти.
CALL WaitINCER ;Последний байт картинки "GFX\entire.scr"
LD A,3*8+0 ;будет находиться по адресу 49151
CALL Clearuchik
CALL Printik
DW 16384
DB "Assembler FOREVER ..."+128
CALL WaitINCER
XOR A
CALL Clearuchik
LD HL,ENTIREL
LD DE,18432
LD BC,2048
LDIR
HALT
LD DE,22528+256
INC B
LDIR
RET
ENTIREL IncBIN "GFX\entire.scr"
EFFx3_END
UNPHASE
PackerXP EFFx3
B19.S EQU $-49152
PAGE 20 ;Для красоты, что бы что-то валялось в странице
ORG 49152
DB "CJASM Is The Best ..."+128
B20.S EQU $-49152
PAGE 22 ;Для красоты, что бы что-то валялось в странице
ORG 49152
DB "HAVA NAVA VOCHEZ ??? ..."+128
B22.S EQU 16384
PAGE 23 ;Для красоты, что бы что-то валялось в странице
ORG 49152
DB "NAVA NAIN VOCHEZ ??? ..."+128
B23.S EQU $-49152
PAGE 16 ;Депакер, который будет использоваться как в деме,
ORG 23296 ;так и в LOADER'е
DEPACK
PUSH DE
INC HL
LD C,(HL)
INC HL
LD B,(HL)
DEC HL
DEC HL
DEC DE
EX DE,HL
ADD HL,BC
PUSH HL
EX DE,HL
AND A
PUSH HL
SBC HL,DE
POP HL
JNC DEPAx1
LDDR
JMP DEPAx2
DEPAx1
INC HL
INC DE
SBC HL,BC
EX DE,HL
SBC HL,BC
EX DE,HL
LDIR
DEPAx2
POP HL
POP DE
DEPACKX DSQ.DePacker ;Распаковщик by IMP
B23296.S EQU $-23296
;Programm Block ...
ORG 23552
INT: PUSHA ;Прерывание
ICLR LD A,0 ;Для примера, сюда запихивается цвет бордюра вне INT'а
PUSH AF ;да бы можно было понять, что все блоки распаковываются
AND 7 ;и запускаются автоматически
OUT (254),A
POP AF
OR 10000000B
LD (ICLR+1),A
INCER LD A,1 ;Счёчик по секунде, что бы синхронезироваться после
DEC A ;затраченного времени на распаковку и другую фингню.
JNZ INCERx1
LD A,50
INCERx1 LD (INCER+1),A
POPA
EI
RET
Clearuchik: ;Вызов процедуры очистки экрана, которая лежит в 19-ой
LD BC,32765 ;странице памяти между двумя запакованными блоками
EXA
LD A,19
OUT (C),A
EXA
JP CLR_P19
OrgInt INT,INT ;Утилита из Speccy.az8, устанавливающая в ближайшем
StackSP EQU INT.VecAddr ;адресе вектор прерывания, стек лепится перед вектором,
;нпдо же его куда-нибудь поместить
WaitINCER: ;Ждём окончание секунды
LD HL,INCER+1
LD A,(HL)
DEC A
JNZ WaitINCER
RET
M1 ;Цикл запуска трёх частей, в одной из которых
RunXP EFFx1 ;появляется наш логотип
RunXP EFFx2
RunXP EFFx3
JMP M1
Printik: ;Печать текста
POP HL
LD E,(HL)
INC HL
LD D,(HL)
INC HL
PR1 LD A,(HL)
PUSH AF HL
RLCA
RLCA
RLCA
LD L,A
AND 00000011B
ADD A,60
LD H,A
LD A,L
AND 11111000B
LD L,A
LD B,D
.8 ;Восем раз повторить нужно !!! =)
LD A,(HL)
LD (DE),A
INC L
INC D
..
ORG $-2 ;Стираем лишние команды, будем экономны !!! =)
LD D,B
POP HL AF
INC E
INC HL
RLCA
JNC PR1
PUSH HL
RET
DEPACKXP: ;Распаковка блока и запуск его, так как он депачится
LD BC,32765 ;сразу послет CALL DEPACKX
OUT (C),A
CALL DEPACKX
FREEBLOCK
;Start Of Programm
START: ;Сюда происходит JMP из LOADER'а, так как этот кусок
DI ;запускается только раз, его в будущем сотрут
LD A,(22528) ;части ГИГА-демы !!! =)
RRCA
RRCA
RRCA
LD (ICLR+1),A
LD SP,StackSP
LD BC,32765
LD A,16
OUT (C),A
LD A,INT.VEC
LD I,A
LD HL,INT
LD (INT.VecAddr),HL
IM 2
EI
JMP M1 ;Интересно, в итоге получился "JP M1" или "JR M1" ?
.1
INCLUDE "loader.az8" ;Там лоадер всё запакует и сделает готовый для
ORG @. ;использования файл, запихнув его в TRD
..
SaveLabels "wl.txt" ;Для примера сохраним все мекти, которые были
;в проекте
;ВСЁ !!! нано-дема отова ... Кстати, вы обратили внимание, на то, что дема
;компилится вообще во всю область памяти, и на ВАСИКовские переменные !!! =)
;
;В итоге всё это ужалось в 4352, с учётом нулей, при сохранении запакованных
;страниц для блоковой загрузки по секторам ... Не экономно, но облом делать
;качественную версию ... В игре Surgicsl Fantasy увидите качественную структуру
;файла, имеющий до 300-та запакованных файлов, блоков и других кусков.
;
Можно-ли подобное откомпилировать в CJASM'е ? Я лишь нажимаю "ентер" и получаю готовый файл, которым уже можно пользоваться !!!