; RISC OS support code for pgp
; (c) 1997 Philipp Hullmann <hullmann@nano.fkp.uni-hannover.de>

	GET	s.arm_regs

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Code

	AREA	|C$$code|, CODE, READONLY

filetype_mask
	DCD	&000fff00
topbit_mask
	DCD	&fff00000

XOS_WriteC			*	&20000
XOS_ReadC			*	&20004
XOS_Byte			*	&20006
XOS_File			*	&20008
XOS_ReadModeVariable		*	&20035
XTerritory_ReadCurrentTimeZone	*	&63048

;---------------------------------------------------------------------
; Write a character to the current output stream. Unfortunately,
; output to stdout via stdio functions gets GSTrans'ed, so we have
; to use the low-level SWI.
;
; void os_writec(char c);

	EXPORT	os_writec
wrcn_s	DCD	"os_writec"
	ALIGN	4
wrcn_e	DCD	&ff000000 + wrcn_e - wrcn_s

os_writec
	SWI	XOS_WriteC
	MOVS	pc, lr

;---------------------------------------------------------------------
; int read_screen_width(void);

	EXPORT	read_screen_width
rswn_s	DCD	"read_screen_width"
	ALIGN	4
rswn_e	DCD	&ff000000 + rswn_e - rswn_s

read_screen_width
	MOV	a1, #135
	SWI	XOS_Byte
	MOV	a1, a3			; screen mode number
	MOV	a2, #1			; number of text columns - 1
	SWIVC	XOS_ReadModeVariable
	ADD	a1, a3, #1
	MOVVS	a1, #0
	MOVCS	a1, #0
	MOVS	pc, lr


;---------------------------------------------------------------------
; int read_screen_height(void);

	EXPORT	read_screen_height
rshn_s	DCD	"read_screen_height"
	ALIGN	4
rshn_e	DCD	&ff000000 + rshn_e - rshn_s

read_screen_height
	MOV	a1, #135
	SWI	XOS_Byte
	MOV	a1, a3			; screen mode number
	MOV	a2, #2			; number of text rows - 1
	SWIVC	XOS_ReadModeVariable
	ADD	a1, a3, #1
	MOVVS	a1, #0
	MOVCS	a1, #0
	MOVS	pc, lr


; --------------------------------------------------------------------
; Read object type
; int read_object_type(const char *filename);

	EXPORT	read_object_type

rotn_s	DCB 	"read_object_type", 0
	ALIGN	4
rotn_e	DCD	&ff000000 + rotn_e - rotn_s

read_object_type
	MOV	ip, sp
	STMFD	sp!, {v1, v2, fp, ip, lr, pc}
	SUB	fp, ip, #4
	CMP	sp, sl
	BLLT	|x$stack_overflow|

	MOV	a2, a1		; pointer to file name
	MOV	a1, #5		; read catalogue info, use File$Path
	SWI	XOS_File	; corrupts v1 and v2!
	MOVVS	a1, #0		; return 0 in case of an error
	LDMEA	fp, {v1, v2, fp, sp, pc}^	; return

; --------------------------------------------------------------------
; Read the file type
; int read_filetype(const char *filename);

	EXPORT	read_filetype

rdftn_s	DCB 	"read_filetype", 0
	ALIGN	4
rdftn_e	DCD	&ff000000 + rdftn_e - rdftn_s

read_filetype
	MOV	ip, sp
	STMFD	sp!, {v1, v2, fp, ip, lr, pc}
	SUB	fp, ip, #4
	CMP	sp, sl
	BLLT	|x$stack_overflow|

	MOV	a3, a2		; file type
	MOV	a2, a1		; pointer to file name
	MOV	a1, #5
	SWI	XOS_File
	MVNVS	a1, #1		; return -1 in case of an error
	BVS	read_filetype_end
	LDR	a3, topbit_mask
	AND	a1, a2, a3
	CMP	a1, a3
	MVNNE	a1, #1
	BNE	read_filetype_end
	LDR	a3, filetype_mask
	AND	a4, a2, a3
	MOV	a1, a4, LSR #8
read_filetype_end
	LDMEA	fp, {v1, v2, fp, sp, pc}^	; return

; --------------------------------------------------------------------
; Set the file type
; void set_filetype(const char *filename, int type);

	EXPORT	set_filetype

stftn_s	DCB 	"set_filetype", 0
	ALIGN	4
stftn_e	DCD	&ff000000 + stftn_e - stftn_s

set_filetype
	MOV	ip, sp
	STMFD	sp!, {v1, v2, fp, ip, lr, pc}
	SUB	fp, ip, #4
	CMP	sp, sl
	BLLT	|x$stack_overflow|

	MOV	a3, a2		; file type
	MOV	a2, a1		; pointer to file name
	MOV	a1, #18
	SWI	XOS_File
	LDMEA	fp, {v1, v2, fp, sp, pc}^	; return

; --------------------------------------------------------------------
; Read the offset from UTC to the current time zone in centiseconds
; int read_timezone(void);

	EXPORT	read_timezone

rtznn_s	DCB 	"read_timezone", 0
	ALIGN	4
rtznn_e	DCD	&ff000000 + rtznn_e - rtznn_s

read_timezone
	SWI	XTerritory_ReadCurrentTimeZone
	MOVVS	a1, #0
	MOVVC	a1, a2
	MOVS	pc, lr		; return

; --------------------------------------------------------------------
; Read a character from the keyboard,
; int getch(void);

	EXPORT	getch

gtchn_s	DCB 	"getch", 0
	ALIGN	4
gtchn_e	DCD	&ff000000 + gtchn_e - gtchn_s

getch
	SWI	XOS_ReadC
	MOVVS	a1, #0
	MOVCS	a1, #0
	MOVS	pc, lr		; return


; --------------------------------------------------------------------
; Check if there is a character in the kbd buffer
; int kbhit(void);

	EXPORT	kbhit

kbhtn_s	DCB 	"kbhit", 0
	ALIGN	4
kbhtn_e	DCD	&ff000000 + kbhtn_e - kbhtn_s

kbhit
	MOV	a1, #145
	MOV	a2, #0
	MOV	a3, #0
	SWI	XOS_Byte
	CMP	a3, #0
	MOVEQ	a1, #0
	BEQ	kbhit_end
	MOV	a1, #138	; re-insert byte into kbd buffer
	MOV	a2, #0
	SWI	XOS_Byte
	MOV	a1, #1
kbhit_end
	MOVS	pc, lr		; return

	END
