	PAGE 70
	.comment #

	RCVASCII.MAC

	24.09.85

empfaengt ASCII-Files ueber die SIO-A und legt sie als Disk-File ab.
Der Empfang erfolgt zeilenweise bis CR/LF. Nach CR/LF wird optional ein 
Acknowledge/Not Acknowledge (Hex 06/15) gesendet, jenachdem ob die Zeile
fehlerfrei erkannt wurde oder nicht.
Falls ein Fehler auftrat, wird die Zeile nochmal empfangen.
Die Zeilen werden sofort um angehaengte Blanks beschnitten, ansonsten 
unveraendert uebernommen. 
Optional kann der Filename als erste Zeile empfangen werden.
Die Datenleitungen des Verbindunskabels muessen "verdreht" sein.
Handshaking aus der Sicht des ELZET80:
- Empfangen eines Records variabler Laenge (bis LF)
- Falls gewaehlt, Senden des Ack/Nack-Codes
  Ack (Hex 06), falls Zeile ohne Error empfangen wurde
  Nack (Hex 15), falls waehrend des Transfers ein Error entdeckt wurde
  (z.B. SIO-Ueberlauf)
- Der Empfang endet, wenn End of File (Hex 1A) erkannt wird.

Der Empfang kann jederzeit durch Tastendruck abgebrochen werden.
#
	.Z80
	ENTRY RCVASC

RCVASC:	JP START

;--------------- Konstanten und Variablen ---------

LF	EQU 0AH		;LINE FEED
CR	EQU 0DH		;CARRIAGE RETURN
ACK	EQU 06H		;ACKNOWLEDGE
NACK	EQU 15H		;NO ACKNOWLEDGE
EOF	EQU 1AH		;END OF FILE MARKER
BDOS	EQU 5		;BDOS EINSPRUNG
FBASE	EQU 6		;FDOS BASIS ADRESSE
SIOC	EQU 6		;SIO-A CONTROL PORT
SIOD	EQU 4		;SIO-A DATA PORT

SIOREG:	DB 11011000B	;RESET
	DB 1,00000000B	;NO INTERRUPTS
	DB 3,11000001B	;RCV 8 BIT/CHAR 
	DB 4,11000100B	;x64 CLOCK, 1 STOP BIT
	DB 5,01101010B	;DTR, TSM 8 BIT/CHAR, TRANSMIT ENABLE, RTS
SIOLEN	EQU $-SIOREG

DRIVE:	DB 0		;OUTPUT DISK DRIVE
FNFLAG:	DB 0		;FILENAME EMPFANG FLAG
ACKFLG: DB 0		;ACKNOWLEDGE SENDEN FLAG
ERRFLG:	DB 0		;SIO ERROR FLAG
OPNFLG:	DB 0		;FILE OPEN FLAG

BUFANF:	DW 0		;BUFFER-ANFANG
BUFEND:	DW 0		;BUFFER-ENDE
DATEND:	DW 0		;DATA ENDE

RCNT:	DW 0		;RECORD COUNT
LINANF:	DW 0		;ZEILENANFANG

INPBUF:	DB 12		;INPUT BUFFER
	DB 0		;TATSAECHL.LAENGE
	DS 12		;12 ZEICHEN

STRING:	DW 0		;OUTPUT STRING
	DW 0		;5 ZEICHEN
	DB 0
	DB '$'

CRLF:	DB 0DH,0AH,'$'

ACKCNT:	DW 0		;ZAEHLER FUER ACK-REPEAT
ACKCHR:	DB 0		;LETZTES ACK-ZEICHEN

ACKSTR:	DB 6,6,6,6,6,6,6,6

FCB:	DS 33		;FILE CONTROL BLOCK
FCBLEN	EQU $-FCB

;--------------- Ausgabe-Strings ------------------

HEADER:	DB 0CH
	DB 'RCVASCII - Version 1.2   24.09.85   (c) A.Herrmann'
	DB 0DH,0AH
	DB '$'

SIOMSG: DB 0DH,0AH
	DB 'SIO-A (Ports 04/06) 9600 Bd, '
	DB '8 Bits/Char, 1 Stop Bits, No Parity, DTR, RTS'
	DB '$'

BUFMSG:	DB 0DH,0AH,0AH
	DB 'Buffer Laenge = '
	DB '$'

EQUMSG:	DB ' = '
	DB '$'

KBYMSG:	DB ' KByte'
	DB '$'

DRVMSG:	DB 0DH,0AH,0AH
	DB 'Files auf Drive ? (A/B/C)  '
	DB '$'

FILMSG:	DB 0DH,0AH,0AH
	DB 'File-Name',0DH,0AH
	DB '- eingeben    E',0DH,0AH
	DB '- empfangen   R   '
	DB '$'

ACKMSG:	DB 0DH,0AH,0AH
	DB 'Ack/Nack (Hex 06/15) nach jeder Zeile ? (Y/N)  '
	DB '$'

ACKBES:	DB ' Ack sent '
	DB 0DH,0AH
	DB '$'

RCVMSG:	DB 0DH,0AH,0AH
	DB 'Empfange File-Name (11 Chars)  '
	DB '$'

ENTMSG:	DB 0DH,0AH,0AH
	DB 'File-Name ? (filename.ext / RETURN=Ende)  '
	DB '$'

DATMSG:	DB 'Bin auf Empfang...  '
	DB '$'

RECMSG:	DB '.Record'
	DB 0DH
	DB '$'

VETMSG: DB 0DH,0AH
	DB 'File auf Disk schreiben ? (Y/N)  '
	DB '$'

LENMSG:	DB 0DH,0AH
	DB 'Daten-Laenge = '
	DB '$'

DSKMSG:	DB 'File auf Disk'
	DB '$'

EMPMSG:	DB 'File leer - nicht auf Disk geschrieben'
	DB '$'

ERRMSG:	DB 0DH,0AH,0AH
	DB '*** Disk Schreib-Fehler ***'
	DB '$'

SERMSG:	DB 0DH,0AH,0AH
	DB '*** SIO-A Empfangs-Fehler ***'
	DB 0DH,0AH
	DB '$'

ABOMSG:	DB 0DH,0AH,0AH
	DB '*** Programm-Abbruch ***'
	DB '$'

RSTMSG:	DB 0DH,0AH,0AH
	DB 'Restart ? (Y/N)  '
	DB '$'

;--------------- PROGRAMM-ANFANG ------------------
		
START:	LD DE,HEADER	;MELDUNG
	CALL PRINT

	LD HL,SIOREG	;SIO-A INIT.
	LD B,SIOLEN
	LD C,SIOC
	OTIR
	LD DE,SIOMSG
	CALL PRINT

	LD HL,PRGEND	;BUFFER-ANFANG BESTIMMEN
	LD L,0
	INC H
	LD (BUFANF),HL
	EX DE,HL

	LD HL,(FBASE)	;BUFFER-ENDE = FDOS-ANFANG
	DEC H		;MINUS "AUSLAUF-ZONE" VON 512 BYTES
	LD (BUFEND),HL	;BUFFER LAENGE BERECHNEN
	SCF
	SBC HL,DE
	PUSH HL
	CALL CONVRT	;HL-WERT NACH STRING KONVERTIEREN
	LD DE,BUFMSG
	CALL PRINT	;UND AUSGEBEN
	LD DE,STRING
	CALL PRINT
	LD DE,EQUMSG
	CALL PRINT	;AUCH IN K BYTE
	POP HL
	CALL KBYTE
	LD DE,STRING
	CALL PRINT
	LD DE,KBYMSG
	CALL PRINT
	LD DE,CRLF
	CALL PRINT

