Register

User Break Controller for SH7305

Talk about anything you like
Junior Member
User avatar
Posts: 3
Joined: Wed Feb 13, 2019 5:44 pm
Calculators: None

User Break Controller for SH7305

Postby Yatis » Thu Sep 05, 2019 4:13 pm

Hello everyone :)

Recently I try to create a UBC-tool for SH7305 (SH4 based MPU).
I use these addresses for the UBC's setup (based on SH4-A and SH7724 documentation).

FF200000 --> UBC.CBR0
FF200004 --> UBC.CRR0
FF200008 --> UBC.CAR0
FF20000C --> UBC.CAMR0
FF200020 --> UBC.CBR1
FF200024 --> UBC.CRR1
FF200028 --> UBC.CAR1
FF20002C --> UBC.CAMR1
FF200030 --> UBC.CDR1
FF200034 --> UBC.CDMR1
FF200038 --> UBC.CETR1
FF200600 --> UBC.CCMFR
FF200620 --> UBC.CBCR

But when I try to initialize or read the content of each register I've got 0x00000000, so I think that the UBC isn't here.
Can someone know where is the User Break Controller for SH7305 ? Or if the UBC has been removed ?

Thanks.

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: User Break Controller for SH7305

Postby SimonLothar » Fri Sep 06, 2019 11:34 pm

The UBC of the SH7305 exists and works as expected.
But the process to get it working is a bit complicated.
First you need some assembler run time library, which must be placed in an unused RAM-area.
I append the source of the assembler run time library only for a first reference. There are some include-files, which I did not add yet.
It is only one step of several.
You need a G3A to install and access the run time library and set up the UBC.
Then you would need some external device to visualize the UBC-interrupt-handler's reaction (F. i. I used the serial interface to send the data to some program on my PC).

Assembler-Source: Show
;;;;;;;;;;;;;;;;;;;;;;;;;;
; FD803000 is an assembler modul, which is designed to support the SH7305 UBC,
; install a basic exception/interrupt-redirection frame,
; exception/interrupt-redirection seems to be extremely simple on the SH7305-calculators,
; because the SH7305-OSes use a RAM-interrupt-handler-address-table.
;
; list of references:
; [1] renesas 7705-manual REV 2.00-2003.9.19
; [2] "SHC Manual.PDF" (included in the FX9860G SDK)
; [3] renesas 7730-manual Rev.3.00 2010.09
; the 7724 is a better match for the 7305, but its manual is under NDA.
;
; it is important to set the assembler-option -cpu=sh4, to have the assembler accept the DBR-instructions.
; though, the SH7305 does not contain a FPU.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;
; Hint: The formerly used RAM location 0xFD802000 cannot be used with fx-9860 SH-4 calculators. The range seems to be used by the OS on these calculators.
; The system provides for a standard wrapper, the entry point is the start of the binary.
; additionally the entrypoint is stored at offset 0x20.
; UserBreakIntHandler is the procedure, the exception/interrupt-system should be redirected to.
; the function to install the redirection is InstallUserBreak (function 8 of the jump-table).
;
;;;;;;;;;;;;;;;;;;;;;;;;;;
PROCESSOR_FAMILY: .DEFINE "SH-4A"
PROCESSOR: .DEFINE "7305"
; because there are some differences between fx-CG and fx-9860 SH-4, a Replacement Symbol OS is needed.
; it should be set in the hmake-file
.AIFDEF OS
.AELSE
.AERROR
.AENDI
;OS: .DEFINE "fxCG"
;OS: .DEFINE "fx9860"

.include "F:\CASIO\ASM_COMMON\SH_REGISTERS.SRC"
; OSfx.inc f. i. contains the syscall numbers, which are used.
.include "F:\CASIO\ASM_COMMON\OSfx.inc"
.include "F:\CASIO\ASM_COMMON\UBC.INC"

REDIRECT_EXCINT: .DEFINE "0"

REDIRECTION_EXCINT_EXAMPLE: .DEFINE "SERIAL_DUMP"
;REDIRECTION_EXCINT_EXAMPLE: .DEFINE "RAM_DUMP"
;DUMP_RAM: .DEFINE "h'880CB2D8"
;DUMP_RAM_SIZE: .DEFINE "h'00C0"
;DUMP_RAM_SIZE: .DEFINE "h'04B0"
;DUMP_RAM: .DEFINE "h'FD801450"
;DUMP_RAM_SIZE: .DEFINE "h'0040"
;DUMP_RAM: .DEFINE "h'FD801790"
;DUMP_RAM_SIZE: .DEFINE "h'0010"
;REDIRECTION_EXCINT_EXAMPLE .DEFINE "DISPLAY_REGISTERS"
PUTDISP_DD .DEFINE "1"

DRAW_WHAT: .DEFINE "VRAM"
DRAW_WITH_DELAY: .DEFINE "TRUE"

USB: .DEFINE "0"


.SECTION P,CODE,ALIGN=4
;;;;;;;;;;;;;;;;;;;;;;;;;;
Wrapper:
mov.l #TableStart, r2
SHLL2 r0
MOV.L @(r0,r2),r0
JMP @r0
NOP

?gap:
.RES.B h'20-(?gap-Wrapper)
; at offset h'20 of the binary file, the absolute wrapper address is stored
; prepared for future use
.DATA.L Wrapper
; the INT_COUNTER should stay located at offset 0x24. It is useful for basic diagnostic purposes.
INT_COUNTER .RES.L 1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.SECTION D,DATA,ALIGN=4
WAIT_FOR_SERIAL .RES.L 1

NO_ERROR .EQU 0
NOT_INSTALLED_ERROR .EQU 1
ALREADY_INSTALLED_ERROR .EQU 2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.ALIGN 4
TableStart:
.DATA.L Serial_DumpStack ; 0
.DATA.L SetInterruptHandler ; 1
.DATA.L GetInterruptHandler ; 2
.DATA.L GetTableStart ; 3
.DATA.L GetRunLibIDPtr ; 4
.DATA.L GetDBR ; 5
.DATA.L PostInstallation ; 6
.DATA.L unused_fno
.DATA.L InstallUserBreak ; 8
.DATA.L unused_fno
.DATA.L unused_fno
.DATA.L unused_fno

.SECTION P,CODE,ALIGN=4

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; int InstallUserBreak( void*ADDR )
; programs the USER BREAK CONTROLLER
; see [1], p. 562, si 12.12.2008
; see [3], p. 1016, si 12.04.2011
; if the parameter is zero, the UBC will be deactivated.

; typedef struct {
; int addr;
; int value;
; } TUBC;

; the parameter ADDR is a pointer to an array of TUBC
; the first item contains (h'55424300, 0) and is checked.
; if it is not as it should be, the UBC clock is switched off and the function quits.
; the last item contains h'55424300, h'FFFFFFFF and is checked to detect the end of the list.
; in between there are the register-addresses and values to set.
; if an register-address is zero, the item is ignored.
; "...Make sure to set all registers related to breaks before setting BBRA/BBRB." ([1], p. 555).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

InstallUserBreak:
mov.l r14, @-r15
mov.l #h'10000000, r2
stc sr, r3
mov.l r3, @-r15
or r2, r3
ldc r3, sr ; block exceptions, interrupts and user breaks
; [1], p. 35; [3], p. 37

mov #0, r14

mov.l #WAIT_FOR_SERIAL, r3
mov #1, r0
mov.l r0, @r3

mov.l #UserBreakIntHandler, r3
ldc r3, DBR ; only possible with assembler-option cpu=sh4

; prepare UBC clock switching
mov.l #MSTPCR0, r3
mov.l @r3, r2

tst r4, r4 ; parameter valid?
bt ?UBC_Off

; the 1st item's addr-member has to be UBC_ID
mov.l @r4, r5
mov.l #UBC_ID, r0
cmp/eq r5, r0
bf ?UBC_Off

; the 1st item's value-member has to be zero
add #4, r4
mov.l @r4, r5
tst r5, r5
bt/s UBC_ON
add #4, r4

; switch Off UBC clock
?UBC_Off:
mov.l #MSTP017, r0
or r0, r2
mov.l r2, @r3

exit_InstallUserBreak
mov r14, r0

mov.l @r15+, r3
ldc r3, sr

rts
mov.l @r15+, r14

; switch ON UBC clock
UBC_ON:
mov.l #~MSTP017, r0
and r0, r2
bra ?UBC_setup_skip
mov.l r2, @r3

?UBC_setup_loop:
add #1, r14
mov.l @r4, r3

tst r3, r3 ; if addr-member is zero, then ignore
bt/s ?UBC_setup_skip
add #4, r4

mov.l #UBC_ID, r0
cmp/eq r3, r0
bt ?UBC_setup_quit

mov.l @r4, r0

mov.l #CBR0, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CRR0, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CAR0, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CAMR0, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CBR1, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CRR1, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CAR1, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CAMR1, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CDR1, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CDMR1, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CETR1, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CCMFR, r5
cmp/eq r3, r5
bt ?long_op

mov.l #CBCR, r5
cmp/eq r3, r5
bt ?long_op

bra ?UBC_setup_skip
nop

?byte_op:
add #4, r4
mov.l @r4, r5
tst r5, r5
bf ?byte_read

bra ?UBC_setup_skip
mov.b r0, @r3

?byte_read
bra ?UBC_setup_skip
mov.b @r3, r0

?word_op:
add #4, r4
mov.l @r4, r5
tst r5, r5
bf ?word_read

bra ?UBC_setup_skip
mov.w r0, @r3

?word_read
bra ?UBC_setup_skip
mov.w @r3, r0

?long_op:
add #4, r4
mov.l @r4, r5
tst r5, r5
bf ?long_read

bra ?UBC_setup_skip
mov.l r0, @r3

?long_read
mov.l @r3, r0

?UBC_setup_skip:
bra ?UBC_setup_loop
add #4, r4

?UBC_setup_quit:
; ICBI because of [3], p. 1020, note 1 A.
XICBI 3

bra exit_InstallUserBreak
add #1, r14

.POOL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UserBreakIntHandler
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
UserBreakIntHandler:
PUSH_EXP_BASE_REG
mov.l #h'12345678, r3
mov.l r3, @-r15
sts.l pr, @-r15

mov.l #INT_COUNTER, r3
mov.l @r3, r2
add #1, r2
mov.l r2, @r3

.AIF "PUTDISP_DD" EQ "1"
mov.l #syscall_entry, r2
mov.l #scBdisp_PutDisp_DD, r0
jsr @r2
nop
.AENDI

bsr Serial_DumpStack
nop

; mov.l #syscall_entry, r2
; mov.l #scMsgBoxPush, r0
; jsr @r2
; mov #4, r4

; mov.l #syscall_entry, r2
; mov.l #scBdisp_PutDisp_DD, r0
; jsr @r2
; nop

; mov.l #h'A44B0000, r3
; mov.w #h'4000, r2
; ?wait
; mov.w @r3, r0
; cmp/eq r2, r0
; bf ?wait

; mov.l #syscall_entry, r2
; mov.l #scMsgBoxPop, r0
; jsr @r2
; nop

lds.l @r15+, pr
mov.l @r15+, r3
POP_EXP_BASE_REG

STC SGR, R15 ; only possible with assembler-option cpu=sh4
rte
nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EXPERIMENTAL REDIRECTION FUNCTION
; the routine sends the stack to the serial interface (115kBaud, e, 8, 1)
; it pushes the stack pointer itself and an operation id onto the stack before sending
; this is done to include the informaton in the data stream.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Serial_DumpStack:
mov.l r13, @-r15 ; (1)
mov.l r14, @-r15 ; (1A)
sts.l pr, @-r15 ; (2)

mov.l r7, @-r15 ; (3)
mov.l r6, @-r15 ; (4)
mov.l r5, @-r15 ; (5)
mov.l r4, @-r15 ; (6)
mov.l r0, @-r15 ; (6A)

mov.l #SIZE_TO_DUMP, r14

.AIFDEF DUMP_RAM_SIZE
mov.l #DUMP_RAM_SIZE, r5
add r14, r5
.AELSE
mov r14, r5
.AENDI

mov.l r5, @-r15 ; push size to transfer (7)
mov.l r15, @-r15 ; push current stack pointer (7A)
mov.l #h'AA55A5A5, r13
mov.l r13, @-r15 ; push operation id (not currently used by the serial-receiver,
; but included for future use) (8)
; useful while inspecting the buffer

mov r15, r13 ; current stack pointer
add r15, r14

mov r14, r5
bsr innerDumpBuffer
mov r13, r4

.AIFDEF DUMP_RAM_SIZE
mov.l #DUMP_RAM, r13
mov.l #DUMP_RAM_SIZE, r14
add r13, r14
mov r14, r5
bsr innerDumpBuffer
mov r13, r4
.AENDI

ADD #h'C, r15 ; (8+7+7A)

mov.l @r15+, r0 ; (6A)
mov.l @r15+, r4 ; (6)
mov.l @r15+, r5 ; (5)
mov.l @r15+, r6 ; (4)
mov.l @r15+, r7 ; (3)

lds.l @r15+, pr ; (2)
mov.l @r15+, r14 ; (1A)
rts
mov.l @r15+, r13 ; (1)

;;;;;
innerDumpBuffer:
; open serial with 115kBaud, e, 8, 1
mov.l r13, @-r15 ; (1)
mov.l r14, @-r15 ; (1A)
sts.l pr, @-r15 ; (2)

add #-8, r15
mov r4, r13
mov r5, r14

mov r15, r4

mov #0, r0
mov.b r0, @r4
mov.b r0, @(3,r4)
mov.b r0, @(5,r4)
mov #9, r0
mov.b r0, @(1,r4)
mov #2, r0
mov.b r0, @(2,r4)
mov #1, r0
mov.b r0, @(4,r4)

; bra ?exit
; nop

mov.l #syscall_entry, r2
mov.l #scSerialOpen, r0
jsr @r2
nop

mov.l #syscall_entry, r2
mov.l #scSerialDisableInt, r0
jsr @r2
nop

?try_send:
bsr OneSend ; send next stack byte
mov.b @r13, r4

cmp/eq #NO_FIFO_SPACE, r0
bt ?try_send

tst r0, r0
bf ?try_close ; on any other error => quit

add #1, r13
cmp/hi r13, r14
bt ?try_send

?try_close:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; wait for serial ping
mov.l #WAIT_FOR_SERIAL, r3
mov.l @r3, r0
tst r0, r0
bt ?check_serial_2

?check_serial:
mov.l #SCFDR0, r3
mov.w @r3, r0
mov.w #h'001F, r2
and r2, r0

tst r0, r0
bt ?check_serial

mov.l #SCFRDR0, r3
mov.b @r3, r0
mov.b #"A", r2
cmp/eq r2, r0
bt ?exit_serial
mov.b #"B", r2
cmp/eq r2, r0
bf ?check_serial

mov.l #WAIT_FOR_SERIAL, r3
mov #0, r0
mov.l r0, @r3

bra ?exit_serial
nop

?check_serial_2:
mov.l #SCFDR0, r3
mov.w @r3, r0
mov.w #h'001F, r2
and r2, r0

tst r0, r0
bt ?exit_serial

mov.l #SCFRDR0, r3
mov.b @r3, r0
mov.b #"A", r2
cmp/eq r2, r0
bf ?exit_serial

mov.l #WAIT_FOR_SERIAL, r3
mov #1, r0
mov.l r0, @r3

?exit_serial
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

?try_close_loop:
mov.l #syscall_entry, r2
mov.l #scSerialClose, r0
; mov.l #scCommClose, r0
jsr @r2
mov.b #wait_for_pending_transmissions, r4

cmp/eq #transmissions_pending, r0
bt ?try_close_loop

try_close_loop_exit:
add #8, r15
lds.l @r15+, pr ; (2)
mov.l @r15+, r14 ; (1A)
rts
mov.l @r15+, r13 ; (1)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; the routine sends any memory range to the serial interface (115kBaud, e, 8, 1)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Serial_DumpBuffer:
sts.l pr, @-r15 ; (2)

bsr innerDumpBuffer

lds.l @r15+, pr ; (2)
rts
nop

OneSend:
mov.l #syscall_entry, r2
mov.l #scSerialTransmitOne, r0
jmp @r2
nop

fxCG_Syscall:
mov.l #SYSCALL_ENTRY, r2
jmp @r2
nop

;;;;; ( void*addr, int count )
innerDumpBufferX:
mov.l r14, @-r15 ; (1)
mov.l r13, @-r15 ; (1A)
sts.l pr, @-r15 ; (2)
mov.l r12, @-r15 ; (2A)
mov.l r11, @-r15 ; (2B)
mov.l r10, @-r15 ; (2C)
mov.l r9, @-r15 ; (2D)

mov r4, r10
mov r5, r11

mov.l #h'88030000-4, r14
mov.l @r14, r9
tst r9, r9
add #-1, r9
mov.l r9, @r14

bf ?memcpy_skip

mov.l #h'88030000, r14

?memcpy_RAM:
mov.l @r10, r12
mov.l r12, @r14

add #4, r10
cmp/hi r10, r11
bt/s ?memcpy_RAM
add #4, r14

; mov.l r10, @r14
; add #4, r14
; mov.l r11, @r14
; add #4, r14
; mov.l r14, @r14

?memcpy_skip:
mov.l @r15+, r9 ; (2D)
mov.l @r15+, r10 ; (2C)
mov.l @r15+, r11 ; (2B)
mov.l @r15+, r12 ; (2A)
lds.l @r15+, pr ; (2)
mov.l @r15+, r13 ; (1A)
rts
mov.l @r15+, r14 ; (1)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EXPERIMENTAL REDIRECTION FUNCTION
; the routine sends the stack to memory block 0x8803C000.
; This memory range is part of MCS, so check that it is actually not used.
; Sometimes useful in connection with an user-break-exception handler.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.AIF "OS" EQ "fx9860"

RAM_DumpStack:
mov r15, r5 ; memcpy source
mov.l r13, @-r15 ; (1)
mov.l r14, @-r15 ; (1A)
sts.l pr, @-r15 ; (2)

mov.l #h'88040000, r4 ; upper limit of system RAM (starting at 88030000)
mov.l #h'88024000, r6 ; stack upper limit
sub r5, r6 ; length of used stack
sub r6, r4 ; start address in stack sdadow area (target)

mov.l #h'8803C000, r1 ; stack shadow lower limit, normally never reached

mov.l #syscall_entry, r2
mov.l #scMemCpy, r0

jsr @r2 ; syscall
mov.l r4, @r1 ; save the current stack shadow top

lds.l @r15+, pr ; (2)
mov.l @r15+, r14 ; (1A)
rts
mov.l @r15+, r13 ; (1)

.POOL

.AENDI

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EXPERIMENTAL REDIRECTION FUNCTION
; the routine displays regsiters of interest and waits.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;DisplayRegisters:
;; mov.l r13, @-r15
;; mov.l r14, @-r15
;; sts.l pr, @-r15
;;
;; mov.l #debug_stack, r2
;; jsr @r2
;; mov #h'2c, r4
;;
;; lds.l @r15+, pr
;; mov.l @r15+, r14
;; rts
;; mov.l @r15+, r13

.POOL


; DEBUG DISPLAY
;
; bsr display_int_as_hex
; mov r12, r4

; bsr display_int_as_hex
; mov r13, r4

; bra ?return
; nop
;
; DEBUG DISPLAY


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; direct draw a pattern to the display
; used as debug aid. si 11.6.2009
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DrawPattern:
sts.l pr, @-r15

.AIF "DRAW_WHAT" EQ "PATTERN"
mov #32, r5
mov #h'FF, r6
bsr WriteToPage
mov #7, r4

mov #33, r5
mov #h'FF, r6
bsr WriteToPage
mov #7, r4

mov #34, r5
mov #h'FF, r6
bsr WriteToPage
mov #7, r4

.AELSE

bsr Bdisp_PutDisp_DD
nop

.AENDI

.AIF "DRAW_WITH_DELAY" EQ "TRUE"
mov.l #10000000, r4
?loop:
dt r4
bf ?loop
.AENDI


lds.l @r15+, pr
RTS
NOP

.POOL

WriteToPage:
mov #4, r3
mov.l #h'B4010000, r7
mov #7, r1
mov.l #h'B4000000, r0
mov.b r3, @r0
mov.w #h'C0, r2
or r2, r5
mov.b r5, @r7 ; reg4 : X (0..19)
mov.b r3, @r0
mov.b r4, @r7 ; reg4 : Y (0..63)
mov.b r1, @r0
rts
mov.b r6, @r7 ; reg7:DATA

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Bdisp_PutDisp_DD:
mov.l #syscall_entry, r2
mov.l #scBdisp_PutDisp_DD, r0
jmp @r2
nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; display_int_as_hex in a box
; r4 is the integer to display
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.AIF "OS" EQ "fx9860"

display_int_as_hex:
sts.l pr, @-r15 ; push pr
add #-h'C, r15 ; reserve some stack as working buffer

mov.l #syscall_entry, r2
mov.l #scLongToAscHex, r0
mov r15, r5 ; buffer
jsr @r2
mov #8, r6 ; digits

; draw a box
mov.l #syscall_entry, r2
mov.l #scDispBox, r0
jsr @r2
mov #3, r4 ; count of lines

; locate the cursor
mov #3, r5 ; row
bsr locate
mov #4, r4 ; column

; print a message
mov.l r15, r4
bsr Print
nop

; wait for any key
mov.l #syscall_entry, r2
mov.l #scGetKey, r0
jsr @r2
mov r15, r4

add #h'C, r15 ; restore stack
lds.l @r15+, pr ; pop pr

rts
nop

.POOL

.AENDI

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EXPERIMENTAL REDIRECTION FUNCTION
; Display something
; this is a demonstration of how to display a messagebox and wait for any key
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.AIF "OS" EQ "fx9860"

display_some:
mov.l r13, @-r15 ; push r13
sts.l pr, @-r15 ; push pr

add #-h'4, r15 ; reserve some stack as return buffer for getkey

bra ?label1
nop

mov.l #syscall_entry, r2
mov.l #scDispError, r0
jsr @r2
mov #2, r4

bra ?return
nop

?label1:
; draw a box
mov.l #syscall_entry, r2
mov.l #scDispBox, r0
jsr @r2
mov #5, r4 ; count of lines

; locate the cursor
mov #3, r5 ; row
bsr locate
mov #4, r4 ; column

; print a message
mov.l #TestMessage1, r4
bsr Print
nop

; locate the cursor
mov #5, r5 ; row
bsr locate
mov #5, r4 ; column

; print a message
mov.l #TestMessage2, r4
bsr Print
nop

; wait for any key
mov.l #syscall_entry, r2
mov.l #scGetKey, r0
jsr @r2
mov r15, r4

?return:
add #h'4, r15 ; adjust the stack pointer
lds.l @r15+, pr ; pop pr
rts
mov.l @r15+, r13 ; pop r13

Print:
sts.l pr, @-r15 ; push pr
mov.l #syscall_entry, r2
mov.l #scPrint, r0
jsr @r2
nop
lds.l @r15+, pr ; pop pr
rts
nop

locate:
sts.l pr, @-r15 ; push pr
mov.l #syscall_entry, r2
mov.l #scLocate, r0
jsr @r2
nop
lds.l @r15+, pr ; pop pr
rts
nop

.POOL

.AENDI

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; "unused"-dummy
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
unused_fno:
rts
nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; return a pointer to a ASCIZZ string list,
; which first two strings are displayed by INSIGHT after install
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetRunLibIDPtr:
mov.l #RunLibID, r0
rts
nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetDBR:
stc DBR, r0
rts
nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; this routine is a callback by INSIGHT after RunLib installation
; if it returns 0, INSIGHT does nothing
; if it returns bit 0 set (0x01), INSIGHT appends a file,
; which name's pointer has to be returned in r4
; (the files start and length is stored in the RunLib information block
; starting at #h'801FFFE0)
; if it returns bit 1 set (0x02), INSIGHT autoinstalls an experimental exception/interrupt hook
; (see below)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PostInstallation:
mov #0, r0 ; install none
.AIF "REDIRECT_EXCINT" EQ "1"
or #2, r0
.AENDI
rts
nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; void SetInterruptHandler( int intno, void*handler );
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SetInterruptHandler:
mov.l #RAM_INTERRUPT_TABLE, r2
shll2 r4
add r2, r4
mov.l @r4, r1
rts
mov.l r5, @r4

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; int GetInterruptHandler( int intno, void*handler );
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetInterruptHandler:
mov.l #RAM_INTERRUPT_TABLE, r2
shll2 r4
add r2, r4
rts
mov.l @r4, r0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; int GetTableStart( void );
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetTableStart:
mov.l #TableStart, r0
rts
nop

; .include "fxCG_display.src"
; .include "fxCG_DEBUG.src"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.SECTION C,DATA,ALIGN=4
RunLibID:
.AIF "OS" EQ "fx9860"
.SDATAZ "UBC fx9860 SH-4 RTL"
.AENDI
.AIF "OS" EQ "fxCG"
.SDATAZ "UBC fxCG RTL"
.AENDI
.include "RunLib_version.inc"
.include "datetime.inc"

.SDATAZ ""

TestMessage1:
.SDATAZ "Redirection OK!"
TestMessage2:
.SDATAZ " Congrats!"


.END
I'll be back!

Junior Member
User avatar
Posts: 3
Joined: Wed Feb 13, 2019 5:44 pm
Calculators: None

Re: User Break Controller for SH7305

Postby Yatis » Fri Oct 18, 2019 2:35 pm

Hello!

Sorry for this late response. I'm glad to know that the UBC exists on SH7305 but when I try to read or write into it, I see only 0x00000000.
So the UBC's addresses that I use is good? Why I can not use it even when I am in the P1 area?

Thanks.

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: User Break Controller for SH7305

Postby SimonLothar » Wed Oct 23, 2019 5:00 am

Yatis wrote:I'm glad to know that the UBC exists on SH7305 but when I try to read or write into it, I see only 0x00000000.
So the UBC's addresses that I use is good? Why I can not use it even when I am in the P1 area?


Modules, which usually are not used in the calculator's OS, must be switched on.

Search for "switch ON UBC clock" in the assembler piece, which I added in my previous post.
I'll be back!

Return to Free Discussion

Who is online

Users browsing this forum: No registered users and 9 guests