; **** FLOP - SDA Floppy Disc Transfer (ALPHA II) ****
base	equ	2800h
suspend equ	0109h	; Block Voluntarily
io	equ	0130h	; Screenhandler
stow	equ	013fh	; Write Spool Control Sector
spool	equ	0142h	; (DE) -> next spool sector
unspool equ	0145h	; Oldest spool sector -> (DE)
idler	equ	0166h	; Suspend with Escape option
input	equ	016ch	; Mainframe String -> (HL)
echo	equ	0172h	; A -> Mainframe with echo wait
reset	equ	017bh	; Reset Disc System
print	equ	0187h	; (HL) -> print line
mark	equ	0190h	; Mark Escape Point
;
; Z80 OP Codes--
ldir	equ	0b0edh
djnz	equ	00010h
sspd	equ	073edh	; LD (nn),SP
lspd	equ	07bedh	; LD SP,(nn)
;
; ASCII codes--
nul	equ	00h
cr	equ	0dh
so	equ	0eh
si	equ	0fh
dc4	equ	14h
esc	equ	1bh
gs	equ	1dh
fs	equ	1ch
time	equ	7fh
s	equ	80h
;
; Inter-Task communication--
label	equ	01c2h	; -> Spool Diskette Label
ctl	equ	01d0h	; System Control Block
mstate	equ	ctl+12	; B0: Electronic (not Terminal) Mode
flags	equ	ctl+18	; B1: Buffer Area in use
htrk	equ	ctl+28	; Spool Header Track/Sector (3 bytes)
sector	equ	5000h	; Workspace (256 bytes)
count	equ	sector+1
parms	equ	sector+256
buffer	equ	sector+512 ; Input Buffer (21*11+1 bytes)
;
	org	base
	lxi	h,parms !call input !mvi m,nul	; run parameters
	mov	d,h !mov e,l !inx d !lxi b,86 !dw ldir ; zero-fill
	lda	parms !sta msg4+30 !lxi h,slow !cpi 'S' !jz h1
	lxi	h,fast !cpi 'F' !jz h1 !ora a !jnz h2 ; File Transfer
h1	shld	mode !mvi a,'P' !sta parms	; SDA Transfer
h2	call	idler !lxi h,flags !dw 04ecbh ; BIT 1,(HL)
	jnz	h2 !dw 0cecbh ; SET 1,(HL)	; seize buffers
	call	suspend !lhld label !lxi d,ido !lxi b,25 !dw ldir ; Drop DTR
	lhld	label !xchg !lxi h,id !lxi b,13 !dw ldir
	call	reset !call mark !jnz quit	; Load SDA DATA diskette
	lxi	h,parms+1 !mov a,m !ora a !cnz init
	lhld	label !lxi d,33 !dad d !lxi d,parms+1 !lxi b,7 !dw ldir
	lxi	b,11 !dad b !lxi b,77 !dw ldir	; setup run parameters
	lda	parms !cpi 'P' !lxi h,scr0 !jc $+6 !lxi h,scr1 !call io
	call	openi !call head !lda parms !cpi 'P' !jc nprod !jmp sda
;
open0	lda	parms !cpi 'P' !jc open 	; must use empty disc
	lhld	label !lxi d,32 !dad d !cmp m !rz !lxi h,scr6 !jmp $+6
open	lxi	h,scr7 !call io !call reset	; change disk
openi	lxi	h,0 !shld added !lxi h,sector !shld pout
	lxi	d,19 !call check !jnz open0 ; disc not empty
	lxi	d,22 !call check !lxi h,s2+2 !dw 096cbh ; RES 2,(HL)
	jz	init !lxi h,s2+2 !dw 0d6cbh ; SET 2,(HL)
	jmp	init
;
check	lhld	label !dad d !xchg !lxi h,3 !dad d !mvi b,3
ck1	ldax	d !cmp m !rnz !inx d !inx h !dw djnz+(ck1-$-2)*256
	ret
;
close	lxi	d,sector !call spool !call fline !lhld added !xchg
	lhld	label !lxi b,44 !dad b !mov m,e !inx h !mov m,d !xchg
	lxi	d,msg4+24 !call bd5 !call stow !lxi h,msg4 !jmp print
;
head	lhld	label !lxi b,51 !dad b !lxi b,8*256 !call io ; name
	lhld	label !lxi b,44 !dad b !mov e,m !inx h !mov d,m !xchg
	lxi	d,scr5+16 !call bd5 !lxi h,scr5 !call io !call confirm
	lxi	h,scr8 !call io
	lxi	d,msg1+41 !lxi h,s1+3 !lxi b,3 !dw ldir ; www
	lxi	d,msg1+53 !lxi h,s2+3 !lxi b,5 !dw ldir ; pp.yy
	lxi	h,itext !mvi b,s !call print !lxi h,msg1 !jmp print
