┌----------------------------------------┐
│░░░░░░░░░░░░ Программирование ░░░░░░░░░░│
└----------------------------------------┘
(C) SpaceS
Hi, world! Я снова в Lprint'е! (а где бу-
рные аплодисменты?)
Ну ничего, и без них я смогу написать че-
го-нибудь. Итак, сейчас я поделюсь с вами
плодами своих извращательств над демкой...
А вот название ее не скажу, а то ругаться
будете. Вобщем, сами в процессе чтения
поймете.
1) Как определить, сколько килобайт у ва-
шей тачки:
MEMORY ld bc,32765
ld hl,49152
ld de,4113 ;#1011
out (c),d
ld (hl),l
out (c),e
ld (hl),c
out (c),d
ld a,(hl)
or a
jr z,128kb
C этим легко разобраться, так что идем да-
льше:
2) Определение наличия у компа муз. платы:
Muzak ld bc,65533
ld a,0
out (c),a
ld b,191
ld a,64
out (c),a
ld b,255
in a,(c)
cp 64
jr z,есть
Тут тоже все просто.
3) Если муз. плата все же нашлась предыду-
щей процедуркой, то теперь можно опреде-
лить ее тип:
Tip ld bc,65533
ld a,16
out (c),a
in a,(c)
cp 255
jr nz,AY-8910/12
jr YAMAHA 2149F
4) А сейчас самое интересное:
Определения количества тактов у компью-
тера за 1 прерывание.
TAKTS org #8055
di
ld hl,30720 ;создание про-
ld a,121 ;цедуры обра-
LABAO5 ld (hl),a ;ботки
inc l ;прерываний
jr nz,LABAO5 ;
inc h ;Адрес самой
ld (hl),a ;процедуры:
dec a ;31097
ld i,a ;
im 2
ld a,201 ;201=ret
ld (31097),a
ld hl,LABAO7
ld (31098),hl
ld de,0 ;счетчик=0
ld hl,LABAOб
ld a,195 ;195=jp
ei ;
halt ;2 раза вхолос-
ei ; тую
halt ;
ei ;
ld (31097),a ; поехали!
LABAOб inc de ;de=de+1
jp (hl) ;jp LABAOб
;inc de=бтактов
;jp (hl)=Чтак.
LABAO7 di ;сюда перейдет
;выполнение
;после подсчета
;тактов
;(со 2-м прер.)
pop af ;снимаем со
;стека адрес во-
;зврата
inc de
inc de ;в de-количество
;тактов,поделен-
;ное на 10
Ну а дальше-дело техники. Для вывода ко-
личества тактов можете воспользоваться ал-
горитмом все той же демы (имеется в виду
вывод в 1Oтичной системе)
1) Сразу печатаете нуль в последнем разря-
де.
2) 4 раза делите de на 10 (остаток - это и
будет следующий разряд)
3) Все
Но вопрос: как делить?
А вот как:
Вход:de-число1 (2 байта)
:bc-65536-число2 (2 байта)
Выход:a-остаток от деления
:de=число1/число2
DELENIE ld hl,0
ld a,e
add a,a
rl d
adc hl,hl
add hl,bc
jr c,NABAS7
sbc hl,bc
NABAS7 rla
rl d
NABAS8 adc hl,hl
add hl,bc
jr c,NABAбO
NABAS9 sbc hl,bc
NABAбO rla
rl d
NABAб1 adc hl,hl
add hl,bc
jr c,NABAб2
sbc hl,bc
NABAб2 rla
rl d
adc hl,hl
add hl,bc
jr c,NABAбЗ
sbc hl,bc
NABAбЗ rla
rl d
adc hl,hl
add hl,bc
jr c,NABAбЧ
sbc hl,bc
NABAбЧ rla
rl d
adc hl,hl
add hl,bc
jr c,NABAб5
sbc hl,bc
NABAб5 rla
rl d
adc hl,hl
add hl,bc
jr c,NABAбб
sbc hl,bc
NABAбб rla
rl d
adc hl,hl
add hl,bc
jr c,NABAб7
sbc hl,bc
NABAб7 rla
rl d
adc hl,hl
add hl,bc
jr c,NABAб8
sbc hl,bc
NABAб8 rla
rl d
adc hl,hl
add hl,bc
jr c,NABAб9
sbc hl,bc
NABAб9 rla
rl d
adc hl,hl
add hl,bc
jr c,NABA70
sbc hl,bc
NABA70 rla
rl d
adc hl,hl
add hl,bc
jr c,NABA71
sbc hl,bc
NABA71 rla
rl d
adc hl,hl
add hl,bc
jr c,NABA72
sbc hl,bc
NABA72 rla
rl d
adc hl,hl
add hl,bc
jr c,NABA73
sbc hl,bc
NABA73 rla
rl d
adc hl,hl
add hl,bc
jr c,NABA74
sbc hl,bc
NABA74 rla
rl d
adc hl,hl
add hl,bc
jr c,NABA75
sbc hl,bc
NABA75 rla
rl d
ld e,a
ret
Разобрались? Если нет, то думайте. Если же
не думается, то разберитесь сначала с про-
цедурой умножения из MOVE#10, а потом и
с этим все станет ясно.
И напоследок скажу, что все это наглым об-
разом (а точнее-STS'ом) выдрано из ACTION
MEGADEMO, надеюсь, что VAV меня простит,т.
к. без его демы я до всего вышенаписанного
и не додумался бы.
Alex> Прочитал я все вышенаписанное и ре-
шил кое что добавить от себя.
Сперва я хочу дать небольшой совет SPA-
CES - переходи в HEX-систему. Я раньше сам
писал в DEC, но потом, поняв преимущества
HEX, постепенно перешел в нее (между 32765
и #7FFD разницы может и нет, но вот между
4113 и #1011 есть. Или сравни 16384,16640,
16896, 17152, 17408, 17664, 17290, 18176 и
#4000, #4100, #4200, #4300, #4400, #4500,
#4600, #4700 - что легче запоминается ?).
Ну и еще пару слов по поводу теперь уже
моих программок. Не все они принадлежат
мне, некоторые я так же "дерганул" из де-
мок (например ECSTASY). Так же в моих про-
граммках вы сможете увидеть комманды типа
LD HL,KB_128 и CALL PRINT - это просто об-
ращение на подпрограмму печати тескта, но
сама эта подпрограмма, а так же и тексты,
приведены сдесь не будут (сами напишите -
не маленькие :). И последнее. В моих про-
гах Вы почти не найдете комментариев -
не такие они и сложные.
5,4,3,2,1,0,-1,-2,-3 Старт...
Сначала еще одна программа проверка на
наличие 128Кб (если Вы желаете проверить
наличие большей памяти, и использовать ее
в своей проге, то лучше воспользуйтесь
процедуркой из приложения к ZX-FORMAT #05
/она же в SPECTROFON #22/).
LD HL,#C000
LD BC,#7FFD
LD A,#10
OUT (C),A
LD (HL),A
INC A
OUT (C),A
LD (HL),A
DEC A
OUT (C),A
CP (HL)
LD HL,KB_128
JR Z,$+4
LD HL,KB_48
CALL PRINT
А вот еще одна моя оригинальная провер-
ка:
ORG <#8000 ; адрес должен быть
LD BC,#7FFD ; меньше #8000
LD A,#15
OUT (C),A
LD (LABEL+#8000),A
LABEL RST 0 ; при 48Кб - сброс
LD A,#10 ; при 128Кб продол-
OUT (C),A ; жаем работу
Догадались как она работает ?
Так как SPACES привел процедуру провер-
ки наличия AY в DEC-виде, то я решил при-
вести ее еще раз, но уже в HEX-виде (она
немного отличается от вышеприведенной, но
не существенно, так как я ее сам подсмот-
рел в ACTION /Сначала у меня стоял музы-
кальный сопроцессор AY-3-8910 и я как то
не обращал внимания на то, что ACTION
сообщала мне, что у меня стоит 10-ый соп-
роцессор. Но однажды я заменил его на
YM2148F и запустив ACTION я с удивлением
увидел сообщения, что у меня теперь стоит
YMAHA. До этого момента я и не подозревал,
что возможно програмно определить тип сто-
ящего на компе музыкального сопроцессора.
Тогда я тоже влез в ACTION и подсмотрел
как это определяется/.
LD BC,#FFFD
XOR A
OUT (C),A
LD B,#BF
LD A,#40
OUT (C),A
LD B,#FF
IN A,(C)
CP #40
LD HL,ABSENT
JR NZ,CONT
LD A,#10
OUT (C),A
IN A,(C)
CP #FF
LD HL,AY_3
JR NZ,CONT
LD HL,YM2149F
CONT CALL PRINT
Программа определения наличия теневого
ОЗУ (SHADOW RAM). Определяет два типа под-
ключения.
DI
IN A,(#FB) ; включить теневое ОЗУ
CALL CHECK
IN A,(#7B) ; выключить ОЗУ
JR NC,CNT ; если есть - то выход
LD BC,#FFЗE
LD A,#C7
OUT (C),A ; включить теневое ОЗУ
PUSH BC
CALL CHECK
POP BC
LD A,#C0
OUT (C),A ; выключить ОЗУ
LD HL,ABSENT
JR C,EXT
CNT CALL CONV ; перевод числа из A в
; символьный вид в HL
EXT CALL PRINT
...
CHECK LD BC,#7FFD
LD DE,#1000
LD HL,0
LD A,(HL)
DEC (HL)
CP (HL)
SCF
RET Z ; Возврат если нет ОЗУ
OUT (C),E
LD A,32 ; 32Кб
LD (#ЗFFF),A
OUT (C),D
LD A,16 ; 1бКб
LD (#ЗFFF),A
RRCA ; 8Кб
LD (#1FFF),A
RRCA ; ЧКб
LD (#OFFF),A
RRCA ; 2Кб
LD (#07FF),A
OUT (C),E
LD A,(#ЗFFF) ; В рег A результат
OUT (C),D
AND A ; сброс CARRY
RET
Проверка наличие порта #FF
LD HL,#5800 ; заносим в атрибуты
LD DE,#5801 ; число #FF
LD BC,#02FF
LD (HL),#40
LDIR
EI
LD BC,#0800 ; В BC счетчик
HALT
LD HL,FF_YES
LOOP_0 IN A,(#FF)
CP #40
JR Z,LAB_X
DEC BC
LD A,B
OR C
JR NZ,LOOP_0
LD HL,ABSENT
LAB_X CALL PRINT
Данная программа НЕ ОПРЕДЕЛЯТ неверно
сделанный порт #FF!
Так же повотрю программу для определе-
ния количества тактов между прерываниями
компьютера.
ORG >#7FFF
DI
LD HL,#FEOO ; Организация режима
LD A,H ; IM 2
LD I,A
DEC A
LD (HL),A
INC L
JR NZ,$-2
INC H
LD (HL),A
LD A,#C9 ; Временно блокируем
LD (#FDFD),A ; программу возврата
LD HL,RETURN ; Заносим адрес возв-
LD (#FDFE),HL; рата из подсчета
IM 2
LD DE,0 ; Обнуляем счетчик
LD HL,CYC
LD A,#C3
EI
HALT ; холостой прогон
EI
HALT ; холостой прогон
EI
LD (#FDFD),A ; Разблок. возврат
CYC INC DE ; считаем такты
JP (HL)
RETURN DI
POP AF ; приводим стек в исходное
INC DE ; состояние
INC DE
В регистре DE кол-во тактов деленное
на десять (например 7166 это 71660
тактов).
Определения наличия медленой памяти
(SLOW RAM) т.е. тип машины - однополевая
или двухполевая.
LD A,3 ; счетчик холостых прерыв.
LD HL,INT_1 ; адрес возврата
LD (#FDFE),HL
LD BC,0 ; обнуляем счетчик
EI
HALT
HALT
LOOP_1 LD HL,(#4000) ; работа с SLOW RAM
LD (#4000),HL
INC BC
JR LOOP
INT_1 DEC A
EI
RET NZ ; возврат из холостого INT
DI
POP HL ; востанавливаем стек
PUSH BC ; сохраняем результат
LD HL,INT_2 ; адрес возврата
LD (#FDFE),HL
LD A,3 ; счетчик холостых прерыв.
LD BC,0 ; обнуляем счетчик
EI
HALT
HALT
LOOP_2 LD HL,(#FEOO) ; работа с FAST RAM
LD (#FEOO),HL
INC BC
JR LOOP_2
INT_2 DEC A
EI
RET NZ ; возврат из холостого INT
DI
POP HL ; востанавливаем стек
POP HL ; восстанав. старый резул.
XOR A
SBC HL,BC ; сверяем оба результата
LD HL,ABSENT ; SLOW RAM ABSENT
JR Z,$+5
LD HL,PRESENT ; SLOW RAM PRESENT
CALL PRINT
Ну и последняя прога. Определение CDOS-
модема и порта к которому он подключен.
Сразу хочу предупредить, что эту прогу я
написал для ARS'овского модема и будет ли
она определять московские модемы я не знаю
Дело в том, что минские модемы подключают-
ся с неполной адресацией, к порту номер
которого содержит один или два бита сбро-
шеных в ноль, а остальные биты равны еде-
нице. Поиск начинается с порта #FC и далее
вниз. Трубка на модеме должна быть положе-
на.
LD B,#FC
LL_1 LD C,B ;Заносим в C адрес порта
IN A,(C) ;читаем значение порта и
CP #DF ;сверяем его с #DF
JR Z,CL_1 ;если равно, то доп.прв.
RL DJNZ LL_1 ;иначе продолжить поиск
LD HL,ABSENT ; модем не найден!
JR EL
CL_1 LD E,0 ;обнуляем счетчик
LD B,8 ;кол-во проверяемых битов
LD A,C ;в рег. A - адрес порта
LL_3 RRA ;проверка бита на ноль
JR C,LL_2
INC E ; если бит равен 0, то E=E+1
LL_2 DJNZ LL_3 ; Все биты проверены ?
LD B,C ; восстановить регистр B
DEC E ; в номере порта один бит
; равен нулю ?
JR Z,$+5 ; если да, то модем есть
DEC E ; в номере порта два бита
; равны нулю ?
JR NZ,RL ; если нет, то продолжить
; поиск
LD A,#10 ; стандартная процедура
OUT (C),A ; проверки наличия
IN A,(C) ; модема из CDOS
AND #20
JR Z,EL
XOR A
OUT (C),A
IN A,(C)
AND #20
JR NZ,EL
LD HL,PRESENT
EL CALL PRINT ; модем есть. в рег. C
; номер порта.
Вот и все на сегодня.
P.S. Если в вышеприведенной программе
встретились некоторые недоработки или
ошибки, то извините - данный текст набира-
лся по памяти.
Other articles: