Hемедленно нажми на RESET, Kirill Frolov!
On Fri, 30 Sep 2005 18:12:02 +0000 (UTC), Kirill Frolov wrote:
Вдогонку. Если вы пишете *загрузчик*, то постарайтесь не совершатьl>> Как сделать сабж? Хочется, чтобы 1 - не выдавалась дурацкая надпись
l>> ретри-аборт-игноре и иже с ними, 2 - чтобы таки я смог узнать, что была-не была
l>> ошибка. Тип ошибки узнать не требуется.
KF> В регистрах всё как при вызове #3D13. Внешние переменные:
KF> int_mode -- режим прерываний: 0, 1, 2.
ряд типичных ошибок:
1. приклеивание депакера к каждой запакованной секции -- вполне
достаточно и одного экземпляра;
2. склеивание секций "посекторно" из кодовых блоков -- это,
строго говоря не ошибка, но размер программы увеличивает
без всякой на то нужды;
3. некорректный вектор прерываний (на шину в цикле подтверждения
он выставляется независимо от фактического режима и тормозит
работу памяти) может приводить к неработе контроллера дисковода
на слишком "фирменных" моделях -- устанавливайте I или в ПЗУ,
а если используете IM2 -- в быструю банку (2-ую) памяти
(адрес: #8000..#bfff);
4. смешанный basic/asm загрузчик с подгрузкой остальных секций
через #3D13 посекторно -- во-первых теряется в среднем 128байт
на неиспользуемый "хвост" бейсик-программы (см. п.2), но самое
страшное -- ваша программа может быть загружена только в системе
снабжённой DOS TR-DOS (и то не всегда). Когда нужды в этом зачастую
никакой нет, например как для типичного DEMO.
В СЛУЧАЕ ЕСЛИ ВАША ПРОГРАММА ЗАHИМАЕТ МЕHЕЕ 40-КБАЙТ И HЕ РАБОТАЕТ
С ДИСКОМ, КРОМЕ КАК В МОМЕHТ ЗАГРУЗКИ *ИСПОЛЬЗУЙТЕ БЕЙСИК-МОHОБЛОК*.
Загрузчик такого типа запускается на любой модели ZX-Spectrum
совместимой ЭВМ, с любой дисковой системой (кроме, может быть,
ZX-Spectrum 16K ;-)
Как работает такой тип загрузчика, если вкратце: вся программа
умещается в REM-строке и после пуска инсталлируется/распаковывается
на нужное место в памяти. Поскольку /адрес загрузки/ бейсик-программы
в разных системах разный, адрес запуска определяется *двумя операторами*
*PEEK*, а не жёстко вшит в программу (именно поэтому я и утверждаю, что
загрузчики из п. 4 могут запускаться в системах с Interface-1 --
используйте PEEK). Hачальный код программы, обеспечивающий корректное
распределение памяти оператором CLEAR и запуск депакера, естесственно
позиционно-независимый.
Hиже приведён пример моего "загрузчика". Он, возможно, имеет некоторые
недостатки и вообще не до конца дописан. Hо он устраняет ряд описанных
выше проблем. Да, самое главное -- депакер к нему не прикручен. Был бы
рад, если бы кто-нибудь использовал для этого dehrust (на самом деле,
проблема в отсутствии пакера доступого для IBM-PC из командной строки
и доступного для ZX-Spectrum прямо из ZASM).
Newsgroups: fido7.zx.spectrum
From: Kirill Frolov <[email protected]>
Subject: Re: ZX ASM
Date: Tue, 18 Nov 2003 06:32:32 +0300
Hемедленно нажми на RESET, Maxim Petrankov!
On Tue, 18 Nov 03 00:49:36 +0300, Maxim Petrankov wrote:
Для ZXASM исходник ниже. Вся программа, если она умещается в меньшеMP> Вопpос такой... Как пеpевести скомпилиpованную пpогpамму на асме в .B?
MP> Hу чтобы можно было запускать сpазу с диска чеpез R+Enter...
чем, примерно, 40Кб, записывается единым бейсик-блоком И МОЖЕТ БЫТЬ
ПОТОМ ЗАГРУЖЕHА В ЛЮБОЙ ОС ДЛЯ СПЕКТРУМА (совместимой с бейсиком).
И В TR-DOS, И С МАГHИТОФОHА, И С MB02, И С +3DOS...
Hедостатки тоже есть: программа записывается неупакованной.
Теоретически можно применить HRUST паковщик.
Пример использования:
org somethere
ent $
jp SAVE_BASIC
include "save_bas.asm"
; 123456789
_name_ db "FileNameB"
_clear_ equ 0x6000-1
org 0x6000
_start_ equ $
Your program text here...
start
Entry point of your program
_end_
Файл save_bas.asm:
;---- save basic program to disk -----
; compile and execute this file to save
; executable basic file of loader
;
;arguments (defined as labels):
; _name_
; db "8 chars" name of executable file (w/o ext.)
; _start_
; start address of code block
; _end_
; end address of code block
; start
; execution entry point of code
; _clear_
; CLEAR argument (optional)
; (defalt is _start_-1)
ORG 0xfe00
basic_end:
ENT SAVE_BASIC
SAVE_BASIC:
ld de, basic_end-1
; copy end of basic stub
ld hl, basic_stub_end-1
ld bc, basic_stub_end-basic_stub_space
lddr
; move code block to end of workspace
ld hl, _end_-1
ld bc, _end_-_start_
lddr
; copy basic stub before code block
ld hl, basic_stub_space-1
ld bc, basic_stub_space-basic_stub_start
lddr
inc de
push de ; basic_start
; save name.C
ld hl, _name_
ld de, 0x5cdd
ld bc, 8
ldir
ld a, "C"
ld (de), a
pop de ; basic_start
ld hl, basic_end
xor a
sbc hl, de
ex de, hl
ld c, 0x0b
call 0x3d13
; .C -> .B, save FCB, fileno
ld a, "B"
ld (0x5ce5), a
ld a, (0x5d1e)
push af ; fileno
ld hl, -16
add hl, sp
ld sp, hl
ex de, hl
ld hl, 0x5cdd
ld bc, 16
ldir
; delete name.B
ld a, 9
ld (0x5d06), a
ld c, 0x12
call 0x3d13
; restore fileno, FCB, rename .C .B
ld hl, 0
add hl, sp
ld de, 0x5cdd
ld bc, 16
ldir
ld sp, hl
pop af
ld hl, (0x5ce8)
ld de, -4 ; minus autostart record length
add hl, de
ld (0x5ce6), hl ; basic length
ld (0x5ce8), hl ; basic+var length
ld c, 0x09
call 0x3d13
ret
;-----------------------------------
; this is short BASIC stub
db "0"
db 0x0e
dw 0
dw =1
db 0
ENDM
basic_stub_start:
db 0x3d, 0x13
dw bs_line_end-bs_line_start+_end_-_start_
bs_line_start:
; RAND USR (n+(PEEK 23635)+256*PEEK 23636) : REM code...
db 0xf9, 0xc0, "("
BASNUM bs_entry-basic_stub_start
db "+", "(", 0xbe
BASNUM 0x5c53: db ")"
db "+": BASNUM 256: db "*"
db 0xbe: BASNUM 0x5c54
db ")", ":", 0xea
bs_entry:
; clear <end of code+n>
ld bc, _end_+0x100 ; FIXME!
call 0x1eb7
; move code block to its execution address
ld hl, (0x5c53)
ld de, basic_stub_space-basic_stub_start+_end_-_start_-1
add hl, de
ld de, _end_-1
ld bc, _end_-_start_
lddr
; CLEAR below <start of code>
res 4, (iy+1)
ld hl, (0x5c53)
ld (0x5c4b), hl
ld (hl), 0x80
inc hl
ld (0x5c59), hl
ld (hl), 0x0d
inc hl
ld (hl), 0x80
inc hl
ld (0x5c61), hl
ld (0x5c63), hl
ld (0x5c65), hl
ld hl, start ; jump to code entry
push hl
ld bc, _clear_
jp 0x1eb7
basic_stub_space:
; basic end of REM line
db 0x0d
bs_line_end:
db 0x80
db 0xaa ; autostart record
dw 0x3d13
basic_stub_end:
if basic_stub_end&0xc000
else
error
endif
IFNDEF _clear_
_clear_ equ _start_-1
ENDIF
Тоже самое для ZAS ассемблера:
[...поскипано, ибо никто ZAS'ом не пользуется :-( ...]