Не, ПЗУшный рандом очень тормозной и хочет калькулятор, которым делитна ноль.
Вид для печати
Код:scan_kbd
ld a,-2
ld c,a
ld hl,kb_buf
dup 7
ld b,a
ini
rlca
edup
ld b,a
ini
xor a
in a,(-2)
cpl
and #1f
ld (cur_keys),a
ret z
scf
ret
scan_ctrl
ld bc,k_table
ld de,kb_buf
exx
ld b,8
scan_ctrl0
exx
ld a,(bc)
inc bc
ld l,a
ld h,0
add hl,de
ld a,(bc)
inc bc
and (hl)
cp 1
exx
rr e
djnz scan_ctrl0
ld a,e
ld (cur_keys),a
kemp_act ret
ld bc,#001f
in a,(c)
and #0f
or e
ld (cur_keys),a
ret
scan_tbl
ld hl,kb_buf
ld b,8
scan_tbl0
ld c,#10
scan_tbl1
ld a,(hl)
and c
cp 1
jr c,scan_tbl2
rrc c
jr nc,scan_tbl1
inc hl
djnz scan_tbl0
ld c,b
ret
scan_tbl2
ld a,8
sub b
ld b,a
ret
t_table
db 2,4
db 1,16
db 1,1
db 2,8
k_table
; p o a q Sp En H
db 5, 1 ;p
db 5, 2 ;o
db 1, 1 ;a
db 2, 1 ;q
db 2, 1 ;
db 2, 16 ;T
db 2, 8 ;R
db 5, 16 ;Y
cur_keys db 0
old_keys db 0
prs_keys db 0
key_prsed db 0
kb_buf ds 8
; 1 2 4 8 16
;#fe 0 cs z x c v
;#fd 1 a s d f g
;#fb 2 q w e r t
;#f7 3 1 2 3 4 5
;#ef 4 0 9 8 7 6
;#df 5 p o i u y
;#bf 6 en l k j h
;#7f 7 sp ss m n b
keys_table
db #01,"ZXCV"
db "ASDFG"
db "QWERT"
db "12345"
db "09876"
db "POIUY"
db #0d,"LKJH"
db #20,#02,"MNB",#00
key_char
ld de,keys_table
ld hl,kb_buf
ld c,8
key_char0
ld a,(hl)
inc hl
ld b,5
key_char1
rra
jr nc,key_char2
inc de
djnz key_char1
dec c
jr nz,key_char0
key_char2
ld a,(de)
ld (key_prsed),a
ret
Против математики не попрёшь. :)
Хотя это не идеальное решение, при больших числах X будет заметна неравномерность распределения случайных чисел, в пределах единицы. То есть например двойка будет выпадать чаще тройки. Чтобы уменьшить этот эффект, можно добавить разрядов (умножать на рандом(0..FFFFFF). Чтобы совсем устранить, надо сложнее: Надо найти самую старшую единицу у X. Подготовить маску с нужным числом единиц. ( например для X=5 маска будет 7, для 191 маска будет 255) потом вызывать рандом, маскировать, сравнивать с X, до тех пор пока не получится числа в нужных пределах. Непонятно сколько будет работать программа, зато правильное распределение.
У меня тоже всю клаву светит, примерно так:
Код:MODULE KEYBOARD
; Начало массива клавиш
KEY_MAP:
DS #28,#00
KEY_A EQU KEY_MAP+#00
KEY_B EQU KEY_MAP+#01
KEY_C EQU KEY_MAP+#02
KEY_D EQU KEY_MAP+#03
KEY_E EQU KEY_MAP+#04
KEY_F EQU KEY_MAP+#05
KEY_G EQU KEY_MAP+#06
KEY_H EQU KEY_MAP+#07
KEY_I EQU KEY_MAP+#08
KEY_J EQU KEY_MAP+#09
KEY_K EQU KEY_MAP+#0A
KEY_L EQU KEY_MAP+#0B
KEY_M EQU KEY_MAP+#0C
KEY_N EQU KEY_MAP+#0D
KEY_O EQU KEY_MAP+#0E
KEY_P EQU KEY_MAP+#0F
KEY_Q EQU KEY_MAP+#10
KEY_R EQU KEY_MAP+#11
KEY_S EQU KEY_MAP+#12
KEY_T EQU KEY_MAP+#13
KEY_U EQU KEY_MAP+#14
KEY_V EQU KEY_MAP+#15
KEY_W EQU KEY_MAP+#16
KEY_X EQU KEY_MAP+#17
KEY_Y EQU KEY_MAP+#18
KEY_Z EQU KEY_MAP+#19
KEY_0 EQU KEY_MAP+#1A
KEY_1 EQU KEY_MAP+#1B
KEY_2 EQU KEY_MAP+#1C
KEY_3 EQU KEY_MAP+#1D
KEY_4 EQU KEY_MAP+#1E
KEY_5 EQU KEY_MAP+#1F
KEY_6 EQU KEY_MAP+#20
KEY_7 EQU KEY_MAP+#21
KEY_8 EQU KEY_MAP+#22
KEY_9 EQU KEY_MAP+#23
KEY_SPC EQU KEY_MAP+#24
KEY_ENT EQU KEY_MAP+#25
KEY_CS EQU KEY_MAP+#26
KEY_SS EQU KEY_MAP+#27
;-----------------------------------------------------------------------------------------
; Процедура сканирования портов клавиатуры
CHECK_KEYS:
LD (SCAN_SP+1),SP
LD SP,KEY_TAB ; Опрос клавиатуры
LD DE,MAIN.KEY_MAP
LD BC,#28FF
SCANLP POP HL
LD A,L
IN A,(#FE)
AND H
ADD A,C
SBC A,A
LD (DE),A
INC E
DJNZ SCANLP
SCAN_SP LD SP,#0000
RET
;------------------------------------------------------------------------------------------------------------
; Таблица портов клавиатуры
KEY_TAB:
DB #FD,1 ;#14
DB #7F,16 ;#23
DB #FE,8 ;#21
DB #FD,4 ;#16
DB #FB,4 ;#0C
DB #FD,8 ;#17
DB #FD,16 ;#18
DB #BF,16 ;#19
DB #DF,4 ;#11
DB #BF,8 ;#1A
DB #BF,4 ;#1B
DB #BF,2 ;#1C
DB #7F,4 ;#25
DB #7F,8 ;#24
DB #DF,2 ;#12
DB #DF,1 ;#13
DB #FB,1 ;#0A
DB #FB,8 ;#0D
DB #FD,2 ;#15
DB #FB,16 ;#0E
DB #DF,8 ;#10
DB #FE,16 ;#22
DB #FB,2 ;#0B
DB #FE,4 ;#20
DB #DF,16 ;#0F
DB #FE,2 ;#1F
DB #EF,1 ;#09
DB #F7,1 ;#00
DB #F7,2 ;#01
DB #F7,4 ;#02
DB #F7,8 ;#03
DB #F7,16 ;#04
DB #EF,16 ;#05
DB #EF,8 ;#06
DB #EF,4 ;#07
DB #EF,2 ;#08
DB #7F,1 ;#27
DB #BF,1 ;#1D
DB #FE,1 ;#1E
DB #7F,2 ;#26
ENDMODULE
Может уже где и обсуждалось, но не нашёл:
Как подсчитать сколько фреймов занимает какая-либо процедура?
Причём не тактов (они могут быть по разному в зависимости от данных), а именно сколько INTов успевает проходить.
Можно конечно вешать счётчик на IM2, но если прога меняет стек?
Например выбирает данные с него - прерывания приходится запрещать.