Autor Wątek: Procedury, routines - wymiana plików, poprawki itp.  (Przeczytany 8938 razy)

Abrimaal

  • *****
  • Wiadomości: 965
  • Miejsce pobytu:
    Lemmingrad
  • Zamulator
    • Games for ULA plus
Procedury, routines - wymiana plików, poprawki itp.
« dnia: 2012.03.25, 23:45:57 »
Poszukuję scrollera, może być najprostszy, byleby działał.
Mam kod z jakiejś gazety z 1988, ale nie wyświetla nic.
Na tyle ile potrafię, szukałem błędów, jednak 20 lat bez programowania w asm udzieliło się.
Może ktoś będzie na tyle chętny pomóc.
Powienien przewijać w dolnej linii text zaczynający się od 40000 i zakończony Enter (CHR$ 13),
o jeden pixel w lewo i wracać tam skąd został wywołany.
ORG 36200
L1 LD HL,39999
PUSH HL
PUSH HL
S1 POP HL
POP HL
INC HL
LD A, (HL)
CP 13
JR Z, L1
PUSH HL
CP 144
JR NC, L2
LD HL, (23606)
JR L3
L2 LD HL, (23675)
SUB 144
L3 LD D,0
LD E,A
LD B,8
L4 ADD HL, DE
DJNZ L4
PUSH HL
LD D,128
L10 POP IX
PUSH IX
LD HL,20735
LD E,8
L7 LD A,D
AND (IX+0)
JR Z, L5
SCF
L5 PUSH HL
LD B,32
L6 LD A,(HL)
RLA
LD (HL),A
DEC HL
DJNZ L6
INC IX
POP HL
INC H
DEC E
JR NZ, L7
L9 RRA
JR NZ, L10
POP HL
POP HL
EI
RET
AY Music, ULA plus.

matofesi

  • *****
  • Wiadomości: 2048
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedury, routines - wymiana plików, poprawki itp.
« Odpowiedź #1 dnia: 2012.03.26, 08:43:24 »
Nie wiem, czy dokładnie czegoś takiego oczekiwałeś, ale masz... W załączniku tap z działającym przykładem. A kod jest taki:
        org 32768

main_loop:
        halt
        call one_scroll
        ld bc,$7ffe
        in a,(c)
        and 1
        jr nz, main_loop
        ret

one_scroll:
        di

        ld a,(bpos)
        or a
        jr nz,skip_text
        ld a,7
        ld (bpos),a
text_adr: equ $+1
        ld hl,text
        ld a,(hl)
        inc hl
        ld (text_adr),hl
        cp 13
        jr nz,get_char
        ld hl,text
        ld a,(hl)
        inc hl
        ld (text_adr),hl
get_char:
        ld h,0
        ld l,a
        add hl,hl
        add hl,hl
        add hl,hl
        ld de,15360
        add hl,de
        ld de,buf
        rept 8
          ldi
        endm
        jr do_scroll
skip_text:
        dec a
        ld (bpos),a

do_scroll:
        ld hl,20704+31
        ld de,buf
        ld b,8
loop1:
        push hl
        ld c,32
        ld a,(de)
        rla
        ld (de),a
loop2:
        ld a,(hl)
        rla
        ld (hl),a
        dec hl
        dec c
        jr nz,loop2
        inc de
        pop hl
        inc h
        djnz loop1

        ei
        ret

buf:    ds 8
bpos:   db 0
text:   defm "Tekst scrollera... wpisany jako parametr dla defm albo "
        defm "w dowolne miejsce w pamieci a wtedy zamiast text: defm "
        defm "nalezy uzyc text: equ adres_tekstu "
        db 13
        end 32768


Na początku jest pętla odpalająca jako test - możesz ją usunąć i zassemblować sobie pod potrzebny adres tylko samą procedurę "one_scroll" i ją wołać z BASICa co ramkę (sprawdziłem - też działa). Tekst masz wpisany w defm na końcu, ale jeśli chcesz go mieć w innym miejscu to defm zamieniasz na odpowiednie equ. Procedura - za wyjątkiem zmiennych (buf, bpos i text_adr) jest relokowalna. Zmienne można przerzucić na przykład do bufora drukarki albo w ekran po przysłonięciu atrybutami i wtedy będzie całkowicie relokowalna, ale to już zostawiam jako pracę domową ;)

Cały kod oczywiście używa składni pasmo i przy jego użyciu testowy tap generuje się tak:
pasmo --name srol --tapbas sroll.asm sroll.tap

matofesi

  • *****
  • Wiadomości: 2048
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedury, routines - wymiana plików, poprawki itp.
« Odpowiedź #2 dnia: 2012.03.26, 10:53:00 »
A tu jeszcze jedno o co pytałeś - na szybko zmontowany kursor graficzny.

Kod jest taki sobie, ale działa.

Procedura na starcie czyta współrzędne strzałki z 23296 (x) i 23297 (y) (nie będzie więc działać w trybie 128 - tam trzeba gdzieś przenieść zmienne). Po wywołaniu wyświetla strzałkę, której bitmapa znajduje się na końcu kodu (16x16 pikseli przesunięte 8 razy - każda klatka ma 48 bajtów) nakładając (bez maskowania, choć to powinno się dać dość łatwo dorobić) na istniejący obraz ale bez ruszania atrybutów. Następnie czeka na klawisze - obsługa przesuwania to procedura move_arrow - ją trzeba by zmodyfikować, żeby zmienić sterowanie - teraz jest QAOP. Strzałka jest przesuwana z buforowaniem - nie psuje zawartości ekranu. Po wciśnięciu spacji albo 1 (obsługa tego jest już w głównej pętli i tam trzeba zmieniać obsługę) strzałka jest kasowana i procedura wraca do BASICa zostawiając w 23296 i 23297 współrzędne a dodatkowo w 23298 jest 1 jeśli wciśnięto spację lub 0 jeśli wciśnięto 1 (rozróżnienie select/cancel).

Na podstawie współrzędnych można wykonać jakieś działanie a potem wywołać procedurę jeszcze raz, co przywróci strzałkę w to samo miejsce i pozwoli na dalszy wybór.

Żeby sobie uprościć pisanie strzałka nie dochodzi całkiem do lewego brzegu - maksymalna zwracana współrzędna to 238x190.

Kod oczywiście jak zwykle dla pasmo.

    org 32768

    ld a,(23296)
    ld (pos_x),a
    ld a,(23297)
    ld (pos_y),a

    call buffer_it

main_loop:
    halt
    call restore_it

    call move_arrow

    call buffer_it
    call put_arrow

    ld e,0
    ld bc,$f7fe
    in a,(c)
    and 1
    jr z,exit_loop

    ld e,1
    ld bc,$7ffe
    in a,(c)
    and 1

    jr nz,main_loop
exit_loop:
    push de
    call restore_it
    pop de
    ld a,(pos_x)
    ld (23296),a
    ld a,(pos_y)
    ld (23297),a
    ld a,e
    ld (23298),a
    ret

buffer_it:
    ld a,(pos_x)
    ld c,a
    ld a,(pos_y)
    ld b,a
    call pixel_address
    ld de,buf
    ld b,16

    ld a,(pos_y)
    cp 175
    jr c,buffer_it1
    ld b,a
    ld a,192
    sub b
    ld b,a
buffer_it1:
    push hl
    ld a,(hl)
    ld (de),a
    inc l
    inc de
    ld a,(hl)
    ld (de),a
    inc l
    inc de
    ld a,(hl)
    ld (de),a
    inc de
    pop hl
    call next_hl
    djnz buffer_it1

    ret

restore_it:
    ld a,(pos_x)
    ld c,a
    ld a,(pos_y)
    ld b,a
    call pixel_address

    ld de,buf

    ld b,16

    ld a,(pos_y)
    cp 175
    jr c,restore_it1
    ld b,a
    ld a,192
    sub b
    ld b,a
restore_it1:
    push hl
    ld a,(de)
    ld (hl),a
    inc l
    inc de
    ld a,(de)
    ld (hl),a
    inc l
    inc de
    ld a,(de)
    ld (hl),a
    inc de
    pop hl
    call next_hl
    djnz restore_it1
    ret

put_arrow:
    ld a,(pos_x)
    ld c,a
    ld a,(pos_y)
    ld b,a
    call pixel_address

    push hl
    ld h,0
    ld l,a
    add hl,hl
    add hl,hl
    add hl,hl
    add hl,hl
    push hl
    pop de
    add hl,hl
    add hl,de
    ld de,arrow
    add hl,de
    pop de
    ex de,hl

    ld b,16

    ld a,(pos_y)
    cp 175
    jr c,put_arrow1
    ld b,a
    ld a,192
    sub b
    ld b,a
put_arrow1:
    push hl
    ld a,(de)
    or (hl)
    ld (hl),a
    inc l
    inc de
    ld a,(de)
    or (hl)
    ld (hl),a
    inc l
    inc de
    ld a,(de)
    or (hl)
    ld (hl),a
    inc l
    inc de
    pop hl
    call next_hl
    djnz put_arrow1
    ret