DRSPEZ:	LD DE,DRVMSG	;DRIVE SPEZ.
	CALL PRINT
	CALL INPUT
	SUB 40H
	JR C,DRSPEZ
	CP 4
	JR NC,DRSPEZ
	LD (DRIVE),A

FISPEZ:	LD DE,FILMSG	;FILE NAME EINGABE SPEZ.
	CALL PRINT
	CALL INPUT
	SUB 'E'
	JR Z,FISPE1
	SUB 'R'-'E'
	JR NZ,FISPEZ
	INC A
FISPE1:	LD (FNFLAG),A

ACSPEZ:	LD DE,ACKMSG
	CALL PRINT
	CALL INPUT
	SUB 'N'
	JR Z,ACSPE1
	SUB 'Y'-'N'
	JR NZ,ACSPEZ
	INC A
ACSPE1:	LD (ACKFLG),A

;--------------- MAIN LOOP ------------------------

MLOOP:	LD B,FCBLEN	;NAECHSTEN FILE EMPFANGEN
	LD HL,FCB	;FILE CONTROL BLOCK INIT.
	XOR A
	LD (OPNFLG),A
FLOOP:	LD (HL),A
	INC HL
	DJNZ FLOOP

	LD A,(DRIVE)	;DRIVE IN FCB
	LD (FCB),A

FILNAM:	LD A,(FNFLAG)	;WOHER FILENAME?
	OR A
	JP Z,INPNAM

;------ FILE NAME EMPFANGEN ----------

RCVNAM:	LD DE,RCVMSG	;FILE NAME EMPFANGEN
	CALL PRINT
	LD HL,INPBUF+2
	XOR A
	LD C,A		;ZEICHENZAEHLER
	LD (ERRFLG),A	;CLEAR ERROR FLAG

NLOOP:	LD A,1		;CHECK READ REG.1
	OUT (SIOC),A	;FOR ERRORS
	IN A,(SIOC)
	AND 70H
	JP Z,NLOOP0

	LD A,1		;LOAD ERROR FLAG
	LD (ERRFLG),A
	LD A,30H	;SIO ERROR RESET
	OUT (SIOC),A

NLOOP0:	IN A,(SIOC)	;ZEICHEN DA?
	AND 1
	JR NZ,GETNCH

	PUSH BC
	CALL KEYHIT	;CONSOLE ABFRAGEN
	POP BC
	JR Z,NLOOP
	JP ABORT

GETNCH:	IN A,(SIOD)	;ZEICHEN EINLESEN
	CP CR
	JR Z,NLOOP	;CR UEBERGEHEN
	CP LF
	JR Z,NLOOP1	;BEI LF IST SCHLUSS
	LD (HL),A	;ZEICHEN 
	INC HL		;ABLEGEN
	INC C		;UND ZAEHLEN
	LD A,C
	CP 12		;NACH 12 ZEICHEN IST SCHLUSS
	JP NZ,NLOOP 

NLOOP1:	LD A,(ERRFLG)	;WARS WAS?
	OR A
	JR Z,NLOOP2

	LD A,(ACKFLG)
	OR A
	JP Z,NLOOP2

	LD A,NACK	;NEIN. DANN NOCHMAL
	CALL ACKNOW
	JP RCVNAM

NLOOP2:	LD A,C		;ANZAHL DER ZEICHEN
	LD (INPBUF+1),A
	CALL STOFCB	;NAMEN IN FCB BRINGEN

	LD A,'$'	;FILE NAME AUSGEBEN
	LD (FCB+12),A
	LD DE,FCB
	CALL PRINT
	XOR A
	LD (FCB+12),A

	LD A,(ACKFLG)
	OR A
	JP Z,RCVDAT

	LD A,ACK
	CALL ACKNOW	;ACKNOWLEDGE SENDEN
	JP RCVDAT

;------ FILE NAME EINGEBEN ---------

