home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / EXTRA-ST / CPM-80-E / CPM-0.2 / CPM-0 / cpm-0.2 / z80-sources / system / xccp2.mac < prev    next >
Encoding:
Text File  |  1994-06-06  |  36.9 KB  |  1,688 lines

  1. ;****************************************************************;
  2. ;*                                *;
  3. ;*        ZDOS Version 1.0                *;
  4. ;*        extended CCP Features for Cp/M            *;
  5. ;*        (c) 1985 by Michael Bischoff            *;
  6. ;*                                *;
  7. ;*        TANDY VERSION (Bios: E300h)            *;
  8. ;*                                *;
  9. ;****************************************************************;
  10. ;*                                *;
  11. ;*        edit history:                    *;
  12. ;* 26.05.1985:    nochmal neu }berarbeitet.            *;
  13. ;*        Ben|tigt jetzt CBIOS-Rou-            *;
  14. ;*        tine bei CBIOS + 33h zum            *;
  15. ;*        'merken' des Userpath.                *;
  16. ;* 27.05.1985:    Ben|tigt Routine nicht mehr.            *;
  17. ;*        jetzt ist von 40h bis 4fh            *;
  18. ;*        der BIOS-Scratch-Bereich des            *;
  19. ;*        Cp/M daf}r reserviert. Bei            *;
  20. ;*        Systemstart sollte da korrekt             *;
  21. ;*        initialisiert werden                *;
  22. ;* 16.06.1985:    Der Bereich f}r PATH ist jetzt von        *;
  23. ;*        8h bis 11h. ERA ohne Argumente ist        *;
  24. ;*        jetzt abgefangen und COPY kopiert        *;
  25. ;*        nicht mehr auf sich selber.            *;
  26. ;*        Die Zero-Page ist jetzt voll belegt.        *;
  27. ;*        Der BDOS-Ansprung geht wieder }ber        *;
  28. ;*        5h, damit die RSM-Module funktio-        *;
  29. ;*        nieren.                        *;
  30. ;* 11.08.1985:    COPY kopiert jetzt auch R/O-Dateien.        *;
  31. ;*        Sollte STAT.COM $R/O oder $R/W nicht        *;
  32. ;*        akzeptieren, so liegt dies daran, da~        *;
  33. ;*        STAT das Attribut im deffcb2 erwartet,        *;
  34. ;*        ZDOS aber das '/'-Zeichen nicht in den        *;
  35. ;*        FCB }bernimmt (korrekt laut Cp/M-Hand-        *;
  36. ;*        buch)                        *;  
  37. ;*        Alle Befehle mit /Q Option nehmen jetzt        *;
  38. ;*        die Eingabe 'G' (go) an. Dies bewirkt        *;
  39. ;*        eine automatische 'N'-Eingabe aller        *;
  40. ;*        weiteren Abfragen.                *;
  41. ;* 08.09.1985    Diese Version ist ein COM-File, welches ein    *;
  42. ;*        Overlay bei D000h benutzt, wenn BIG_DOS auf    *;
  43. ;*        einen Wert definiert wird. Die Zero-Page    *;
  44. ;*        wurde umgestellt und arbeitet jetzt mit PAS-    *;
  45. ;*        CAL/M zusammen (ab 10h MM DD YY HH MM in BCD)    *;
  46. ;* 15.09.1985    Diese Version geht in Richtung einer wirklich    *;
  47. ;*        universellen Form, die auf allen Rechnern    *;
  48. ;*        laufen sollte. Anforderungen: 1) BIOS springt    *;
  49. ;*        beim Kaltstart CCP an, danach CCP+3. 2)    Die    *;
  50. ;*        Zero-Page bleibt unver{ndert. (0-f, 30-37,    *;
  51. ;*        3b-5b)                        *;
  52. ;* 29.09.1985    Die Labels CCP und BDOS eingef}hrt, das Label    *;
  53. ;*        BASE (Top Memory f}r Dateinamen-sammelei) va-    *;
  54. ;*        riabel gemacht und auf 8000h gesetzt.        *;
  55. ;* 04.10.1985    Label BASE von 8000h auf 9000h gesetzt, da    *;
  56. ;*        die WordStar-Overlays f}r COPY zu gro~ waren.    *;
  57. ;* 23.11.1985    Control-ECHO wieder erlaubt, conditional execu-    *;
  58. ;*        tion eingebaut bei Zeilen, die mit '?' beginnen    *;
  59. ;* 08.05.1986    Befehl EXIT eingebaut. Dieser Befehl l|scht die    *;
  60. ;*        A:$$$.SUB-Datei und beendet somit Job-Control    *;
  61. ;* 19.05.1986    [nderung in Conditional-Statements: TRUE ist    *;
  62. ;*        wegen Kompatibilit{t zu UNIX jetzt 0.        *;
  63. ;*        BASE ist jetzt variabel.            *;
  64. ;* 31.05.1986    Batch-Verarbeitung angefangen.            *;
  65. ;*        Diese Version ist ein Transientes Programm    *;
  66. ;* 06.06.1986    Batch-Verarbeitung ist jetzt auf dem Stand des    *;
  67. ;*        DO.COM. Vorteil: Es k|nnen wesentlich l{ngere    *;
  68. ;*        Batch-Dateien verarbeitet werden. Zus{tzliche    *;
  69. ;*        Kommandos sind GOTO label, :label, ARGS (weist    *;
  70. ;*        $1=$2, $2=$3... zu) Bei Warmstart wird Vector    *;
  71. ;*        (6) korrigiert, da Ausstieg aus dem DDTZ ein    *;
  72. ;*        Problem war.                    *;
  73. ;* 28.08.1987    Habe diese Version irgendwo gefunden und XSUB    *;
  74. ;*        verbessert.                    *;
  75. ;* 24.10.1987    Angepasst an Tandy II (noch nicht ausprobiert)    *;
  76. ;* 27.10.1987    Version ausprobiert, l{uft soweit. Folgende    *;
  77. ;*        [nderungen durchgef}hrt:            *;
  78. ;*        I)  PATH initialisiert                *;
  79. ;*        II) BDOS-Aufruf }ber RST 30H herausgenommen    *;
  80. ;*                                *;
  81. ;****************************************************************;
  82.  
  83. cbios        equ 0e300h        ;zum Berechnen der Position
  84. ccpsize        equ 0c06h        ; 1K l{nger
  85.  
  86. false        equ 0
  87. true        equ not false
  88. r_enab        equ false        ;'R'-Command (we have better in INLINE)
  89. c_enab        equ true        ;conditional execution
  90.  
  91.         .z80            ;geschrieben in ZILOG-Code
  92.         if1
  93.         .printx $ Assembling ZDOS Extended Version vom 24.10.1987 $
  94.         .printx $ TANDY-Version, BIOS E300h, extended XSUB        $
  95.         else
  96.         .printx $ ...Pass 2 $
  97.         endif
  98.  
  99. fill        macro length,byte
  100.         rept length
  101.         db byte
  102.         endm
  103.         endm
  104.  
  105. echoflag    equ 0037h        ;ECHO-Flag
  106. pathtab        equ 0008h        ;PATH-Tabelle
  107.  
  108. ccp_fcb        equ 003bh        ;default FCB for internal use
  109. deffcb        equ 005ch        ;default FCB address
  110. deffcb2        equ 006ch        ;default FCB address 2
  111. defdma        equ 0080h        ;default DMA address
  112.  
  113. tab        equ 09h            ;ASCII Tabulator
  114. cr        equ 0dh            ;ASCII carriage return
  115. lf        equ 0ah            ;ASCII linefeed
  116. ctrl_z        equ 1ah            ; end-of-file
  117.  
  118. ;****************************************************************;
  119. ;*                                *;
  120. ;*        BDOS-Systemcalls                *;
  121. ;*                                *;
  122. ;****************************************************************;
  123.  
  124. system_reset    equ 0
  125. console_in    equ 1
  126. console_out    equ 2
  127. reader_in    equ 3
  128. punch_out    equ 4
  129. list_out    equ 5
  130. direct_conio    equ 6
  131. get_iobyte    equ 7
  132. set_iobyte    equ 8
  133. print_string    equ 9
  134. inline        equ 0ah
  135. get_con_status    equ 0bh
  136. return_version    equ 0ch
  137. disk_reset    equ 0dh
  138. select_disk    equ 0eh
  139. open_file    equ 0fh
  140. close_file    equ 10h
  141. srch_for_first    equ 11h
  142. srch_for_next    equ 12h
  143. delete_file    equ 13h
  144. read_seq    equ 14h
  145. write_seq    equ 15h
  146. make_file    equ 16h
  147. rename_file    equ 17h
  148. get_login_vec    equ 18h
  149. get_cur_disk    equ 19h
  150. set_dma_addr    equ 1ah
  151. get_alloc_addr    equ 1bh
  152. set_ro_disk    equ 1ch
  153. get_ro_vector    equ 1dh
  154. set_file_attr    equ 1eh
  155. get_dpb_addr    equ 1fh
  156. set_get_user    equ 20h
  157. read_random    equ 21h
  158. write_random    equ 22h
  159. comp_file_size    equ 23h
  160. set_rand_rec    equ 24h
  161. reset_drive    equ 25h
  162.  
  163.  
  164. wr_rand_with_0    equ 28h
  165.  
  166. bdos        macro callnr,arg    ;Macro ruft BDOS auf
  167.         ifnb <arg>        ;Argument ist Funktionsnummer
  168.         ld de,arg        ;evtl. auch Parameter
  169.         endif            ;
  170.         ld c,callnr        ;
  171.         call bdos_entry        ;Ausf}hrung
  172.         endm            ;
  173.  
  174. ;bdos        macro callnr,arg    ;diese Version benutzt RST 30H
  175. ;        ifnb <arg>        ;gleich
  176. ;        ld de,arg        ;gleich
  177. ;        endif            ;gleich
  178. ;        rst 30h            ;rufe BDOS auf
  179. ;        db callnr        ;holt sich der Restart
  180. ;        endm            ;
  181.  
  182. ccp        equ cbios-0dfah-ccpsize
  183. bdos        equ ccp+ccpsize
  184.  
  185. ;base        equ 9000h        ;hier drunter werden die DIRECTORY-
  186.                     ;Eintr{ge gesammelt! VORSICHT!
  187.                     ;kann mit RSM und GO kollidieren
  188.                     ; ACHTUNG: jetzt variabel!
  189. stacktop    equ bdos
  190.  
  191. bdos_entry    equ 5            ;(nicht cbios-0dfah)
  192.  
  193.  
  194.  
  195. entry:        ld a,(cbios+5)        ; pr}fe, ob XCCP schon geladen...
  196.         sub high(cbios)
  197.         jr nc,entry_ok
  198. bad:        bdos print_string,errmsg
  199.         ret
  200. errmsg:        db 'first quit your current CCP$'
  201. old_sub:    db 1,'$$$     SUB',0,0,0,0
  202.         dw 0,0,0,0,0,0,0,0
  203.         db 0
  204.  
  205. entry_ok:    ld hl,newccp        ; kopiere Programm nach oben
  206.         ld de,ccp
  207.         ld bc,ccpsize
  208.         ldir
  209.  
  210.         ld hl,0041h        ; db 'A',0
  211.         ld (pathtab),hl
  212.  
  213.         ld hl,(cbios+4)        ; BIOS-warmboot true entry
  214.         ld (remwboot),hl
  215.         ld hl,ccp+3
  216.         ld (cbios+4),hl
  217.  
  218.         bdos delete_file,old_sub; l|sche alte $$$.SUB-Datei
  219.  
  220.         xor a
  221.         ld (echoflag),a
  222.         ld hl,0
  223.         push hl
  224.         ld hl,defdma
  225.         ld a,(hl)
  226.         or a
  227.         ret z
  228.         ld c,a
  229. skip_spaces:    inc hl
  230.         ld a,(hl)
  231.         cp ' '
  232.         jr nz,copy_line
  233.         dec c
  234.         jr nz,skip_spaces
  235.         ret
  236. copy_line:    ld b,0
  237.         ld de,inline_count
  238.         ld a,c
  239.         ld (de),a
  240.         inc de
  241.         inc c        ; 00 auch kopieren
  242.         ldir
  243.         jp cold_entry
  244.  
  245. newccp:
  246.         .phase ccp        ;Beginn des ZDOS
  247.  
  248.         jp xbdos        ;Sprungvektor 1
  249. _exit:        jp warm_entry        ;Sprungvektor 2
  250.  
  251. inline_buffer:    db 7fh            ;
  252. inline_count:    db 0            ;
  253. inline_text:    db '*** ZDOS Version 1.2  written by M. Bischoff June 1986 ***',0
  254.  
  255.         if $ gt inline_count+80h
  256.         .printx $ FATAL: Initialization Routine needs too much memory $
  257.         endif
  258.  
  259.         fill inline_count+80h-$,0    ;um auf den richtigen Platz zu kommen
  260.  
  261. pointer_1:    dw inline_text        ;
  262. pointer_2:    dw 0            ;
  263.  
  264. xbdos:        ld a,c
  265.         cp 10            ; get string
  266.         jp nz,bdos
  267.         ld a,(echoflag)
  268.         and 6
  269.         cp 6
  270.         jp nz,bdos
  271.         ld a,(de)        ; max Anzahl
  272.         inc de
  273.         push de
  274.         ld c,a
  275.         ld b,a
  276. xsubloop:    call read_batch
  277.         inc de
  278.         ld (de),a
  279.         cp ctrl_z
  280.         jr z,end_of_xsub
  281.         cp lf
  282.         jr z,xsub_full
  283.         call akku_out
  284.         djnz xsubloop
  285. xsub_full:    pop de
  286.         ld a,c
  287.         sub b
  288.         ld (de),a
  289.         ret
  290.  
  291. end_of_xsub:    call del_subm
  292.         jr xsub_full
  293.  
  294. subfcb:        db 1,'AUTOEXEC','SUB',0,0,0,0
  295.         dw 0,0,0,0,0,0,0,0
  296.         db 0
  297. remain:        db 0+1
  298. sub_ptr:    dw sub_buffer
  299. sub_buffer:    ds 128
  300.  
  301. read_sect:    push de
  302.         push bc
  303.         ld a,(current_user)
  304.         push af
  305.         ld a,0
  306. sub_user    equ $-1
  307.         call set_user
  308.         bdos set_dma_addr,sub_buffer
  309.         ld de,subfcb
  310.         bdos read_seq
  311.         or a
  312.         ld hl,sub_buffer
  313.         ld a,128
  314.         jr z,not_eof
  315.         ld a,ctrl_z
  316.         ld (hl),a
  317.         ld a,1
  318. not_eof:    ld (sub_ptr),hl
  319.         ld (remain),a
  320.         pop af
  321.         call set_user
  322.         pop bc
  323.         pop de
  324.         ret
  325.  
  326. read_batch:    push hl            ; all regs saved
  327.         ld hl,remain
  328.         dec (hl)
  329.         call z,read_sect
  330.         ld hl,(sub_ptr)
  331.         ld a,(hl)
  332.         inc hl
  333.         ld (sub_ptr),hl
  334.         pop hl
  335.         and 7fh
  336.         cp cr
  337.         jr z,read_batch
  338.         ret
  339.  
  340. get_batch_line:    ld hl,inline_text
  341.         ld b,127
  342.         call read_batch
  343.         cp ctrl_z
  344.         jr z,end_of_batch
  345. batch_loop:    cp lf
  346.         jr z,line_full
  347.         cp '$'
  348.         jr z,variable
  349.         cp '^'
  350.         jr z,control_chr
  351. no_var:        ld (hl),a
  352.         inc hl
  353.         djnz next_batch
  354.                 ;line too long
  355. line_too_long:    ld hl,toolongmsg
  356.         jp error_hl
  357. toolongmsg:    db 'Batch line too long',0
  358. next_batch:    call read_batch
  359.         cp ctrl_z
  360.         jr nz,batch_loop
  361. end_of_batch:    call del_subm
  362. line_full:    ld (hl),0
  363.         ld a,127
  364.         sub b
  365.         ld (inline_count),a
  366.         ret
  367. control_chr:    call read_batch
  368.         cp ' '
  369.         jr c,next_batch+3
  370.         and 1fh
  371.         jr no_var
  372. variable:    call read_batch
  373.         cp ' '
  374.         jr c,next_batch+3
  375.         cp '1'
  376.         jr c,no_var
  377.         cp '9'
  378.         jr nc,no_var
  379.         ld de,(argptr)
  380.         sub '1'
  381.         jr z,point_arg
  382.         ld c,a
  383. skip_arg:    ld a,(de)
  384.         or a
  385.         jr z,next_batch        ; keine Variable vorhanden
  386. skip_it_2:    inc de
  387.         ld a,(de)
  388.         or a
  389.         jr nz,skip_it_2
  390.         inc de
  391.         dec c
  392.         jr nz,skip_arg
  393. point_arg:    ld a,(de)
  394.         or a
  395.         jr z,next_batch
  396.         ld (hl),a
  397.         inc hl
  398.         inc de
  399.         djnz point_arg
  400.         jr line_too_long
  401.  
  402. ;****************************************************************;
  403. ;*                                *;
  404. ;*        Bis hier die h{ufig ben|tigten            *;
  405. ;*        Unterprogramme. Es folgt die            *;
  406. ;*        Tabelle der Befehle und ihrer            *;
  407. ;*        Ansprungadressen.                *;
  408. ;*                                *;
  409. ;****************************************************************;
  410.  
  411.  
  412. space_out:    ld a,' '        ;gib ein Leerzeichen aus
  413. akku_out:    push de            ;gib Akku aus.
  414.         push bc            ;Die Register DE und BC werden
  415.         ld e,a            ;gerettet
  416.         bdos console_out    ;gib Zeichen }ber BDOS aus
  417.         pop bc            ;hole Register zur}ck
  418.         pop de            ;
  419.         ret            ;und zur}ck ins Hauptprogramm
  420.  
  421. crlf_out:    ld a,cr            ;gib Carriage-return und Linefeed aus
  422.         call akku_out        ;
  423.         ld a,lf            ;
  424.         jr akku_out        ;
  425.  
  426. prompt_out:    ld bc,prompt        ;gibt Promptmeldung aus
  427. crlf_bc_out:    call crlf_out        ;gib cr, lf und Text ab bc aus
  428. ab_bc_out:    ld a,(bc)        ;gib Text ab bc aus (bis 0)
  429.         or a            ;
  430.         ret z            ;
  431.         ;cp ' '            ;ist es ein Ctrl-Zeichen?
  432.         ;jr nc,normal_out    ;nein
  433.         ;ld a,'^'        ;sonst graphisch darstellen
  434.         ;call akku_out        ;ausgeben
  435.         ;ld a,(bc)        ;erneut Zeichen holen
  436.         ;add a,40h        ;Upper case character
  437. normal_out:    call akku_out        ;
  438.         inc bc            ;
  439.         jr ab_bc_out        ;
  440.  
  441. set_defdma:    ld de,80h        ;set default DMA address
  442.         bdos set_dma_addr    ;
  443.         ret
  444.  
  445. set_def_drive:    ld a,(default_drive)    ;setze Defaultlaufwerk
  446. set_drive:    cp 255            ;schon gesetzt?
  447. current_drive    equ $-1            ;wird hier geladen
  448.         ret z            ;wenn gleich, kein BDOS-Aufruf
  449.         ld (current_drive),a    ;neues Current-Drive
  450.         ld e,a            ;f}r BDOS
  451.         bdos select_disk    ;}ber RST 30H
  452.         ld e,1            ;markiere 'other' f}r COPY
  453.         ret            ;
  454.  
  455. open_seq:    ld de,ccp_fcb        ;|ffnet Datei zum sequentiellem Lesen
  456. open_fcb:    ld c,open_file        ;
  457. bdos_store_w0:    xor a            ;oder Schreiben.
  458.         ld (ccp_fcb+12),a    ;ex
  459.         ld (ccp_fcb+14),a    ;s2
  460.         ld (ccp_fcb+32),a    ;setze Record-Count im Extend auf 0
  461. bdos_store:    call bdos_entry        ;
  462.         ld (result_byte),a    ;speichere Ergebnis
  463.         inc a            ;wenn vorher 0ffh war,
  464.         ret            ;dann return mit Zero-Flag gesetzt
  465.  
  466. sff_ccp_fcb:    ld de,ccp_fcb        ;default CCP FCB
  467.         ld c,srch_for_first    ;search for first
  468.         jr bdos_store        ;suche und speichere Ergebnis
  469.  
  470. delete_ccp_fcb:    ld de,ccp_fcb        ;l|sche File ccp_fcb
  471.         bdos delete_file    ;Datei l|schen
  472.         ret
  473.  
  474. set_def_user:    ld a,(default_user)    ;setze Default-User
  475. set_user:    cp 255
  476. current_user    equ $-1            ;damit nicht unn|tig BDOS aufgerufen wird
  477.         ret z
  478.         ld (current_user),a    ;abspeichern
  479.         ld e,a            ;setzte User (A)
  480.         bdos set_get_user    ;BDOS-Funktion
  481.         ld e,1
  482.         ret
  483.  
  484. read_ccp_fcb:    ld de,ccp_fcb        ;lies sequentiell aus ccp_fcb
  485. read_seqf:    bdos read_seq        ;BDOS-Funktionscode
  486.         or a            ;Ergebnis?
  487.         ret            ;
  488.  
  489. const_uchar:    bdos get_con_status    ;wurde eine Taste gedr}ckt?
  490.         or a            ;
  491.         ret z            ;keine Taste gedr}ckt
  492. conin:        bdos console_in        ;bedingungslos Taste einlesen
  493.         or a            ;or a, damit Status von const_uchar richtig
  494.         ret
  495.  
  496. del_subm:    push hl
  497.         ld hl,echoflag
  498.         res 2,(hl)
  499.         res 1,(hl)
  500.         pop hl
  501.         ret
  502.  
  503. get_user_line:    ld a,(echoflag)
  504.         bit 1,a
  505.         jr z,no_submit
  506.         call get_batch_line
  507.         ld a,(echoflag)        ;echo on or off?
  508.         bit 0,a
  509.         jr z,has_line        ;dann auch keine Abfrage, ob Taste gedr}ckt
  510.  
  511.         call prompt_out        ;Prompt ausgeben
  512.         ld bc,inline_text    ;gib gelesene Zeile aus
  513.         call ab_bc_out        ;
  514.         call const_uchar    ;wurde Taste gedr}ckt?
  515.         jr z,has_line        ;nein
  516.         call del_subm        ;ja, dann breche SUBMIT ab
  517.         jp reentry        ;und gehe in die Hauptschleife
  518.  
  519. no_submit:    call prompt_out
  520.         ld de,inline_buffer
  521.         bdos inline         ;lies }ber BDOS von Tastatur ein
  522.  
  523. has_line:    ld hl,inline_count    ;Z{hler eingelesene Buchstaben
  524.  
  525.         if r_enab        ;R-enable
  526.         ld a,(hl)        ;
  527.         dec a            ;war Z{hler 1 ?
  528.         jr nz,no_repeat        ;wenn nicht, ist R nicht m|glich
  529.         inc hl            ;pointet auf erstes (einziges) Zeichen
  530.         ld a,(hl)        ;einlesen...
  531.         dec hl            ;Pointer zur}ck
  532.         or ' '            ;CAPS=>lower
  533.         cp 'r'            ;R-Kommando?
  534.         jr nz,no_repeat        ;wenn nicht
  535.         ld de,5201h        ;vorl{ufig R<cr>
  536. repeatmem    equ $-2            ;Initial value = R<cr>
  537.         ld (inline_count),de    ;und abgespeichert
  538. no_repeat:
  539.         endif
  540.         ld c,5fh        ;convert to upper case
  541.         ld b,(hl)        ;nochmal die Anzahl der Zeichen
  542.         inc b            ;einen erh|hen f}r Abschlu~byte 00
  543. to_upper:    inc hl            ;Schleife, wandelt Zeile in Gro~buchstaben um
  544.         ld a,(hl)        ;n{chstes Zeichen
  545.         cp 9            ;ist es ein Tabulator?
  546.         jr nz,notab        ;nein
  547.         ld (hl),' '        ;sonst in Leerzeichen umwandeln,
  548. notab:        cp 'a'            ;da CCP allergisch gegen TABs ist
  549.         jr c,next_conv        ;wenn kleiner als a, keine [nderung
  550.         cp 'z'+1        ;wenn gr|~er als z auch nicht
  551.         jr nc,next_conv        ;sondern n{chstes Zeichen
  552.         and c                  ;to UPPER case
  553.         ld (hl),a        ;und abspeichern
  554. next_conv:    cp '"'
  555.         jr nz,next_conv2
  556.         set 5,c
  557. next_conv2:    djnz to_upper        ;Schleife wiederholen bis Ende
  558.         ld (hl),b        ;b ist jetzt 0, schlie~t Zeile ab
  559.  
  560. continue:
  561.         if r_enab
  562.         ld hl,(inline_count)    ;hier steigt SUBMIT ein
  563.         ld (repeatmem),hl    ;neuer Wert f}r R<cr>
  564.         endif
  565.  
  566.         ld hl,inline_text    ;Zeiger initialisieren
  567.  
  568.         if c_enab    ;Conditional enable
  569.         ld a,(hl)
  570.         sub '?'        ;conditional line?
  571.         jr nz,true_exec
  572.         inc hl
  573.         ld a,0
  574. return_code    equ $-1
  575.         or a
  576.         jp nz,get_user_line
  577.         endif
  578.  
  579. true_exec:    ld (pointer_1),hl    ;
  580.         ret            ;und zur}ck
  581.  
  582. no_error:    cp a
  583.         ret
  584. test:        ld a,(de)        ;pr}fe Zeichen auf G}ltigkeit f}r Dateinamen
  585.         or a            ;Ende der Zeile?
  586.         ret z            ;ja
  587.         cp ' '            ;space?
  588.         jp c,no_error        ;Controlsequenzen sind nicht erw}nscht
  589.         ret z            ;zero auch bei space
  590.         exx            ;save Registers
  591.         ld b,18            ;Anzahl der ung}ltigen Zeichen
  592.         ld hl,char_tabelle    ;
  593. check_char:    cp (hl)            ;
  594.         jr z,invalid_ch        ;
  595.         inc hl            ;
  596.         djnz check_char        ;
  597.         exx            ;
  598.         or a            ;
  599.         ret            ;valid characters
  600. invalid_ch:    exx            ;wieder alten Registersatz
  601.         ret            ;mit ZERO Flag
  602.  
  603.  
  604.  
  605. get_next_ptr:    ld hl,(pointer_1)    ;da war er vorher gespeichert
  606. get_next_hl:    ld a,(hl)        ;erstes Zeichen
  607.         or a            ;wenn Zeilenende,
  608.         ret z            ;dann return
  609.         cp ' '            ;wenn space,
  610.         ret nz            ;dann weitersuchen, bis Space gefunden
  611.         inc hl            ;dazu Pointer erh|hen
  612.         jr get_next_hl        ;
  613.  
  614. setup_fcb:    ld de,ccp_fcb        ;Default FCB
  615. setup_fcb_de:    push de            ;FCB Beginn
  616.         xor a            ;jetzt Default-Drive
  617.         ld (de),a        ;in FCB-Drivefeld
  618.         call get_next_ptr    ;erhasche erstes Zeichen des Namens
  619.         ld (pointer_2),hl    ;f}r Error-Ausgabe
  620.         ex de,hl        ;
  621.         jr z,fill_fcb        ;war garnichts
  622.         inc de            ;
  623.         ld a,(de)        ;zweites Zeichen
  624.         dec de            ;
  625.         cp ':'            ;Laufwerksangabe?
  626.         jr nz,fill_fcb        ;nein
  627.         ld a,(de)        ;ist eine Laufwerkangabe
  628.         sub 'A'            ;
  629.         cp 'P'            ;
  630.         jr nc,fill_fcb        ;falsche Laufwerkangabe wird ignoriert
  631.         inc de            ;zeigt jetzt auf ':'
  632.         inc de            ;
  633.         inc a            ;
  634.         ld (hl),a        ;
  635.  
  636. fill_fcb:    ld b,8            ;8 Characters Filename
  637.         call UP2        ;generieren
  638.         ld b,3            ;3 Characters Fileextension
  639.         call UP2a        ;generieren (aber . anders behandeln)
  640.  
  641.         ld b,3            ;setze diverse Z{hler auf 0
  642. set_0:        inc hl            ;
  643.         ld (hl),0        ;
  644.         djnz set_0        ;
  645.  
  646.         ld (pointer_1),de    ;weiter geht's beim ersten Byte hinter dem Namen
  647.         pop hl            ;nochmal FCB Adresse
  648.  
  649.         ld bc,11*256        ;z{hle ? im FCB
  650.         ld a,'?'        ;
  651. count_wildcart:    inc hl            ;
  652.         cp (hl)            ;ist es Fragezeichen?
  653.         jr nz,test_next        ;
  654.         inc c            ;Z{hler erh|hen
  655. test_next:    djnz count_wildcart    ;next one
  656.         ld a,c            ;Anzahl
  657.         or a            ;ZERO-Flag richtig setzen
  658.         ret            ;und zur}ck
  659.  
  660. UP2a:        cp '.'
  661.         jr nz,fill_space
  662.         inc de
  663. UP2:        call test
  664.         jr z,fill_space
  665.         inc hl
  666.         cp '*'
  667.         jr nz,not_all
  668.         ld (hl),'?'
  669.         jr next_x
  670. not_all:    ld (hl),a
  671.         inc de
  672. next_x:        djnz UP2
  673.         cp '*'
  674.         jr nz,ignore_rest    ;es fehlt noch inc de
  675.         inc de
  676. ignore_rest:    call test
  677.         ret z            ;ok, nichts mehr an Buchstaben da
  678.         inc de
  679.         jr ignore_rest        ;weil zu lang!
  680. fill_space:    inc hl            ;Rest des Teiles mit space f}llen
  681.         ld (hl),' '
  682.         djnz fill_space
  683.         ret
  684.  
  685. ;****************************************************************;
  686. ;*                                *;
  687. ;*            ZDOS Entry-Point            *;
  688. ;*        bei cold_entry wird die im Buffer        *;
  689. ;*        befindliche Kommandozeile ausgef}hrt        *;
  690. ;*                                *;
  691. ;****************************************************************;
  692.                     ;
  693. warm_entry:    xor a
  694.         ld (inline_count),a
  695. cold_entry:    ld sp,stacktop        ;hat eigenen Stack
  696.         ld a,e            ; return-code
  697.         ld (return_code),a
  698.         ld hl,ccp        ; setze Sprungvektoren richtig
  699.         ld (6),hl        ; BDOS-Entry
  700.  
  701.         ld a,255
  702.         ld (current_user),a    ;User now undefined
  703.         ld (current_drive),a    ;Drive auch
  704.         call set_def_user    ;dem BDOS Default-Usernummer mitteilen
  705.                     ;und auch selber merken
  706.         bdos disk_reset        ;Drive A=Online
  707.         ld a,(default_drive)    ;und merken
  708.         ld (4),a        ;
  709.         call set_drive        ;f}r das BDOS
  710.         ld a,(inline_count)
  711.         or a
  712.         jr nz,common
  713.                     ;
  714. reentry:    ld sp,stacktop        ;Neuinitialisation Stack
  715.         ld hl,new_drive
  716.         ld a,(hl)
  717.         ld (hl),0
  718.         or a
  719.         jr z,reentry_nodrv
  720.         dec a
  721.         ld (default_drive),a
  722.         call set_drive
  723. reentry_nodrv:    ld a,0            ;set Byte (4) correct
  724. default_user    equ $-1
  725.         ld c,a            ;merken
  726.         rlca
  727.         rlca
  728.         rlca
  729.         rlca
  730.         ld b,a
  731.         ld a,0
  732. default_drive    equ $-1
  733.         or b        
  734.         ld (4),a
  735.         and 00001111b        ;wieder nur Default-Disklaufwerk
  736.         ld hl,prompt        ;prompt string
  737.         add a,'A'        ;Offset zum ASCII-Code
  738.         ld (hl),a        ;und ausgeben
  739.         inc hl            ;Pointer erh|hen
  740.         ld a,c            ;Default-Usernummer
  741.         cp 10            ;zweistellig?
  742.         jr c,einstellig        ;
  743.         sub 10            ;dann zieh Rest auch ab
  744.         ld (hl),'1'        ;speichere einen Zehner
  745.         inc hl            ;Pointer + 1
  746. einstellig:    add a,'0'        ;Offset ASCII
  747.         ld (hl),a        ;und ausgeben
  748.         inc hl            ;jetzt letztes Zeichen
  749.         ld (hl),'>'        ;noch ein Teil des Prompts
  750.         inc hl
  751.         ld (hl),0
  752.         call get_user_line    ;Eingabe einer Kommandozeile von
  753.                     ;Keyboard oder SUBMIT-File
  754. common:        ld hl,(6)        ; bottom RSM or BDOS
  755.         ld l,0
  756.         ld (TPA_top),hl        ; store it!
  757.         call set_def_drive
  758.         call set_def_user
  759.         ld hl,error        ;h{ufigstes Ansprungziel auf den Stack
  760.         push hl
  761.         call set_defdma        ;setze Default DMA Adresse
  762.         call setup_fcb        ;generiere Dateinamen
  763.         ret nz            ;if * or ? in Filename => ERROR
  764.  
  765.         ld (tail_beginn),de    ;Beginn der restl. Kommandozeile
  766.         ld hl,ccp_fcb+9        ;wurde Fileextension eingegeben?
  767.         ld a,(hl)
  768.         cp ' '
  769.         ret nz            ;wenn ja, error
  770.         ld (hl),'C'        ;sonst ist sie COM
  771.         inc hl
  772.         ld (hl),'O'
  773.         inc hl
  774.         ld (hl),'M'
  775.  
  776.         ld a,(ccp_fcb)        ;wurde lfw: angegeben?
  777.         or a            ;wenn ja, kann es nur
  778.         jp nz,TRANSIENT        ;ein transientes Programm sein
  779.  
  780.         ld hl,tabelle        ;pr}fe, ob ein eingebautes Kommando vorliegt
  781. next_command:    ld e,(hl)        ;als erstes steht Zieladresse
  782.         inc hl            ;auf dem Stack
  783.         ld d,(hl)
  784.         inc hl
  785.         push de
  786.         xor a            ;Test, ob Ende der Tabelle
  787.         cp (hl)            ;wenn Befehl mit 00 beginnt
  788.         ret z            ;auf dem Stack ist Adresse
  789.         ld (beginn_name),hl
  790.         ld de,ccp_fcb+1        ;Beginn des Namens
  791.         ld b,4            ;L{nge Kommando
  792. vergleiche:    ld a,(de)        ;eingegebenes Zeichen
  793.         cp (hl)            ;= verlangtem Zeichen?
  794.         jr nz,onefail        ;nein
  795.         inc hl            ;sonst restliche Zeichen pr}fen
  796.         inc de            ;dazu Pointer erh|hen
  797.         djnz vergleiche        ;und Vergleich wiederholen
  798.         ld a,(de)        ;der Rest des FCB mu~ space sein
  799.         cp ' '
  800.         pop de            ;R}ckkehradresse
  801.         jr nz,next_command
  802.         push de            ;wird doch ben|tigt
  803.         jp setup_fcb        ;da meist gebraucht, danach ins Programm
  804.  
  805. onefail:    inc hl            ;Kommando sah anders aus
  806.         djnz onefail        ;Pointer updaten
  807.         pop de            ;Ansprungadresse
  808.         jr next_command        ;und n{chstes versuchen
  809.  
  810. test_end_ptr:    ld hl,(pointer_1)    ;Anfang letzter Bytefolge
  811. test_end_hl:    call get_next_hl    ;n{chstes Zeichen
  812.         ret z            ;mu~ 00 sein
  813.         jr error_hl        ;sonst ERROR
  814.  
  815. error:        ld hl,(pointer_2)
  816. error_hl:    ld c,l
  817.         ld b,h
  818. error_bc:    call crlf_bc_out
  819.         ld a,'?'
  820.         call akku_out
  821.         call del_subm
  822.         xor a
  823.         ld (new_drive),a
  824.         jp reentry
  825.  
  826. only_this:    call test_end_ptr    ;darf kein zweiter FCB folgen
  827. test_lfw_ext:    ld hl,ccp_fcb        ;da steht die Zahl drin
  828.         ld a,(ccp_fcb+9)    ;"file extension"
  829.         sub ' '            ;sollte jetzt 0 sein
  830.         or (hl)            ;Drive sollte Default sein
  831.         jr nz,error        ;sonst Error
  832.         inc hl            ;auf ccp_fcb+1
  833.         ret            ;so ist es OK
  834.  
  835. get_number:    call test_lfw_ext    ;reine Zahl erw}nscht
  836.         ld c,a            ;steht 0 drin...
  837.         ld a,(hl)        ;get digit
  838. next_digit:    sub '0'
  839.         cp 10
  840.         jr nc,error
  841.         ld b,a
  842.         ld a,c
  843.         cp 26            ;schon mehr ?
  844.         jr nc,error        ;weil beim multiplizieren ]bertrag ent-
  845.         add a,a            ;stehen w}rde
  846.         ld c,a
  847.         add a,a
  848.         add a,a
  849.         add a,c            ;Akku := Akku * 10
  850.  
  851.         add a,b            ;jetzt die neue Ziffer dazu!
  852.         jr c,error
  853.         ld c,a
  854.         inc hl
  855.         ld a,(hl)
  856.         cp ' '
  857.         ret z
  858.         or a
  859.         jr nz,next_digit
  860.         ret            ;return number in c
  861.  
  862. loadprog:    ld hl,100h
  863. TR2:        push hl
  864.         ex de,hl
  865.         bdos set_dma_addr
  866.         ld de,ccp_fcb
  867.         call read_seqf
  868.         pop hl
  869.         ret nz
  870.         ld de,0080h
  871.         add hl,de
  872.         ld a,(TPA_top+1)
  873.         cp h
  874.         jr nz,TR2
  875. bad_load:    ld bc,text_bad_load
  876.         jp exit_with_print
  877.  
  878. ;=======================================;
  879. ;                    ;
  880. ;        C O P Y            ;
  881. ;                    ;
  882. ;=======================================;
  883.  
  884. COPY:        ld d,20h        ;default-drive=error
  885.         call collect_d
  886. loopcopy:    call end_files_test
  887.         push de
  888.         call set_drv_usr    ;to selected
  889.         call open_seq
  890.         call loadprog        ;load file into memory
  891.         push hl            ;HL is Maxmem+1
  892.         call set_def_drive
  893.         call set_def_user
  894.         pop hl
  895.         call saveupro        ;write it back a la save
  896.         pop de
  897.         jr loopcopy
  898.  
  899. ;=======================================;
  900. ;                    ;
  901. ;        P A T H            ;
  902. ;                    ;
  903. ;=======================================;
  904.  
  905. PATH:        call only_this        ;darf nichts folgen und
  906.                     ;darf weder Laufwerk noch extension
  907.         ld a,(hl)        ;angegeben sein
  908.         cp ' '
  909.         ld bc,pathtab
  910.         jr z,exit_with_print
  911.         ld e,c
  912.         ld d,b
  913.         ld bc,7
  914. pathloop:    cp 40h            ;n{chstes Zeichen
  915.         ret c            ;Error, wenn kein Buchstabe
  916.         cp 'P'+1
  917.         ret nc
  918.         ldi
  919.         xor a
  920.         ld (de),a        ;erst mal beenden...
  921.         ld a,(hl)        ;ein weiteres
  922.         cp ' '
  923.         jr nz,pathloop        ;weiter geht's
  924.         inc c
  925.         ret z            ;wenn es 8 Zeichen waren
  926. to_reentry2:    jp reentry
  927.  
  928.         ;
  929.         ;===============================================
  930.         ;
  931. bad_drive:    ld bc,bad_drive_txt
  932. exit_with_print:call crlf_bc_out
  933.         jp to_reentry2
  934.  
  935. set_drv_usr:    ld e,0            ;modify-Flag
  936.         ld a,0
  937. temp_user    equ $-1
  938.         call set_user        ;anderer als Defaultuser
  939.  
  940.         ld a,(temp_drive)    ;
  941.         jp set_drive        ;auch anderes Drive
  942.  
  943. collect:    ld d,0
  944. collect_d:    ld e,20h        ;jr nz,...
  945.         ld a,(default_user)
  946.         ld (temp_user),a    ;temporary User
  947.         call get_next_ptr
  948.         cp '/'
  949.         ld c,0            ;User number
  950.         jr nz,opt_end
  951.         ld (pointer_2),hl
  952. next_opt:    inc hl
  953.         ld a,(hl)
  954.         and 11011111b        ;00 oder Spaces
  955.         jr z,opt_end        ;nix mehr
  956.         and 11111001b        ;Test auf Q, S, U, W
  957.         cp 'Q'
  958.         ld a,(hl)
  959.         jr nz,must_be_digit    ;sonst error
  960.         rrca
  961.         and 3
  962.         ld b,a
  963.         inc b
  964.         ld a,40h
  965. turn:        rlca
  966.         djnz turn
  967.         or d
  968.         ld d,a
  969.         jr next_opt
  970.  
  971. must_be_digit:    call next_digit        ;versuche, eine Usernummer einzulesen
  972.         or a
  973.         jp nz,error        ;Ende
  974.         ld a,c
  975.         cp 16
  976.         jp nc,error
  977.         ld (temp_user),a
  978. opt_end:    call test_end_hl    ;darf nichts mehr folgen
  979.         ld a,d
  980.         rrca            ;S=>Carry
  981.         jr nc,not_only_sys
  982.         ld e,28h        ;jr z,off
  983. not_only_sys:    rrca            ;U=>Carry
  984.         jr nc,not_only_user    ;
  985.         ld e,3eh        ;ld a,...
  986. not_only_user:    ld a,e
  987.         ld (jpselect),a
  988.         ld a,d
  989.         ld (option_bits),a    ;Q und W
  990.  
  991.         ld hl,ccp_fcb
  992.         ld a,(hl)
  993.         dec a
  994.         jp p,other_drive
  995.         ld a,(default_drive)
  996. other_drive:    ld (temp_drive),a
  997.         ld (hl),0
  998.         inc hl
  999.         ld a,(hl)
  1000.         cp ' '
  1001.         jr nz,isn_all
  1002.         bit 6,d            ;era?
  1003.         jp nz,error        ;einfach ERA geht nicht
  1004.         ld b,11
  1005. loop:        ld (hl),'?'
  1006.         inc hl
  1007.         djnz loop
  1008. isn_all:    bit 5,d            ;Copy?
  1009.         push af            ;Copy?
  1010.         call set_drv_usr
  1011.         pop af
  1012.         jr z,no_eq_test
  1013.         xor a
  1014.         or e            ;wurde umgeschaltet?
  1015.         jp z,bad_drive
  1016.         
  1017. no_eq_test:    call set_drv_usr
  1018.  
  1019.         call sff_ccp_fcb
  1020.         jr z,none_found
  1021.         ld de,0
  1022. TPA_top        equ $-2
  1023.         dec de            ;load names below ZDOS or RSM
  1024. collectloop:    ld a,d
  1025.         or a
  1026.         ld bc,no_room_text
  1027.         jp z,exit_with_print    ;raus und melden
  1028. enough_space:    ld a,0
  1029. result_byte    equ $-1
  1030.         rrca
  1031.         rrca
  1032.         rrca
  1033.         add a,80h+10        ;2.last char of filename
  1034.         ld l,a
  1035.         ld h,0
  1036.         bit 7,(hl)
  1037. jpselect:    jr nz,noaccept
  1038.         inc l
  1039.         ld a,0
  1040. option_bits    equ $-1            ;evtl fragen, ob }berhaupt...
  1041.         rlca            ;Bit 7(Q) => Carry
  1042.         jr nc,take_it
  1043.         push de
  1044.         push hl
  1045.         ld de,-10        ;zeigte vorher auf 11.Zeichen
  1046.         add hl,de        ;hl jetzt Pointer auf Filename
  1047.         call crlf_file_out    ;Dateinamen ausgeben
  1048.         call space_out
  1049.         ld de,0
  1050. beginn_name    equ $-2            ;dir, era, copy, type        
  1051.         ld bc,0401h
  1052.         call fno2        ;ausgeben
  1053.         ld bc,q_mark
  1054.         call ab_bc_out
  1055. askkill:    call conin
  1056.         cp 3
  1057.         jp z,reentry
  1058.         and 0dfh        ;to upper
  1059.         pop hl
  1060.         pop de
  1061.         cp 'Y'
  1062.         jr z,take_it
  1063.         cp 'N'
  1064.         jr z,noaccept
  1065.         cp 'G'
  1066.         jr z,go_copy
  1067.         push de
  1068.         push hl
  1069.         jr askkill
  1070.  
  1071. take_it:    ld bc,11
  1072.         lddr
  1073. noaccept:    push de
  1074.         ld c,srch_for_next
  1075.         call bdos_store
  1076.         pop de
  1077.         jr nz,collectloop
  1078. go_copy:    call bubble_sort    ;hier moeglichkeit, dateien zu sortieren...
  1079.         inc de
  1080.         ld a,(TPA_top+1)
  1081.         cp d
  1082.         ret nz
  1083. none_found:
  1084. no_file:    ld bc,no_file_text
  1085.         call crlf_bc_out
  1086.         jp reentry
  1087. end_files_test:    ld a,(TPA_top+1)
  1088.         cp d
  1089.         jp z,reentry
  1090.         push de
  1091.         ex de,hl
  1092.         ld de,ccp_fcb+1
  1093.         ld bc,11
  1094.         ldir
  1095.         ex (sp),hl
  1096.         call crlf_file_out
  1097.         pop de
  1098.         ret
  1099.  
  1100. crlf_file_out:    ex de,hl
  1101.         call crlf_out
  1102. filename_out:    ld bc,0802h        ;ab de, de nach auf 1 Zeichen sp{ter
  1103. fno2:        ld a,(de)
  1104.         inc de
  1105. rein:        call akku_out
  1106.         djnz fno2
  1107.         dec c
  1108.         ret z
  1109.         ld b,4
  1110.         ld a,'.'
  1111.         jr rein        
  1112.  
  1113. ;=======================================;
  1114. ;                    ;
  1115. ;        E C H O            ;
  1116. ;                    ;
  1117. ;=======================================;
  1118.  
  1119. ECHO:        call only_this        ;kein zweiter FCB
  1120.         ld a,(hl)        ;darf nur Y oder N folgen
  1121.         cp 'Y'            ;erstes Zeichen
  1122.         jr z,echo_on
  1123.         sub 'N'
  1124.         ret nz            ;weder Y noch N
  1125. echo_on:    and 1
  1126.         ld hl,echoflag
  1127.         res 0,(hl)
  1128.         or (hl)
  1129.         ld (hl),a
  1130. to_reentry3:    jp reentry
  1131.  
  1132. ;=======================================;
  1133. ;                    ;
  1134. ;        X S U B            ;
  1135. ;                    ;
  1136. ;=======================================;
  1137.  
  1138. XSUB:        ld hl,echoflag        ; do easy job
  1139.         set 2,(hl)        ; that's all
  1140.         jr to_reentry3
  1141.  
  1142. ;=======================================;
  1143. ;                    ;
  1144. ;        E X I T            ;
  1145. ;                    ;
  1146. ;=======================================;
  1147.  
  1148. EXIT:        call del_subm        ; l|sche nur $$$.SUB
  1149.         jr to_reentry3        ; sonst nichts
  1150.  
  1151. ;=======================================;
  1152. ;                    ;
  1153. ;        E R A            ;
  1154. ;                    ;
  1155. ;=======================================;
  1156.  
  1157. ERAQ:        ld d,0c0h        ; Q-Option schon gesetzt
  1158.         db 21h
  1159. ERA:        ld d,40h        ; keine Option gesetzt, aber ERA
  1160.         call collect_d
  1161. kill_loop:    call end_files_test
  1162.         push de
  1163.         call delete_ccp_fcb
  1164.         pop de            ;pointer next file
  1165.         jr kill_loop
  1166.  
  1167. ;=======================================;
  1168. ;                    ;
  1169. ;        D I R            ;
  1170. ;                    ;
  1171. ;=======================================;
  1172.  
  1173. zeilcount:    db 0
  1174. DIR:        call collect
  1175.         ld a,1
  1176.         ld (zeilcount),a
  1177. dirloop:    ld a,(TPA_top+1)
  1178.         cp d
  1179.         jp z,to_reentry3
  1180.         ld hl,zeilcount
  1181.         dec (hl)
  1182.         ld a,' '
  1183.         jr nz,no_newline
  1184.         ld (hl),5
  1185.         call crlf_out
  1186.         ld a,0
  1187. temp_drive    equ $-1
  1188.         add a,'A'
  1189. no_newline:    call akku_out
  1190.         ld a,':'
  1191.         call akku_out
  1192.         call space_out
  1193.         call filename_out
  1194.         jr dirloop
  1195.  
  1196. ;=======================================;
  1197. ;                    ;
  1198. ;        U S E R            ;
  1199. ;                    ;
  1200. ;=======================================;
  1201.  
  1202. USERa:        call setup_fcb        ;alternate USER-Befehl = /nn
  1203. USER:        call test_end_ptr    ;nach Usernummer Schlu~
  1204.         call get_number
  1205.         ld a,c
  1206.         cp 16
  1207.         ret nc
  1208.         ld (default_user),a
  1209.         call set_user
  1210.         jp reentry
  1211.  
  1212. ;=======================================;
  1213. ;                    ;
  1214. ;        S A V E            ;
  1215. ;                    ;
  1216. ;=======================================;
  1217.  
  1218. SAVE:        call get_number
  1219.         ld h,c
  1220.         ld l,0
  1221.         inc h
  1222.         push hl            ;maxmem+1
  1223.         call setup_fcb
  1224.         jp nz,error
  1225.         call test_end_ptr
  1226.         pop hl
  1227.         call saveupro
  1228.         jp reentry
  1229.  
  1230. saveupro:    push hl
  1231.         call delete_ccp_fcb
  1232.         ld de,ccp_fcb
  1233.         ld hl,ccp_fcb+9        ;1.char Extension
  1234.         res 7,(hl)        ;reset R/O-Bit
  1235.         ld c,make_file        ;make FCB
  1236.         call bdos_store_w0
  1237.         jr z,no_space
  1238.         ld de,100h        ;start TPA
  1239. SAVE1:        pop hl            ;maxmem+1
  1240.         push hl
  1241.         or a
  1242.         sbc hl,de        ;=jetzige DMA?
  1243.         jr z,save_close        ;dann Schlu~!
  1244.         ld hl,80h
  1245.         add hl,de
  1246.         push hl
  1247.         bdos set_dma_addr
  1248.         bdos write_seq,ccp_fcb
  1249.         or a
  1250.         pop de
  1251.         jr z,SAVE1
  1252.         bdos close_file,ccp_fcb
  1253. no_space:    ld bc,no_space_text
  1254.         jp exit_with_print
  1255.  
  1256. save_close:    pop hl
  1257.         bdos close_file,ccp_fcb
  1258.         inc a
  1259.         jr z,no_space
  1260.         jp set_defdma
  1261.  
  1262. ;=======================================;
  1263. ;                    ;
  1264. ;        T Y P E            ;
  1265. ;                    ;
  1266. ;=======================================;
  1267.  
  1268. MORE_0:        ld d,4            ;automatic /w
  1269.         db 21h
  1270. MORE:        ld d,0
  1271.         call collect_d        ;damit ZERO-Flag richtig bleibt
  1272.         push de
  1273. drucke_0:    ld a,21
  1274.         jr drucke+1
  1275. drucke_rst:    pop hl
  1276.         ld de,-11
  1277.         add hl,de
  1278.         push hl
  1279.         jr drucke_0
  1280.  
  1281. drucke:        xor a
  1282.         ld (linecount),a
  1283.         pop de
  1284.         call end_files_test
  1285.         push de
  1286.         call open_seq
  1287.         call crlf_out
  1288. DRUCKE1:    call read_ccp_fcb
  1289.         jr nz,drucke
  1290.         ld bc,80h
  1291. DRUCKE2:    ld a,(bc)
  1292.         cp 1ah            ;EOF
  1293.         jr z,drucke
  1294.  
  1295.         push bc
  1296.         cp lf
  1297.         jr nz,DRUCKE3
  1298.  
  1299.         ld hl,option_bits    ;anhalten?
  1300.         bit 2,(hl)
  1301.         jr z,continuous        ;nein!
  1302.         ld a,0
  1303. linecount    equ $-1
  1304.         dec a
  1305.         jp m,page_end
  1306.         ld (linecount),a
  1307.         jr DRUCKE3a
  1308.  
  1309. page_end:    ld bc,more_text
  1310.         call crlf_bc_out
  1311.         call conin
  1312.         push af
  1313.         ld bc,un_more
  1314.         call ab_bc_out
  1315.         pop af
  1316.         cp cr            ;Eine Zeile weiter?
  1317.         jr z,DRUCKE3b
  1318.         pop bc
  1319.         or ' '
  1320.         cp 'n'            ;next File?
  1321.         jr z,drucke_0        ;dann volle Seite vorschieben
  1322.         cp 'q'
  1323.         jp z,reentry        ;Abbruch?
  1324.         cp 'r'            ;restart this file?
  1325.         jr z,drucke_rst
  1326.         push bc
  1327.         ld a,21            ; else next page
  1328.         ld (linecount),a
  1329.         jr DRUCKE3b
  1330.  
  1331. continuous:    ;call const_uchar    ;disabled, da }ber BDOS-Statusabfrage
  1332.         ;jp nz,reentry        ;^S, ^C m|glich ist!
  1333. DRUCKE3a:    ld a,lf
  1334. DRUCKE3:    call akku_out
  1335. DRUCKE3b:    pop bc
  1336.         inc c
  1337.         jr nz,DRUCKE2
  1338.         jr DRUCKE1
  1339.  
  1340. ;=======================================;
  1341. ;                    ;
  1342. ;        R E N            ;
  1343. ;                    ;
  1344. ;=======================================;
  1345.  
  1346. REN:        ret nz            ;war ambiguous Filename
  1347.         call get_next_ptr    ;jetzt mu~ das '='-Zeichen folgen
  1348.         cp '='            ;ist es das?
  1349.         ret nz            ;sonst ERROR
  1350.         inc hl            ;Pointer updaten
  1351.         ld (pointer_1),hl    ;
  1352.  
  1353.         call sff_ccp_fcb    ;existiert Soll-Name?
  1354.         ld bc,text_exists    ;"File exists"
  1355.         jp nz,exit_with_print    ;ausschreiben und weg
  1356.         ld hl,ccp_fcb        ;sonst in Feld 2 schieben
  1357.         ld de,ccp_fcb+16    ;
  1358.         ld bc,16        ;
  1359.         ldir            ;
  1360.         call setup_fcb        ;zweiten Dateinamen holen
  1361.         ret nz            ;ambiguous file name
  1362.  
  1363.         call test_end_ptr    ;ist jetzt Schlu~?
  1364.  
  1365.         ld hl,ccp_fcb
  1366.         ld a,(ccp_fcb+16)
  1367.         or a
  1368.         jr z,drive_ok
  1369.         cp (hl)
  1370.         jr z,drive_ok
  1371.         push af
  1372.         xor a
  1373.         or (hl)
  1374.         jp nz,bad_drive
  1375.         pop af
  1376.         ld (hl),a
  1377. drive_ok:    call sff_ccp_fcb
  1378.         jp z,no_file
  1379.         ld de,ccp_fcb
  1380.         bdos rename_file
  1381.         jp reentry
  1382.  
  1383. ;=======================================;
  1384. ;                    ;
  1385. ;    Transientes Programm laden    ;
  1386. ;                    ;
  1387. ;=======================================;
  1388.  
  1389. TRANSIENT:    ld a,(ccp_fcb+1)    ;Feld f}r erstes Zeichen des Programmnamens
  1390.         sub ' '
  1391.         jr nz,program
  1392.         ld hl,ccp_fcb        ;Drive Code
  1393.         or (hl)            ;auch gleich 0?
  1394.         jr z,comment        ;dann nur <Enter> gedr}ckt
  1395.         ld (new_drive),a
  1396. comment:    call get_next_ptr
  1397.         jr z,to_reentry
  1398.         inc hl
  1399.         ld (pointer_1),hl
  1400.         cp '/'            ;alternate USER-Befehl
  1401.         jp z,USERa
  1402.         cp ':'
  1403.         jr z,to_reentry        ;is_comment
  1404.         cp ';'
  1405.         jr z,to_reentry        ;is_comment
  1406.         sub '"'
  1407.         ret nz            ;dann ERROR
  1408.         ld a,(echoflag)        ;ECHO on
  1409.         and 11b
  1410.         cp 11b
  1411.         ld b,h
  1412.         ld c,l
  1413.         call nz,crlf_bc_out
  1414. to_reentry:    jp reentry
  1415.  
  1416. program:    ld hl,(pointer_1)
  1417.         ld a,(hl)
  1418.         sub '/'            ;Option?
  1419.         jr nz,no_user_nr
  1420.         inc hl
  1421.         ld c,a            ;0
  1422.         call next_digit-1
  1423.         ld (pointer_1),hl
  1424.         ld (tail_beginn),hl
  1425.         ld a,c
  1426.         cp 16
  1427.         ret nc            ;zu gro~
  1428.         call set_user
  1429. no_user_nr:    ld de,pathtab
  1430.         ld a,(ccp_fcb)
  1431.         or a
  1432.         jr z,loadloop        ;suche auf Laufwerken
  1433.         ld de,pathtab+7        ;Pointer auf 0
  1434.         jr reinload
  1435. loadloop:    ld a,(de)
  1436.         sub 40h
  1437.         jp c,batchfile?
  1438.         inc de
  1439.         ld (ccp_fcb),a
  1440. reinload:    push de
  1441.         call open_seq
  1442.         pop de
  1443.         jr z,loadloop
  1444.         call loadprog        ;load progam into mem
  1445.         call set_def_user
  1446.         call setup_fcb
  1447. GO:        ld de,ccp_fcb+16
  1448.         call setup_fcb_de
  1449.         xor a
  1450.         ld (ccp_fcb+32),a
  1451.         ld de,deffcb
  1452.         ld hl,ccp_fcb
  1453.         ld bc,21h
  1454.         ldir
  1455.  
  1456.         ld hl,0
  1457. tail_beginn    equ $-2
  1458.         ld de,81h        ;ab da wird Command-Tail gespeichert
  1459. transfer2:    cp (hl)            ;a ist noch 0
  1460.         ldi            ;}bertrage
  1461.         jr nz,transfer2        ;n{chstes Byte
  1462. end_tr:        ld a,e
  1463.         sub defdma+2        ;L{nge des Restes
  1464.         ld (defdma),a        ;abspeichern
  1465.         ld a,(echoflag)
  1466.         and 11b
  1467.         cp 10b
  1468.         call nz,crlf_out    ;Zeilenvorschub, wenn nicht BAT&NOECHO
  1469.         call set_defdma        ;Default DMA setzen
  1470.         pop af            ;Error-Adresse
  1471.         call 100h        ;starte Programm
  1472.         if c_enab
  1473.         ld (return_code),a
  1474.         endif
  1475. has_all:    ld a,255
  1476.         ld (current_user),a    ;User now undefined
  1477.         ld (current_drive),a    ;Drive auch
  1478.         jp reentry        ;Hauptschleife
  1479.  
  1480. batchfile?:    ld hl,ccp_fcb+9
  1481.         ld (hl),'S'
  1482.         inc hl
  1483.         ld (hl),'U'
  1484.         inc hl
  1485.         ld (hl),'B'
  1486.         ld a,1
  1487.         ld (ccp_fcb),a
  1488.         call open_seq
  1489.         ret z            ; nicht gefunden
  1490.         ld a,(current_user)
  1491.         ld (sub_user),a
  1492.         ld a,1
  1493.         ld (remain),a
  1494.         ld hl,ccp_fcb
  1495.         ld de,subfcb
  1496.         ld bc,21h
  1497.         ldir
  1498.         ld hl,echoflag
  1499.         set 1,(hl)
  1500.         ld hl,(tail_beginn)
  1501.         ld de,argspace
  1502.         ld (argptr),de
  1503. loop_wait:    ld a,(hl)
  1504.         inc hl
  1505.         cp ' '
  1506.         jr z,loop_wait
  1507.         or a
  1508.         jr z,line_ends
  1509. loop_copy:    ld (de),a
  1510.         inc de
  1511.         ld a,(hl)
  1512.         and not ' '
  1513.         jr z,arg_ends
  1514.         ld a,(hl)
  1515.         inc hl
  1516.         jr loop_copy
  1517. arg_ends:    ld (de),a
  1518.         inc de
  1519.         or (hl)
  1520.         jr nz,loop_wait
  1521. line_ends:    ld (de),a
  1522.         call crlf_out
  1523.         jr has_all
  1524.  
  1525. GOTO:        call only_this
  1526.         ld (pointer_2),hl    ; f}r ERROR
  1527.         xor a
  1528.         ld (subfcb+20h),a    ; current record
  1529.         inc a
  1530.         ld (remain),a
  1531. search_label:    ld hl,echoflag
  1532.         bit 1,(hl)
  1533.         ret z
  1534.         call get_batch_line
  1535.         ld hl,inline_text
  1536.         ld a,(hl)
  1537.         cp ':'
  1538.         jr nz,search_label
  1539.  
  1540.         ld de,ccp_fcb
  1541.         inc de
  1542.         ld a,(de)
  1543.         cp '"'
  1544.         jr z,cmp_label    
  1545.         dec de
  1546. cmp_label:    inc hl
  1547.         inc de
  1548.         ld a,(de)
  1549.         cp (hl)
  1550.         jr z,cmp_label
  1551.         cp ' '            ; end of label?
  1552.         jr nz,search_label
  1553.         jp reentry        ; found!
  1554.         
  1555. QUIT:        ld hl,bdos
  1556.         ld (6),hl
  1557.         ld hl,0
  1558. remwboot    equ $-2
  1559.         ld (cbios+4),hl
  1560.         rst 0            ; Kaltstart
  1561.  
  1562. ARGS:        ld hl,(argptr)
  1563.         ld a,(hl)
  1564.         or a
  1565.         ret z
  1566. srch_next_arg:    inc hl
  1567.         ld a,(hl)
  1568.         or a
  1569.         jr nz,srch_next_arg
  1570.         inc hl
  1571.         ld (argptr),hl
  1572.         jp reentry
  1573.  
  1574. ;Bubblesort zum Sortieren der Dateinamen vor der Ausgabe DIR
  1575.  
  1576. bubble_sort:    push de
  1577.         xor a
  1578.         ld (sort_flag),a
  1579.         inc de
  1580.         ld hl,11    ;L{nge Dateiname
  1581.         add hl,de
  1582. sort_loop:    ld a,(TPA_top+1)
  1583.         cp h
  1584.         jr z,one_thru    ;ein Pass durch
  1585.         ld b,11
  1586. cmp_word:    ld a,(de)
  1587.         cp (hl)
  1588.         jr nz,different
  1589.         inc hl
  1590.         inc de
  1591.         djnz cmp_word
  1592.         jr sort_loop
  1593. different:
  1594. exchange?:    jr c,no_ex    ; bzw. jr nc,.. (auf-/absteigend)
  1595.         ld c,(hl)
  1596.         ld a,(de)
  1597.         ld (hl),a
  1598.         ld a,c
  1599.         ld (de),a
  1600.         ld a,0ffh
  1601.         ld (sort_flag),a; mark anything has changed
  1602. no_ex:        inc hl
  1603.         inc de
  1604.         djnz exchange?
  1605.         jr sort_loop
  1606.  
  1607. one_thru:    pop de
  1608.         ld a,0
  1609. sort_flag    equ $-1
  1610.         or a
  1611.         jr nz,bubble_sort
  1612.         ret        ; Ausgang sort
  1613.  
  1614. tabelle:    ;Tabelle der eingebauten Kommandos und ihrer Ansprung-
  1615.         ;Adressen
  1616.  
  1617.         dw DIR
  1618.         db 'DIR '
  1619.         dw DIR
  1620.         db 'D   '
  1621.         dw DIR
  1622.         db 'LS  '
  1623.  
  1624.         dw ERA
  1625.         db 'ERA '
  1626.         dw ERA
  1627.         db 'DEL '
  1628.         dw ERA
  1629.         db 'RM  '
  1630.         dw ERAQ
  1631.         db 'ERAQ'
  1632.  
  1633.         dw MORE
  1634.         db 'TYPE'
  1635.         dw MORE
  1636.         db 'CAT '
  1637.         dw MORE_0
  1638.         db 'MORE'
  1639.  
  1640.         dw SAVE
  1641.         db 'SAVE'
  1642.         dw REN
  1643.         db 'REN '
  1644.         dw USER
  1645.         db 'USER'
  1646.         dw COPY
  1647.         db 'COPY'
  1648.         dw GO
  1649.         db 'GO  '
  1650.         dw PATH
  1651.         db 'PATH'
  1652.         dw ECHO
  1653.         db 'ECHO'
  1654.         dw XSUB
  1655.         db 'XSUB'
  1656.         dw EXIT
  1657.         db 'EXIT'
  1658.         dw QUIT
  1659.         db 'QUIT'
  1660.         dw ARGS
  1661.         db 'ARGS'
  1662.         dw GOTO
  1663.         db 'GOTO'
  1664.         dw TRANSIENT
  1665.         db 0            ;Ende der Tabelle
  1666.  
  1667. prompt:        db 'A15>',0        ;Prompt String
  1668. char_tabelle:    db '"<>.,;:=[\]_%|()/',7fh                    ;
  1669. bad_drive_txt:    db 'Bad Drive',0
  1670. no_file_text:    db 'No File',0
  1671. no_room_text:    db 'Filename-List full',0
  1672. more_text:    db '<More>',0
  1673. un_more:    db cr,tab,cr,0
  1674. no_space_text:    db 'No Space',0
  1675. text_bad_load:    db 'Bad load',0
  1676. text_exists:    db 'File exists',0
  1677.  
  1678. q_mark:        db ' it? ',0
  1679. new_drive:    db 0
  1680.  
  1681. argptr:        dw argspace
  1682. argspace:
  1683.         ift $ gt bdos-33-22-128    ;das vorletzte ist Stack Space
  1684.         .printx $ FATAL: ZDOS Module too big!! $
  1685.         endif
  1686.         .dephase
  1687.         end entry
  1688.