************************************************
*                                              *
*          Flex & BASIC 51 col on rom          *
*                                              *
*          for emulation of DRAGON 32 64KRAM   *
*                                              *
*        menu with "DK" auto-start cart        *
*               or EXEC&HFB00                  *         
* **********************************************

* see read_me.txt for thanks, memory map and more

*FB00*****************************************************
* temporary storage, destroyed by console screen

 ORG 		$FB00
 PUT *

START		lbra	START1

cursor_blink	equ	$8009 ; (basic)
scan_keyboard	equ	$8006 ; keybord input routine (basic)
OUTSTR   	equ   	$90E5 ; print string at X+1 to DEVNUM (basic)
OUTCH   	equ   	$B54A ; print char A to DEVNUM (basic)
Clear_screen	equ	$BA77 ; (basic)
WARMS		equ	$CD03 ; return +++ (flex)
PSTRING		equ	$CD1E ; print string (flex)

* DW Printer, code included by me in flexcor 9.1
DEVNUM		equ	$6F   ; I/O type, $fe for Printer (basic)
PRINTtoDW	equ	$CCE4 ; print to DW (flex)


initmsg		fcb $0D,/For Dragon with 64K RAM/,$0D,0
initmsg1	fcb $0D,/1 RUN flex9.1 & basic 51 col/,$0D,0
initmsg2	fcb $0D,/  SEE infos FLEX LOCAL CMD/,$0D,$0D,0
initmsg3	fcb $0D,/2 only GO 64KRAM MODE/,$0D,0
initmsg3a	fcb $0D,/  dload WILL BE INSTALLED IF D32/,$0D,0
initmsg4	fcb $0D,/ELSE exit/,$0D,0
initmsg5	fcb /64K RAM WIH dload/,$0D,0
Err_message	fcb $0D,/DW ERROR, CONTINUE FOR DEMO/,0

DATEBUFF	rmb	6 ; yy,mm,dd, 0,0,0
timeop		fcb	$23 ; DW code for time



START1		
* menu 1,2,3
		ORCC  #$50
		jsr	Clear_screen
		ldx 	#initmsg -1
		jsr OUTSTR
		ldx 	#initmsg1 -1
		jsr OUTSTR
		ldx 	#initmsg2 -1
		jsr OUTSTR
		ldx 	#initmsg3 -1
		jsr OUTSTR
		ldx 	#initmsg3a -1
		jsr OUTSTR		
		ldx 	#initmsg4 -1
		jsr OUTSTR
inloop		jsr	cursor_blink
		jsr	scan_keyboard	
		beq	inloop
		jsr	OUTCH ; echo the chr
		cmpa	#49 ; 1
		beq	START2
		cmpa	#50 ; 2
		bne	SOFT_RESET

* menu2, exit in 64K ram mode with DLOAD
		jsr	MODE64K
		jsr	Clear_screen
		ldx 	#initmsg5 -1
		jsr 	OUTSTR	
		ldx	#$2001 ; patch "BRA $01"
		stx	$B463 ; so don't clear screen on soft reset

* return with soft reset
SOFT_RESET	jmp	$B44F 


START2
* go to 64K ram Mode & install DLOAD in original D32 basic
* if necessary	
		jsr	MODE64K

* init serial  & load date in buffer to test DW access
		ldx	#$ff20
		ldb	#2
		stb	,x

		ldx	#timeop
		ldy	#1
		jsr	DWWrite
		ldx	#DATEBUFF
		ldy	#6
		jsr	DWRead
		bne	DW_ERROR

* patch flex 9.1 for DATE
		jsr 	DW_DATE

START3
* install hooks to use BASIC with flex 51 col console & Keybord
* install local commands MON & INFOS
	 	jsr	$e4ec ; HOOKS in drivers code

GOFLEX		jmp	$cd00 ; boot flex

DW_ERROR	ldx 	#Err_message -1
		jsr 	OUTSTR
inloop1		jsr	cursor_blink
		jsr	scan_keyboard	
		beq	inloop1
		bra	START3 ; continue without DW for DEMO

***********sub get DW_DATE for flex & print in decimal
DD		equ	$cc0f
MM		equ	$cc0e
YY		equ	$cc10

* flexcor91 to modify
DATEQ		equ	$CAD0 ; DATE (MM,DD,YY) with real date
GDATE		equ	$CA50 ;  
	* GDATE LDX #DATEQ
	*       JSR PRINT
	*       jmp	$CA6E ; bypass date ask


DW_DATE
* inhibit date quest
		lda	#$7E
		sta	GDATE+6
		ldx	#$CA6E
		stx	GDATE+7

* store date in DW & convert to decimal
		lda	DATEBUFF+1 ; month 1-12
		sta	MM
		jsr 	HEX2DEC
		stb	DATEQ+6
		sta	DATEQ+7

		lda	DATEBUFF+2 ; day 1-31
		sta	DD
		jsr 	HEX2DEC
		stb	DATEQ+9
		sta	DATEQ+10

		lda	DATEBUFF ; year 0-39
		suba	#100
		sta	YY
		jsr	HEX2DEC
		stb	DATEQ+12
		sta	DATEQ+13
		lda	#$20
		sta	DATEQ+15	
		rts


************sub convert hex (a) to decimal 2 digits 01-39 (b,a)
* OUTNUM   equ   $957A       ; print number in D to DEVNUM
		