INPNAM:	LD DE,ENTMSG	;VON CONSOLE
	CALL PRINT
	LD C,10
	LD DE,INPBUF
	CALL BDOS

	LD A,(INPBUF+1)	;STRING LAENGE
	OR A
	JP Z,RESTRT	;=0 ?

	CALL STOFCB	;FILENAME IN FCB BRINGEN
	JP RCVDAT

;--------------- EMPFANG DES FILES -------------

RCVDAT:	LD DE,CRLF
	CALL PRINT
	LD DE,DATMSG	;DATEN EMPFANGEN
	CALL PRINT

	LD HL,0		;RECORD COUNT INIT.
	LD (RCNT),HL
	LD HL,(BUFANF)	;POINTER AUF BUFFER-ANFANG
	LD (LINANF),HL

	LD DE,CRLF
	CALL PRINT

;--------------- NAECHSTE ZEILE ---------------

RCVLN:	XOR A		;SIO ERROR FLAG LOESCHEN
	LD (ERRFLG),A

DLOOP:	LD A,1		;CHECK READ REG.1
	OUT (SIOC),A	;FOR ERRORS
	IN A,(SIOC)
	AND 70H
	JP Z,DLOOP1

;	PUSH HL
;	LD DE,SERMSG	;SIO ERROR
;	CALL PRINT
;	POP HL
	LD A,1		;LOAD ERROR FLAG
	LD (ERRFLG),A
	LD A,30H	;SIO ERROR RESET
	OUT (SIOC),A

DLOOP1:	IN A,(SIOC)	;ZEICHEN DA?
	AND 1
	JR NZ,GETDCH
	
	CALL KEYHIT	;ABBRECHEN?
	JP NZ,VETO
	CALL CHKACK	;CHECK, OB ACK WIEDERHOLEN
	JP DLOOP

GETDCH:	IN A,(SIOD)	;ZEICHEN

	CP EOF		;EXIT, FALLS END OF FILE
	JP Z,READY

	CP LF		;END OF LINE ?
	JP Z,NEWLN

	LD (HL),A	;UEBERNEHMEN
	INC HL		;UND ABLEGEN
	JP DLOOP

NEWLN:	LD A,(ERRFLG)
	OR A
	JP NZ,REPLN	;BEI ERROR WIEDERHOLEN

	LD A,20H	;ANGEHAENGTE BLANKS ELIMINIEREN.
	DEC HL		;VOR CR
NEWLN1:	DEC HL
	CP (HL)
	JR Z,NEWLN1
	INC HL

NEWLN2:	LD A,CR		;CARRIAGE RETURN UND
	LD (HL),A
	INC HL
	LD A,LF		;LINE FEED
	LD (HL),A	;ANHAENGEN
	INC HL		;UND ABLEGEN

	LD (LINANF),HL	;NAECHSTEN ZEILENANFANG MERKEN

	PUSH HL
	LD HL,(RCNT)	;RECORD COUNTER INKR.
	INC HL
	LD (RCNT),HL
	CALL CONVRT	;UND AUSGEBEN
	LD DE,STRING
	CALL PRINT
	LD DE,RECMSG
	CALL PRINT
	POP HL

	CALL KEYHIT	;KEY HIT AUF CONSOLE?
	JP NZ,VETO

	EX DE,HL	;BUFFER-ENDE ERREICHT?
	LD HL,(BUFEND)
	SCF
	SBC HL,DE
	EX DE,HL
	CALL C,BUFULL

	LD A,(ACKFLG)	;GGF. ACK SENDEN
	OR A
	JP Z,RCVLN	;SONST NAECHSTE ZEILE

	LD A,ACK
	JP SNDACK

REPLN:	LD HL,(LINANF)
	LD A,(ACKFLG)	;GGF. NACK SENDEN
	OR A
	JP Z,RCVLN	;SONST NAECHSTE ZEILE

	LD A,NACK

SNDACK:	CALL ACKNOW
	JP RCVLN	;NAECHSTE ZEILE

;------ Filename in FCB bringen -------------

