home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / piprsx.arc / PIPRSX.MAC < prev    next >
Encoding:
Text File  |  1990-02-04  |  12.2 KB  |  462 lines

  1.         title    'CP/M Plus PIP Erweiterung'
  2.  
  3. ; patches 1 bis 7: W. Muees '89
  4. ; patch 8: T. Reh 260190
  5. ; umgeschrieben f}r Z80 T. Reh 300190
  6.  
  7. ; RSX zur Erweiterung von PIP um folgende Funktionen:
  8. ; a) Wenn die Quelldatei einen Byte Count <> 0 hat, wird dieser auch in der
  9. ;    Zieldatei eingetragen.
  10. ; b) Ist das Archive-Attribute der Quelldatei gesetzt, wird es auch in der
  11. ;    Zieldatei gesetzt.
  12. ; c) Existieren Zeiteintr{ge f}r die Quelldatei, erh{lt die Zieldatei diese
  13. ;    Daten.
  14. ; d) Die Eingabe von Laufwerk und User in der Form 'DU:' ist f}r Quell- und
  15. ;    Zielangabe zul{ssig.
  16.  
  17. ; Das Kopieren von Archive-Attribut und Byte Count ist kein Problem, da CP/M-
  18. ; Plus Funktionen hierf}r besitzt. Zeiteintr{ge lassen sich nur mit einer
  19. ; 'unsauberen' Methode kopieren: man mu~ die BIOS-Funktion zum Setzen der
  20. ; Zeitvariablen im SCB blockieren und die gew}nschten Werte direkt in den SCB
  21. ; eintragen. Deswegen kann diese Methode nur in Systemen funktionieren, in
  22. ; denen die Uhr nicht durch Interrupts den SCB aktualisiert, sondern }ber die
  23. ; BIOS-Funktion 26 'Time'.
  24. ; [nderung gegen}ber Original von W. Muees: Es ist nun erlaubt, PIPRSX auch
  25. ; innerhalb residenter Programme zu verwenden, die den Warmstart-Vektor auf
  26. ; Adresse 0000h ver{ndern. (T. Reh 270190)
  27.  
  28. ; Konstanten:
  29.  
  30. false    equ    0        ; Boolsche Konstanten
  31. true    equ    not false
  32.  
  33. test    equ    false        ; Protokollausgaben auf Drucker
  34.  
  35. cmdbuf    equ    237Dh        ; Kopie der Kommandozeile von PIP
  36. srcxfcb    equ    22C7h        ; Startadresse erweiterter Source-FCB
  37. tmpfcb    equ    22F6h        ; Startadresse FCB f}r tempor{re Operationen
  38. dstxfcb    equ    2325h        ; Startadresse erweiterter Dest-FCB
  39. actpos    equ    2371h        ; aktuelle Position innerhalb FCB (Parser)
  40. actfcb    equ    247Ch        ; Adresse des aktuellen FCB (Parser)
  41. useerr    equ    21BAh        ; 'Invalid User Number' Fehlereinsprung
  42. offuse    equ    45        ; Offset f}r User in XFCB
  43.  
  44. cr    equ    0Dh        ; ASCII Carriage Return
  45. lf    equ    0Ah        ; ASCII Line Feed
  46.  
  47. ; Print-Macro f}r Kontrollausgaben auf Drucker:
  48.  
  49. print    macro    string
  50.     local    str
  51.     ld    hl,str
  52.     call    pstring
  53.     dseg
  54. str:    db    string,cr,lf,0
  55.     cseg
  56.     endm
  57.  
  58. ;*********************************************************************
  59.  
  60.     cseg
  61.  
  62. ; RSX Header :
  63.  
  64. serial:    defb    0,0,0,0,0,0     ; serial number field
  65. start:    jp    instal         ; jump to start of RSX
  66. next:    jp    0        ; link to BDOS
  67. prev:    defw    0        ; link to previous RSX
  68. remove:    defb    true        ; remove after operation
  69. nonbnk:    defb    false        ; loaded on every system
  70. rsxnam:    defb    'PIPRSX  '    ; name of RSX
  71. loader:    defb    0        ; loader flag
  72. reserv:    defw    0        ; reserved area
  73.  
  74. ; Installation der RSX-Unterprogramme in PIP.COM.
  75. ; Wird einmalig bei Aufruf von BDOS 12 durchgef}hrt.
  76.  
  77. instal:    ld    a,c
  78.     cp    12        ; Return Version Number ?
  79.     jr    nz,next        ; nur bei diesem Aufruf patchen
  80.     ld    hl,pattab
  81.     ld    bc,8FFh        ; B=8 Patches, C=255 (wegen LDI)
  82. patlop:    ld    e,(hl)
  83.     inc    hl
  84.     ld    d,(hl)
  85.     inc    hl        ; zu patchende Adresse in DE
  86.     ld    a,0CDh
  87.     ld    (de),a        ; CALL-Befehl einsetzen
  88.     inc    de
  89.     ldi
  90.     ldi            ; Zieladresse einsetzen (C wird dekrementiert)
  91.     djnz    patlop        ; alle 8 Patches durchf}hren
  92.  
  93.     ld    de,scbpb
  94.     ld    c,49
  95.     call    next        ; 'Get SCB 3Ah' = Addresse des SCB
  96.     ld    a,h        ; SCB Page
  97.     ld    (scbdat+1),a    ; Adresse des Datum-Wortes im SCB
  98.     inc    a        ;   (LSB der Adressen ist konstant)
  99.     ld    (timjmp+1),a    ; Adresse des TIME-Einsprungs in der BIOS-Leiste
  100.  
  101.     if    test
  102.     print    'PIP.COM patched'
  103.     endif
  104.  
  105.     ld    c,12
  106.     jr    next        ; das war's patchen, weiter mit BDOS 12
  107.  
  108. pattab:    defw    06CCh,patch1    ; zu patchende Stellen in PIP.COM
  109.     defw    0E62h,patch2    ; sowie die Adressen der zugeh|rigen
  110.     defw    0E75h,patch3    ; PIPRSX-Unterprogramme
  111.     defw    0E21h,patch4
  112.     defw    1871h,patch5
  113.     defw    0B69h,patch6
  114.     defw    195Ah,patch7
  115.     defw    1EE2h,patch8
  116.  
  117. scbpb:    defb    3Ah,0        ; SCB PB : Get SCB address
  118.  
  119. ;*********************************************************************
  120.  
  121. ; Patch 1 :     Nach Eingabe der Kommandozeile.
  122. ;        Pr}fen, ob Kopieren der Attribute zul{ssig.
  123. ;        Unzul{ssig, wenn mehrere Dateien bearbeitet werden (z.B.
  124. ;        Anf}gen) oder bei ver{ndernden Optionen.
  125.  
  126. patch1:    if    test
  127.     print    'PATCH 1 reached'
  128.     endif
  129.  
  130.     xor    a
  131.     call    vc_inh        ; Alle RSX-Variablen l|schen
  132.  
  133.     ld    c,0        ; Flag: nicht zwischen [ und ]
  134.     ld    hl,cmdbuf
  135.     ld    b,(hl)        ; B = Anzahl eingegebener Zeichen
  136.     inc    b        ; Korrektur
  137. buftst:    inc    hl        ; Zeiger auf n{chstes Zeichen
  138.     dec    b
  139.     jr    z,p1end        ; keine weiteren Zeichen : Ende
  140.     ld    a,(hl)        ; Zeichen holen
  141.     bit    0,c
  142.     jr    nz,opttst    ; innerhalb Options-Klammern: Option pr}fen
  143.     cp    ','
  144.     jr    z,p1mult    ; Komma: mehrere Input-Dateien!
  145.     cp    '['
  146.     jr    nz,buftst    ; [ : Anfang der Optionen
  147.     inc    c        ; dann C=1 : Flag gesetzt
  148.     jr    buftst        ; weiter mit n{chstem Zeichen
  149.  
  150. opttst:    cp    ']'
  151.     jr    z,optend    ; Optionsklammer geschlossen: Flag r}cksetzen
  152.     and    5Fh        ; --> Gro~schrift (geht nur bei Buchstaben)
  153. otst1:    push    hl
  154.     push    bc
  155.     ld    hl,optlst
  156.     ld    bc,optlen
  157.     cpir            ; Zeichen in '{ndernden Optionen' suchen
  158.     pop    bc
  159.     pop    hl
  160.     jr    nz,buftst    ; nicht gefunden: Option erlaubt
  161.  
  162. p1mult:    ld    a,true
  163.     ld    (inhibit),a    ; Inhibit setzen: Attribute nicht kopieren
  164.     if    test
  165.     print    'MULTIPLE SOURCE FILES or CHANGING COPY'
  166.     endif
  167. p1end:    ld    bc,dstxfcb    ; Original-Code in PIP.COM
  168.     ret
  169.  
  170. optlst:    defb    'DFILNPQSTUZ'    ; Liste der 'verbotenen Optionen'
  171. optlen    equ    $-optlst
  172.  
  173. optend:    dec    c        ; C wieder 0 : nicht in Optionsausdruck
  174.     jr    buftst        ; weiter suchen
  175.  
  176. ;*********************************************************************
  177.  
  178. ; Patch 2 :    Vor dem \ffnen der Quelldatei.
  179. ;        FCB patchen, so da~ der Byte Count ermittelt wird.
  180.  
  181. patch2:    if    test
  182.     print    'PATCH 2 reached'
  183.     endif
  184.  
  185.     ld    hl,srcxfcb+32    ; 'CR' byte auf FF setzen
  186.     ld    (hl),0FFh    ; --> BDOS-OPEN bringt Byte Count zur}ck.
  187.     ld    bc,srcxfcb    ; Original-Code
  188.     ret
  189.  
  190. ;*********************************************************************
  191.  
  192. ; Patch 3 :    Nach erfolgreichem \ffnen der Quelldatei.
  193. ;        Byte Count, Arcv-Flag und Zeiteintrag speichern.
  194.  
  195. patch3:    if    test
  196.     print    'PATCH 3 reached'
  197.     endif
  198.  
  199.     ld    hl,srcxfcb+32
  200.     ld    a,(hl)        ; Byte Count der ge|ffneten Datei
  201.     ld    (bytcnt),a    ; speichern
  202.     ld    (hl),0        ; CR des FCB wieder auf 0 setzen
  203.  
  204.     if    test
  205.     or    a
  206.     jr    z,p3ncnt
  207.     print    'File has byte count'
  208. p3ncnt:    endif
  209.  
  210.     ld    hl,srcxfcb+11
  211.     ld    a,(hl)        ; t3' enth{lt Archive-Flag
  212.     and    80h
  213.     ld    (arcflg),a    ; Flag = 00 or 80 hex, speichern
  214.  
  215.     if    test
  216.     or    a
  217.     jp    z,p3narc
  218.     print    'File has archive bit set'
  219. p3narc:    endif
  220.  
  221.     ld    hl,srcxfcb    ; Quell-FCB in internen Puffer kopieren,
  222.     ld    de,intfcb    ; da BDOS 102 den FCB-Inhalt zerst|rt.
  223.     push    de
  224.     ld    bc,36
  225.     ldir
  226.     xor    a
  227.     ld    (stampd),a    ; Annahme : keine Zeiteintr{ge
  228.     pop    de        ; Adresse des internen FCB
  229.     ld    c,102
  230.     call    next        ; BDOS aufrufen: Zeiteintr{ge ermitteln
  231.     or    a
  232.     jr    nz,p3end    ; bei Fehler Zeiteintr{ge nicht beeinflussen
  233.  
  234.     ld    hl,intfcb+28
  235.     call    getstp        ; versuchen, 'Update Stamp' zu lesen
  236.  
  237.     if    test
  238.     jr    z,p3crea    ; kein Update Stamp : Create Stamp versuchen
  239.     push    bc
  240.     push    de
  241.     print    'File has UPDATE stamp'
  242.     pop    de
  243.     pop    bc
  244.     jr    p3end
  245.     else
  246.     jr    nz,p3end    ; Update Stamp vorhanden: verwenden
  247.     endif
  248.  
  249. p3crea:    ld    hl,intfcb+24
  250.     call    getstp        ; versuchen, 'Create' oder 'Access' zu lesen
  251.     jr    z,p3end        ; kein Eintrag : nichts tun
  252.  
  253.     if    test
  254.     push    bc
  255.     push    de
  256.     print    'File has CREATE stamp'
  257.     pop    de
  258.     pop    bc
  259.     endif
  260.  
  261. p3end:    ld    a,(2412h)    ; Original PIP.COM
  262.     ret
  263.  
  264. getstp:    ld    a,(hl)
  265.     inc    hl
  266.     or    (hl)        ; Pr}fen ob Datum <> 0
  267.     ld    (stampd),a    ; Flag speichern
  268.     dec    hl        ; HL wieder auf Anfang Datenfeld
  269.     ld    de,date        ; Ziel : Datum-Speicher
  270.     ld    bc,4        ; 4 Bytes kopieren (Datum und Zeit)
  271.     ldir
  272.     ret
  273.  
  274. ;*********************************************************************
  275.  
  276. ; Patch 4 :    Vor dem Erzeugen der Zieldatei. Systemzeit manipulieren.
  277.  
  278. patch4:    if    test
  279.     print    'PATCH 4 reached'
  280.     endif
  281.  
  282.     ld    a,(inhibit)
  283.     or    a
  284.     jr    nz,p4end    ; Attribute nicht kopieren: Ende
  285.     ld    a,(stampd)
  286.     or    a
  287.     jr    z,p4end        ; Keine Zeiteintr{ge zu kopieren: Ende
  288.  
  289.     ld    hl,(timjmp)    ; Adresse des BIOS-26 Einsprungs
  290.     ld    a,(hl)
  291.     cp    0C3h        ; 'JP'-Befehl dort ?
  292.     jr    nz,p4end    ; nein: lieber nichts patchen
  293.  
  294.     ld    (changed),a    ; Flag setzen: SCB und BIOS manipuliert
  295.     ld    (hl),0C9h    ; 'JMP' durch 'RET'-Befehl ersetzen
  296.     ld    hl,date        ; Speicher Datum und Zeit von Quelldatei
  297.     ld    de,(scbdat)    ; Ziel: Datenfelder im SCB
  298.     ld    bc,4        ; 4 Byte in den SCB kopieren
  299.     ldir
  300.  
  301.     if    test
  302.     print    'SYSTEM date&time changed'
  303.     endif
  304.  
  305. p4end:    ld    bc,tmpfcb    ; Original PIP.COM
  306.     ret
  307.  
  308. ;*********************************************************************
  309.  
  310. ; Patch 5 :    Nach Schlie~en der Zieldatei. Systemzeit restaurieren.
  311.  
  312. patch5:    if    test
  313.     print    'PATCH 5 reached'
  314.     endif
  315.  
  316.     call    restor        ; BIOS-Einsprung wieder hinbiegen
  317.     ld    a,(237Bh)    ; Original PIP.COM
  318.     ret
  319.  
  320. ;*********************************************************************
  321.  
  322. ; Patch 6 :    Im Error-Handler. RSX r}cksetzen f}r evtl. Wiedergebrauch.
  323.  
  324. patch6:    if    test
  325.     print    'PATCH 6 reached'
  326.     endif
  327.  
  328.     ld    a,true
  329.     call    vc_inh        ; Alle RSX-Variablen r}cksetzen
  330.     ld    a,(2368h)    ; Original PIP.COM
  331.     ret
  332.  
  333. ;*********************************************************************
  334.  
  335. ; Patch 7 :    Vor dem Zuweisen und Setzen der Zieldatei-Attribute
  336.  
  337. patch7:    if    test
  338.     print    'PATCH 7 reached'
  339.     endif
  340.  
  341.     ld    a,(inhibit)
  342.     or    a
  343.     jr    nz,p7end    ; keine Attribute kopieren: Ende
  344.     ld    a,(bytcnt)
  345.     ld    (dstxfcb+32),a    ; Byte Count in Ziel-XFCB einsetzen
  346.     ld    hl,dstxfcb+6
  347.     set    7,(hl)        ; f6' setzen (Flag: Set Byte Count)
  348.     ld    hl,dstxfcb+11    ; Zeiger auf t3 (t3' ist Archive-Flag)
  349.     ld    a,(arcflg)
  350.     or    (hl)
  351.     ld    (hl),a        ; t3' entsprechend Quelle setzen
  352.     call    vclear        ; Variablen l|schen
  353. p7end:    ld    bc,dstxfcb    ; Original PIP.COM
  354.     ret
  355.  
  356. ;*********************************************************************
  357.  
  358. ; Patch 8 : Parser f}r 'DU:'-Eingaben manipulieren.
  359.  
  360. patch8:    ld    a,(actpos)    ; derzeitige Zeichenposition im Parser
  361.     sub    2
  362.     cp    2
  363.     jr    nc,p8end    ; nicht 2 oder 3 : keine g}ltige DU-Angabe
  364.     ld    b,a        ; B = 0 oder 1 (bei 1 bzw. 2 Stellen User)
  365.     ld    hl,(actfcb)    ; Zeiger auf bereits begonnenen 'Dateinamen'
  366.     inc    hl        ; -> Drive-Buchstabe
  367.     inc    hl        ; -> 1. Ziffer Usernummer
  368.     ld    a,(hl)
  369.     sub    '0'
  370.     cp    10
  371.     jr    nc,p8end    ; keine Ziffer 0..9 : Abbruch
  372.     dec    b
  373.     jr    nz,pat8_1    ; actpos war 2 : nur eine Ziffer
  374.     inc    hl        ; -> 2. Ziffer
  375.     ld    b,a        ; Zehner nach B
  376.     add    a,a
  377.     add    a,a
  378.     add    a,b
  379.     add    a,a
  380.     ld    b,a        ; 10 * Zehner nach B
  381.     ld    a,(hl)        ; 2. Ziffer
  382.     sub    '0'
  383.     cp    10
  384.     jr    nc,p8end    ; keine Ziffer 0..9 : Abbruch
  385.     add    a,b        ; User = 10 * Zehner + Einer
  386. pat8_1:    cp    16
  387.     jp    nc,useerr    ; Fehler: Usernummer zu hoch
  388.     ld    ix,(actfcb)
  389.     ld    (ix+offuse),a    ; User im XFCB entsprechend Angabe setzen
  390.     ld    a,1
  391.     ld    (actpos),a    ; actpos = 1, damit Drive-Code ok
  392. p8end:    ld    a,(actpos)    ; Originalcode in PIP.COM
  393.     ret            ; zur}ck in PIP.COM
  394.  
  395. ;******************************************************************************
  396.  
  397. ; Variablen initialisieren, Einsprung in BIOS-26 wiederherstellen.
  398.  
  399. vc_inh:    ld    (inhibit),a    ; vorher Wert in A --> Inhibit-Flag
  400.  
  401. vclear:    xor    a
  402.     ld    (bytcnt),a    ; Zwischenspeicher f}r Byte-Count l|schen
  403.     ld    (arcflg),a    ; Archive nicht gesetzt
  404.     ld    (srcxfcb+32),a    ; Source: CR=0
  405.  
  406. restor:    ld    a,(changed)    ; Wurde BIOS-Einsprung gepatcht ?
  407.     or    a
  408.     ret    z        ; nein: Ende
  409.     ld    hl,(timjmp)
  410.     ld    (hl),0C3h    ; sonst Sprungbefehl restaurieren
  411.     xor    a
  412.     ld    (changed),a    ; BIOS-Einsprung wieder Original
  413.  
  414.     if    test
  415.     print    'SYSTEM date&time restored'
  416.     endif
  417.  
  418.     ret
  419.  
  420. ;*********************************************************************
  421.  
  422. ; Datenbereich:
  423.  
  424.     dseg
  425.  
  426. scbdat:    defw    00F4h        ; Adresse des Datum-Wortes im SCB
  427. timjmp:    defw    004Eh        ; Adresse des TIME-Einsprungs der BIOS-Leiste
  428.  
  429. inhibit:defs    1        ; 'true' wenn keine Attribute kopiert werden
  430. changed:defs    1        ; Flag <> 0 wenn BIOS-Einsprung manipuliert
  431. stampd:    defs    1        ; Flag <> 0 wenn Source Zeiteintr{ge hat
  432.  
  433. bytcnt:    defs    1        ; Byte Count der Quelldatei
  434. arcflg:    defs    1        ; Archive Attribut der Quelldatei (00 oder 80)
  435. date:    defs    2        ; Datum und Uhrzeit aus Update-Eintrag
  436. time:    defs    2        ; Reihenfolge mu~ <date,time> sein
  437.  
  438. intfcb:    defs    36        ; Kopie des Quell-FCB (ohne Erweiterungen)
  439.  
  440. ;*********************************************************************
  441.  
  442. ; Routine zum Ausdrucken von Texten als Test-Protokoll.
  443. ; S{mtliche Register k|nnen zerst|rt werden.
  444.  
  445.     if    test
  446.     cseg
  447. pstring:ld    a,(hl)
  448.     inc    hl
  449.     or    a
  450.     ret    z        ; NUL-Character : Ende
  451.     push    hl
  452.     ld    c,a        ; Zeichen nach C
  453.     ld    hl,(timjmp)    ; Adresse Einsprung BIOS-26
  454.     ld    l,0Fh        ; Adresse Einsprung BIOS-5 'List Output'
  455.     call    ipchl        ; Als UP Aufrufen
  456.     pop    hl
  457.     jr    pstring        ; weiter bis NUL-Char
  458. ipchl:    jp    (hl)
  459.     endif
  460.  
  461.     end
  462.