[SharpMZ] zvlastni chovani PIO-Z80

Michal Hucik - ORDOZ ordoz na ordoz.com
Neděle Leden 22 18:55:38 CET 2017


Ahoj,

zkoumam dnes trochu podrobneji PIO. Zdrojak na hrani je v priloze, 
nicmene tam neni zadna vizualizace chovani - vysledky pozoruju analyzerem.

Vsimnul jsem si zajimave veci:

Branu A nastavim do MODE3 a povolim ji generovani interruptu - je celkem 
jedno, jak pritom nastavim IO masku pro vstupy a vystupy, jake podminky 
LOW, HIGH), nebo jakou nastavim vstupni masku - pro vygenerovani 
popisovaneho ukazu muzu klidne ponechat vsechny piny v OUT rezimu a v 
maskou pro generovani interruptu je navic uplne vypnout, avsak podminku 
AND/OR musim vzdy nastavit jako "OR".

Nyni na CTRL port brany A poslu zmenu mode na kterykoliv jiny modus, nez 
je MODE3, napr. 0x0f - vystup bajtu. V momente, kdy to udelam, tak mi 
PIO posle signal /INT ... Dokonce i kdyz brane A pred zmenou modu 
nejprve zakazu generovani interruptu, pak zmenim na MODE0 a pak povolim 
interrupt (0x03, 0x0f, 0x83), tak i v takovem pripade posle PIO do Z80 
pozadavek na falesny interrupt...

Kdyz jsem zkusil tento pokus na brane B (BTW: jeji I/O piny jsou 
pripojeny na invertory a pri nastaveni B jako vstupu je na nich trvale k 
videni log1), tak se to takhle nechova.

O to zajimavejsi mi prijde fakt, ze v MODE 0, 1 a 2 ma byt interrupt 
generovan pouze aktivaci vstupniho signalu /STROBE, ktery je u brany A 
pripojen natvrdo na Vcc, takze k jeho aktivaci spravne nikdy dojit nemuze.

Podle schematu zapojeni PIO-Z80 v MZ-800 mne nenapada zadny duvod proc 
by se to takhle melo chovat, pokud neobjevite zadnou pricinu ani vy, tak 
se asi bude jednat o nejakou mouchu v samotnem pijovi.

Jinak u Zdenka jsem tohle chovani nezkoumal, ale divil bych se, kdyby 
tam nejakou takovouto zaludnost mel implementovanu.

Pokud by jste si chteli s testovacim programkem pohrat a aktivovat 
interrupt pomoci rutinek ctc0_out0 a ctc0_out1, tak u Zdenka s rtim 
neuspejete. V mem soucasnem emu to sice funguje, nicmene ne uplne 
spravne, protoze tam prvni udalost pro int ignoruju, coz neni uplne 
shodne s tim, jak se chova Sharp.

Jeste dalsi zajimava vec, ktere jsem si vsimnul te to, ze pokud nastavim 
branu A jako vstupni, tak PA0 a PA1 se mi jevi byt trvale v log1, PA6 a 
PA7 mi vetsinou sdelovaly stav log0, nicmene na PA6 se mi obcas na 
nejakou dobu objevila i log1 (je to opet vstup do hradla, ktere je 
ovladano SW2 na zadni strane MZ800). Mel jsem tam chvili pripojeny i 
osciloskop a skutecne se tam ta uroven napeti obcas trochu zvedla v 
zavislosti na tom, jak jsem menil I/O a MODE ... bylo to vsak sotva na 
hranici pro log1 - to uz je ale asi ducharina, kterou se nema smysl pri 
emulaci zabyvat.

Michal


------------- další část ---------------
HTML příloha byla odstraněna...
URL: http://mail.ordoz.com/pipermail/sharpmz/attachments/20170122/b3a23ddc/attachment.html 
------------- další část ---------------

pio_pa_ctrl:    equ 0xfc
pio_pb_ctrl:    equ 0xfd
pio_pa_data:    equ 0xfe
pio_pb_data:    equ 0xff

pio_ctrl:    equ pio_pa_ctrl


    org ( 0x2000 - 0x80 )
    db  0x01
    ; 16 znaku + 0x0d
    db  "PIO TEST        "
    db 0x0d
    dw (prgend - prgstart) ; size
    dw prgstart ; start
    dw prgstart ; exec

    org 0x2000