;
confirm lxi	d,s1+3 !lhld label !lxi b,33 !dad b !lxi b,3 !dw ldir ; www
	lxi	d,s2+3 !lxi b,2 !dw ldir ; pp
	inx	d !lxi b,2 !dw ldir ; yy
	lxi	h,scr2 !call io !cpi 1 !rc !cnz modify !jmp confirm
modify	cpi	3 !rz !lxi b,37 !jc $+6 !lxi b,39 ; BC=offset
	lhld	label !dad b !xchg !mov b,a !mov c,a
my1	mov	a,m !cpi '0' !rc !cpi '9'+1 !rnc !inx h !dw djnz+(my1-$-2)*256
	dcx	h !dw 0b8edh ; LDDR		; override label data
	lxi	d,parms+1 !lhld label !lxi b,33 !dad b !lxi b,7 !dw ldir
	lxi	h,s2+2 !dw 096cbh ; RES 2,(HL)
	jmp	stow
;
; *********** Reinitialize SDA diskette ***************
init	lhld	label !lxi d,16 !dad d !mov d,h !mov e,l
	inx	d !inx d !inx d !lxi b,12 !dw ldir
	xra	a !stax d !inx d !lxi h,parms !lxi b,8 !dw ldir
	push	h !mov h,d !mov l,e !mvi m,0 !inx d !lxi b,7 !dw ldir
	inx	d !inx d !mvi a,81h !stax d !inx d
	pop	h !lxi b,77 !dw ldir
	jmp	stow
;
; ******************* File Transfer **********************
nprod	mvi	a,gs !call echo 	; prompt for next record
	lxi	h,buffer !call input !jz lprod !push b
	call	extent !jnz pd1 !sub e !jnz pd1 ; not last track/sector
	call	close !lxi h,scr4 !call io !call open ; change disc
pd1	lhld	added !inx h !shld added !pop b ; BC=record length
	lhld	pout !call ppack !shld pout !xchg ; pack 6-bit chars
	lxi	h,-sector-128 !dad d !jnc nprod ; no buffer overflow
	mov	b,h !mov c,l		; keep length
	lxi	h,-128 !dad d !shld pout; reset spool pointer
	lxi	d,sector !call spool !lxi h,sector+128 !lxi d,sector
	mov	a,b !ora c !jz $+5 !dw ldir ; shunt overflow data
	call	fline !jmp nprod
lprod	call	close !lxi h,foot !call print !jmp quit
;
ppack	mov	m,c !inx h !lxi d,buffer !push d
pp1	xthl	!call char !mov e,a !call char !mov d,a !call char
	rlc	!rlc !call ad !call ad !call ade !call ade !mov b,a
	mov	b,a !call char !ora b !xthl
	mov	m,e !inx h !dcr c !jz pp2
	mov	m,d !inx h !dcr c !jz pp2
	mov	m,a !inx h !dcr c !jz pp2 !dcr c !jnz pp1
pp2	pop	d !ret
ad	dw	027cbh,012cbh ; SLA A ; RL D
	ret
ade	dw	027cbh,012cbh,013cbh ; SLA A ; RL D ; RL E
	ret
char	mov	a,m !inx h
ch1	sui	20h !jp $+5 !mvi a,3fh !cpi 40h !jnc ch1 !ret
;
; ***************** SDA Transfer ********************
sda	lxi	d,htrk !call tts	; save Header slot
	lxi	b,6 !dad b !xchg !lxi h,htrk !lxi b,3 !dw ldir ; prev tt.ss
	call	bumpi
nblk	call	prompt !lxi h,buffer	; ready for next block
	call	input !jz last !mvi m,nul !lxi d,buffer
nrec	lhld	mode !call hl
	push	h !lhld pout !call pack !call pack !call bump
	pop	d !ldax d !ora a !jnz nrec !jmp nblk
;
last	lda	count !ora a !cnz flush
	lhld	label !lxi d,44 !dad d !mov e,m !inx h !mov d,m
	push	h !inx h !mov m,e !inx h !mov m,d ; previous item count
	lhld	added !dad d !shld total !xchg
	pop	h !mov m,d !dcx h !mov m,e !call stow !call tail