next_hl:
    inc     h
    ld      a,h
    and     7
    jp      nz,next_hl_skip
    ld      a,l
    add     a,32
    ld      l,a
    jp      c,next_hl_skip
    ld      a,h
    sub     8
    ld      h,a
next_hl_skip:
    ret

pixel_address:
    ld a,b
    and a
    rra
    scf
    rra
    and a
    rra
    xor b
    and $f8
    xor b
    ld h,a
    ld a,c
    rlca
    rlca
    rlca
    xor b
    and $c7
    xor b
    rlca
    rlca
    ld l,a
    ld a,c
    and 7
    ret

move_arrow:
    ; O/P
    ld bc,$dffe
    in a,(c)
    ld e,0
    bit 0,a
    jr nz,move_arrow1
    ld e,1
move_arrow1:
    bit 1,a
    jr nz,move_arrow2
    ld e,-1
move_arrow2:
    ld d,0
    ; Q
    ld bc,$fbfe
    in a,(c)
    and 1
    jr nz,move_arrow3
    ld d,-1
move_arrow3:
    ; A
    ld bc,$fdfe
    in a,(c)
    and 1
    jr nz,move_arrow4
    ld d,1
move_arrow4:
    ld a,(pos_x)
    add a,e
    cp 239
    jr nc,move_arrow5
    ld (pos_x),a
move_arrow5:
    ld a,(pos_y)
    add a,d
    cp 191
    ret nc
    ld (pos_y),a
    ret


pos_x: db 0
pos_y: db 191

buf: ds 48

arrow:
    db %00000000, %00000000, %00000000
    db %01111111, %10000000, %00000000
    db %01111111, %00000000, %00000000
    db %01111110, %00000000, %00000000
    db %01111100, %00000000, %00000000
    db %01110100, %00000000, %00000000
    db %01100010, %00000000, %00000000
    db %01000001, %00000000, %00000000
    db %00000000, %10000000, %00000000
    db %00000000, %01000000, %00000000
    db %00000000, %00100000, %00000000
    db %00000000, %00010000, %00000000
    db %00000000, %00001000, %00000000
    db %00000000, %00000100, %00000000
    db %00000000, %00000010, %00000000
    db %00000000, %00000000, %00000000

    db %00000000, %00000000, %00000000
    db %00111111, %11000000, %00000000
    db %00111111, %10000000, %00000000
    db %00111111, %00000000, %00000000
    db %00111110, %00000000, %00000000
    db %00111010, %00000000, %00000000
    db %00110001, %00000000, %00000000
    db %00100000, %10000000, %00000000
    db %00000000, %01000000, %00000000
    db %00000000, %00100000, %00000000
    db %00000000, %00010000, %00000000
    db %00000000, %00001000, %00000000
    db %00000000, %00000100, %00000000
    db %00000000, %00000010, %00000000
    db %00000000, %00000001, %00000000
    db %00000000, %00000000, %00000000

    db %00000000, %00000000, %00000000
    db %00011111, %11100000, %00000000
    db %00011111, %11000000, %00000000
    db %00011111, %10000000, %00000000
    db %00011111, %00000000, %00000000
    db %00011101, %00000000, %00000000
    db %00011000, %10000000, %00000000
    db %00010000, %01000000, %00000000
    db %00000000, %00100000, %00000000
    db %00000000, %00010000, %00000000
    db %00000000, %00001000, %00000000
    db %00000000, %00000100, %00000000
    db %00000000, %00000010, %00000000
    db %00000000, %00000001, %00000000
    db %00000000, %00000000, %10000000
    db %00000000, %00000000, %00000000

    db %00000000, %00000000, %00000000
    db %00001111, %11110000, %00000000
    db %00001111, %11100000, %00000000
    db %00001111, %11000000, %00000000
    db %00001111, %10000000, %00000000
    db %00001110, %10000000, %00000000
    db %00001100, %01000000, %00000000
    db %00001000, %00100000, %00000000
    db %00000000, %00010000, %00000000
    db %00000000, %00001000, %00000000
    db %00000000, %00000100, %00000000
    db %00000000, %00000010, %00000000
    db %00000000, %00000001, %00000000
    db %00000000, %00000000, %10000000
    db %00000000, %00000000, %01000000
    db %00000000, %00000000, %00000000

    db %00000000, %00000000, %00000000
    db %00000111, %11111000, %00000000
    db %00000111, %11110000, %00000000
    db %00000111, %11100000, %00000000
    db %00000111, %11000000, %00000000
    db %00000111, %01000000, %00000000
    db %00000110, %00100000, %00000000
    db %00000100, %00010000, %00000000
    db %00000000, %00001000, %00000000
    db %00000000, %00000100, %00000000
    db %00000000, %00000010, %00000000
    db %00000000, %00000001, %00000000
    db %00000000, %00000000, %10000000
    db %00000000, %00000000, %01000000
    db %00000000, %00000000, %00100000
    db %00000000, %00000000, %00000000

    db %00000000, %00000000, %00000000
    db %00000011, %11111100, %00000000
    db %00000011, %11111000, %00000000
    db %00000011, %11110000, %00000000
    db %00000011, %11100000, %00000000
    db %00000011, %10100000, %00000000
    db %00000011, %00010000, %00000000
    db %00000010, %00001000, %00000000
    db %00000000, %00000100, %00000000
    db %00000000, %00000010, %00000000
    db %00000000, %00000001, %00000000
    db %00000000, %00000000, %10000000
    db %00000000, %00000000, %01000000
    db %00000000, %00000000, %00100000
    db %00000000, %00000000, %00010000
    db %00000000, %00000000, %00000000

    db %00000000, %00000000, %00000000
    db %00000001, %11111110, %00000000
    db %00000001, %11111100, %00000000
    db %00000001, %11111000, %00000000
    db %00000001, %11110000, %00000000
    db %00000001, %11010000, %00000000
    db %00000001, %10001000, %00000000
    db %00000001, %00000100, %00000000
    db %00000000, %00000010, %00000000
    db %00000000, %00000001, %00000000
    db %00000000, %00000000, %10000000
    db %00000000, %00000000, %01000000
    db %00000000, %00000000, %00100000
    db %00000000, %00000000, %00010000
    db %00000000, %00000000, %00001000
    db %00000000, %00000000, %00000000

    db %00000000, %00000000, %00000000
    db %00000000, %11111111, %00000000
    db %00000000, %11111110, %00000000
    db %00000000, %11111100, %00000000
    db %00000000, %11111000, %00000000
    db %00000000, %11101000, %00000000
    db %00000000, %11000100, %00000000
    db %00000000, %10000010, %00000000
    db %00000000, %00000001, %00000000
    db %00000000, %00000000, %10000000
    db %00000000, %00000000, %01000000
    db %00000000, %00000000, %00100000
    db %00000000, %00000000, %00010000
    db %00000000, %00000000, %00001000
    db %00000000, %00000000, %00000100
    db %00000000, %00000000, %00000000
    end 32768
