home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-06-06 | 31.9 KB | 1,343 lines |
- MACLIB biosbase.def
- ;****************************************************************;
- ;* *;
- ;* ZDOS Version 1.0 *;
- ;* extended CCP Features for Cp/M *;
- ;* (c) 1985 by Michael Bischoff *;
- ;* *;
- ;****************************************************************;
- ;* *;
- ;* edit history: *;
- ;* 26.05.1985: nochmal neu }berarbeitet. *;
- ;* Ben|tigt jetzt CBIOS-Rou- *;
- ;* tine bei CBIOS + 33h zum *;
- ;* 'merken' des Userpath. *;
- ;* 27.05.1985: Ben|tigt Routine nicht mehr. *;
- ;* jetzt ist von 40h bis 4fh *;
- ;* der BIOS-Scratch-Bereich des *;
- ;* Cp/M daf}r reserviert. Bei *;
- ;* Systemstart sollte da korrekt *;
- ;* initialisiert werden *;
- ;* 16.06.1985: Der Bereich f}r PATH ist jetzt von *;
- ;* 8h bis 11h. ERA ohne Argumente ist *;
- ;* jetzt abgefangen und COPY kopiert *;
- ;* nicht mehr auf sich selber. *;
- ;* Die Zero-Page ist jetzt voll belegt. *;
- ;* Der BDOS-Ansprung geht wieder }ber *;
- ;* 5h, damit die RSM-Module funktio- *;
- ;* nieren. *;
- ;* 11.08.1985: COPY kopiert jetzt auch R/O-Dateien. *;
- ;* Sollte STAT.COM $R/O oder $R/W nicht *;
- ;* akzeptieren, so liegt dies daran, da~ *;
- ;* STAT das Attribut im deffcb2 erwartet, *;
- ;* ZDOS aber das '/'-Zeichen nicht in den *;
- ;* FCB }bernimmt (korrekt laut Cp/M-Hand- *;
- ;* buch) *;
- ;* Alle Befehle mit /Q Option nehmen jetzt *;
- ;* die Eingabe 'G' (go) an. Dies bewirkt *;
- ;* eine automatische 'N'-Eingabe aller *;
- ;* weiteren Abfragen. *;
- ;* 08.09.1985 Diese Version ist ein COM-File, welches ein *;
- ;* Overlay bei D000h benutzt, wenn BIG_DOS auf *;
- ;* einen Wert definiert wird. Die Zero-Page *;
- ;* wurde umgestellt und arbeitet jetzt mit PAS- *;
- ;* CAL/M zusammen (ab 10h MM DD YY HH MM in BCD) *;
- ;* 15.09.1985 Diese Version geht in Richtung einer wirklich *;
- ;* universellen Form, die auf allen Rechnern *;
- ;* laufen sollte. Anforderungen: 1) BIOS springt *;
- ;* beim Kaltstart CCP an, danach CCP+3. 2) Die *;
- ;* Zero-Page bleibt unver{ndert. (0-f, 30-37, *;
- ;* 3b-5b) *;
- ;* 29.09.1985 Die Labels CCP und BDOS eingef}hrt, das Label *;
- ;* BASE (Top Memory f}r Dateinamen-sammelei) va- *;
- ;* riabel gemacht und auf 8000h gesetzt. *;
- ;* 04.10.1985 Label BASE von 8000h auf 9000h gesetzt, da *;
- ;* die WordStar-Overlays f}r COPY zu gro~ waren. *;
- ;* 23.11.1985 Control-ECHO wieder erlaubt, conditional execu- *;
- ;* tion eingebaut bei Zeilen, die mit '?' beginnen *;
- ;* 08.05.1986 Befehl EXIT eingebaut. Dieser Befehl l|scht die *;
- ;* A:$$$.SUB-Datei und beendet somit Job-Control *;
- ;* 19.05.1986 [nderung in Conditional-Statements: TRUE ist *;
- ;* wegen Kompatibilit{t zu UNIX jetzt 0. *;
- ;* BASE ist jetzt variabel. *;
- ;* *;
- ;****************************************************************;
-
- false equ 0
- true equ not false
- r_enab equ false ;'R'-Command (we have better in INLINE)
- c_enab equ true ;conditional execution
-
- .z80 ;geschrieben in ZILOG-Code
- if1
- .printx $ Assembling ZDOS System-Track Version vom 19.05.1986 $
- else
- .printx $ ...Pass 2 $
- endif
-
- fill macro length,byte
- rept length
- db byte
- endm
- endm
-
- echoflag equ 0037h ;ECHO-Flag
- pathtab equ 0008h ;PATH-Tabelle
-
- ccp_fcb equ 003bh ;default FCB for internal use
- deffcb equ 005ch ;default FCB address
- deffcb2 equ 006ch ;default FCB address 2
- defdma equ 0080h ;default DMA address
-
- tab equ 09h ;ASCII Tabulator
- cr equ 0dh ;ASCII carriage return
- lf equ 0ah ;ASCII linefeed
-
- ;****************************************************************;
- ;* *;
- ;* BDOS-Systemcalls *;
- ;* *;
- ;****************************************************************;
-
- system_reset equ 0
- console_in equ 1
- console_out equ 2
- reader_in equ 3
- punch_out equ 4
- list_out equ 5
- direct_conio equ 6
- get_iobyte equ 7
- set_iobyte equ 8
- print_string equ 9
- inline equ 0ah
- get_con_status equ 0bh
- return_version equ 0ch
- disk_reset equ 0dh
- select_disk equ 0eh
- open_file equ 0fh
- close_file equ 10h
- srch_for_first equ 11h
- srch_for_next equ 12h
- delete_file equ 13h
- read_seq equ 14h
- write_seq equ 15h
- make_file equ 16h
- rename_file equ 17h
- get_login_vec equ 18h
- get_cur_disk equ 19h
- set_dma_addr equ 1ah
- get_alloc_addr equ 1bh
- set_ro_disk equ 1ch
- get_ro_vector equ 1dh
- set_file_attr equ 1eh
- get_dpb_addr equ 1fh
- set_get_user equ 20h
- read_random equ 21h
- write_random equ 22h
- comp_file_size equ 23h
- set_rand_rec equ 24h
- reset_drive equ 25h
-
-
- wr_rand_with_0 equ 28h
-
- bdos macro callnr,arg ;Macro ruft BDOS auf
- ifnb <arg> ;Argument ist Funktionsnummer
- ld de,arg ;evtl. auch Parameter
- endif ;
- ld c,callnr ;
- call bdos_entry ;Ausf}hrung
- endm ;
-
- bdos macro callnr,arg ;diese Version benutzt RST 30H
- ifnb <arg> ;gleich
- ld de,arg ;gleich
- endif ;gleich
- rst 30h ;rufe BDOS auf
- db callnr ;holt sich der Restart
- endm ;
-
- ccp equ cbios-1600h
- bdos equ ccp+806h
-
- ;base equ 9000h ;hier drunter werden die DIRECTORY-
- ;Eintr{ge gesammelt! VORSICHT!
- ;kann mit RSM und GO kollidieren
- ; ACHTUNG: jetzt variabel!
- stacktop equ bdos
-
- bdos_entry equ 5 ;(nicht cbios-0dfah)
-
-
-
- db 36 ;(erster Sektor)
- db 36+16 ;(letzter Sektor+1)
-
- .phase ccp ;Beginn des ZDOS
-
- jp init ;Sprungvektor 1
- jp warm_entry ;Sprungvektor 2
-
- inline_buffer: db 7fh ;
- inline_count: db 7 ;
- inline_text: db 'PATH AB',0 ;
- db '****************' ;
- db '* ZDOS Ver 1.1 *' ;
- db '* M. Bischoff *' ;
- db '* May-27 1985 *' ;
- db '****************' ;
-
- init: ld hl,bdos ;mache ein JP BDOS aus dem ersten
- ld (ccp+4),hl ;Sprungvektor, dann ist FREEZE einfacher
- ld hl,'@' ;initial PATH
- ld (pathtab),hl ;store it in ZEROPAGE
- ld b,8
- ld hl,rst30 ;Tabelle f}r Bytes 30h..37h
- ld de,30h
- loop_init: ld a,(hl)
- ld (de),a
- inc hl
- inc de
- djnz loop_init ;bis 8 Byte }bertragen sing
- jp cold_entry
-
- rst30: ex (sp),hl ;hl = Aufrufadresse + 1
- ld c,(hl) ;da steht die Funktionsnummer
- inc hl ;return 1 Byte weiter
- ex (sp),hl ;R}ckkehradresse wieder auf Stack
- jr $+2-36h+5 ;und in das BDOS
- db 0 ;lastkey (used by BDOS)
- db 0 ;Echoflag (OFF)
-
- if $ gt ccp+88h
- .printx $ FATAL: Initialization Routine needs too much memory $
- endif
-
- fill ccp+88h-$,0 ;um auf den richtigen Platz zu kommen
-
- pointer_1: dw inline_text ;
- pointer_2: dw 0 ;
-
-
-
- ;****************************************************************;
- ;* *;
- ;* Bis hier die h{ufig ben|tigten *;
- ;* Unterprogramme. Es folgt die *;
- ;* Tabelle der Befehle und ihrer *;
- ;* Ansprungadressen. *;
- ;* *;
- ;****************************************************************;
-
-
- space_out: ld a,' ' ;gib ein Leerzeichen aus
- akku_out: push de ;gib Akku aus.
- push bc ;Die Register DE und BC werden
- ld e,a ;gerettet
- bdos console_out ;gib Zeichen }ber BDOS aus
- pop bc ;hole Register zur}ck
- pop de ;
- ret ;und zur}ck ins Hauptprogramm
-
- crlf_out: ld a,cr ;gib Carriage-return und Linefeed aus
- call akku_out ;
- ld a,lf ;
- jr akku_out ;
-
- prompt_out: ld bc,prompt ;gibt Promptmeldung aus
- crlf_bc_out: call crlf_out ;gib cr, lf und Text ab bc aus
- ab_bc_out: ld a,(bc) ;gib Text ab bc aus (bis 0)
- or a ;
- ret z ;
- ;cp ' ' ;ist es ein Ctrl-Zeichen?
- ;jr nc,normal_out ;nein
- ;ld a,'^' ;sonst graphisch darstellen
- ;call akku_out ;ausgeben
- ;ld a,(bc) ;erneut Zeichen holen
- ;add a,40h ;Upper case character
- normal_out: call akku_out ;
- inc bc ;
- jr ab_bc_out ;
-
- set_defdma: ld de,80h ;set default DMA address
- bdos set_dma_addr ;
- ret
-
- set_def_drive: ld a,(default_drive) ;setze Defaultlaufwerk
- set_drive: cp 255 ;schon gesetzt?
- current_drive equ $-1 ;wird hier geladen
- ret z ;wenn gleich, kein BDOS-Aufruf
- ld (current_drive),a ;neues Current-Drive
- ld e,a ;f}r BDOS
- bdos select_disk ;}ber RST 30H
- ld e,1 ;markiere 'other' f}r COPY
- ret ;
-
- open_seq: ld de,ccp_fcb ;|ffnet Datei zum sequentiellem Lesen
- open_fcb: ld c,open_file ;
- bdos_store_w0: xor a ;oder Schreiben.
- ld (ccp_fcb+12),a ;ex
- ld (ccp_fcb+14),a ;s2
- ld (ccp_fcb+32),a ;setze Record-Count im Extend auf 0
- bdos_store: call bdos_entry ;
- ld (result_byte),a ;speichere Ergebnis
- inc a ;wenn vorher 0ffh war,
- ret ;dann return mit Zero-Flag gesetzt
-
- sff_ccp_fcb: ld de,ccp_fcb ;default CCP FCB
- ld c,srch_for_first ;search for first
- jr bdos_store ;suche und speichere Ergebnis
-
- delete_ccp_fcb: ld de,ccp_fcb ;l|sche File ccp_fcb
- bdos delete_file ;Datei l|schen
- ret
-
- set_def_user: ld a,(default_user) ;setze Default-User
- set_user: cp 255
- current_user equ $-1 ;damit nicht unn|tig BDOS aufgerufen wird
- ret z
- ld (current_user),a ;abspeichern
- ld e,a ;setzte User (A)
- bdos set_get_user ;BDOS-Funktion
- ld e,1
- ret
-
- read_ccp_fcb: ld de,ccp_fcb ;lies sequentiell aus ccp_fcb
- read_seqf: bdos read_seq ;BDOS-Funktionscode
- or a ;Ergebnis?
- ret ;
-
- const_uchar: bdos get_con_status ;wurde eine Taste gedr}ckt?
- or a ;
- ret z ;keine Taste gedr}ckt
- conin: bdos console_in ;bedingungslos Taste einlesen
- or a ;or a, damit Status von const_uchar richtig
- ret
-
- get_user_line: ld a,1 ;lies neue Befehlszeile von Tastatur oder $$$.SUB
- submitflag equ $-1 ;wenn hier erst mal 0 drin ist, kein SUBMIT
- or a ;
- jr z,end_submit ;
-
- bdos set_dma_addr,inline_count ;da soll der Record hin
- ld de,sub_fcb ;lies neue Befehlszeile ein
- call open_fcb ;sieh nach, ob A:$$$.SUB existiert
- j≥ z,end_submit ;wenn nicht, l|sche Datei
- ld a,(sub_fcb+15) ;Datei existiert, hole Anzahl Records
- dec a ;-1 => letzte Recordnummer
- ld (sub_fcb+32),a ;abspeichern, wird als n{chstes gelesen
- ld de,sub_fcb ;Zeiger auf FCB
- call read_seqf ;und lesen...
- jr nz,end_submit ;End of file? dann l|schen
- ld hl,sub_fcb+14 ;
- ld (hl),0 ;(im Handbuch steht: "for system use")
- inc hl ;Anzahl Records
- dec (hl) ;einen weniger
- bdos close_file,sub_fcb ;Datei dichtmachen
- inc a ;hat geklappt?
- jr z,end_submit ;nein, dann l|sche A:$$$.SUB
- ld a,(echoflag) ;echo on or off?
- rrca ;bit 0 z{hlt
- jr nc,continue ;dann auch keine Abfrage, ob Taste gedr}ckt
-
- call prompt_out ;Prompt ausgeben
- ld bc,inline_text ;gib gelesene Zeile aus
- call ab_bc_out ;
- call const_uchar ;wurde Taste gedr}ckt?
- jr z,continue ;nein
- call del_subm ;ja, dann breche SUBMIT ab
- jp reentry ;und gehe in die Hauptschleife
-
- end_submit: call del_subm ;versuche, A:$$$.SUB zu l|schen
- call prompt_out
- ld de,inline_buffer
-
- bdos inline ;lies }ber BDOS von Tastatur ein
- ld hl,inline_count ;Z{hler eingelesene Buchstaben
-
- if r_enab ;R-enable
- ld a,(hl) ;
- dec a ;war Z{hler 1 ?
- jr nz,no_repeat ;wenn nicht, ist R nicht m|glich
- inc hl ;pointet auf erstes (einziges) Zeichen
- ld a,(hl) ;einlesen...
- dec hl ;Pointer zur}ck
- or ' ' ;CAPS=>lower
- cp 'r' ;R-Kommando?
- jr nz,no_repeat ;wenn nicht
- ld de,5201h ;vorl{ufig R<cr>
- repeatmem equ $-2 ;Initial value = R<cr>
- ld (inline_count),de ;und abgespeichert
- no_repeat:
- endif
- ld c,5fh ;convert to upper case
- ld b,(hl) ;nochmal die Anzahl der Zeichen
- inc b ;einen erh|hen f}r Abschlu~byte 00
- to_upper: inc hl ;Schleife, wandelt Zeile in Gro~buchstaben um
- ld a,(hl) ;n{chstes Zeichen
- cp 9 ;ist es ein Tabulator?
- jr nz,notab ;nein
- ld (hl),' ' ;sonst in Leerzeichen umwandeln,
- notab: cp 'a' ;da CCP allergisch gegen TABs ist
- jr c,next_conv ;wenn kleiner als a, keine [nderung
- cp 'z'+1 ;wenn gr|~er als z auch nicht
- jr nc,next_conv ;sondern n{chstes Zeichen
- and c ;to UPPER case
- ld (hl),a ;und abspeichern
- next_conv: cp '"'
- jr nz,next_conv2
- set 5,c
- next_conv2: djnz to_upper ;Schleife wiederholen bis Ende
- ld (hl),b ;b ist jetzt 0, schlie~t Zeile ab
-
- continue:
- if r_enab
- ld hl,(inline_count) ;hier steigt SUBMIT ein
- ld (repeatmem),hl ;neuer Wert f}r R<cr>
- endif
-
- ld hl,inline_text ;Zeiger initialisieren
-
- if c_enab ;Conditional enable
- ld a,(hl)
- sub '?' ;conditional line?
- jr nz,true_exec
- inc hl
- ld a,0
- return_code equ $-1
- or a
- jp nz,get_user_line
- endif
-
- true_exec: ld (pointer_1),hl ;
- ret ;und zur}ck
-
- del_subm: ld hl,submitflag ;pr}fe, ob A:$$$.SUB schon gel|scht ist
- xor a ;
- cp (hl) ;na?
- ret z ;jawoll!
- ld (hl),a ;sonst wird es jetzt getan
- bdos delete_file,sub_fcb;FCB daf}r
- ret
- no_error: cp a
- ret
- test: ld a,(de) ;pr}fe Zeichen auf G}ltigkeit f}r Dateinamen
- or a ;Ende der Zeile?
- ret z ;ja
- cp ' ' ;space?
- jp c,no_error ;Controlsequenzen sind nicht erw}nscht
- ret z ;zero auch bei space
- exx ;save Registers
- ld b,18 ;Anzahl der ung}ltigen Zeichen
- ld hl,char_tabelle ;
- check_char: cp (hl) ;
- jr z,invalid_ch ;
- inc hl ;
- djnz check_char ;
- exx ;
- or a ;
- ret ;valid characters
- invalid_ch: exx ;wieder alten Registersatz
- ret ;mit ZERO Flag
-
-
-
- get_next_ptr: ld hl,(pointer_1) ;da war er vorher gespeichert
- get_next_hl: ld a,(hl) ;erstes Zeichen
- or a ;wenn Zeilenende,
- ret z ;dann return
- cp ' ' ;wenn space,
- ret nz ;dann weitersuchen, bis Space gefunden
- inc hl ;dazu Pointer erh|hen
- jr get_next_hl ;
-
- setup_fcb: ld de,ccp_fcb ;Default FCB
- setup_fcb_de: push de ;FCB Beginn
- xor a ;jetzt Default-Drive
- ld (de),a ;in FCB-Drivefeld
- call get_next_ptr ;erhasche erstes Zeichen des Namens
- ld (pointer_2),hl ;f}r Error-Ausgabe
- ex de,hl ;
- jr z,fill_fcb ;war garnichts
- inc de ;
- ld a,(de) ;zweites Zeichen
- dec de ;
- cp ':' ;Laufwerksangabe?
- jr nz,fill_fcb ;nein
- ld a,(de) ;ist eine Laufwerkangabe
- sub 'A' ;
- cp 'P' ;
- jr nc,fill_fcb ;falsche Laufwerkangabe wird ignoriert
- inc de ;zeigt jetzt auf ':'
- inc de ;
- inc a ;
- ld (hl),a ;
-
- fill_fcb: ld b,8 ;8 Characters Filename
- call UP2 ;generieren
- ld b,3 ;3 Characters Fileextension
- call UP2a ;generieren (aber . anders behandeln)
-
- ld b,3 ;setze diverse Z{hler auf 0
- set_0: inc hl ;
- ld (hl),0 ;
- djnz set_0 ;
-
- ld (pointer_1),de ;weiter geht's beim ersten Byte hinter dem Namen
- pop hl ;nochmal FCB Adresse
-
- ld bc,11*256 ;z{hle ? im FCB
- ld a,'?' ;
- count_wildcart: inc hl ;
- cp (hl) ;ist es Fragezeichen?
- jr nz,test_next ;
- inc c ;Z{hler erh|hen
- test_next: djnz count_wildcart ;next one
- ld a,c ;Anzahl
- or a ;ZERO-Flag richtig setzen
- ret ;und zur}ck
-
- UP2a: cp '.'
- jr nz,fill_space
- inc de
- UP2: call test
- jr z,fill_space
- inc hl
- cp '*'
- jr nz,not_all
- ld (hl),'?'
- jr next_x
- not_all: ld (hl),a
- inc de
- next_x: djnz UP2
- cp '*'
- jr nz,ignore_rest ;es fehlt noch inc de
- inc de
- ignore_rest: call test
- ret z ;ok, nichts mehr an Buchstaben da
- jp error ;weil zu lang!
- fill_space: inc hl ;Rest des Teiles mit space f}llen
- ld (hl),' '
- djnz fill_space
- ret
-
- ;****************************************************************;
- ;* *;
- ;* ZDOS Entry-Point *;
- ;* bei cold_entry wird die im Buffer *;
- ;* befindliche Kommandozeile ausgef}hrt *;
- ;* *;
- ;****************************************************************;
- ;
- warm_entry: xor a ;Anzahl der Zeichen im
- ld (inline_count),a ;Buffer auf 0 setzen
- ;
- cold_entry: ld sp,stacktop ;hat eigenen Stack
- push bc ;Usernummer/Disknummer
- ld a,c ;Drive Nr.
- ld (4),a ;in Defauldrive speichern
- rra ;
- rra ;
- rra ;
- rra ;
- and 00001111b ;Drivenummer ausblenden
- ld (default_user),a ;und merken
- call set_user ;dem BDOS Usernummer mitteilen
- ;und auch selber merken
- bdos disk_reset ;Drive A=Online
- pop bc ;Usernummer/Disknummer
- ld a,c ;
- and 00001111b ;nur die Laufwerknummer selektieren
- ld (default_drive),a ;und merken
- call set_drive ;f}r das BDOS
- ;
- ld a,(inline_count) ;pr}fe, ob Startup-Kommando ausgef}hrt
- or a ;werden mu~
- jr nz,common ;wenn Buffer gef}llt
- ;
- reentry: ld sp,stacktop ;Neuinitialisation Stack
- ld hl,new_drive
- ld a,(hl)
- ld (hl),0
- or a
- jr z,reentry_nodrv
- dec a
- ld (default_drive),a
- call set_drive
- reentry_nodrv: ld a,0 ;set Byte (4) correct
- default_user equ $-1
- ld c,a ;merken
- rlca
- rlca
- rlca
- rlca
- ld b,a
- ld a,0
- default_drive equ $-1
- or b
- ld (4),a
- and 00001111b ;wieder nur Default-Disklaufwerk
- ld hl,prompt ;prompt string
- add a,'A' ;Offset zum ASCII-Code
- ld (hl),a ;und ausgeben
- inc hl ;Pointer erh|hen
- ld a,c ;Default-Usernummer
- cp 10 ;zweistellig?
- jr c,einstellig ;
- sub 10 ;dann zieh Rest auch ab
- ld (hl),'1' ;speichere einen Zehner
- inc hl ;Pointer + 1
- einstellig: add a,'0' ;Offset ASCII
- ld (hl),a ;und ausgeben
- inc hl ;jetzt letztes Zeichen
- ld (hl),'>' ;noch ein Teil des Prompts
- inc hl
- ld (hl),0
- call get_user_line ;Eingabe einer Kommandozeile von
- ;Keyboard oder SUBMIT-File
- common: ld a,(7) ; bottom RSM or BDOS
- cp high(ccp)
- jr c,rsm_exist
- ld a,high(ccp) ; CCP is lower
- rsm_exist: ld h,a
- ld l,0
- ld (TPA_top),hl ; store it!
- call set_def_drive
- call set_def_user
- ld hl,error ;h{ufigstes Ansprungziel auf den Stack
- push hl
- call set_defdma ;setze Default DMA Adresse
- call setup_fcb ;generiere Dateinamen
- ret nz ;if * or ? in Filename => ERROR
-
- ld (tail_beginn),de ;Beginn der restl. Kommandozeile
- ld hl,ccp_fcb+9 ;wurde Fileextension eingegeben?
- ld a,(hl)
- cp ' '
- ret nz ;wenn ja, error
- ld (hl),'C' ;sonst ist sie COM
- inc hl
- ld (hl),'O'
- inc hl
- ld (hl),'M'
-
- ld a,(ccp_fcb) ;wurde lfw: angegeben?
- or a ;wenn ja, kann es nur
- jp nz,TRANSIENT ;ein transientes Programm sein
-
- ld hl,tabelle ;pr}fe, ob ein eingebautes Kommando vorliegt
- next_command: ld e,(hl) ;als erstes steht Zieladresse
- inc hl ;auf dem Stack
- ld d,(hl)
- inc hl
- push de
- xor a ;Test, ob Ende der Tabelle
- cp (hl) ;wenn Befehl mit 00 beginnt
- ret z ;auf dem Stack ist Adresse
- ld (beginn_name),hl
- ld de,ccp_fcb+1 ;Beginn des Namens
- ld b,4 ;L{nge Kommando
- vergleiche: ld a,(de) ;eingegebenes Zeichen
- cp (hl) ;= verlangtem Zeichen?
- jr nz,onefail ;nein
- inc hl ;sonst restliche Zeichen pr}fen
- inc de ;dazu Pointer erh|hen
- djnz vergleiche ;und Vergleich wiederholen
- ld a,(de) ;der Rest des FCB mu~ space sein
- cp ' '
- pop de ;R}ckkehradresse
- jr nz,next_command
- push de ;wird doch ben|tigt
- jp setup_fcb ;da meist gebraucht, danach ins Programm
-
- onefail: inc hl ;Kommando sah anders aus
- djnz onefail ;Pointer updaten
- pop de ;Ansprungadresse
- jr next_command ;und n{chstes versuchen
-
- test_end_ptr: ld hl,(pointer_1) ;Anfang letzter Bytefolge
- test_end_hl: call get_next_hl ;n{chstes Zeichen
- ret z ;mu~ 00 sein
- jr error_hl ;sonst ERROR
-
- error: ld hl,(pointer_2)
- error_hl: ld c,l
- ld b,h
- error_bc: call crlf_bc_out
- ld a,'?'
- call akku_out
- call del_subm
- xor a
- ld (new_drive),a
- jp reentry
-
- only_this: call test_end_ptr ;darf kein zweiter FCB folgen
- test_lfw_ext: ld hl,ccp_fcb ;da steht die Zahl drin
- ld a,(ccp_fcb+9) ;"file extension"
- sub ' ' ;sollte jetzt 0 sein
- or (hl) ;Drive sollte Default sein
- jr nz,error ;sonst Error
- inc hl ;auf ccp_fcb+1
- ret ;so ist es OK
-
- get_number: call test_lfw_ext ;reine Zahl erw}nscht
- ld c,a ;steht 0 drin...
- ld a,(hl) ;get digit
- next_digit: sub '0'
- cp 10
- jr nc,error
- ld b,a
- ld a,c
- cp 26 ;schon mehr ?
- jr nc,error ;weil beim multiplizieren ]bertrag ent-
- add a,a ;stehen w}rde
- ld c,a
- add a,a
- add a,a
- add a,c ;Akku := Akku * 10
-
- add a,b ;jetzt die neue Ziffer dazu!
- jr c,error
- ld c,a
- inc hl
- ld a,(hl)
- cp ' '
- ret z
- or a
- jr nz,next_digit
- ret ;return number in c
-
- loadprog: ld hl,100h
- TR2: push hl
- ex de,hl
- bdos set_dma_addr
- ld de,ccp_fcb
- call read_seqf
- pop hl
- ret nz
- ld de,0080h
- add hl,de
- ld a,(TPA_top+1)
- cp h
- jr nz,TR2
- bad_load: ld bc,text_bad_load
- jp exit_with_print
-
- ;=======================================;
- ; ;
- ; C O P Y ;
- ; ;
- ;=======================================;
-
- COPY: call collect
- loopcopy: call end_files_test
- push de
- call set_drv_usr ;to selected
- call open_seq
- call loadprog ;load file into memory
- push hl ;HL is Maxmem+1
- call set_def_drive
- call set_def_user
- pop hl
- call saveupro ;write it back a la save
- pop de
- jr loopcopy
-
- ;=======================================;
- ; ;
- ; P A T H ;
- ; ;
- ;=======================================;
-
- PATH: call only_this ;darf nichts folgen und
- ;darf weder Laufwerk noch extension
- ld a,(hl) ;angegeben sein
- cp ' '
- ld bc,pathtab
- jr z,exit_with_print
- ld e,c
- ld d,b
- ld bc,7
- pathloop: cp 40h ;n{chstes Zeichen
- ret c ;Error, wenn kein Buchstabe
- cp 'P'+1
- ret nc
- ldi
- xor a
- ld (de),a ;erst mal beenden...
- ld a,(hl) ;ein weiteres
- cp ' '
- jr nz,pathloop ;weiter geht's
- inc c
- ret z ;wenn es 8 Zeichen waren
- to_reentry2: jp reentry
-
- ;
- ;===============================================
- ;
- bad_drive: ld bc,bad_drive_txt
- exit_with_print:call crlf_bc_out
- jp to_reentry2
-
- set_drv_usr: ld e,0 ;modify-Flag
- ld a,0
- temp_user equ $-1
- call set_user ;anderer als Defaultuser
-
- ld a,(temp_drive) ;
- jp set_drive ;auch anderes Drive
-
- collect: ld a,(default_user)
- ld (temp_user),a ;temporary User
- call get_next_ptr
- cp '/'
- ld de,20h ;jr nz,...
- ld c,0 ;User number
- jr nz,opt_end
- ld (pointer_2),hl
- next_opt: inc hl
- ld a,(hl)
- and 11011111b ;00 oder Spaces
- jr z,opt_end ;nix mehr
- and 11111001b ;Test auf Q, S, U, W
- cp 'Q'
- ld a,(hl)
- jr nz,must_be_digit ;sonst error
- rrca
- and 3
- ld b,a
- inc b
- ld a,40h
- turn: rlca
- djnz turn
- or d
- ld d,a
- jr next_opt
-
- must_be_digit: call next_digit ;versuche, eine Usernummer einzulesen
- or a
- jp nz,error ;Ende
- ld a,c
- cp 16
- jp nc,error
- ld (temp_user),a
- opt_end: call test_end_hl ;darf nichts mehr folgen
- ld a,d
- rrca ;S=>Carry
- jr nc,not_only_sys
- ld e,28h ;jr z,off
- not_only_sys: rrca ;U=>Carry
- jr nc,not_only_user ;
- ld e,3eh ;ld a,...
- not_only_user: ld a,e
- ld (jpselect),a
- ld a,d
- ld (option_bits),a ;Q und W
-
- ld hl,ccp_fcb
- ld a,(hl)
- dec a
- jp p,other_drive
- ld a,(default_drive)
- other_drive: ld (temp_drive),a
- ld (hl),0
- inc hl
- ld de,(beginn_name) ;Pointer auf ersten Buchstaben des Commandos
- ld a,(hl)
- cp ' '
- ld a,(de)
- jr nz,isn_all
- cp 'E' ;era?
- jp z,error ;einfach ERA geht nicht
- ld b,11
- loop: ld (hl),'?'
- inc hl
- djnz loop
- isn_all: push af ;Copy?
- call set_drv_usr
- pop af
- sub 'C'
- jr nz,no_eq_test
- or e ;wurde umgeschaltet?
- jp z,bad_drive
-
- no_eq_test: call set_drv_usr
-
- call sff_ccp_fcb
- jr z,none_found
- ld de,0
- TPA_top equ $-2
- dec de ;load names below ZDOS or RSM
- collectloop: ld a,d
- or a
- ld bc,no_room_text
- jp z,exit_with_print ;raus und melden
- enough_space: ld a,0
- result_byte equ $-1
- rrca
- rrca
- rrca
- add a,80h+10 ;2.last char of filename
- ld l,a
- ld h,0
- bit 7,(hl)
- jpselect: jr nz,noaccept
- inc l
- ld a,0
- option_bits equ $-1 ;evtl fragen, ob }berhaupt...
- rlca ;Bit 7(Q) => Carry
- jr nc,take_it
- push de
- push hl
- ld de,-10 ;zeigte vorher auf 11.Zeichen
- add hl,de ;hl jetzt Pointer auf Filename
- call crlf_file_out ;Dateinamen ausgeben
- call space_out
- ld de,0
- beginn_name equ $-2 ;dir, era, copy, type
- ld bc,0401h
- call fno2 ;ausgeben
- ld bc,q_mark
- call ab_bc_out
- askkill: call conin
- cp 3
- jp z,reentry
- and 0dfh ;to upper
- pop hl
- pop de
- cp 'Y'
- jr z,take_it
- cp 'N'
- jr z,noaccept
- cp 'G'
- jr z,go_copy
- push de
- push hl
- jr askkill
-
- take_it: ld bc,11
- lddr
- noaccept: push de
- ld c,srch_for_next
- call bdos_store
- pop de
- jr nz,collectloop
- go_copy: ;hier moeglichkeit, dateien zu sortieren...
- inc de
- ld a,(TPA_top+1)
- cp d
- ret nz
- none_found:
- no_file: ld bc,no_file_text
- call crlf_bc_out
- jp reentry
- end_files_test: ld a,(TPA_top+1)
- cp d
- jp z,reentry
- push de
- ex de,hl
- ld de,ccp_fcb+1
- ld bc,11
- ldir
- ex (sp),hl
- call crlf_file_out
- pop de
- ret
-
- crlf_file_out: ex de,hl
- call crlf_out
- filename_out: ld bc,0802h ;ab de, de nach auf 1 Zeichen sp{ter
- fno2: ld a,(de)
- inc de
- rein: call akku_out
- djnz fno2
- dec c
- ret z
- ld b,4
- ld a,'.'
- jr rein
-
- ;=======================================;
- ; ;
- ; E C H O ;
- ; ;
- ;=======================================;
-
- ECHO: call only_this ;kein zweiter FCB
- ld b,(hl) ;darf nur Y oder N folgen
- inc hl
- ld a,(hl) ;zweites Zeichen mu~ space sein
- cp ' '
- ret nz
- ld a,b ;erstes Zeichen
- cp 'Y' ;erstes Zeichen
- jr z,echo_on
- sub 'N'
- ret nz ;weder Y noch N
- echo_on: ld (echoflag),a
- to_reentry3: jp reentry
-
- ;=======================================;
- ; ;
- ; E X I T ;
- ; ;
- ;=======================================;
-
- EXIT: call del_subm ; l|sche nur $$$.SUB
- jr to_reentry3 ; sonst nichts
-
- ;=======================================;
- ; ;
- ; E R A ;
- ; ;
- ;=======================================;
-
- ERA: call collect
- kill_loop: call end_files_test
- push de
- call delete_ccp_fcb
- pop de ;pointer next file
- jr kill_loop
-
- ;=======================================;
- ; ;
- ; D I R ;
- ; ;
- ;=======================================;
-
- zeilcount: db 0
- DIR: call collect
- ld a,1
- ld (zeilcount),a
- dirloop: ld a,(TPA_top+1)
- cp d
- jp z,to_reentry3
- ld hl,zeilcount
- dec (hl)
- ld a,' '
- jr nz,no_newline
- ld (hl),5
- call crlf_out
- ld a,0
- temp_drive equ $-1
- add a,'A'
- no_newline: call akku_out
- ld a,':'
- call akku_out
- call space_out
- call filename_out
- jr dirloop
-
- ;=======================================;
- ; ;
- ; U S E R ;
- ; ;
- ;=======================================;
-
- USERa: call setup_fcb ;alternate USER-Befehl = /nn
- USER: call test_end_ptr ;nach Usernummer Schlu~
- call get_number
- ld a,c
- cp 16
- ret nc
- ld (default_user),a
- call set_user
- jp reentry
-
- ;=======================================;
- ; ;
- ; S A V E ;
- ; ;
- ;=======================================;
-
- SAVE: call get_number
- ld h,c
- ld l,0
- inc h
- push hl ;maxmem+1
- call setup_fcb
- jp nz,error
- call test_end_ptr
- pop hl
- call saveupro
- jp reentry
-
- saveupro: push hl
- call delete_ccp_fcb
- ld de,ccp_fcb
- ld hl,ccp_fcb+9 ;1.char Extension
- res 7,(hl) ;reset R/O-Bit
- ld c,make_file ;make FCB
- call bdos_store_w0
- jr z,no_space
- ld de,100h ;start TPA
- SAVE1: pop hl ;maxmem+1
- push hl
- or a
- sbc hl,de ;=jetzige DMA?
- jr z,save_close ;dann Schlu~!
- ld hl,80h
- add hl,de
- push hl
- bdos set_dma_addr
- bdos write_seq,ccp_fcb
- or a
- pop de
- jr z,SAVE1
- bdos close_file,ccp_fcb
- no_space: ld bc,no_space_text
- jp exit_with_print
-
- save_close: pop hl
- bdos close_file,ccp_fcb
- inc a
- jr z,no_space
- jp set_defdma
-
- ;=======================================;
- ; ;
- ; T Y P E ;
- ; ;
- ;=======================================;
-
- MORE: call collect ;damit ZERO-Flag richtig bleibt
- push de
- drucke: xor a
- ld (linecount),a
- pop de
- call end_files_test
- push de
- call open_seq
- call crlf_out
- DRUCKE1: call read_ccp_fcb
- jr nz,drucke
- ld bc,80h
- DRUCKE2: ld a,(bc)
- cp 1ah ;EOF
- jr z,drucke
-
- push bc
- cp lf
- jr nz,DRUCKE3
-
- ld hl,option_bits ;anhalten?
- bit 2,(hl)
- jr z,continuous ;nein!
- ld a,0
- linecount equ $-1
- dec a
- jp m,page_end
- ld (linecount),a
- jr DRUCKE3a
-
- page_end: ld bc,more_text
- call crlf_bc_out
- call conin
- cp 3
- jp z,reentry
- cp cr
- jr z,one_weiter
- pop bc
- cp '.' ;next File?
- jr z,drucke
- push bc
- ld a,21 ; else next page
- ld (linecount),a
- one_weiter: ld bc,un_more
- call ab_bc_out
- jr DRUCKE3b ;da ab_bc_out Steuerzeichen umwandelt
-
- continuous: ;call const_uchar ;disabled, da }ber BDOS-Statusabfrage
- ;jp nz,reentry ;^S, ^C m|glich ist!
- DRUCKE3a: ld a,lf
- DRUCKE3: call akku_out
- DRUCKE3b: pop bc
- inc c
- jr nz,DRUCKE2
- jr DRUCKE1
-
- ;=======================================;
- ; ;
- ; R E N ;
- ; ;
- ;=======================================;
-
- REN: ret nz ;war ambiguous Filename
- call get_next_ptr ;jetzt mu~ das '='-Zeichen folgen
- cp '=' ;ist es das?
- ret nz ;sonst ERROR
- inc hl ;Pointer updaten
- ld (pointer_1),hl ;
-
- call sff_ccp_fcb ;existiert Soll-Name?
- ld bc,text_exists ;"File exists"
- jp nz,exit_with_print ;ausschreiben und weg
- ld hl,ccp_fcb ;sonst in Feld 2 schieben
- ld de,ccp_fcb+16 ;
- ld bc,16 ;
- ldir ;
- call setup_fcb ;zweiten Dateinamen holen
- ret nz ;ambiguous file name
-
- call test_end_ptr ;ist jetzt Schlu~?
-
- ld hl,ccp_fcb
- ld a,(ccp_fcb+16)
- or a
- jr z,drive_ok
- cp (hl)
- jr z,drive_ok
- push af
- xor a
- or (hl)
- jp nz,bad_drive
- pop af
- ld (hl),a
- drive_ok: call sff_ccp_fcb
- jp z,no_file
- ld de,ccp_fcb
- bdos rename_file
- jp reentry
-
- ;=======================================;
- ; ;
- ; Transientes Programm laden ;
- ; ;
- ;=======================================;
-
- TRANSIENT: ld a,(ccp_fcb+1) ;Feld f}r erstes Zeichen des Programmnamens
- sub ' '
- jr nz,program
- ld hl,ccp_fcb ;Drive Code
- or (hl) ;auch gleich 0?
- jr z,comment ;dann nur <Enter> gedr}ckt
- ld (new_drive),a
- comment: call get_next_ptr
- jr z,to_reentry
- inc hl
- ld (pointer_1),hl
- cp '/' ;alternate USER-Befehl
- jp z,USERa
- sub '"'
- ret nz ;dann ERROR
- ld a,(echoflag) ;ECHO on
- rrca
- ld b,h
- ld c,l
- call nc,crlf_bc_out
- to_reentry: jp reentry
-
- program: ld hl,(pointer_1)
- ld a,(hl)
- sub '/' ;Option?
- jr nz,no_user_nr
- inc hl
- ld c,a ;0
- call next_digit-1
- ld (pointer_1),hl
- ld (tail_beginn),hl
- ld a,c
- cp 16
- ret nc ;zu gro~
- call set_user
- no_user_nr: ld de,pathtab
- ld a,(ccp_fcb)
- or a
- jr z,loadloop ;suche auf Laufwerken
- ld de,pathtab+7 ;Pointer auf 0
- jr reinload
- loadloop: ld a,(de)
- sub 40h
- ret c ;nicht Syntax, sondern File nicht existent
- inc de
- ld (ccp_fcb),a
- reinload: push de
- call open_seq
- pop de
- jr z,loadloop
- call loadprog ;load progam into mem
- call set_def_user
- call setup_fcb
- GO: ld de,ccp_fcb+16
- call setup_fcb_de
- xor a
- ld (ccp_fcb+32),a
- ld de,deffcb
- ld hl,ccp_fcb
- ld bc,21h
- ldir
-
- ld hl,0
- tail_beginn equ $-2
- ld de,81h ;ab da wird Command-Tail gespeichert
- transfer2: cp (hl) ;a ist noch 0
- ldi ;}bertrage
- jr nz,transfer2 ;n{chstes Byte
- end_tr: ld a,e
- sub defdma+2 ;L{nge des Restes
- ld (defdma),a ;abspeichern
- call crlf_out ;Zeilenvorschub
- call set_defdma ;Default DMA setzen
- pop af ;Error-Adresse
- call 100h ;starte Programm
- if c_enab
- ld (return_code),a
- endif
- ld a,255
- ld (current_user),a ;User now undefined
- ld (current_drive),a ;Drive auch
- jp reentry ;Hauptschleife
-
- tabelle: ;Tabelle der eingebauten Kommandos und ihrer Ansprung-
- ;Adressen
-
- dw DIR
- db 'DIR '
- dw ERA
- db 'ERA '
- dw MORE
- db 'TYPE'
- dw SAVE
- db 'SAVE'
- dw REN
- db 'REN '
- dw COPY
- db 'COPY'
- dw GO
- db 'GO '
- dw PATH
- db 'PATH'
- dw ECHO
- db 'ECHO'
- dw EXIT
- db 'EXIT'
-
- ; dw USER ; must go in favour of 'UNIX'
- ; db 'USER'
- dw cbios ; simply cold boot
- db 'UNIX'
-
- dw TRANSIENT
- db 0 ;Ende der Tabelle
-
- prompt: db 'A15>',0 ;Prompt String
- char_tabelle: db '"<>.,;:=[\]_%|()/',7fh ;
- bad_drive_txt: db 'Bad Drive',0
- no_file_text: db 'No File',0
- no_room_text: db 'List full',0
- more_text: db '<More>',0
- un_more: db cr,tab,cr,0
- no_space_text: db 'No Space',0
- text_bad_load: db 'Bad load',0
- text_exists: db 'File exists',0
-
- q_mark: db ' it? ',0
- new_drive: db 0
- ift $ gt bdos-33-22 ;das letzte ist Stack Space
- .printx $ FATAL: ZDOS Module too big!! $
- endif
- sub_fcb: db 1,'$$$ SUB'
- fill bdos-6-$,0 ;runde auf
- .dephase
- end
-