quit	lhld	label !xchg !lxi h,ido !lxi b,25 !dw ldir
	call	reset				; reload SPOOL diskette
	lxi	h,flags !dw 08ecbh ; RES 1,(HL) ; release buffers
	lxi	h,mstate !dw 086cbh ; RES 0,(HL); cancel Electronic Mode
	mvi	a,esc !jmp echo
;
fast	lxi	h,8 !dad d !ret
;
slow	xchg	!mov a,m !cpi '+' !jz item !cpi '-' !jz item
	lxi	d,r0+1 !lxi b,3 !dw ldir	; S1-3
	call	dig !adi 40h !sta r0		; S4
	call	dig !rlc !rlc !push psw 	; S5
	mvi	a,'+' !sta sn !call d6b !ani 03h !mov b,a
	pop	psw !ora b !lxi d,r0+4 !jmp sl01
item	sta	sn !inx h !lxi d,r0+4 !lxi b,4 !dw ldir ; S1-4
	mvi	a,' ' !sta r0 !call d6b !ani 07h !lxi d,r0
sl01	adi	20h !push h !lxi h,binx !mov m,a !lxi b,4 !dw ldir
	pop	h !lxi d,r0 !ret
;
fline	lxi	d,scr3a+3 !lxi h,buffer !lxi b,6 !dw ldir
	lxi	h,scr3a !call io		; Record No
line	lxi	d,scr3+24 !lhld added !call bd5
	lxi	d,wstts !call tts		; get current track, sector
	lxi	d,scr3+9 !lhld wstts !call bd2	; Track -> ASCII
	lxi	d,scr3+20 !lda wstts+2 !mov l,a !call bd2 ; Sector -> ASCII
	lxi	h,scr3 !jmp io
;
tail	lxi	d,msg3+57 !lhld htrk !call bd2	; Track -> ASCII
	lxi	d,msg3+60 !lda htrk+2 !mov l,a !call bd2 ; Sector -> ASCII
	lxi	d,msg3+39 !lhld added !call bd5
	lxi	d,msg3+24 !lhld total !call bd5
	lxi	h,msg3+24 !lxi d,scr5+16 !lxi b,5 !dw ldir
	lxi	h,scr5 !call io
	lxi	h,msg3 !call print !lxi h,foot !jmp print
;
; *********************************************************
;
prompt	call	extent !jnz pr1 !sub e !jnz pr1 ; not last track/sector
	lda	count !ora a !jnz pr2		; last sector not empty
pr1	jc	pr2 !mvi a,gs !jmp echo 	; enough space remains
pr2	lxi	h,scr4 !call io !mvi a,fs !jmp echo
;
extent	lhld	label				; check diskette space
	lxi	b,13 !dad b !mov e,m !inx h !mov d,m !inx h !mov a,m
	lxi	b,4 !dad b !mov c,m !inx h !mov b,m !inx h !mov l,m
	xchg	!dcx h !dcr a !ora a !dw 042edh ; SBC HL,BC
	ret
;
bump	lhld	pout !mov a,m !lxi d,6 !dad d !shld pout
	ani	0c0h !cz add1			; item record
	lxi	h,count !inr m !mov a,m !cpi 21 !rnz ; sector not full
flush	lxi	h,sector !mvi m,1 !xchg !call spool
bumpi	call	line !lxi h,count !mvi m,0 !inx h !shld pout !ret
add1	lhld	added !inx h !shld added !ret
;
d6b	xchg	!lxi h,bin
	xra	a !mov m,a !inx h !mov m,a !inx h !mov m,a !lxi h,e5
	call	mul !call mul !call mul !call mul !call mul !call mul
	lda	sn !cpi '-' !jnz db01	; positive
	lxi	h,bin !xra a !sub m !mov m,a !inx h
	mvi	a,0 !sbb m !mov m,a !inx h
	mvi	a,0 !sbb m !mov m,a
; Expand 24 bit binary to 4 bytes--
db01	lda	bin !mov c,a !ani 3fh !adi 20h !sta binx+3
	lda	bin+1 !mov b,a !lda bin+2
	dw	3fcbh,18cbh,19cbh ; SRL A ; RR B ; RR C
	dw	3fcbh,18cbh,19cbh ; SRL A ; RR B ; RR C
	adi	20h !sta binx !mov a,b
	dw	3fcbh,19cbh,3fcbh,19cbh ; SRL A ; RR C ; SRL A ; RR C
	adi	20h !sta binx+1 !mov a,c !dw 3fcbh,3fcbh ; SRL A ; SRL A
	adi	20h !sta binx+2 !lda binx !sui 20h !xchg !ret
