org #0100 nolist write "patch22.com" ; ; ------ >>> Labeldefinitionen <<< ----------------- ; wboot equ #0000 ;Warmstart bdos equ #0005 ;BDOS-Entry ; ; ------ >>> CP/M Version pr}fen <<< --------------- ; ld c,12 ;CP/M Version ermitteln call bdos ld a,l cp #22 ld de,notcpm2 ;Zeiger auf Fehlermeldung jp nz,prt_msg ;Springe wenn nicht CP/M 2 ; ; ------ >>> Initialisierung <<< ------------------- ; ; In dieser Schleife wird, ausgehend vom Warmstart ; Einsprung bei #0000, die CALLSYS-Adresse gesucht. ; Beim 'kleinen AMSDOS' CP/M ist dies z.B. #AD33. ; Die Adresse wird je nach DOS-Version und CP/M Gr|~e ; automatisch richtig ermittelt. Der SYSCALL-Entry ; wird dann hinter die CALLs bei 'ERROFF' & 'ERROLD' ; geschrieben. ; ld hl,(#0001) ld de,#0018 add hl,de search ld a,(hl) inc hl cp #cd ;Ist es ein CALL ? call ld_hlhl jr nz,search ;Nein, dann weiter ; ld (erroff+3),hl ld (errold+3),hl ; ; ------ >>> Programmstart <<< --------------------- ; call erroff ;Fehlermeldungen aus ; ld de,header ;Zeiger auf Meldung call prt_msg ;Einschaltmeldung ausgeben ; ; ------ >>> Destination-Laufwerk ausw{hlen <<< ---- ; nxtdisc ld a,#02 call locate ld de,seldest call prt_msg selectd call get_key and #df ;Shift to Upper-Case cp "A" jr c,selectd cp "B"+1 jr nc,selectd ; ld (destdrv),a sub "A" ld (drive+1),a ; ; ------ >>> Destination-Diskette verlangen <<< ---- ; ld a,#02 baddest call locate ld de,askdest ld hl,wrteerr call askdisc ld a,#03 jr c,baddest ; ; ------ >>> Bootspur beschreiben <<< -------------- ; ld de,#0000 ;Track 0, Record 0 -> 'DE' ld hl,puffer ;Puffer-Adresse -> 'HL' ld b,#00 ld c,d ;Track-Nummer -> 'BC' call settrk ;Track-Nummer setzen wr_loop ld b,#00 ld c,e ;Sector-Nummer -> 'BC' call setsec ;Sector-Nummer setzen ld b,h ld c,l ;DMA-Adresse -> 'BC' call setdma ;DMA-Adresse setzen ld c,#01 ;#01 => nondeferred write ld a,e ;Der letzte Sector wird cp 27 ; sofort ( nondeferred ) jr z,last_wr ; geschrieben ( flush ) dec c ;#00 => deferred write last_wr call wr_sec ;Sector schreiben ld a,#03 jr c,baddest ;Neuer Versuch bei Fehler ld bc,#0080 ;Pufferadresse um Record- add hl,bc ; l{nge erh|hen inc e ;Sector-Nummer erh|hen ld a,e cp 28 ;Alle Sectoren geschr. ? jr c,wr_loop ;Nein, dann n{chsten Sec. ; ld de,clrline call prt_msg ; ; ------ >>> Nochmal schreiben ? <<< --------------- ; ld a,#02 call locate ld de,again call prt_msg call get_key and #df ;Shift to Upper-Case cp "Y" jp z,nxtdisc ; ; ------ >>> Programm beenden <<< ------------------ ; endprog ld de,finish ;Zeiger auf Meldung jp exit ; ; ------ >>> Diskette anfordern <<< ---------------- ; askdisc push hl ;Fehlertext-Zeiger merken call prt_msg call get_key pop de ;Fehlertext-Zeiger -> 'DE' ; ; ------ >>> Laufwerk einloggen <<< ---------------- ; ; Die in Laufwerk A eingelegte Diskette wird angemel- ; det. Wenn das Carry-Flag beim R}cksprung gel|scht ; ist, war das Einloggen erfolgreich. ; login push de ;Fehlertext-Zeiger merken ld e,#00 ;LOGIN-Flag l|schen drive ld c,$-$ ;Laufwerk x anw{hlen ld hl,#0018 ;Offset f}r SELDSK call jp_bios ;Laufwerk anw{hlen pop de ;Fehlertext-Zeiger -> 'DE' ld a,h ;Wurde das Laufwerk or l ; erfolgreich angew{hlt ? jr z,baddisk ;Read/Write-Error ausgeben ld de,#000a ;Offset f}r DPB-Zeiger add hl,de call ld_hlhl ;DPB-Start -> 'HL' ld a,(hl) ;Records per Track -> 'A' cp 4*9 ;9 Sectoren pro Track ? jr nz,nosystr ;Nein, dann illegal format ld de,#000d ;Offset f}r Systemspuren add hl,de ld a,(hl) ;Anzahl Systemspuren-> 'A' cp 2 ;2 Systemspuren ? ret z ;Ja, dann RET mit No Carry ; nosystr ld de,badform ;Zeiger auf Fehlermeldung baddisk ld a,#02 call locate call prt_msg ;Fehlermeldung ausgeben scf ;Carry gesetzt => Fehler ret ; ; ------ >>> Track setzen <<< ---------------------- ; settrk push de push hl ld hl,#001b ;Offset f}r SETTRK call jp_bios pop hl pop de ret ; ; ------ >>> Sector setzen <<< --------------------- ; setsec push de push hl ld hl,#001e ;Offset f}r SETSEC call jp_bios pop hl pop de ret ; ; ------ >>> DMA-Adresse setzen <<< ---------------- ; setdma push de push hl ld hl,#0021 ;Offset f}r SETDMA call jp_bios pop hl pop de ret ; ; ------ >>> Record schreiben <<< ------------------ ; wr_sec push de push hl ld hl,#0027 ;Offset f}r WRITE call jp_bios ; and a ;Ohne Fehler geschrieben ? jr z,wrte_ok ;Ja, dann RET mit No Carry ; ld a,#02 call locate ld de,wrteerr ;Zeiger auf Fehlermeldung call prt_msg ;Fehlermeldung ausgeben scf ;Carry gesetzt => Fehler ; wrte_ok pop hl pop de ret ; ; ------ >>> BIOS Funktion aufrufen <<< ------------ ; jp_bios push de ex de,hl ;Offset -> 'DE' ld hl,(#0001) add hl,de pop de jp (hl) ; ; ------ >>> Lade 'HL' aus 'HL' und 'HL+1' <<< ----- ; ld_hlhl ld a,(hl) inc hl ld h,(hl) ld l,a ret ; ; ------ >>> Auf eine Taste warten <<< ------------- ; get_key ld hl,#0006 ;Offset f}r CONIN call jp_bios ;Taste lesen cp #03 ;CTRL-C ? ret nz ;Nein, dann RET ; ; ------ >>> Abbruch durch CTRL-C <<< -------------- ; ctrl_c ld de,aborted call prt_msg ld de,abandon ; ; ------ >>> Programm verlassen <<< ---------------- ; exit push de ;Zeiger auf Meldung merken ld de,askcpm ;CP/M Diskette call prt_msg ; verlangen call errold ;Altes Fehlerflag setzen ld hl,#0006 ;Offset f}r CONIN call jp_bios ;Auf Taste warten pop de ;Zeiger auf Meldung-> 'DE' call prt_msg jp wboot ;CP/M Warmstart ; ; ------ >>> ( Fehler- ) Meldung ausgeben <<< ------ ; prt_msg ld c,9 ;Textstring ausgeben jp bdos ; und zur}ck zum CCP ; ; ------ >>> Error-Messages abschalten <<< --------- ; erroff ld a,#ff ;#FF=> Fehlermeldungen aus call $-$ defw #be80 ld (errold+1),a;Alten Zustand merken ret ; ; ------ >>> Altes Error-Flag wieder setzen <<< ---- ; errold ld a,$-$ ;Altes Error-Flag -> 'A' call $-$ defw #be80 ret ; ; ------ >>> Locate <<< ---------------------------- ; ; Der Cursor wird in die durch den Akku angegebenen ; Zeile ( relativ zur Titelzeile ) gebracht. ; locate ld c,#00 ;Aktuelle Zeile -> 'C' cp c ;Gew. Zeile = aktuelle ? ret z ld (locate+1),a;Gew}nschte Zeile merken sub c ;Differenz bilden ld c,#0a ;LF -> 'C' jr nc,go_down ;Springe wenn 'DOWN' inc c ;VT -> 'C' neg go_down ld b,a ;Zeilendifferenz -> 'B' upordwn push bc ;Z{hler und Zeichen merken ld hl,#0009 ;Offset f}r CONOUT push de call jp_bios ;Zeile h|her/tiefer pop de pop bc ;Z{hler und Zeichen holen djnz upordwn ;N{chste Zeile ret ; ; ------ >>> ( Fehler- ) Meldungen <<< ------------- ; notcpm2 defb #07,#0a,#0d defm "Error: Requires CP/M 2.2" defb #0a,#0d,"$" ; header defb #0a,#0d defm "PATCH22 V1.0$" ; seldest defb #0d defm "Modify disc in drive (A or B) ? :_" defb #12,"$" ; badform defb #07,#0d defm "Disc has illegal format" defb #12,"$" ; askdest defb #0d defm "Please insert DESTINATION" defm " disc into drive " destdrv defb "A" defm " then press any key:_" defb #12,"$" ; wrteerr defb #07,#0d defm "A write error occured" defm #12,"$" ; aborted defb #0a,#0a,#0d defm "^C...aborted$" ; askcpm defb #0a,#0a,#0d defm "Please insert a CP/M system disc" defm " into drive A then press any key:_$" ; abandon defb #0a,#0a,#0d defm "PATCH22 V1.0 abandoned" defb #0a,#0d,"$" ; finish defb #0a,#0a,#0d defm "PATCH22 V1.0 finished" defb #0a,#0d,"$" ; again defb #0d defm "Do you wish to reconfigure" defm " another disc (Y/N) ? :_" defb #12,"$" ; clrline defb #0d,#12,"$" ; ; ------ >>> DMA-Puffer f}r Bootspur <<< ----------- ; puffer equ $