;
;=============================================================================
; USRROM.ASM - SAMPLE CUSTOM ROM USER APPLICATION
;=============================================================================
;
; VERSION 1.1	BY - MARTINR	31-MAY-2024
;
; THIS IS AN EXAMPLE USER ROM APPLICATION THAT IS AUTOMATICALLY INCLUDED
; IN THE ROMWBW ROM.  IT IS INVOKED FROM THE BOOT LOADER USING THE
; 'U' (USER APPLICATION) OPTION.  YOU MAY REPLACE THIS SOURCE CODE WITH
; YOUR OWN CUSTOM CODE.  IT WILL BE ASSEMBLED AND INCLUDED WITH YOUR
; CUSTOM ROM BUILD.  REFER TO THE ROMWBW USER GUIDE FOR MORE INFORMATION.
;
; THANKS AND CREDIT TO MARTIN R. FOR PROVIDING THIS APPLICATION!
;
; - THE SOURCE IS ASSEMBLED WITH THE TASM ASSEMBLER.
; - THE APPLICATION MUST START (ORG) AT USR_LOC ($100)
; - THE APPLICATION MUST BE EXACTLY USR_SIZ BYTES.  THIS IS AUTOMATICALLY
;   ENFORCED AT THE END OF THE FILE.
; - AT EXIT, THE APPLICATION SHOULD RETURN TO THE BOOT LOADER USING THE
;   HBIOS WARM RESET FUNCTION AS DEMONSTRATED BELOW.
; - THE APPLICATION MAY MAKE HBIOS FUNCTION CALLS WITHOUT RESTRICTION,
;   BUT CANNOT USE ANY OS (CP/M) FUNCTIONS BECAUSE NO OS IS LOADED.
; - THE APPLICATION MAY NOT CHANGE THE INTERRUPT MODE (WHICH IS DEFINED
;   IN THE ROM CONFIGURATION).  THE SYSTEM'S INTERRUPT
;   MODE CAN BE QUERIED BY AN HBIOS API CALL IF DESIRED.
; - THE APPLICATION MAY TEMPORARILY DISABLE INTERRUPTS BY BRACKETING
;   SECTIONS OF CODE WITH DI/EI AS NEEDED.  IF INTERRUPTS ARE
;   TEMPORARILY DISABLED, THEY SHOULD NOT SHOULD NOT
;   BE LEFT DISABLED ACROSS HBIOS API CALLS.
;
; INCLUDE STD.ASM WHICH DEFINES SOME KEY EQUATES USED BELOW.  MOST
; IMPORTANT ARE USR_LOC, USR_SIZ, AND USR_END.  IT ALSO DEFINES EQUATES
; FOR THE HBIOS FUNCTION CALLS.
;
#INCLUDE "std.asm"
;
	.LIST
;
CR	.EQU	0DH
LF	.EQU	0AH
;
ROWS	.EQU	8		; NUMBER OF PIXEL ROWS PER CHARACTER
COLS	.EQU	8		; NUMBER OF PIXEL COLUMNS PER CHARACTER
;
; APPLICATION WILL WILL BE LOADED AT USR_LOC.  THEREFORE, THE CODE
; MUST "ORG" AT THIS ADDRESS.  TO CHANGE THE LOAD LOCATION OF THIS
; CODE, YOU CAN UPDATE USR_LOC IN STD.ASM.
;
	.ORG	USR_LOC
;
; PLACE STACK AT THE TOP OF AVAILABLE RAM (JUST BELOW THE HBIOS PROXY).
;
	LD	SP,HBX_LOC
;
;*****************************************************************************
;
; DISPLAY BANNER
;
	LD	A,CR
	CALL	COUT
	LD	A,LF
	CALL	COUT		; COUT PRESERVES AF, BC, DE, & HL
	CALL	COUT
	CALL	COUT
;
	LD	HL,BANNER+1	; POINTER TO THE 8X8 CHARACTER BITMAPS
	LD	D,ROWS		; D=ROWS PER CHARACTER
;
NXTLIN:	LD	A,(BANNER)	; FETCH THE NUMBER OF CHARACTERS IN THE BANNER
	LD	E,A
;
NXTCHR:	LD	C,(HL)		; FETCH THE BIT PATTERN FOR THE CHARACTER-LINE
	LD	B,COLS		; 8 COLUMNS PER CHARACTER-LINE
NXTBIT:	SLA	C		; SHIFT-LEFT THE NEXT BIT INTO THE CARRY FLAG
	JR	C, DOT
	LD	A,' '		; IF NO-CARRY THEN PRINT A 'SPACE'
	JR	GAP
DOT:	LD	A,'X'		; IF A CARRY THEN PRINT AN 'X'
GAP:	CALL	COUT		; COUT PRESERVES AF, BC, DE, & HL
	DJNZ	NXTBIT		; GO ROUND AND PRINT ALL 8 BITS FOR THE CHARACTER-LINE