;
; (bin) = (bin) + (DE ASCII) * (HL)
mul	ldax	d !inx d !push d !lxi d,bin !ani 0fh !mov b,a !inr b
mu1	dcr	b !jz mu2
	ldax	d !add m !stax d !inx d !inx h
	ldax	d !adc m !stax d !inx d !inx h
	ldax	d !adc m !stax d !dcx d !dcx h !dcx d !dcx h !jmp mu1
mu2	inx	h !inx h !inx h !pop d !ret
;
dig	mov	a,m !inx h !ani 0fh !ret
;
pack	call	x6 !mov b,a !call x6 !mov c,a !call x6
	ral	!ral !ral !dw 011cbh ; RL C
	ral	!dw 011cbh ; RL C
	ral	!dw 011cbh,010cbh ; RL C ; RL B
	ral	!dw 011cbh,010cbh ; RL C ; RL B
	mov	m,b !inx h !mov m,c !inx h !ani 0c0h !mov b,a
	call	x6 !ora b !mov m,a !inx h !ret
x6	ldax	d !inx d		; pickup 6 bit char
	cpi	60h !jc $+5 !sui 20h !sui 20h !ani 3fh !ret
;
tts	lhld	label !lxi b,19 !dad b !lxi b,3 !dw ldir
	ret
;
bd5	mvi	a,' ' !lxi b,10000 !call digit	; HL bin -> (DE) 5 ASCII
	lxi	b,1000 !call digit
	lxi	b,100 !call digit !jmp $+5
bd2	mvi	a,'0' !lxi b,10 !call digit	; HL bin -> (DE) 2 ASCII
	mov	a,l !ori '0' !stax d !ret
; Divide HL by BC, remainder to HL, ASCII result to (DE)--
digit	ora	a !dw 042edh ; SBC HL,BC
	jc	dt2 !mvi a,'0'		; significant digit
dt1	inr	a !ora a !dw 042edh ; SBC HL,BC
	jnc	dt1 !dad b !stax d !inx d !mvi a,'0' !ret
dt2	dad	b !stax d !inx d !ret
;
hl	pchl
;
e5	db	0a0h,086h,001h	; 100,000
e4	db	010h,027h,000h	;  10,000
e3	db	0e8h,003h,000h	;   1,000
e2	db	064h,000h,000h	;     100
e1	db	00ah,000h,000h	;      10
e0	db	001h,000h,000h	;	1
itext	db	si,cr,esc,'Q',120,cr,nul ; condensed mode, 120 chars/line
msg1	db	s+2,'****** ',time,so,' SDA Data transfer ',dc4
	db	'Wholesaler nnn  Period pp.yy',nul
msg3	db	s+1,'-----> ',time,'  Diskette has nnnnn records, '
	db	'nnnnn added at',so,' R=tt.ss',nul
msg4	db	s+1,'-----> ',time,'  Diskette has nnnnn x records',nul
foot	db	s+4,nul
scr0	db	3,0,0e0h,'Copy File to SDA Diskette',nul
scr1	db	3,0,0e0h,'Transfer SDA Transactions to Diskette',nul
scr2	db	5,0,'Wholesaler      Period      ',s
s1	db	5,37,81h,'www',s
s2	db	5,49,81h,'pp.yy',s
	db	17,0,'Or, enter pp or ppyy',s
	db	18,0,'Or, [ESC] to cancel',s
	db	esc,4,16,0,'To start: Press [ENTER] ',s
	db	15,1,0c0h,nul
scr3	db	12,0,81h,'Track tt  Sector ss, nnnnn records moved',nul
scr3a	db	14,0,0c0h,'nnnnnx',nul
scr4	db	16,0,8dh,'SDA Diskette is full!',nul
scr5	db	14,0,81h,'Diskette has nnnnn records indicated',s,18,1,nul
scr6	db	esc,1,1,1,89h,'Please put correct SDA Diskette '
	db	'in Drive B then press [ENTER]',s,1,1,0a0h,nul
scr7	db	esc,1,1,1,89h,'Please put empty SDA Diskette '
	db	'in Drive B then press [ENTER]',s,1,1,0a0h,nul
scr8	db	14,1,0c0h,nul
id	db	'SDA DATA   ',11,0
ido	ds	25	; original system disc id
added	ds	2	; count of item records written this time
total	ds	2	; save total of item records on diskette
wstts	ds	3	; current track, sector
sn	ds	1	; save sign
bin	ds	3	; binary w/s
binx	ds	4	; expanded binary w/s
mode	ds	2	; -> input processor
pout	ds	2	; Output pointer
r0	ds	8	; next record
	end	base

The QX10 Archive