- Сообщения
- 42
- Счётчик реакций
- 12
- Очки
- 275
В связи с встреченными неточностями хотелось бы рассмотреть формат SCL
Описание ZX Modules неточное
Speccy.info
Бинарный файл в .scl
строка org $8000-14*1-9 - подготовка заголовка файла - слово "SINCLAIR" 8 байт, следующий байт- количество файлов, для бинарного файла равен 1.
После заголовка SCL следуют заголовки файлов:
db "girl C" ;имя файла длиной 8 байт, тип 1 байт
dw 16384;стартовый адрес кодового блока
dw end-begin;размер файла
db (end-begin+255)/256; количество секторов файла.
После заголовков файлов располагаются данные:
begin
incbin "girl.scr"
end
align 256 ; выравнивание секторов, например файл размером 1 байт займет 256 байт.
Подсчитать контрольную сумму можно с помощью LUA. Здесь используется только имя test.scl
SCL-моноблок
Этот трюк известен старой школе: Сначала подготавливается загрузчик на ассемблере, расположенный в строке 1 REM кодовый блок. строка 2 - вызов программы-загрузки. Вслед за программой добавляются файлы, которые будут загружены. После готового варианта нужно удалить оставшиеся файлы и изменить размер секторов программы на Basic в заголовке. Подобную операцию можно сделать с помощью Perfect Commander, выбрав файлы и нажав клавишу Z, подтвердив объединение, нажав Y.
В примере сделан сборка выдранного crackintro:
Здесь в заголовке SCL указан один файл и заголовок будет только для одного файла.
Программа Basic формируется в исходном тексте
Вслед за программой добавлен один кодовый блок wb1.bin, оба файла выравниваются по секторам:
align 256; выравнивание BASIC файла по секторам
incbin "wb1.bin"
align 256; выравнивание кодового блока по секторам
Завершение исходного текста - подсчет контрольной суммы и запись в формате SCL
Загрузка кодового блока из Basic
В этом примере в заголовке SCL указано два файла - Basic, который состоит из простой загрузки и кодовый блок, заранее скомпилированный. Последняя процедура изменена - название создаваемого файла берется из заголовков.
Описание ZX Modules неточное
Speccy.info
Бинарный файл в .scl
Assembler Z80:
device zxspectrum128
macro sectors datab,datae
IF low (datae-datab)=0
db high (datae-datab)
ELSE
db (1+high (datae-datab))
ENDIF
endm
org $8000-14*1-9
scl_b:
;заголовок
db "SINCLAIR"
db 1; один файл
; файл 1
; 12345678t
db "girl C" ;имя файла длиной 8 байт, тип 1 байт
dw 16384;адрес кодового блока
dw end-begin;размер
db (end-begin+255)/256
; данные файлов
begin
incbin "girl.scr"
end
align 256 ; выравнивание секторов
scl_e:
savebin "test.scl",scl_b,scl_e-scl_b; сохранить файл
; подсчет и запись контрольной суммы
LUA
local fp
local checksum
fp = assert(io.open("test.scl", "rb"))
checksum=0
while true do
local byte = fp:read(1)
if byte==nil then
break
end
checksum=checksum+string.byte(byte)
end
assert(fp:close())
print("writing",string.format("%08X",checksum))
fp = assert(io.open("test.scl", "a"))
for i=1,4 do
fp:write(string.char(checksum%256))
checksum=math.floor(checksum/256)
end
-- assert(fp:flush())
assert(fp:close())
ENDLUA
После заголовка SCL следуют заголовки файлов:
db "girl C" ;имя файла длиной 8 байт, тип 1 байт
dw 16384;стартовый адрес кодового блока
dw end-begin;размер файла
db (end-begin+255)/256; количество секторов файла.
После заголовков файлов располагаются данные:
begin
incbin "girl.scr"
end
align 256 ; выравнивание секторов, например файл размером 1 байт займет 256 байт.
Подсчитать контрольную сумму можно с помощью LUA. Здесь используется только имя test.scl
SCL-моноблок
Этот трюк известен старой школе: Сначала подготавливается загрузчик на ассемблере, расположенный в строке 1 REM кодовый блок. строка 2 - вызов программы-загрузки. Вслед за программой добавляются файлы, которые будут загружены. После готового варианта нужно удалить оставшиеся файлы и изменить размер секторов программы на Basic в заголовке. Подобную операцию можно сделать с помощью Perfect Commander, выбрав файлы и нажав клавишу Z, подтвердив объединение, нажав Y.
В примере сделан сборка выдранного crackintro:
Assembler Z80:
device zxspectrum128
entrya=$100
org entrya-14*1-9
scl_b:
db "SINCLAIR"
db 1; количество файлов
;-файл 1
file1:
; 12345678t
db "WestBankB"
dw basic_e-basic_b-4;start
dw basic_e-basic_b-4;длина
db (scl_e-basic_b+255)/256
; org entrya
basic_b:
db #00,#01;номер строки
DW EndLine1 - Line1
Line1:
db #EA ; REM
res 4,(iy+1)
xor a:out ($FE),a
ld hl,$5AFF,de,$5AFe,bc,$1B00-1,(hl),0:lddr
macro trload mema,secs
ld hl,mema
ld bc,5+secs*256
ld de,(#5CF4)
call $3d13
endm
macro pokeb addr,byt
ld a,byt,(addr),a
endm
x2:
di
ld a,$10,bc,$7FFD:out (c),a
di
ld sp,$5fff
trload $6018,$A0
call $6018
pokeb $6241,6
pokeb $6242,$97
pokeb $6235,$72
pokeb $6236,$E3
jp $61a8
jr $
;------------------------------
db #0D
EndLine1:
db #00,#02
DW EndLine2 - Line2
Line2:
;border not pi
db 231,195,167
db #3A; :
db #20,#FD,#B0,#22,#32,#34,#35,#37,#35,#22;clear val "24575"
db #3A; :
db #F9,#C0,#28,#35;randomize usr (5+256*peek val "23635"+peek val "23636"
db #0E,#00,#00,#05,#00,#00,#2B
db #32,#35,#36
db #0E,#00,#00,#00,#01,#00,#2A,#BE
db #B0
db #22,#32,#33,#36,#33,#36,#22;"23635"
db #2B;???
db #BE
db #B0
db #22,#32,#33,#36,#33,#35,#22;"23636"
db #29,#0D;)
db #80
db #AA,1,0;;;;;;;;;;;;;autorun line,change program length to -4, e.g. 83-4=79
EndLine2:
basic_e:
;данные секторов
align 256; выравнивание BASIC файла по секторам
incbin "wb1.bin"
align 256; выравнивание кодового блока по секторам
scl_e: ; сохранение файла и под счет контрольной суммы
savebin "huj.scl",scl_b,scl_e-scl_b
LUA
local fp
local checksum
-- never rename file
fp = assert(io.open("huj.scl", "rb"))
checksum=0
while true do
local byte = fp:read(1)
if byte==nil then
break
end
checksum=checksum+string.byte(byte)
end
assert(fp:close())
print("writing",string.format("%08X",checksum))
fp = assert(io.open("huj.scl", "a"))
for i=1,4 do
fp:write(string.char(checksum%256))
checksum=math.floor(checksum/256)
end
assert(fp:close())
-- имя файла из заголовка
local ss=""
for i=0,7,1 do
ss=ss..string.char( sj.get_byte( sj.get_label("file1")+i ) )
end
ss=ss:match "^%s*(.-)%s*$"
-- print(ss)
os.remove(ss..".scl")
os.rename("huj.scl", ss..".scl")
ENDLUA
Программа Basic формируется в исходном тексте
Бейсик ZX:
1 REM загрузчик
2 BORDER NOT PI:CLEAR VAL "24575":RANDOMIZE USR (5+256*PEEK VAL "23635"+PEEK VAL "23636")
Вслед за программой добавлен один кодовый блок wb1.bin, оба файла выравниваются по секторам:
align 256; выравнивание BASIC файла по секторам
incbin "wb1.bin"
align 256; выравнивание кодового блока по секторам
Завершение исходного текста - подсчет контрольной суммы и запись в формате SCL
Загрузка кодового блока из Basic
Assembler Z80:
device zxspectrum128
macro sectors datab,datae
IF low (datae-datab)=0
db high (datae-datab)
ELSE
db (1+high (datae-datab))
ENDIF
endm
org $8000-14*2-9
scl_b:
;header_b:
db "SINCLAIR"
db 2;два файла
;-1st
file1:
; 12345678t
db "sw1k B"
dw basic_e-basic_b-4;start
dw basic_e-basic_b-4;length?
db (basic_e-basic_b+255)/256; количество секторов BASIC
; 12345678t
;-2nd
db "sw1k C"
dw $8000;start address of code block
dw end-begin;size of code
db(end-begin+255)/256; количество секторов кодового блока
;BASIC
align 256
basic_b:
db #00,10;номер строки
DW EndLine1 - Line1
Line1:
db 231 ; border
db 195 ; not
db 167 ; pi
db ":"
db 218 ; paper
db 195 ; not
db 167 ; pi
db ":"
db 217 ; ink
db 195 ; not
db 167 ; pi
db ":"
db $FD;clear
db $B0;val
db $22,"24575",$22,":"
db $F9;randomize
db $C0;usr
db $B0;val
db $22,"15619",$22,":"
db $EA;rem
db ":"
db $EF;load
db $22,"sw1k",$22
db $AF;code
db #0D
EndLine1:
db #00,20;номер строки
DW EndLine2 - Line2
Line2:
db $F9;randomize
db $C0;usr
db $B0;val
db $22,"25600",$22
db #0D
EndLine2:
db #80;for autorun
db #AA,10,0
basic_e:
align 256
begin
incbin "sw1k.code"
end
align 256
scl_e:
savebin "test.scl",scl_b,scl_e-scl_b
LUA
local fp
local checksum
fp = assert(io.open("test.scl", "rb"))
checksum=0
while true do
local byte = fp:read(1)
if byte==nil then
break
end
checksum=checksum+string.byte(byte)
end
assert(fp:close())
print("writing",string.format("%08X",checksum))
fp = assert(io.open("test.scl", "a"))
for i=1,4 do
fp:write(string.char(checksum%256))
checksum=math.floor(checksum/256)
end
-- assert(fp:flush())
assert(fp:close())
--name
local ss=""
for i=0,7,1 do
ss=ss..string.char( sj.get_byte( sj.get_label("file1")+i ) )
end
ss=ss:match "^%s*(.-)%s*$"
-- print(ss)
os.rename("test.scl", ss..".scl")
ENDLUA