STOFCB:	LD HL,FCB+1	;NAME IN FCB MIT
	LD A,' '	;BLANKS INIT.
	LD B,11
STOFC1:	LD (HL),A
	INC HL
	DJNZ STOFC1

	LD A,(INPBUF+1)	;NAME IN FCB KOPIEREN
	LD C,A
	LD B,0
	LD HL,INPBUF+2
	LD DE,FCB+1
STOFC2:	LD A,'.'	;BIS PUNKT
	CP (HL)
	JR Z,STOEXT
	LD A,(HL)	;ZEICHEN IN A
	CALL CAPIT	;ZU GROSS-BUCHSTABEN MACHEN
	LD (HL),A
	LDI
	LD A,C
	OR A
	JR NZ,STOFC2
	JP STEXIT

STOEXT:	LD DE,FCB+9	;FILE EXTENSION
	INC HL
	DEC C
STOEX1:	LD A,C
	OR A
	JP Z,STEXIT
	LD A,(HL)
	CALL CAPIT
	LD (HL),A
	LDI
	JR STOEX1
STEXIT: RET

;------- Ack/Nack senden -------------------------

ACKNOW: LD (ACKCHR),A	;ACK-CHARACTER RETTEN
	OUT (SIOD),A
	XOR A		;INIT ACK-REPEAT ZAEHLER
	LD (ACKCNT),A
	LD (ACKCNT+1),A
;	PUSH DE
;	LD DE,ACKBES	;BESTAETIGUNG AUF BILDSCHIRM
;	CALL PRINT
;	POP DE
	RET

;------- Acknowledge String senden ------------------

;XX:	PUSH HL		;ACKNOWLEDGE-STRING SENDEN
;	LD B,1
;	LD HL,ACKSTR
;XXX:	IN A,(SIOC)	;OUTPUT BUFFER LEER?
;	AND 4
;	JR Z,XXX
;	LD A,(HL)
;	INC HL
;	OUT (SIOD),A
;	PUSH BC
;	CALL KEYHIT
;	POP BC
;	JP NZ,ABORT
;	DJNZ XXX
;	POP HL

;	LD DE,ACKBES	;BESTAETIGUNG AUF BILDSCHIRM
;	CALL PRINT

;	RET

;-------- Check, ob Ack wiederholen -----------------

CHKACK:	LD A,(ACKCNT)
	DEC A
	LD (ACKCNT),A
	RET NZ
	LD A,(ACKCNT+1)
	DEC A
	LD (ACKCNT+1),A
	RET NZ
	LD A,(ACKCHR)
	CALL ACKNOW
	RET

;------- Buffer voll - auf Diskette schreiben -------

BUFULL:	PUSH HL
	LD (DATEND),HL
	LD HL,(BUFEND)
	CALL DSKWRT
	POP HL		;RESTLICHE BYTES 
	LD DE,(BUFEND)
	XOR A
	SBC HL,DE
	LD B,H
	LD C,L
	LD DE,(BUFANF)	;AN BUFFER-ANFANG SCHIEBEN
	LD HL,(BUFEND)
	LDIR
	EX DE,HL
	RET

 ;------------- File gegen Veto ablegen ----------

VETO:	PUSH HL
	LD DE,VETMSG
	CALL PRINT
	CALL INPUT
	POP HL
	CP 'Y'
	JP Z,READY
	JP RESTRT

;--------------- File ablegen --------------------

READY:	XOR A		;REST BIS ..FF
	SUB L		;MIT EOF-CHAR AUFFUELLEN
	JR Z,READY1
	LD B,A
	LD A,EOF
FILOOP:	LD (HL),A
	INC HL
	DJNZ FILOOP