« Ostatnia zmiana: 2012.03.26, 11:16:13 wysłana przez matofesi »

Abrimaal

  • *****
  • Wiadomości: 965
  • Miejsce pobytu:
    Lemmingrad
  • Zamulator
    • Games for ULA plus
Odp: Procedury, routines - wymiana plików, poprawki itp.
« Odpowiedź #3 dnia: 2012.07.03, 05:05:43 »
Mat, scroller działa wspaniale, lecz to trochę za mało dla mnie, wiem tylko jak przestawić generator znaków.
Czy da się w nim zmienić linię, w której jest wyświetlany (chciałbym uruchomić 2 scrollery).
I jak zmienić kolor tekstu?
AY Music, ULA plus.

matofesi

  • *****
  • Wiadomości: 2048
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedury, routines - wymiana plików, poprawki itp.
« Odpowiedź #4 dnia: 2012.07.03, 09:42:09 »
Pozycję scrollera na ekranie określa parametr instrukcji
ld hl,20704+31

Żeby go przesunąć musisz sobie wyliczyć początek odpowiedniej ośmiopikselowej linii ekranu - 20704 to trzecia tercja ekranu (pierwsza to 16384, druga 18432, trzecia to 20480) a w niej siódmy (licząc od zera) wiersz ekranu czyli 7*32=224, 224+20480=20704. Dodanie 31 ustawia wskaźnik na ostatni bajt linii bo przewijanie robione jest od prawej do lewej.

Żeby uruchomić dwa scrollery na raz musiałbyś tak na prawdę przepisać procedurę dwa razy zmieniając nazwy etykiet i dodając stosowne bufory itp. i oczywiście adres na ekranie.

Ustawienie koloru tekstu to zupełnie inna bajka - scroller dotyka tylko części bitmapowej. Żeby ustawić kolor musisz po prostu zapisać odpowiednie dane do pamięci atrybutów w miejscu w którym scroller będzie wyświetlany.

