Вход

Просмотр полной версии : Поделитесь парой процедур (печать, преобразование в число)



STD
27.07.2016, 18:26
Добрый вечер всем. У кого есть и кому не жалко, поделитесь готовыми рабочими процедурами:

1) печати 42 символа в строке ( в идеале, работающей с полноценным набором из 256 символов, с матрицей 8 на 8, где все символы прижаты к левому краю)

2) процедурой, которая переводит текстовую строку, в которой написано число, в собственно число. Те текст "32000" в число 32000.

Знаю, что в ревю такое было, но большинство журналов на zxpress отсканировано так, что вместо кода каша...

Bedazzle
27.07.2016, 20:44
вдруг поможет, 64 символа выкладывали на восе (http://www.worldofspectrum.org/forums/discussion/34056/small-machine-code-routines-which-maybe-useful#latest)

и ещё на 40 символов тут (https://www.dropbox.com/s/avk21wrmnd1qc1u/40print.asm?dl=0)

https://i.imgur.com/OYGCb50.png

Andrew771
28.07.2016, 00:39
процедурой, которая переводит текстовую строку, в которой написано число, в собственно число. Те текст "32000" в число 32000.
У меня такая есть в библиотеке для компилятора ZX Like Pascal, скачай (http://zx-pk.ru/threads/24967-zx-like-pascal.html) и зайди в файл libasm.lib через любой текстовый редактор. Там много процедур на ассемблере, в том числе и эта.

Destr
28.07.2016, 09:12
42 символа в строке (http://zxpress.ru/search.php?q=42+%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0% BB%D0%B0)

Bedazzle
28.07.2016, 09:31
42 символа в строке (http://zxpress.ru/search.php?q=42+%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0% BB%D0%B0)

топикстартер по ходу, говорит про это:

PR_б4_R LD В,'FОNTб4;

Black Cat / Era CG
28.07.2016, 10:48
PR_б4_R LD В,'FОNTб4;
Ага. Есть там такое. Поэтому проще найти оригинал (журнал в trd/scl, книгу в pdf...) и набирать процедуры уже оттуда руками, ибо качество распознанного текста на zxpress никакое. Но зато легко можно найти в какой книге/журнале есть нужная информация.

Destr
28.07.2016, 11:02
PR_б4_R LD В,'FОNTб4;
Есть такое.
В приложениях часто бывают готовые листинги (у электронных журналов).

ZX-Guide №1 (Ассемблер/Этюды)
Быстрая печать буквы 6x8 (экран в DE):


PUSH DE
LD L,A
LD B,C
LD A,2
RRCA
DJNZ $-1
LD (PRN+1),A
LD H,'FONT
LD B,8
PRGO PUSH HL
LD L,(HL)
PRN LD H,1
PR1 ADD HL,HL
ADD HL,HL
JR NC,PR1
LD A,(DE)
OR H
LD (DE),A
INC E
LD A,L
LD (DE),A
DEC E
INC D
POP HL
INC H
DJNZ PRGO
POP DE

Если шрифт упирается в 0, то уберите LD
B,8,а DJNZ PRGO замените на JR NZ,PRGO.
Регистр C должен содержать 7,5,3 или 1,
причем 7 соответствует нулевой координате
буквы внутри знакоместа(x mod 8=0). Букв в
шрифте 256,и все они прижаты к левому краю
(можно сдвинутые на одну точку вправо).Как
надо изменять C:


LD A,C
SUB 6
JR NC,$+5
INC E
AND 7
LD C,A

STD
28.07.2016, 21:26
Спасибо, всем кто откликнулся, все посмотрю, попробую.

- - - Добавлено - - -

Уф...., Andrew771, спасибо за твою библиотеку, много чего интересного там. Процедуру перевода строки в число нашел, выдрал, изучил, алгоритм понял. Но в шапке процедуры у тебя, если я процедуру правильно понял, несколько неверный коммент для использующих ее стоит. У тебя там написано:
; вход: hl=адрес строки
а на самом деле hl, исходя из процедуры, сначала указывает на байт, определяющий длину преобразуемой строки и только после него начинается сама преобразуемая строка символов, т.е. правильнее было бы так:
; вход: hl= адрес байта,определяющего длину строки; hl+1 - адрес строки

а то пока я первую часть процедуры понял, все эти СР 6, СР 5, СР 4..... думал с ума сойду..... 8)

Но все равно ОГРОМНОЕ спасибо!!!

Andrew771
28.07.2016, 23:46
а на самом деле hl, исходя из процедуры, сначала указывает на байт, определяющий длину преобразуемой строки и только после него начинается сама преобразуемая строка символов, т.е. правильнее было бы так:
; вход: hl= адрес байта,определяющего длину строки; hl+1 - адрес строки
Да, так и есть. В этой библиотеке и при компиляции с Паскаля я так каждую строку храню: первый байт - длина строки, потом сами символы строки.

Black Cat / Era CG
29.07.2016, 02:13
первый байт - длина строки, потом сами символы строки.
Ну это ж как никак древняя паскалевская традиция:)

DenisGrachev
29.07.2016, 10:36
процедурой, которая переводит текстовую строку, в которой написано число, в собственно число. Те текст "32000" в число 32000.


А для какой цели? Если для счёта в игре, то я использую такую штуку от автора AGD. Счёт храниться как строка и печатаешь его как строку, а для добавления используется addScore.




score defb "000000"

addScore ld a,(hl) ; current value of digit.
add a,b ; add points to this digit.
ld (hl),a ; place new digit back in string.
cp 58 ; more than ASCII value '9'?
ret c ; no - relax.
sub 10 ; subtract 10.
ld (hl),a ; put new character back in string.
uscor0 dec hl ; previous character in string.
inc (hl) ; up this by one.
ld a,(hl) ; what's the new value?
cp 58 ; gone past ASCII nine?
ret c ; no, scoring done.
sub 10 ; down by ten.
ld (hl),a ; put it back
jp uscor0 ; go round again.



Т.е. когда нужно добавит счёта, например 5 очков, делаем так:



ld hl,score+5
ld b,5
call addScore


Когда нужно реализовать hiScore, просто сравниваем два набора строк, например так:



checkHiScore
xor a
ld (HI_SCORE_FLAG),a
;cp two sets of ASCII
ld ix,score
ld hl,hScore
ld b,6 ;5 digits only, the 6th one is always 0
chilp ld a,(ix+0) ;new score byte
cp (hl) ;cp old score byte
ret c ;if carry set old score is higher
jr nz,newsc ;nc & nz means new score is higher
inc ix
inc hl
djnz chilp
ret ;reaching here means hi & low score equal
newsc ld hl,score ;ok new score is higher than old hi score
ld de,hScore ;new high score, so ldir it in place
ld bc,6
ldir
;set hi score flag
ld a,1
ld (HI_SCORE_FLAG),a
ret

Destr
29.07.2016, 16:18
Счёт храниться как строка
А чем плох неупакованый (или даже упакованый) BCD ?
Как я понял со строкой этой то просто так к ней ну скажем 314 не прибавишь?

STD
30.07.2016, 13:33
А для какой цели?

Для того, что бы можно было описывать сцены игры и передавать необходимые параметры движку просто текстовым файлом. Я сделал первую версию движка, где команды котируются одним байтом (типа 01 - открыть окно + байты параметров, 02 - ждать нажатие любой клавиши, 03 - вывести спрайт и тд) и нашел редактор (нотепад++), в котором можно помимо текста вводить и печатать и любые однобайтные символы, но набрав 4-5 сцен понял, что хотя это и работает, но дико потом нечитаемо. Поэтому сейчас переделываю движок, что он обрабатывал тектовые файлы типа:
OPWIN 5,5,10,5
PAUS 300
TEXT Вы вошли в пещеру, где протекает подземная река.
PUTSPR 10,10,7,6,30000
....

SAM style
30.07.2016, 14:42
Для того, что бы можно было описывать сцены игры и передавать необходимые параметры движку просто текстовым файлом. Я сделал первую версию движка, где команды котируются одним байтом (типа 01 - открыть окно + байты параметров, 02 - ждать нажатие любой клавиши, 03 - вывести спрайт и тд) и нашел редактор (нотепад++), в котором можно помимо текста вводить и печатать и любые однобайтные символы, но набрав 4-5 сцен понял, что хотя это и работает, но дико потом нечитаемо. Поэтому сейчас переделываю движок, что он обрабатывал тектовые файлы типа:
OPWIN 5,5,10,5
PAUS 300
TEXT Вы вошли в пещеру, где протекает подземная река.
PUTSPR 10,10,7,6,30000
....
Определил кучу макросов с параметрами, которые при компиляции выдают байт-код и сидишь, пользуешь их. В 3-4 раза место экономится по сравнению с текстовым вариантом:
MACRO tRaiseHP id,prc
db 6,24,id,prc
ENDM

...

tNpcAni 0,c00drink
tRaiseHP 0,64
tWaitNPC 0
tEnd

STD
30.07.2016, 16:48
Ну, у меня все равно 90% объема приходится на текст описания локаций и игровой ситуации, так что экономить на предварительной компиляции команд движка смысла нет, а вот простота правки сцен при текстовом описании всех необходимых команд привлекает.

Alex Rider
31.07.2016, 01:59
Печать 42 символов в строке, которую я заоптимизировал по скорости как смог. Печатает с маской и, кажется, с переносом на следующую строку.


write: ; in:
; hl - screen addr
; a' - shift
; hl' - text address (with no control data)




.loop:
exx
ld a,(hl)
inc hl
and a
ret z
exx
call out_char_42
jr .loop


out_char_42: ;
; in
; hl = screen addr
; a = char code
; a' = shift count
; out
; hl = screen addr of next char
; a' = shift count of next char
font_high_address: EQU $ + 2
ld e,a
ld d,#00 ; high font address
ex af
and a
jp z,no_shift ; в a - не код, а смещение!
ld c,a
ex af
ld a,c
neg
sub print_loop_length + 2
ld (shift_instruction_displacement),a
sla c
ld b,high Tables.shift_table
ld a,(bc)
ld (left_place_mask),a
ld (left_clear_mask),a
inc c
ld a,(bc)
ld (right_place_mask),a
ld (right_clear_mask),a
ld b,9
jp print_loop_entry_point
rrca
rrca
rrca
rrca
rrca
rrca
rrca
rrca
print_loop_start:
ld c,a
left_place_mask: equ $ + 1
and 0
xor (hl)
left_clear_mask: equ $ + 1
and 0
xor (hl)
ld (hl),a
inc l
ld a,c
right_place_mask: equ $ + 1
and 0
xor (hl)
right_clear_mask: equ $ + 1
and 0
xor (hl)
ld (hl),a
dec l
inc h
print_loop_entry_point:
ld a,(de)
inc d
print_loop_end:
djnz $
nex_pos_calc:
ld a,h
sub 8
ld h,a
ex af ; restore hl!!!
add a,6
cp 8
jp nc,1F
ex af
ret
1: and 7
ex af
inc l
ret nz
ld a,h
add a,8
ld h,a
ret


no_shift:
ex af
ex de,hl
ld c,#03


ld a,(de)
and c
or (hl)
ld (de),a
inc h
inc d
ld a,(de)
and c
or (hl)
ld (de),a
inc h
inc d
ld a,(de)
and c
or (hl)
ld (de),a
inc h
inc d
ld a,(de)
and c
or (hl)
ld (de),a
inc h
inc d
ld a,(de)
and c
or (hl)
ld (de),a
inc h
inc d
ld a,(de)
and c
or (hl)
ld (de),a
inc h
inc d
ld a,(de)
and c
or (hl)
ld (de),a
inc h
inc d
ld a,(de)
and c
or (hl)
ld (de),a
inc h
inc d
ex de,hl
jp nex_pos_calc




print_loop_length: equ print_loop_end - print_loop_start
shift_instruction_displacement: equ print_loop_end + 1




at_char_42:
; in
; b = row, c = col (in 6-pix chars)
; out
; hl = screen addr
; a' = shift_count




ld a,b
call SYSTEM.GET_SCREEN_ADDRESS
ld a,c
add a,a
add a,c
ld c,a
srl a
srl a
add a,l
ld l,a
ld a,c
and #03
add a,a
ex af
ret




at_pix_42:
; in
; b = row (in shar rows), c = col (in pixels)
; out
; hl = screen addr
; a' = shift_count
ld a,b
call SYSTEM.GET_SCREEN_ADDRESS
ld a,c
srl a
srl a
srl a
add a,l
ld l,a
ld a,c
and #07
ex af
ret




UPD:


GET_SCREEN_ADDRESS EQU #0e9e


UPD2: Это не фантастика оптимизации, но все равно шучтро работает. Пока читал свое сообщение заметил, что при текущем смещении более 4 пикселей относительно границ знакоместа неплохо бы крутить символ влево.

Destr
31.07.2016, 02:45
STD, Очень даже ТРУ ссыль (http://zxpress.ru/article.php?id=8555)
По себе скажу - офигеть как пересмотришь свой подход, если окажусь прав (или неправ) - отпишись (тут на форуму).
Если поленился изучить что и как там - бог тебе судья...

- - - Добавлено - - -

Твой движок (предполагаемый, как ты его описал) - легко может быть реализован на базе статьи.
(спасибо Vitamin`у, он молодец, это мы лохи...)

P.S. Вообще, эта статья прям рекомендация лучших собаководов! (реклама 90-х, тут для поднятия духа, тогда все в рекламу верили).
Хорошо написана, и если не поленится и изучить, то можно написать свой компилятор-интерпретатор/та что угодно! Невзирая на уровни (ну конечно нулевое кольцо не обойти, но ведь задачи такие не ставятся).

STD
31.07.2016, 13:22
Destr, спасибо за тру ссыль, нереально интересно, обязательно всю прочитаю, но такого космоса в моей проге не требуется, никаких текстовых расчетов там нет. Вчера на база процедуры из библиотеки Andrew я уже сделал свою и все даже заработало 8). Если кому-то понадобится - как-то так:


;================================================= ==========
;БЛОК ОБРАБОТКИ ТЕКУЩЕЙ СЦЕНЫ
;(РАСПОЗНАНИЯ УПРАВЛЯЮЩИХ КОДОВ)
;================================================= ==========


;Распознание кода WWN - Work WiNdow
;Установка параметров текущего окна
OSN00 ld hl,(POZIC) : ld a,(hl)
cp "W" : jr nz,OSN01
inc hl : ld a,(hl)
cp "W" : jr nz,OSN01
inc hl : ld a,(hl)
cp "N" : jr nz,OSN01
call COD00 ;Вызываем процедуру обработки команды WWN
inc hl ;Переводим указатель на симлов перевода строки
inc hl ;Переводим указатель на следующий код
ld (POZIC),hl
jp OSN00 ;В начало цикла обработки кодов


;Распознание кода WCL - Window CLear
OSN01 ld hl,(POZIC) : ld a,(hl)
..................
..................


;================================================= ==========
;БЛОК ОБРАБОТЧИКОВ РАСПОЗНАННЫХ КОДОВ
;================================================= ==========

;-------------- COD ##00 ---------------
;ПРОЦЕДУРА УСТАНОВКИ ПАРАМЕТРОВ
;ПРОИЗВОЛЬНОГО ТЕКУЩЕГО ОКНА

COD00 inc hl ;перешли на пробел после команды WWN
inc hl ;перешли на 1ую цифру 1ого преобразованного числа

ld a,2 ; Указали подпрограмме конвертации, что число
ld (RAZR),a ; состоит из двух символов
call CONV ; Вызываем конвертацию текста в число
ld (COLW),a ;СОХРАНИЛИ X КООРД ОКНА

inc hl ;перешли на 1ую цифру второго числа
call CONV
ld (ROWW),a ;СОХРАНИЛИ Y КООРД ОКНА
..........................
.........................
ret


;================================================= ==========
;ПРОЦЕДУРА КОНВЕРТАЦИИ ТЕКСТА В ЧИСЛО
;================================================= ==========
; на входе в HL - адрес первого символа в преобразумом числе
; в RAZR - разрядность преобразуемого числа (длина строки 5,4,3,2 или 1)

CONV ld bc,0 ; Очистили переменную с
ld (CONVR),bc ; результатом преобразования

ld a,(RAZR) ;
cp 5 ;
jr z,CNV5 ; в засисимости от разрядности
cp 4 ; преобразуемого числа
jr z,CNV4 ; будет вызывать подпрограмму
cp 3 ; преобразования каждого разряда
jr z,CNV3 ;
cp 2 ;
jr z,CNV2 ;
cp 1 ;
jr z,CNV1 ;

CNV5 ld bc,10000
call CNVOSN

CNV4 ld bc,1000
call CNVOSN

CNV3 ld bc,100
call CNVOSN

CNV2 ld bc,10
call CNVOSN

CNV1 ld bc,1
call CNVOSN
ret ;ВЫХОД ИЗ ПРОЦЕДУРЫ

CNVOSN push hl
ld a,(hl) ;ВЗЯЛИ ЦИФРУ ИЗ ТЕКСТА
sub 48 ;ПОЛУЧИЛИ ЕЕ ЗНАЧЕНИЕ
ld e,a ;В de ПОЛУЧИЛИ ЦИРФУ
ld d,0 ;ИЗ ТЕКСТА
ld h,b ;В hl ПОЛУЧИЛИ МНОЖИ-
ld l,c ;ТЕЛЬ РАЗРЯДА из ВС
call 12457 ;МНОЖИМ de НА hl
ld de,(CONVR)
add hl,de
ld (CONVR),hl
pop hl
inc hl
ret
RAZR defb 0
CONVR defb 0,0

; На выходе в переменной CONV будет результат - число преобразовааное из текста
; в HL будет адрес, следующего байта за преобразованным числом,
; если это было не последнее число в команде, то HL удет указывать на символ ","
; между числами, если последний - то на байт "перевода строки".

Destr
31.07.2016, 13:52
но такого космоса в моей проге не требуется
Тут цимес в том что не принцип ЧТО делается, а именно КАК это делается (организация анализа и прочее).
В общем дерзай у вдруг внезапно увидишь какая это тема!
(я например несколько раз перечитывал, а потом вдруг глаза открылись что такой подход применим в очень широком поле деятельности, и вообще профессиональная штука, это не IF-THEN какой-нибудь, это совсем другой уровень!).