READY1:	LD (DATEND),HL	;FILE IST EMPFANGEN
	LD DE,(BUFANF)
	XOR A
	SBC HL,DE	;LAENGE BERECHNEN
	JR NZ,NEMPTY	;NICHT-LEERER FILE?
	LD A,(OPNFLG)	;BZW. LEERER REST?
	OR A
	JR NZ,NEMPTY
	LD DE,EMPMSG	;LEERER FILE WIRD NICHT
	CALL PRINT	;ABGELEGT
	JP ABORT

NEMPTY:	CALL DSKWRT	;FILE SCHREIBEN
	LD C,16		;FILE SCHLIESSEN
	LD DE,FCB
	CALL BDOS
	CP 0FFH
	JP Z,DSKERR
	
	LD DE,DSKMSG	;FILE IST AUF DISK
	CALL PRINT

	LD A,ACK	;ACKNOWLEDGE SENDEN UND
	CALL ACKNOW
	JP MLOOP	;WEITER MIT NAECHSTEM FILE

;------ File(-Stueck) auf Diskette schreiben -----

DSKWRT:	PUSH HL
	CALL CONVRT	;UND IN STRING KONVERTIEREN
	LD DE,LENMSG
	CALL PRINT
	LD DE,STRING
	CALL PRINT
	LD DE,EQUMSG
	CALL PRINT	;AUCH IN K BYTE AUSDRUECKEN
	POP HL
	CALL KBYTE
	LD DE,STRING
	CALL PRINT
	LD DE,KBYMSG
	CALL PRINT
	LD DE,CRLF
	CALL PRINT

	LD A,(OPNFLG)	;FILE SCHON OFFEN?
	OR A
	JP NZ,FICONT
	LD C,19		;FILE LOESCHEN
	LD DE,FCB
	CALL BDOS

	LD C,22		;FILE OEFFNEN
	LD DE,FCB
	CALL BDOS
	LD A,0FFH
	LD (OPNFLG),A	;OPEN FLAG SETZEN

FICONT:	LD DE,(BUFANF)	;ERSTE WRITE ADRESSE

WLOOP:	PUSH DE
	LD HL,128	;NEIN, 
	ADD HL,DE	;NAECHSTEN RECORD ANFANG BEST.
	EX DE,HL
	LD HL,(DATEND)	;WUERDE UEBER DATA ENDE HINWEG GESCHRIEBEN?
	XOR A
	SBC HL,DE
	POP DE
	RET C		;JA, RECORD NICHT SCHREIBEN.

	LD C,26		;NEIN,
	PUSH DE
	CALL BDOS	;SET DMA AUF DE
	LD DE,FCB
	LD C,21		;RECORD SCHREIBEN
	CALL BDOS
	POP DE
	OR A		;ERROR?
	JP NZ,DSKERR
	LD HL,128
	ADD HL,DE
	EX DE,HL
	JP WLOOP

;--------------- MAIN LOOP ENDE -------------------

DSKERR:	LD DE,ERRMSG	;DISK WRITE ERROR
	CALL PRINT

ABORT:	LD DE,ABOMSG	;PROGRAMM-ABBRUCH
	CALL PRINT

RESTRT:	LD DE,RSTMSG	;RESTART?
	CALL PRINT
	CALL INPUT
	CP 'Y'
	JP Z,START
	CP 'N'
	JP Z,EXIT
	JR RESTRT

;--------------- SUBROUTINEN ----------------------

KEYHIT:	PUSH HL		;CONSOLE ABFRAGEN
	LD C,6
	LD E,0FFH
	CALL BDOS
	POP HL
	OR A
	RET

INPUT:	PUSH BC		;1 BUCHSTABEN VON CONSOLE
	PUSH DE
	PUSH HL
	LD C,1
	CALL BDOS
	AND 01011111B	;ZU GROSSBUCHST. MASKIEREN
	POP HL
	POP DE
	POP BC
	RET

CAPIT:	CP 60H		;ZEICHEN IN A GGF.
	RET C		;ZU GROSSBUCHSTABEN MACHEN
	SUB 20H
	RET

