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 / xccp.mac < prev    next >
Encoding:
Text File  |  1994-06-06  |  36.5 KB  |  1,681 lines

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