ZXNet эхоконференция «code.zx»
тема: 3Д13 без ретри-аборт-игноре - как?
от: Dratov Denis
кому: lvd
дата: 24 Sep 2005
lvd> Плиз подскажите куда идти (по какому урлю) или так скажите. =)
Может быть есть определенные статьи по этому делу
Hо я самостоятельно еще в 94м году этот вопрос разгребал когда пытался сделать
дсковое меню к PSM.
Во-первых нужно перехватывать вызов BASIC функций через подмену переменной по
адресу #5cc2 (в которой #c9 = ret). Трейсить стек. Через него вызываются разные
функции, типа - отчистка экрана, сканирование клавиатуры, вывода символа.
Подменять эти функции, собирать строки которые идут на вывод, игнорировать
всякие отчистки, сканирования на break и т.д.
Примерно так :)
P.S.: Самому интересно было бы по этому поводу почитать более "научный"
материал или посмотреть даже наработки, поскольку механизм универсален.
от: lvd
кому: All
дата: 24 Sep 2005
Как сделать сабж? Хочется, чтобы 1 - не выдавалась дурацкая надпись
ретри-аборт-игноре и иже с ними, 2 - чтобы таки я смог узнать, что была-не была
ошибка. Тип ошибки узнать не требуется.
Плиз подскажите куда идти (по какому урлю) или так скажите. =)
--
-+- "Пока я намерен бороться со вновь прибывшими." (c) CityAceE
от: Robus
кому: Robus
дата: 25 Sep 2005
Rob> Это просто:
Rob> единственное, при ошибке чтения он будет пытаться читать вечно =)
Это я ошибся, он будет читать несколько раз, в зависимости от переменных, а о
том была-ли ошибка, нужно почитать описания процедур 3Д13...
--
By Rob F. / Entire Group ...
от: Robus
кому: lvd
дата: 25 Sep 2005
lvd> Как сделать сабж? Хочется, чтобы 1 - не выдавалась дурацкая надпись
lvd> ретри-аборт-игноре и иже с ними, 2 - чтобы таки я смог узнать, что была-не
lvd> была ошибка. Тип ошибки узнать не требуется. Плиз подскажите куда идти (по
lvd> какому урлю) или так скажите. =)
Это просто:
DI
LD A,63
LD I,A
XOR A
LD (23613),A
LD HL,51697
LD (23746),HL
IM 1
EI
Безусловно, переменные ВАСИКА должны быть установленны ... =) После
вше-указанных АСМ-строчек ни брейк ни игноры не будут действовать,
единственное, при ошибке чтения он будет пытаться читать вечно =)
--
By Rob F. / Entire Group ...
от: Dratov Denis
кому: Pawel
дата: 25 Sep 2005
Paw> Смотри статью "Обработка дисковых ошибок TR-DOS" на нашем сайте.
Hу это в общем примерно то, о чем я говорил, но ведь это не совсем полное кроме
RIA/ReadOnly еще бываю ошибки типа кривого формата, или отсутствие его, которое
можно уже _уточнить_ через порт состояния.
от: Павел Кисляк
кому: Robus
дата: 25 Sep 2005
Смотри статью "Обработка дисковых ошибок TR-DOS" на нашем сайте
[http://realsoft.nm.ru/download.htm].
от: Ilya Razyev
кому: lvd
дата: 26 Sep 2005
Привет lvd!
Отвечаю на ваше письмо от 24.09.2005, тогда писал(а) lvd
к All, а было тогда на часах 22:44:14.
l> Как сделать сабж? Хочется, чтобы 1 - не выдавалась дурацкая надпись
l> ретри-аборт-игноре и иже с ними, 2 - чтобы таки я смог узнать, что была-не
l> была ошибка. Тип ошибки узнать не требуется.
l> Плиз подскажите куда идти (по какому урлю) или так скажите. =)
zx.pk.ru программирование!!!
Всего хорошего,
Ilya.
BoundlessJack KetchDiLife ScreenBeepGirl\n
Таймыр 2.00 (c) Евгений Варнавский
от: Kirill Frolov
кому: lvd
дата: 30 Sep 2005
Hемедленно нажми на RESET, lvd!
On Sat, 24 Sep 05 21:44:14 +0400, lvd wrote:
l> Как сделать сабж? Хочется, чтобы 1 - не выдавалась дурацкая надпись
l> ретри-аборт-игноре и иже с ними, 2 - чтобы таки я смог узнать, что была-не
l> была ошибка. Тип ошибки узнать не требуется.
В регистрах всё как при вызове #3D13. Внешние переменные:
int_mode -- режим прерываний: 0, 1, 2.
in_trdos -- не равно 0 при вызове функций tr-dos.
Hа выходе: флаг C установлен если произошла ошибка (была перехвачена),
в противном случае флаг C сброшен. Тип ошибки не возвращается, но
там вариантов-то по моему и не особо много: ошибка чтения/записи,
защита записи. Можно посмотреть в переменные TR-DOS. Да, разумеется
сами функции #3D13 могут возвращать признак ошибки без дурацкой надписи
и проверять всё равно надо (поиск файла, например), для чтения-записи
секторов не актуально конечно.
EXPORT global trdos
; call 0x3d13 in safe way
; CF=1 признак фатального завершения
trdos:
ex af, af'
exx
ld hl, 0x5cc2
ld a, (hl)
push af
ld (hl), 0xc3
ld hl, (0x5cc3)
push hl
ld hl, trdos_catch
ld (0x5cc3), hl
ld hl, (0x5c3d)
push hl
ld hl, trdos_fail
push hl
ld hl, 0
ld (0x5d0f), hl
add hl, sp
ld (trdos_sp), hl
ld (0x5c3d), hl
ld hl, in_trdos
ld (hl), 1 ; for im 2
; DOES NOT WORK!
im 1
ld hl, 0x2758
ld iy, 0x5c3a
exa
exx
call 0x3d13
exa
xor a
ld (in_trdos), a
ld a, (int_mode)
cp 2
jr c,trdos_im0
im 2
trdos_im0:
exx
pop hl
pop hl
ld (0x5c3d), hl
pop hl
ld (0x5cc3), hl
pop af
ld (0x5cc2), a
ld hl, 0x2758
exx
exa
or a
ret
trdos_catch:
ex (sp), hl
push af
push de
push hl
ld a, l
or 0x05
ld l, a
ld de, 0-0x0d6f ; 0d6e, 0d6b
adc hl, de
jr z, trdos_fail0
pop hl
pop de
pop af
ex (sp), hl
ret
trdos_fail0:
ld sp, 0
trdos_sp equ $-2
ret
trdos_fail:
xor a
ld (in_trdos), a
ld a, (int_mode)
cp 2
jr c,trdos_im1
im 2
trdos_im1:
pop hl
ld (0x5c3d), hl
pop hl
ld (0x5cc3), hl
pop af
ld (0x5cc2), a
scf
ret
ENDEXP
от: Kirill Frolov
кому: Ilya Razyev
дата: 30 Sep 2005
Hемедленно нажми на RESET, Ilya Razyev!
On Mon, 26 Sep 05 08:42:10 +0400, Ilya Razyev wrote:
l>> Плиз подскажите куда идти (по какому урлю) или так скажите. =)
IR> zx.pk.ru программирование!!!
zxnet://code.zx
от: Kirill Frolov
кому: Dratov Denis
дата: 30 Sep 2005
Hемедленно нажми на RESET, Dratov Denis!
On Sun, 25 Sep 05 17:41:08 +0400, Dratov Denis wrote:
Paw>> Смотри статью "Обработка дисковых ошибок TR-DOS" на нашем сайте.
DD> Hу это в общем примерно то, о чем я говорил, но ведь это не совсем полное
DD> кроме RIA/ReadOnly еще бываю ошибки типа кривого формата, или отсутствие
DD> его, которое можно уже _уточнить_ через порт состояния.
От кривого (например MS-DOS) формата TR-DOS может вообще умереть.
И тут ничего не поделать.
от: Kirill Frolov
кому: All
дата: 30 Sep 2005
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
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:
MP> Вопpос такой... Как пеpевести скомпилиpованную пpогpамму на асме в .B?
MP> Hу чтобы можно было запускать сpазу с диска чеpез R+Enter...
Для ZXASM исходник ниже. Вся программа, если она умещается в меньше
чем, примерно, 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
BASNUM: MACRO
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
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
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'ом не пользуется :-( ...]
|