;
	INC	HL		; POINT TO NEXT CHARACTER-LINE
	DEC	E
	JR	NZ,NXTCHR	; GO ROUND AND PRINT THE NEXT CHARACTER
;
	LD	A,CR		; REACHED THE END OF A LINE, SO PRINT CRLF
	CALL	COUT		; COUT PRESERVES AF, BC, DE, & HL
	LD	A,LF
	CALL	COUT
;
	DEC	D
	JR	NZ,NXTLIN	; GO ROUND AND PRINT THE NEXT LINE
;
;*****************************************************************************
;
; FINISHED DISPLAYING THE BANNER, NOW END THE 'APP' TIDILY
;
	LD	HL,MESSAGE		; PRINT A MESSAGE
	CALL	PRTSTR
	CALL	CIN			; AND WAIT FOR A KEYPRESS
;
	LD	B,BF_SYSRESET		; SYSTEM RESTART
	LD	C,BF_SYSRES_WARM	; WARM START
	RST	08			; CALL HBIOS (DOES NOT RETURN)
;
;*****************************************************************************
;
; SUPPORT ROUTINES
;
; PRINT A STRING OF CHARACTERS STARTING AT HL, ENDING WITH '$'
;
PRTSTR:	LD	A,(HL)
	INC	HL
	CP	'$'
	RET	Z
	CALL	COUT
	JR	PRTSTR
;
; OUTPUT CHARACTER IN A TO CONSOLE DEVICE
;
COUT:	PUSH	AF
	PUSH	BC
	PUSH	DE
	PUSH	HL
	LD	B,BF_CIOOUT
	LD	C,CIO_CONSOLE
	LD	E,A
	RST	08
	POP	HL
	POP	DE
	POP	BC
	POP	AF
	RET
;
; WAIT FOR A CHARACTER FROM THE CONSOLE DEVICE AND RETURN IT IN A
;
CIN:	PUSH	BC
	PUSH	DE
	PUSH	HL
	LD	B,BF_CIOIN
	LD	C,CIO_CONSOLE
	RST	08
	LD	A,E
	POP	HL
	POP	DE
	POP	BC
	RET
;
;*****************************************************************************
;
; DATA SECTION
;
BANNER:
	.DB	6	; THE NUMBER OF CHARACTERS IN THE BANNER
;
#IF FALSE
	; UPPER CASE LOGO ("ROMWBW")
	.DB	%01111100, %00011100, %01000001, %01000001, %01111100, %01000001
	.DB	%01000010, %00100010, %01100011, %01000001, %01000010, %01000001
	.DB	%01000001, %01000001, %01010101, %01000001, %01000001, %01000001
	.DB	%01000001, %01000001, %01001001, %00100010, %01111110, %00100010
	.DB	%01111110, %01000001, %01000001, %00100010, %01000010, %00100010
	.DB	%01000100, %01000001, %01000001, %00101010, %01000001, %00101010
	.DB	%01000010, %00100010, %01000001, %00101010, %01000001, %00101010
	.DB	%01000001, %00011100, %01000001, %00010100, %01111110, %00010100
#ENDIF
;
#IF TRUE
	; UPPER AND LOWER CASE LOGO ("RomWBW")
	.DB	%00000000, %00000000, %00000000, %00000000, %00000000, %00000000
	.DB	%01111000, %00000000, %00000000, %01000100, %01111000, %01000100
	.DB	%01000100, %00000000, %00000000, %01000100, %01000100, %01000100
	.DB	%01000100, %00111000, %00101000, %01000100, %01000100, %01000100
	.DB	%01111000, %01000100, %01010100, %01010100, %01111000, %01010100
	.DB	%01010000, %01000100, %01010100, %01010100, %01000100, %01010100
	.DB	%01001000, %01000100, %01000100, %01101100, %01000100, %01101100
	.DB	%01000100, %00111000, %01000100, %01000100, %01111000, %01000100
#ENDIF
;
MESSAGE:
	.DB	CR,LF,LF
	.DB	"This is an example User Application - why not create your own?",CR,LF
	.DB	"Please see the relevant User Guide section for more information."
	.DB	CR,LF,LF,LF
	.DB	"Press a key to return to Boot Loader.$"
;
; IT IS CRITICAL THAT THE FINAL BINARY BE EXACTLY USR_SIZ BYTES.
; THIS GENERATES FILLER AS NEEDED.  IT WILL ALSO FORCE AN ASSEMBLY
; ERROR IF THE SIZE EXCEEDS THE SPACE ALLOCATED.
;
SLACK	.EQU	(USR_END - $)
;
#IF (SLACK < 0)
	.ECHO	"*** USRAPP IS TOO BIG!!!\n"
	!!!	; FORCE AN ASSEMBLY ERROR
#ENDIF
;
	.FILL	SLACK,$00
	.ECHO	"User ROM space remaining: "
	.ECHO	SLACK
	.ECHO	" bytes.\n"
;
	.NOLIST
;
	.END