HEX2DEC	
		sta	DATEBUFF+3
		ldb	#48
		cmpa	#9
		bhi	lp10
		adda	#48
		rts	
lp10		lda	DATEBUFF+3
		incb	
		cmpa	#19
		bhi	lp11
		adda	#38
		rts
lp11		lda	DATEBUFF+3
		incb
		cmpa	#29
		bhi	lp12
		adda	#28
		rts
lp12		lda	DATEBUFF+3
		incb
		cmpa	#39
		bhi	lp13
		adda	#18
		rts
lp13		clra
		clrb
		rts		

*FD00**************************************************
* temporary code, will be destroyed by flex screen
 ORG 		$FD00
 PUT *

* goes to 64KRam Mode & install DLOAD if original Dragon32 rom
* can be called by EXEC&HFD00
RamBoot64	EQU	$01da ; K7 buffer


* copy 8000-feff (basic & cart) to ram
MODE64K		orcc 	#$50
		clr	Flex_flag
		tst	Flex_flag
		beq	PATCH_bas32 ; yet in 64 K ram Mode

		ldy	#MOVE_64K
		ldx	#RamBoot64	
loop2		lda	,y+
		sta	,x+
		cmpy	#END64
		ble	loop2
		jsr	RamBoot64 ; 64KRam Mode

PATCH_bas32	tst	$be7f ; 0 in original d32 rom
		lbne	prntOY ; yet patched

* patch D32 basic for DLOAD 
		ldy	#$f800
		ldx	#$a089
		stx	ENDX
		ldx	#$a049	
		jsr	MOVE

		ldy	#$f900
		ldx	#$a1cb
		stx	ENDX
		ldx	#$a0f4
		jsr	MOVE

		ldy	#$fa00
		ldx	#$bf37
		stx	ENDX
		ldx	#$be7f
		jsr	MOVE

		lda	#$bd
		sta	$b466
		ldx	#$be7f		
		stx	$b467

		ldy	#DWRead1 ; DWRead & DWWrite
		ldx	#$bf72
		stx	ENDX
		ldx	#$bf38
		jsr	MOVE

prntOY		lda	#89 ; "OY" for 64K ram mode with DLOAD
		sta	$82ed
		rts

************ sub MOVE code to patch
ENDX		fdb	0
MOVE		lda	,y+ ; from Y
		sta	,x+ ; to X
		cmpx	ENDX
		ble	MOVE
		rts	

************ sub to copy to ram boot
MOVE_64K	ORCC  	#$50 	; 1a 50
		ldx	#$8000	; 8e 80 00	
loop1		sta	$ffde 	; b7 ff de
		lda	,x 	; a6 84
		sta	$ffdf 	; b7 ff df
		sta	,x+ 	; a7 80
		cmpx	#$feff 	; 8c fe ff
		ble	loop1 	; 2f f1
END64		rts 		; 39

Flex_flag	fcb	$ff


*FE00*******************************************************
* sub DWRead & DWWrite  used by DLOAD & flex
* + code for FLUSH DW printer buffer

; Drivewire read/write functions for Becker port
; S.Orchard Nov 2021
;
; Entry & exit conditions compatible with
; Darren Atkinson's bitbang serial code
;

; BECKER_STS  equ $ff41  ; (rsdos)
BECKER_STS  equ $ff49  ; (dgndos)
BECKER_DATA  equ BECKER_STS + 1

; read from drivewire server
;   x = buffer
;   y = count
; returns:
;   x = buffer
;   y = checksum
;   z set on success
;   carry clear
;   u preserved

 ORG $FE00
 PUT *

* TABLE
DWRead		jmp	DWRead1
DWWrite		jmp	DWWrite1
FLUSH		jmp	FLUSH1

DWRead1
    clrb              ; init timeout lsb
    pshs b,x,u
    leau ,x           ; buffer address
    ldx #0            ; zero checksum
    lda #2            ; position of Becker port status bit
1   clr ,s            ; init timeout msb & clear carry
2   bita BECKER_STS
    bne 5f            ; data available
4   decb
    bne 2b
    dec ,s            ; timeout msb
    bne 2b
    incb              ; clear z
    puls a,x,u,pc     ; error exit
5   ldb BECKER_DATA
    abx               ; update checksum
    stb ,u+
    leay -1,y
    bne 1b
    leay ,x           ; return checksum in y
    clrb              ; set z
    puls a,x,u,pc     ; successful exit


; write to drivewire server
;   x = buffer
;   y = count
; returns:
;   x = buffer + count
;   y = 0
;   other regs preserved

************************************************

		nop
		nop
		nop

DWWrite1
    pshs cc,a
1   lda ,x+
    sta BECKER_DATA
    leay -1,y
    bne 1b
    puls cc,a,pc

*********** FLUSH printer buffer if clear right arrow
* of DW from flex or from Basic
FlushMessage	fcb	/FLUSH OK/,$04
FlagPrUsed	equ	$cce6
FLUSH1		tst	FlagPrUsed
		bne	flushexit ; exit if printer not used
		lda     #$46
		pshs    a
		leax    ,s
		ldy     #1
		jsr     DWWrite
		puls    a
		ldx	#FlushMessage
		jsr	PSTRING
		dec	FlagPrUsed
flushexit	jmp	$cd03 ; return to +++
