Prepoznavanje in interpretacija HPGL ukazov

Avtor:
Matjaž Finc

VSEBINA

  1. HPGL format
  2. Pretvorba prejetih ASCII znakov vukaz
  3. Glavni program (MAIN)

1. HPGL FORMAT

Uvod

HPGL je 2D grafični format prvotno načrtovan za uporabo na ploterjih HP. Zaradi svoje enostavne strukture in uporabe so ga privzeli tudi ostali proizvajalci ploterjev in CAD programov. Format se uporablja v večini programov za načrtovanje in risanje (npr. AutoCad ipd.).

Osnove

Datoteka HPGL je sestavljena iz več ukazov. Vsi ukazi imajo enako strukturo:

funkcija+argumenti+ločilo

Funkcija (instruction) je sestavljena iz dveh velikih črk. V našem primeru smo uporabili le štiri najosnovnejše funkcije:

  • PU - Pen Up (dvig risala)
  • PD - Pen Down (spust risala)
  • PR - Plot Relative (risanje oz. premikanje po relativnih koordinatah - glede na trenuten položaj)
  • PA - Plot Absolute (risanje oz. premikanje po absolutnih koordinatah - glede na začetno izhodišče)
  • Argumenti (arguments) so lahko različnih tipov (stevila, črke) in so med sabo ločeni z vejico. Vsaka funkcija ima svoje argumente in določeno njihovo zaporedje. Če funkcija argumentov nima, jih enostavno izpustimo in na koncu postavimo ločilo.

    Ločilo (separator) pomeni konec HPGL ukaza. Privzeto ločilo je podpičje.

    Primer - risanje ravne črte od (1,0) do (2,0):

    PU;PA1,0;PD;PR1,0;PU;
     

    Podrobnejši opis najdete na naslovu:

    Wotsit's Format: The programmer's file formats and data formats resource.
     
     

    Vsebina


    2. PRETVORBA PREJETIH ASCII ZNAKOV V UKAZ
    V sprejemni buffer ploter prejme HPGL ukaz v ASCII obliki. ASCII znake je treba pretvoriti v obliko, ki bo ploterju omogočila izvajanje ukaza. V ta namen imamo tri spremenljivke: > UKAZ - ukazni register (8 bitni)

    Ukazni register zgleda takole:

    DAV ONLINE BUSY NEGATIVE APPENDY PENUP RELATIVE STOP
    (MSB)                                                                                           (LSB)

    Pomen posameznih bitov:

    > UKAZX - koordinata X (16 bitna)

    > UKAZY - koordinata Y (16 bitna)
     

    PRETVORBA

    Rutina, ki pretvarja ASCII v ukaz ploterja se imenuje CONVERT. Pri pretvorbi sem privzel, da so v vhodni HPGL datoteki uporabljeni samo ukazi PD, PU, PR in PA ter da so vsi ukazi podani strukturno pravilno.

    Uporabljenih je tudi nekaj subrutin:
     

    Test prebranega znaka

    Program najprej preveri če je zadnji ukaz v celoti izvršen in če je ploter preipravljen na sprejem novega ukaza (DAV=0, ONLINE=0, BUSY=0). Če so ti pogoji izpolnjeni, prebere prvi naslednji znak v sprejemnem bufferju. Če je slučajno buffer poln (ni vrnjenega znaka oz. Z=1) prekinemo izvajanje rutine. Naslednji korak je ugotavljanje prebranega znaka. Prvi prebrani znak ni nujno prva črka ukaza - če je v prejšnjem ciklu pretvorba bila nedokončana (ostane DAV=0) oz. če je bil buffer poln preden smo v njega spravili celoten ukaz (nismo prebrali znak do konca). Torej, ta znak je lahko črka (prva ali druga črka ukaza), številka (del X ali Y koordinate), vejica (vmesno ločilo med argumenti za X in Y koordinato), minus (predznak X ali Y koordinate) ali  podpičje (ločilo - konec ukaza). Če je prebrani znak vejica, potem se nastavi zastavica APPENDY=1, kar nam pove katero koordinato bomo obdelovali (če bo slučajno buffer poln, in bomo v naslednjem ciklu prebrali število).

    CONVERT ldaa UKAZ
            anda #%11100000 ;najprej pogleda ce je DAV=1, ONLINE=1, BUSY=1
            bne DAVEND1 ;ce je, skoci na konec
            jsr RECCHR  ;prebere prvi znak na vrsti
            beq DAVEND1 ;ce v bufferju ni znaka gre na konec
            cmpa #","
            bmi DAVEND1
            cmpa #"A"  ;preveri ce je crka
            bpl CRKA  ;ce je skoci na test za crke
            cmpa #";"  ;ali je podpicje
            beq JEPD2  ;ce je skoci na konec (JEPOD)
            jsr MINUS1  ;ali je minus
            bne VEJMIN  ;ce ni, skoci na test za vejico
            ldaa UKAZ
            anda #%00001000 ;katero koordinato moramo obdelovati (naslednji znak)
            bne JEVJ  ;ce je APPENDY=1 vpisujemo Y
            bra STEVIL  ;ce ni, pa vpisujemo X

    DAVEND1 bra DAVEND2 ;pomozni skok zaradi prevelike dolzine

    VEJMIN  cmpa #","
            beq VEJTS1
            ldaa UKAZ
            anda #%00001000
            beq NIVEJ
            bra NIPOD1

    Ugotavljanje črke

    S tem delom programa ugotavljamo, kateri ukaz bomo izvajali. Vsaka prebrana zadnja črka ukaza nam resetira UKAZX in UKAZY (rutina XY0) in nastavi ustrezne zastavice v ukaznem registru.

    CRKA    cmpa #"P"  ;ce je crka P
            bne NIP  ;ce je, prebere naslednjo, ce ne, pa ugotavlja katera crka je
            jsr RECCHR  ;gleda drugo crko ukaza
            beq DAVEND1 ;ce v bufferju ni znaka gre na konec
    NIP     cmpa #"A"  ;(=A)ali je ukaz PA
            bne RUKAZ  ;ce ni, preverja naprej
            ldaa UKAZ  ;ce je, nastavi zastavico RELATIVE=0
            anda #%11111101
            staa UKAZ
            bra STEVX
    RUKAZ   cmpa #"R"  ;(=R)ali je PR
            bne UUKAZ
            ldaa UKAZ
            oraa #%00000010 ;zastavica RELATIVE=1
            staa UKAZ
    STEVX   jsr XY0
            jsr RECCHR
            beq DAVEND1
            jsr MINUS1
            beq STEVIL
            jmp NIVEJ
            ;bra VEJIC
    JEPD2   bra JEPD
    UUKAZ   cmpa #"U"  ;(=U)ali je PU
            bne DUKAZ
            ldaa UKAZ
            oraa #%00000110 ;nastavitev zastavic PENUP=1, RELATIVE=1
            staa UKAZ
            jsr XY0
            jsr RECCHR  ;pregleda ce je podpicje naslednji
            beq DAVEND1 ;ce v bufferju ni znaka gre na konec
            bra PODPIC1
    DUKAZ   ldaa UKAZ  ;ce ni nobena od zgornjih, potem je PD (oz. crka D)
            anda #%11111011 ;PENUP=0
            oraa #%00000010 ;nastavitev zastavice RELATIVE=1
            staa UKAZ
            jsr XY0
            jsr RECCHR  ;pregleda ce je podpicje
            beq DAVEND1 ;ce v bufferju ni znaka gre na konec
            bra PODPIC1
    JEPD    bra JEPD1  ;pomozni skoki zaradi prevelike dolzine
    DAVEND2 bra DAVEND3
    JEVJ    bra JEVEJ
    NIPOD1  bra NIPOD
    VEJTS1  bra VEJTST

    Računanje X koordinate

    Prebrani ASCII znak iz bufferja najprej spremenimo v število (odštejemo ASCII vrednost znaka ‘0’). Če je spremenljivka UKAZX prazna (vrednost 0), novo prebrano število enostavno shranimo v spremenljivko.  Če pa je v spremenljivki UKAZX že kakšna neničelna vrednost, jo pomnožimo z (desetiškim) faktorjem 10 in prištejemo na novo prebrano število. To ponavljamo, dokler prebrani znak ni vejica. Množenje s faktorjem deset izvedemo s pomočjo ‘shiftanja’ v levo (množenje z 2) in to takole:

    število*10 = število*2*2*2+število+število

    ;---Racunanje X koordinate---
    STEVIL  jsr RECCHR
            beq DAVEND2 ;ce v bufferju ni znaka gre na konec
            jmp VEJICA  ;ali je slučajno ze vejica
    NIVEJ   suba #"0"  ;pretvori ASCII v stevilo
            psha    ;shrani v sklad
            ldd UKAZX  ;ali je to prva stevilka po vrsti
            bne RACUNX ;ce ni, moramo staro vsebino *10 in pristeti novo
            pula    ;prvo stevilko po vrsti le zacasno zapisemo v UKAZX
            tab    ;tu moramo uporabiti celotni akumulator (D=A,B)
            clra
            std UKAZX
            bra STEVIL  ;ponovimo (dokler ni vejice - potem Y koordinato)
    RACUNX  ldd UKAZX  ;množenje z 10 za X koordinato:******
            asld    ;*2
            asld    ;*2
            asld    ;*2
            addd UKAZX  ;+zacetna vrednost
            addd UKAZX  ;+zacetna vrednost
            std UKAZX  ;nazaj v X
            pula    ;potegnemo zadnje stevilo iz sklada
            tab    ;akum. D pretvorimo v obliko '00000000,stevilo'
            clra
            addd UKAZX  ;pristejemo novo stevilko (enice)
            std UKAZX
            bra STEVIL
    DAVEND3 jmp DAVEND4 ;pomozni skoki zaradi prevelike dolzine
    JEPD1   bra JEPOD
    PODPIC1 bra PODPIC
    VEJIC   bra VEJICA
     

    Pomožna veja za test vejice (VEJICA) naredi naslednje:

    ;---Pomozna veja za test vejice---
    VEJICA  cmpa #","  ;ali je vejica
            bne NIVEJ  ;ce ni, je stevilo oz. koordinata X
    VEJTST  ldaa UKAZ
            anda #%00010000 ;ce je, pogledamo ce je X negativen
            beq NINEG
            ldd UKAZX  ;in ga pretvorimo v neg. stevilo*******
            coma
            comb
            addd #1
            std UKAZX
    NINEG   ldaa UKAZ
            oraa #%00001000 ;postavimo APPENDY=1
            ;anda #%11101111 ;brisemo NEG
            staa UKAZ
            jsr RECCHR
            beq DAVEND4
            jsr MINUS1
            beq JEVEJ  ;gremo racunat Y koordinato
            bra PODPIC

    Računanje Y koordinate

    Ta podveja programa naredi podobno kot ‘računanje X koordinate’. Vmes testiramo za podpičje (skok na podvejo PODPIC).

    ;---Racunanje Y koordinate---
    JEVEJ   jsr RECCHR
            beq DAVEND4  ;ce v bufferju ni znaka gre na konec
            bra PODPIC
    NIPOD   suba #"0"  ;pretvori ASCII v stevilo
            psha   ;shrani v sklad
            ldd UKAZY  ;ali je to prva stevilka po vrsti
            bne RACUNY  ;ce ni, moramo staro vsebino *10 in pristeti novo
            pula   ;prvo stevilko po vrsti le zacasno zapisemo v UKAZY
            tab   ;tu moramo uporabiti celotni akumulator (D=A,B)
            clra
            std UKAZY
            bra JEVEJ  ;ponovimo (dokler ni podpicja - potem konec)
    RACUNY  ldd UKAZY  ;množenje z 10 za Y:
            asld   ;*2
            asld   ;*2
            asld   ;*2
            addd UKAZY  ;+zacetna vrednost
            addd UKAZY  ;+zacetna vrednost
            std UKAZY  ;nazaj v Y
            pula
            tab
            clra
            addd UKAZY  ;pristejemo novo stevilko (enice)
            std UKAZY
            bra JEVEJ

    ;---Pomozna veja za test podpicja---
    PODPIC  cmpa #";"  ;ce je podpicje potem JEPOD
            bne NIPOD  ;ce ni pa racunamo Y
            bra JEPOD

    4.5.  Konec rutine

    Preveri ali je treba UKAZY dvojiško komplementirati (zastavica NEG), resetira zastavici APPENDY in NEG, postavi DAV=1.

    ;---Konec rutine---
    JEPOD   ldaa UKAZ
            anda #%00010000 ;pogleda ce je zadnjo koord. treba spremenit v negativno
            beq JEY
            ldd UKAZY  ;in ga pretvorimo v neg. stevilo
            coma
            comb
            addd #1
            std UKAZY
    JEY     ldaa UKAZ
            anda #%11100111 ;brise APPENDY in NEG
            oraa #%10000000 ;postavi DAV=1
            staa UKAZ
            bra DAVEND4
    DAVEND4 rts
     

    Zaključek

    Po končani rutini CONVERT so ukazni register UKAZ in pozicijski spremenljivki UKAZX in UKAZY pripravljeni na nadaljno uporabo (izris oz. izvedba ukaza). Ko bo ukaz izveden (DAV=0) oz. sprejemni buffer ponovno napolnjen, bo CONVERT izvedel novo pretvorbo za naslednji ukaz.

    Vsebina



    3. GLAVNI PROGRAM (MAIN)

    Vsebina




    GLAVNA STRAN

    Tekst je napisal Matjaž Finc
    Stran je uredil Miha Krejan

    25. Marec 1999