prgstart:
    ; inicializace MZ800
    di
    im 2
    ld a,0x00 ; mz800 320x200 na 4A
    out (0xce),a

    ; inicializace CTC0
    call ctc0_out0
;    call ctc0_out1

    ; dame si cas na spusteni sigma analyzeru
    call wait


    ; inicializace PIO-Z80
    call set_ivector
    ei

    ld a, 0x0f
    out (pio_ctrl), a

    ;call wait

    call set_ivector

    ld a, 0x0f
    out (pio_ctrl), a

    ; pokud hned nasleduje di, tak CPU uz ten INT neprijme
    nop

    ;call ctc0_out1
    ;call ctc0_out0
    ;call ctc0_out1

    ;halt

stop:
    di
    halt


wait:
    ld bc,0x06cf
    ld de,0x0000
    ld l,0x10 ; necelych 10 sekund
    xor a
wait_loop:
    cpl
    out (c), a
    dec e
    jr nz,wait_loop
    dec d
    jr nz,wait_loop
    dec l
    jr nz,wait_loop
    ret


ctc0_out0:
    ld a,0x30 ; CTC0, MODE0, LSB + MSB
    out (0xd7),a
    ret

ctc0_out1:
    ld a,0x32 ; CTC0, MODE1, LSB + MSB
    out (0xd7),a
    ret

set_ivector:
    ld hl, ivector_addr
    bit 0, l
    jr z,ivector_is_even
    inc hl
ivector_is_even:
    push hl
    pop ix
    ld hl,interrupt_routine
    ld (ix + 0), l
    ld (ix + 1), h
    push ix
    pop hl
    ld a,h
    ld i,a
    ld a,l
    ld hl, pioz80_init_data
    ld (hl), a
    ;ld bc, 0x06fc
    ld b, 0x06
    ld c,pio_ctrl
    otir
    ret


; inicializacni data pro z80pio
pioz80_init_data:
    db 0x00            ; dolni cast adresy int. vectoru (nulty bit musi byt 0!)

    db 0xcf            ; dolni 4 bity musi byt 1111, horni 2 pak
                       ; mod nasledujici operace 0 - out, 1 - in,
                       ; 2 - bidir, 3 - control
                       ; 4. a 5. bit nemaji vyznam

    db 0x3f            ; v modu 3 musi nasledovat I/O Register Control Word
                       ; Vstup - 1, vystup - 0
                       ;
                       ; PA0 - IN - /RDA (LPT)
                       ; PA1 - IN - /STA (LPT)
                       ; PA2 - IN - GND
                       ; PA3 - IN - GND
                       ; PA4 - IN - /CTC0 (pozor, je invertovany!)
                       ; PA5 - IN - /HBLN
                       ; PA6 - OUT - IRT (LPT)
                       ; PA7 - OUT - RDP (LPT)


    db 0x97            ; dolni 4 bity musi byt 0111 -
                       ; 7 - 1/0 En.INT/disable
                       ; 6 - 1/0 AND/OR,
                       ; 5 - 1/0 Hi/Low, 
                       ; 4 - Mask follows
                       ; 0x97 = 1001 0111

    db 0xff
    ;db 0xef            ; protoze v predch. slove byl 4b = 1,
                       ; nasleduje bitova maska. Sledovany jsou jen
                       ; piny, jejihz bity jsou 0
                       ;
                       ; 0xef - 4. bit (/CTC0)
                       ; 0xdf - 5. bit (HBLN)

    db 0x83            ; pri spodnich 0011, 7 bit povoluje/zakazuje
                       ; interrupt - (stejne jako u 0111)
                       ;
                       ; 0x03 - disable
                       ; 0x83 - enable


ivector_addr:
    db 0x00
    dw 0x0000

interrupt_routine:
if 0
    xor a
    ld bc,0x06cf
    ld de,0x2000
border_loop:
    inc a
    out (c), a
    jr nz,border_loop
    dec e
    jr nz,border_loop
    dec d
    jr nz,border_loop
endif

    ei
    reti
prgend:


Další informace o konferenci SharpMZ