PRINT:	PUSH HL		;STRING OUTPUT AUF CONSOLE
	LD C,9
	CALL BDOS
	POP HL
	RET

KBYTE:			;INTEGER IN HL IN K BYTE AUSDRUECKEN
	LD B,10		;D.H. DURCH 2^10 DIVIDIEREN
KBYTE1:	SRL L
	SRL H
	JR NC,KBYTE2
	SET 7,L
KBYTE2:	DJNZ KBYTE1
	CALL CONVRT	;UND NACH STRING KONVERTIEREN
	RET

CONVRT:	LD DE,STRING	;INTEGER IN HL 5-STELLIG
	LD BC,5		;NACH STRING KONVERTIEREN
	EX DE,HL
	ADD HL,BC
	DEC HL
	EX DE,HL
	LD B,C

	PUSH DE		;HL GROESSER GLEICH HEX A000 ?
	EX DE,HL
	LD HL,0A000H
	SCF
	SBC HL,DE
	JR NC,CONVR0

	EX DE,HL	;JA, ERSTMAL A000H = 40960 ABZIEHEN
	LD DE,0A000H
	CCF
	SBC HL,DE
	CALL DIV10	;UND DIE DIFFERENZ ALLEIN TEILEN
	POP DE
	CALL RCODE	;REST CODIEREN
	DEC B		;1 STELLE WENIGER
	PUSH DE
	LD DE,1000H	;AUF DEN QUOTIENTEN 1000H = 4096
	ADD HL,DE	;WIEDER DRAUF
	POP DE
	JR CONVR1	;UND NORMAL WEITER

CONVR0:	EX DE,HL	;NEIN
	POP DE

CONVR1: CALL DIV10	;HL DURCH 10 DIVIDIEREN
	CALL RCODE	;REST CODIEREN
	DJNZ CONVR1	;ALLE STELLEN GENERIERT ?

	LD HL,STRING	;FUEHRENDE NULLEN
	LD A,'0'
COLOOP:	CP (HL)
	JR NZ,CONVEX
	LD (HL),' '	;DURCH BLANKS ERSETZEN
	INC HL
	JR COLOOP	
CONVEX:	RET

DIV10:	PUSH BC		;DIVIDIERT HL DURCH 10.
	PUSH DE
	LD B,12		;DIVIDEND HAT 12+4 BITS.
	LD D,0A0H	;DIVISOR (=10) IM OBEREN HALBBYTE VON D
	LD E,0
DIVBIT:	XOR A		;CLEAR CARRY FLAG
	ADD HL,HL	;HL 1 BIT NACH LINKS
	PUSH AF		;SAVE CARRY FLAG
	XOR A		;CLEAR CARRY FLAG
	SBC HL,DE	;"GEHT DE IN HL"?
	INC HL		;ANGENOMMEN, JA.
	JR NC,DIVCNT	;FALLS NICHT
	POP AF		;UND FALLS VORHER
	JR C,DIVNXT	;KEIN CARRY,
	ADD HL,DE	;SUBTRAKTION UND
	DEC HL		;QUOTIENTEN-STELLE
	JR DIVNXT	;ZURUECKNEHMEN.
DIVCNT:	POP AF
DIVNXT:	DJNZ DIVBIT
	POP DE
	POP BC
	RET

RCODE:	LD A,H		;REST AUS DEM OBEREN HALBBYTE
	RR A		;VON H INS UNTERE SCHIEBEN,
	RR A
	RR A
	RR A
	AND 0FH		;HERAUSMASKIEREN,
	OR 30H		;ALS ASCII-ZEICHEN CODIEREN
	LD (DE),A	;UND ABSPEICHERN.
	LD A,H		;QUOTIENT STEHT IN L UND 
	AND 0FH		;UNTEREM HALBBYTE VON H
	LD H,A
	DEC DE
	RET

;--------------- PROGRAMM-ENDE --------------------

EXIT:	JP 0		;WARMBOOT

PRGEND	EQU $

	END
