Иногда нужно быстро сделать загрузчик интро в формате .TAP. Удобнее всего использовать ассемблер Pasmo, ввести
start
;тут код
end start
и скомпилировать pasmo - tape src.asm
А если понадобится свой загрузчик с печатью текста и установкой цвета? Как вариант - использовать две утилиты bas2tap и bin2tap
Вчера убил целый день чтобы сделать готовый код в sjasmplus. Основная заморочка - подсчет контрольных сумм заголовков и блоков на кассете.
В версии 1.20.3 есть нужная команда:
;tape for sjasmplus v1.20.3
DEFINE relname "Chess" ; name of release
DEFINE tapname "chess.tap" ; .TAP filename
device zxspectrum48
ORG #6000
begin
ld hl,$4000
ld b,$18
ld a,$aa
ch:
ld (hl),a
inc l
jr nz,ch
cpl
inc h
djnz ch
ret
end
basicb:
db 0,10 ;line number
dw line10e-line10b ; length of line10
line10b:
db 253; clear
db 176; val
db 34
; db "24575"
LUA ALLPASS
ss=string.format("%05d",tostring( sj.get_label("begin")-1 ) )
for i=1,5,1 do
sj.add_byte(tonumber(string.byte(string.sub(ss,i,i))))
end
ENDLUA
db 34,":"
db 239;load
db 34,34; ""
db 175,13 ; code
line10e:
db 0,20 ;line number
dw line20e-line20b ; length of line20
line20b:
db 249 ; randomize
db 192 ; usr
db 176 ; val
db 34
; db "24576"
LUA ALLPASS
ss=string.format("%05d",tostring( sj.get_label("begin") ) )
for i=1,5,1 do
sj.add_byte(tonumber(string.byte(string.sub(ss,i,i))))
end
ENDLUA
db 34,13
line20e:
basice:
EMPTYTAP tapname
SAVETAP tapname,BASIC,relname,basicb,basice-basicb,10
SAVETAP tapname,CODE,relname,begin,end-begin
display /d,line10e-line10b;end-begin
; savesna "!void.sna",begin
DEFINE relname "Chess" ; name of release
DEFINE tapname "chess.tap" ; .TAP filename
device zxspectrum48
ORG #6000
begin
ld hl,$4000
ld b,$18
ld a,$aa
ch:
ld (hl),a
inc l
jr nz,ch
cpl
inc h
djnz ch
ret
end
basicb:
db 0,10 ;line number
dw line10e-line10b ; length of line10
line10b:
db 253; clear
db 176; val
db 34
; db "24575"
LUA ALLPASS
ss=string.format("%05d",tostring( sj.get_label("begin")-1 ) )
for i=1,5,1 do
sj.add_byte(tonumber(string.byte(string.sub(ss,i,i))))
end
ENDLUA
db 34,":"
db 239;load
db 34,34; ""
db 175,13 ; code
line10e:
db 0,20 ;line number
dw line20e-line20b ; length of line20
line20b:
db 249 ; randomize
db 192 ; usr
db 176 ; val
db 34
; db "24576"
LUA ALLPASS
ss=string.format("%05d",tostring( sj.get_label("begin") ) )
for i=1,5,1 do
sj.add_byte(tonumber(string.byte(string.sub(ss,i,i))))
end
ENDLUA
db 34,13
line20e:
basice:
EMPTYTAP tapname
SAVETAP tapname,BASIC,relname,basicb,basice-basicb,10
SAVETAP tapname,CODE,relname,begin,end-begin
display /d,line10e-line10b;end-begin
; savesna "!void.sna",begin
Здесь все просто - задать имена для tap-ки, имя файла и добавить код интро. Но версия ассемблера определяется как вирус и я решил переписать под старую версию. Сформировал готовые заголовки/блоки и перешел к подсчету контрольных сумм на случай, если что-то изменится. И тут пришел тупик - Lua не понимает XOR.
Заменил. Позже, после отдыха переписал фрагменты Lua, заработало.
DEFINE relname "Chess" ; name of release
OUTPUT code.tap ; filename
LUA ALLPASS
function tcs(l1,l2,c)
-- local c=0
for i=l1,l2,1 do --start from 255
local b=sj.get_byte(i)
local r=0
local w=1
--calc not supported XOR
for j=0,7,1 do
b1=b-2*math.floor(b/2)
b2=c-2*math.floor(c/2)
-- r=math.floor(r/2)+128*math.abs(b1-b2)
r=r+w*math.abs(b1-b2)
w=w*2
b=math.floor(b/2)
c=math.floor(c/2)
end
c=r
end
sj.add_byte(c)
end
function name_add()
local ss=sj.get_define("relname")
ss=string.gsub(ss,'"',"")
while string.len(ss)<10 do
ss=ss.." "
end
for i=1,10,1 do
sj.add_byte(tonumber(string.byte(string.sub(ss,i,i))))
end
end
function n2s(numba)
ss=string.format("%05d",tostring( numba ) )
for i=1,5,1 do
sj.add_byte(tonumber(string.byte(string.sub(ss,i,i))))
end
end
ENDLUA
device zxspectrum48
; OUTPUT code.tap
;basic
;remove that comments
;13 00<--header length
;00<--always 0 standard header
;00<--always 0 program header
;43 68 65 73 73 20 20 20 20 20 <-padded filename
;22 00<--data length
;0A 00<--autostart line
;22 00<--program length
;64<-----checksum byte
;24 00<--length of second block+2
;FF<---flag byte:0 for headers,FF-data block
;00 0A 0F 00 FD B0 22 32 34 35 37 35 22 3A EF 22 22 AF 0D 00 14 0B 00 F9 C0 B0 22 32 34 35 37 36 22 0D -Basic program
;58<--checksum
org 0
db $13,0
hdr2b:
db 0,0
LUA ALLPASS
name_add()
ENDLUA
dw basice-basicb ; data length
db 10,0 ; autostart
dw basice-basicb ; program length
hdr2e:
; db $64 ; checksum byte
LUA ALLPASS
tcs(sj.get_label("hdr2b"),sj.get_label("hdr2e"),0)
ENDLUA
dw basice-basicb+2 ; data length
db $FF ; flag 'data block'
basicb:
db 0,10 ;line number
dw line10e-line10b ; length of line10
line10b:
db 253; clear
db 176; val
db 34
; db "24575"
LUA ALLPASS
n2s(sj.get_label("begin")-1)
ENDLUA
db 34,":"
db 239;load
db 34,34; ""
db 175,13 ; code
line10e:
db 0,20 ;line number
dw line20e-line20b ; length of line20
line20b:
db 249 ; randomize
db 192 ; usr
db 176 ; val
db 34
; db "24576"
LUA ALLPASS
n2s(sj.get_label("begin"))
ENDLUA
db 34,13
line20e:
basice:
; db $58 ;checksum byte
LUA ALLPASS
tcs(sj.get_label("basicb")-1,sj.get_label("basice"),0)
ENDLUA
;header for code
;13 00<--header length
;00<--always 0 standard header
;03<--always 3 code header
;43 68 65 73 73 20 20 20 20 20<-padded filename
;10 00<--data length
;00 60<--code start
;00 80<--program length
;9D<-----checksum byte
;12 00<--length of second block+2
;FF<---flag byte:0 for headers,FF-data block
;21 00 40 06 18 3E AA 77 2C 20 FC 2F 24 10 F8 C9
;B9<-----checksum
;code
db $13,00;<--header length
hdr1b:
db 00;<--always 0 standard header
db 03;<--always 3 code header
;43 68 65 73 73 20 20 20 20 20<-padded filename
LUA ALLPASS
name_add()
ENDLUA
dw end-begin;10 00<--data length
dw begin;00 60<--code start
dw $8000;00 80<--program length
hdr1e:
; db $9D;<-----checksum byte
LUA ALLPASS
tcs(sj.get_label("hdr1b"),sj.get_label("hdr1e"),0)
ENDLUA
dw end-begin+2;12 00<--length of second block+2
db $FF;<---flag byte:0 for headers,FF-data block
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;code starts here ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG #6000
begin
ld hl,$4000
ld b,$18
ld a,$aa
ch:
ld (hl),a
inc l
jr nz,ch
cpl
inc h
djnz ch
ret
end
; db $B9;<-----checksum
LUA ALLPASS
tcs(sj.get_label("begin")-1,sj.get_label("end"),255)
ENDLUA
В ближайшем времени собираюсь испытать свои изыски и надеюсь, что заработает.
Комментарии
Отправить комментарий