PDA

Просмотр полной версии : 3Д13 без ретри-аборт-игноре - как?



lvd
24.09.2005, 19:52
Как сделать сабж? Хочется, чтобы 1 - не выдавалась дурацкая надпись ретри-аборт-игноре и иже с ними, 2 - чтобы таки я смог узнать, что была-не была ошибка. Тип ошибки узнать не требуется.

Плиз подскажите куда идти (по какому урлю) или так скажите. =)

Dexus
24.09.2005, 20:25
Плиз подскажите куда идти (по какому урлю) или так скажите. =)
Может быть есть определенные статьи по этому делу
Но я самостоятельно еще в 94м году этот вопрос разгребал когда пытался сделать дсковое меню к PSM.
Во-первых нужно перехватывать вызов BASIC функций через подмену переменной по адресу #5cc2 (в которой #c9 = ret). Трейсить стек. Через него вызываются разные функции, типа - отчистка экрана, сканирование клавиатуры, вывода символа. Подменять эти функции, собирать строки которые идут на вывод, игнорировать всякие отчистки, сканирования на break и т.д.
Примерно так :)

P.S.: Самому интересно было бы по этому поводу почитать более "научный" материал или посмотреть даже наработки, поскольку механизм универсален.

Robus
25.09.2005, 01:44
Как сделать сабж? Хочется, чтобы 1 - не выдавалась дурацкая надпись ретри-аборт-игноре и иже с ними, 2 - чтобы таки я смог узнать, что была-не была ошибка. Тип ошибки узнать не требуется.

Плиз подскажите куда идти (по какому урлю) или так скажите. =)

Это просто:

DI
LD A,63
LD I,A
XOR A
LD (23613),A
LD HL,51697
LD (23746),HL
IM 1
EI

Безусловно, переменные ВАСИКА должны быть установленны ... =) После вше-указанных АСМ-строчек ни брейк ни игноры не будут действовать, единственное, при ошибке чтения он будет пытаться читать вечно =)

Robus
25.09.2005, 01:47
Это просто:
единственное, при ошибке чтения он будет пытаться читать вечно =)

Это я ошибся, он будет читать несколько раз, в зависимости от переменных, а о том была-ли ошибка, нужно почитать описания процедур 3Д13...

Pawel
25.09.2005, 11:01
Смотри статью "Обработка дисковых ошибок TR-DOS" на нашем сайте (http://realsoft.nm.ru/download.htm).

Dexus
25.09.2005, 12:40
Смотри статью "Обработка дисковых ошибок TR-DOS" на нашем сайте.
Ну это в общем примерно то, о чем я говорил, но ведь это не совсем полное кроме RIA/ReadOnly еще бываю ошибки типа кривого формата, или отсутствие его, которое можно уже _уточнить_ через порт состояния.

Ilya Razyev (500:3432/13)
28.09.2005, 16:35
Привет lvd!

Отвечаю на ваше письмо от 24.09.2005, тогда писал(а) lvd
к All, а было тогда на часах 22:44:14.


l> Как сделать сабж? Хочется, чтобы 1 - не выдавалась дурацкая надпись
l> ретри-аборт-игноре и иже с ними, 2 - чтобы таки я смог узнать, что была-не
l> была ошибка. Тип ошибки узнать не требуется.

l> Плиз подскажите куда идти (по какому урлю) или так скажите. =)


zx.pk.ru программирование!!!

Всего хорошего,
Ilya.

\Boundless\Jack Ketch\Di\Life Screen\Beep\Girl\
Таймыр 2.00 (c) Евгений Варнавский

Kirill Frolov (500:812/1.507)
01.10.2005, 21:52
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 (500:812/1.507)
01.10.2005, 21:52
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 (500:812/1.507)
01.10.2005, 21:52
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 (500:812/1.507)
01.10.2005, 21:52
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:


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

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'ом не пользуется :-( ...]

Shadow Maker
14.01.2009, 23:22
Нуно как-то научить трдос жить при отсутствии диска в дисководе... Как? Вон Робусова подходит наверное, если расскажете как инфинитповторы включить. Или может есть что-то простое эффективное?

GriV
15.01.2009, 19:18
Лично я задачу не понял. Объясни?

Shadow Maker
15.01.2009, 19:46
Прочитай сообщение 3 в этой теме. Надо то же самое, только в настоящем вечном цикле.

Robus
17.01.2009, 07:33
Нуно как-то научить трдос жить при отсутствии диска в дисководе... Как? Вон Робусова подходит наверное, если расскажете как инфинитповторы включить. Или может есть что-то простое эффективное?

Смотри ... По адресу 23613 прописываешь адрес, где будет лежать адрес, указывающий на адрес процедуры исполнения ошибок !!! Я знаю, что это ужасно звучит, но не я это придумывал ...



;Инитим
DI
LD A,63
LD I,A
LD HL,ERROR_PTR
LD (23613),HL
LD HL,51697
LD (23746),HL
IM 1
EI

;Процедура чтения трека
LD (DOS_ERROR+1),SP
... ЧИТАЕМ ТРЕК

;Новая точка обработки ошибок
DW 0 ;Обязательно нужно !!!
ERROR_PTR DW DOS_ERROR
DOS_ERROR:
LD SP,Восста стек такой какой был перед началом чтения трека
JP Снова На Последнюю Процедуру Чтения


Это, конечно же поверхностно ... Но основа такова ... Вообще-то, что бы было всё правильно нужно немного больше кода, часть чтения трека надо вынести наружу ... Такое есть ... Не понятно, нужно ли тебе восстанавливать переменные ??? Потому что если надо, то можно такое реалезовать !!!

Shadow Maker
17.01.2009, 12:42
Мне надо загрузить файл и на случай, если вдруг там какой-то умник вытащит дискету - чтобы не повисло всё, а продолжило нормально читать когда засунет.