W powyższym przykładzie dla adresu bitmapy 20704 adres atrybutów to 22528+23*32=23264 a ustawienie żółtego INKa z czarnym PAPERem w linii scrollera to na przykład taki kawałek kodu:
ld hl,23264
ld de,23265
ld bc,31
ld (hl),6
ldir

A w ogóle jeśli chodzi o scrollery i zrozumienie tego jak się je robi to zapraszam tutaj: http://www.speccy.pl/articles.php?article_id=11 - przykładowy kod jest dokładnie opisany ;)

Abrimaal

  • *****
  • Wiadomości: 965
  • Miejsce pobytu:
    Lemmingrad
  • Zamulator
    • Games for ULA plus
Odp: Procedury, routines - wymiana plików, poprawki itp.
« Odpowiedź #5 dnia: 2012.07.03, 22:06:06 »
To już wczoraj testowałem, zmieniałem adres i do wszystkich nazw etykiet i zmiennych dodałem 2, to pewnie coś przegapiłem, choć pasmo zassemblował "podwójny" kod bez błędów. Popróbuję jeszcze.
AY Music, ULA plus.

matofesi

  • *****
  • Wiadomości: 2048
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedury, routines - wymiana plików, poprawki itp.
« Odpowiedź #6 dnia: 2012.07.03, 23:04:30 »
Nie wiem co ci nie poszło... Podwójny kod z ustawianiem kolorów wygląda tak:

org 32768

    ld hl,23232
    ld de,23233
    ld bc,32
    ld (hl),57
    ldir
    ld bc,31
    ld (hl),58
    ldir

main_loop:
halt
call one_scroll1
        call one_scroll2
ld bc,$7ffe
in a,(c)
and 1
jr nz, main_loop
ret

one_scroll1:
di

ld a,(bpos1)
or a
jr nz,skip_text1
ld a,7
ld (bpos1),a
text_adr1: equ $+1
ld hl,text1
ld a,(hl)
inc hl
ld (text_adr1),hl
cp 13
jr nz,get_char1
ld hl,text1
ld a,(hl)
inc hl
ld (text_adr1),hl
get_char1:
ld h,0
ld l,a
add hl,hl
add hl,hl
add hl,hl
ld de,15360
add hl,de
ld de,buf1
rept 8
  ldi
endm
jr do_scroll1
skip_text1:
dec a
ld (bpos1),a

do_scroll1:
ld hl,20704+31
ld de,buf1
ld b,8
loop11:
push hl
ld c,32
ld a,(de)
rla
ld (de),a
loop21:
ld a,(hl)
rla
ld (hl),a
dec hl
dec c
jr nz,loop21
inc de
pop hl
inc h
djnz loop11

ei
ret

buf1: ds 8
bpos1: db 0
text1: defm "Tekst scrollera... wpisany jako parametr dla defm albo "
defm "w dowolne miejsce w pamieci a wtedy zamiast text: defm "
defm "nalezy uzyc text: equ adres_tekstu "
db 13

one_scroll2:
    di

    ld a,(bpos2)
    or a
    jr nz,skip_text2
    ld a,7
    ld (bpos2),a
text_adr2: equ $+1
    ld hl,text2
    ld a,(hl)
    inc hl
    ld (text_adr2),hl
    cp 13
    jr nz,get_char2
    ld hl,text2
    ld a,(hl)
    inc hl
    ld (text_adr2),hl
get_char2:
    ld h,0
    ld l,a
    add hl,hl
    add hl,hl
    add hl,hl
    ld de,15360
    add hl,de
    ld de,buf2
    rept 8
      ldi
    endm
    jr do_scroll2
skip_text2:
    dec a
    ld (bpos2),a

do_scroll2:
    ld hl,20704+31-32
    ld de,buf2
    ld b,8
loop12:
    push hl
    ld c,32
    ld a,(de)
    rla
    ld (de),a
loop22:
    ld a,(hl)
    rla
    ld (hl),a
    dec hl
    dec c
    jr nz,loop22
    inc de
    pop hl
    inc h
    djnz loop12

    ei
    ret

buf2:   ds 8
bpos2:  db 0
text2:  defm "Tekst drugiego scrollera wpisany dokladnie "
    defm "tak samo jak tekst pierwszego scrollera... "
    db 13

end 32768

Pierwszy scroller wyświetla się w najniższej linii ekranu na czerwono (one_scroll1), drugi w przedostatniej na niebiesko (one_scroll2).