You will not be able to post if you are still using Microsoft email addresses such as Hotmail etc
See here for more information viewtopic.php?f=20&t=7296
BOOKMARK THIS PAGE !
https://www.exxosforum.co.uk:8085/IP_CHECK/
You can unban yourself if needed. It also sends me reports to investigate the ban.
DO NOT USE MOBILE / CGNAT DEVICES WHERE THE IP CHANGES CONSTANTLY!
At this time, it is unfortunately not possible to whitelist users when your IP changes constantly.
You may inadvertently get banned because a previous attack may have used the IP you are now on.
So I suggest people only use fixed IP address devices until I can think of a solution for this problem!

Converting HISOFT to 68K ASM "almost" works

News,announcements,programming,fixes,game patches & discussions.
User avatar
exxos
Site Admin
Site Admin
Posts: 27960
Joined: 16 Aug 2017 23:19
Location: UK

Re: Converting HISOFT to 68K ASM "almost" works

Post by exxos »

mrbombermillzy wrote: 09 Feb 2026 20:41 Looks like its using GEMDOS function $09 PRINT LINE which converts numerical data into character data.

Im sure the routine that does the conversion needs further study then... :coffee:
I dunno whats going on, about had enough for today :)

So far setting the year to 26 has come back as 28 and 42 now. Seems like those odd BCD type issues I had years ago.
User avatar
mrbombermillzy
Moderator
Moderator
Posts: 2259
Joined: 03 Jun 2018 19:37

Re: Converting HISOFT to 68K ASM "almost" works

Post by mrbombermillzy »

exxos wrote: 09 Feb 2026 20:45
mrbombermillzy wrote: 09 Feb 2026 20:41 Looks like its using GEMDOS function $09 PRINT LINE which converts numerical data into character data.

Im sure the routine that does the conversion needs further study then... :coffee:
I dunno whats going on, about had enough for today :)

So far setting the year to 26 has come back as 28 and 42 now. Seems like those odd BCD type issues I had years ago.
Yeah, I will have to come back to this. Are you still using the 2nd iteration of code?

Somewhere I recall seeing an addition of 20 to a register. If thats being used, perhaps remove the addition as it could be interpreting as '2' (which will cause the value 26+2=28...possibly.
User avatar
exxos
Site Admin
Site Admin
Posts: 27960
Joined: 16 Aug 2017 23:19
Location: UK

Re: Converting HISOFT to 68K ASM "almost" works

Post by exxos »

mrbombermillzy wrote: 09 Feb 2026 21:01 Yeah, I will have to come back to this. Are you still using the 2nd iteration of code?
Yeah, but ive been stripping things out.. So this is the current base code..

Code: Select all

* Atari ST 68000 Assembly for Devpac
* Original working RTC read code (HiSoft BASIC compatible)
* + Added: set GEMDOS system date/time when no errors
* Updated now:
*   - Removed the "error flag" usage entirely
*   - Mask RTC reads to low byte with ANDI.W #$00FF (no +256 / -$FF00 tricks)
*   - No other behavioural changes intended (corruption messages still print)

        SECTION TEXT

START:
        jsr     GETRTCTIMEDATE
        clr.w   -(sp)
        trap    #1

* BusyWait - returns d0=0 ok, d0=1 timeout
BUSYWAIT:
        movem.l d1/a0,-(sp)
        move.l  #10000,d1
.loop:
        move.w  #$FF0A,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask to low byte
        btst    #7,d0           ; UIP bit
        beq.s   .ok
        subq.l  #1,d1
        bne.s   .loop
        moveq   #1,d0
        bra.s   .exit
.ok:
        moveq   #0,d0
.exit:
        movem.l (sp)+,d1/a0
        rts

GETRTCTIMEDATE:
        movem.l d0-d7/a0-a1,-(sp)

        jsr     BUSYWAIT
        tst.w   d0
        beq.s   .notimeout
        pea     MSG_TIMEOUT(PC)
        move.w  #9,-(sp)
        trap    #1
        addq.l  #6,sp
        bra     .exit
.notimeout:

* Seconds (reg 0)
        move.w  #$FF00,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask
        move.w  d0,d6           ; S%

        jsr     BUSYWAIT

* Minutes (reg 2)
        move.w  #$FF02,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask
        move.w  d0,d5           ; M%

        jsr     BUSYWAIT

* Hours (reg 4)
        move.w  #$FF04,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask
        cmpi.w  #128,d0
        blo.s   .no_pm
        subi.w  #128,d0         ; clear PM bit
.no_pm:
        move.w  d0,d4           ; H%

* Time validity (messages only; no error flag)
        cmpi.w  #24,d4
        bhi.s   .timecorr
        cmpi.w  #60,d5
        bhi.s   .timecorr
        cmpi.w  #60,d6
        bhi.s   .timecorr
        bra.s   .timeok
.timecorr:
        pea     MSG_CORRUPTED(PC)
        move.w  #9,-(sp)
        trap    #1
        addq.l  #6,sp
.timeok:

* Weekday (reg 6)
        move.w  #$FF06,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask
        move.w  d0,d3           ; DY%

* Day (reg 7)
        move.w  #$FF07,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask
        move.w  d0,d2           ; DATE%

* Month (reg 8)
        move.w  #$FF08,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask
        move.w  d0,d1           ; MTH%

* Year (reg 9)
        move.w  #$FF09,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask
        move.w  d0,d7           ; save YR in d7

* Check date validity (messages only; no error flag)
        cmpi.w  #7,d3
        bhi.s   .datecorr
        cmpi.w  #32,d2
        bhi.s   .datecorr
        cmpi.w  #12,d1
        bhi.s   .datecorr
        bra.s   .dateok
.datecorr:
        pea     MSG_CORRUPTED(PC)
        move.w  #9,-(sp)
        trap    #1
        addq.l  #6,sp
.dateok:

* DM bit check (binary mode) (message only; no error flag)
        jsr     BUSYWAIT
        move.w  #$FF0B,(RTC_ADDR)
        move.w  (RTC_DATA),d0
        andi.w  #$00FF,d0       ; <-- mask
        btst    #2,d0           ; DM=1 (binary)
        bne.s   .dmok
        pea     MSG_CORRUPTED(PC)
        move.w  #9,-(sp)
        trap    #1
        addq.l  #6,sp
.dmok:

* --------- set GEMDOS system date/time ----------
        jsr     SET_SYSTEM_TIME

.print_only:
* Print: H M S DATE MTH YEAR
        move.w  d4,d0
        jsr     PRINT_NUM
        move.w  d5,d0
        jsr     PRINT_NUM
        move.w  d6,d0
        jsr     PRINT_NUM
        move.w  d2,d0
        jsr     PRINT_NUM
        move.w  d1,d0
        jsr     PRINT_NUM
        move.w  d7,d0           ; year from d7 (00-99)
        jsr     PRINT_NUM

.exit:
        movem.l (sp)+,d0-d7/a0-a1
        rts

* ------------------------------------------------------------
* SET_SYSTEM_TIME
* Uses: d4=hour d5=min d6=sec d2=day d1=month d7=year(00-99)
* Assumes RTC year is 2000-2099 -> years since 1980 = 20 + year
*
* GEMDOS:
*   Tsetdate (0x2B): packed date = ((year-1980)<<9) | (month<<5) | day
*   Tsettime (0x2D): packed time = (hour<<11) | (min<<5) | (sec>>1)
*
* Note: 68000 immediate shifts only allow #1..#8, so we split <<9 and <<11.
* ------------------------------------------------------------
SET_SYSTEM_TIME:
        movem.l d1-d3,-(sp)

* ---- Pack date into d2.w ----
        move.w  d2,d3           ; save DAY into d3

        move.w  d7,d2           ; year 00-99
        andi.w  #$00FF,d2       ; safety mask
        addi.w  #20,d2          ; years since 1980 (assumes 2000-2099)

        lsl.w   #8,d2           ; <<9 (part 1)
        lsl.w   #1,d2           ; <<9 (part 2)

        andi.w  #$00FF,d1       ; safety mask month
        lsl.w   #5,d1           ; month<<5  (d1 saved by movem)
        or.w    d1,d2
        andi.w  #$00FF,d3       ; safety mask day
        or.w    d3,d2           ; OR in day

        move.w  d2,-(sp)
        move.w  #$2B,-(sp)      ; Tsetdate
        trap    #1
        addq.l  #4,sp

* ---- Pack time into d3.w ----
        move.w  d4,d3           ; hour
        andi.w  #$00FF,d3       ; safety mask

        lsl.w   #8,d3           ; <<11 (part 1)
        lsl.w   #3,d3           ; <<11 (part 2)

        move.w  d5,d1           ; min
        andi.w  #$00FF,d1       ; safety mask
        lsl.w   #5,d1           ; min<<5
        or.w    d1,d3

        move.w  d6,d1           ; sec
        andi.w  #$00FF,d1       ; safety mask
        lsr.w   #1,d1           ; sec>>1
        or.w    d1,d3

        move.w  d3,-(sp)
        move.w  #$2D,-(sp)      ; Tsettime
        trap    #1
        addq.l  #4,sp

        movem.l (sp)+,d1-d3
        rts

* PRINT_NUM: prints 0-99 as decimal string + CRLF (no leading zero)
PRINT_NUM:
        movem.l d1/a1,-(sp)
        lea     BUFFER(PC),a1
        cmpi.w  #10,d0
        bcs.s   .one
        clr.l   d1              ; clear high word for clean dividend
        move.w  d0,d1
        divu.w  #10,d1
        swap    d1              ; remainder in low
        addi.b  #'0',d1
        move.b  d1,1(a1)        ; units
        swap    d1              ; quotient in low
        addi.b  #'0',d1
        move.b  d1,(a1)         ; tens
        moveq   #2,d1
        bra.s   .out
.one:
        addi.b  #'0',d0
        move.b  d0,(a1)
        moveq   #1,d1
.out:
        clr.b   (a1,d1.w)
        pea     (a1)
        move.w  #9,-(sp)
        trap    #1
        addq.l  #6,sp
        pea     CRLF(PC)
        move.w  #9,-(sp)
        trap    #1
        addq.l  #6,sp
        movem.l (sp)+,d1/a1
        rts

        SECTION DATA
RTC_ADDR        EQU     $FF89F0
RTC_DATA        EQU     $FF89F2

MSG_TIMEOUT     DC.B    'RTC TIME OUT!',13,10,0
MSG_CORRUPTED   DC.B    'RTC TIME IS CORRUPTED',13,10,0
CRLF            DC.B    13,10,0

        SECTION BSS
BUFFER          DS.B    10

        END

Somewhere I recall seeing an addition of 20 to a register. If thats being used, perhaps remove the addition as it could be interpreting as '2' (which will cause the value 26+2=28...possibly.
I tried setting it to 18 early on, made no odds.
User avatar
exxos
Site Admin
Site Admin
Posts: 27960
Joined: 16 Aug 2017 23:19
Location: UK

Re: Converting HISOFT to 68K ASM "almost" works

Post by exxos »

Tried a hardwired clock set and that fails same way also.

Code: Select all

* Atari ST 68000 Assembly for Devpac
* Bare-bones sanity test:
*   Hardwire date = 09/02/2026 and time = 00:00:00
*   Calls GEMDOS Tsetdate/Tsettime only (no RTC access at all)
*
* Date packing (Tsetdate, opcode $2B):
*   bits 0-4  = day   (1-31)
*   bits 5-8  = month (1-12)
*   bits 9-15 = year since 1980
*
* For 09/02/2026:
*   year since 1980 = 2026-1980 = 46
*   packed_date = (46<<9) | (2<<5) | 9
*
* Time packing (Tsettime, opcode $2D):
*   bits 0-4  = seconds/2
*   bits 5-10 = minutes
*   bits 11-15= hours
* For 00:00:00 => packed_time = 0

        SECTION TEXT

START:
        jsr     SET_KNOWN_DATETIME
        clr.w   -(sp)           ; Pterm0
        trap    #1

* ------------------------------------------------------------
* SET_KNOWN_DATETIME
* Sets system date/time to 09/02/2026 00:00:00
* ------------------------------------------------------------
SET_KNOWN_DATETIME:
        movem.l d0-d2,-(sp)

* ---- Build packed date in d0.w ----
* day=9, month=2, year_since_1980=46
        move.w  #46,d0          ; year_since_1980
        lsl.w   #8,d0           ; <<9 (68000 shift immed max is 8)
        lsl.w   #1,d0

        move.w  #2,d1           ; month
        lsl.w   #5,d1           ; month<<5
        or.w    d1,d0

        or.w    #9,d0           ; day

* Call GEMDOS Tsetdate(date)
        move.w  d0,-(sp)
        move.w  #$2B,-(sp)
        trap    #1
        addq.l  #4,sp

* ---- Build packed time in d0.w ----
* 00:00:00 => 0
        clr.w   d0

* Call GEMDOS Tsettime(time)
        move.w  d0,-(sp)
        move.w  #$2D,-(sp)
        trap    #1
        addq.l  #4,sp

        movem.l (sp)+,d0-d2
        rts

        END
Capture.PNG

I took out flashyclock.. as well. But wonder if the keyboard RTC is getting in the way somehow :shrug:

That return value nails it:

Gettime returned 00490000

upper word (date) = 0049

lower word (time) = 0000

Decode 0049 as a packed GEMDOS-style date:

day = 0x0049 & 0x1F = 9

month= (0x0049 >> 5) & 0x0F = 2

year = (0x0049 >> 9) & 0x7F = 0 → 1980

So XBIOS Gettime is giving you 09/02/1980, exactly matching CP.

Why your year won’t set via XBIOS on your machine

On STs, XBIOS Settime(22) / Gettime(23) talk to the IKBD (keyboard controller) clock (“hardware clock” in TOS docs). That IKBD clock has well-known limitations/bugs around the year, and many setups effectively behave as if the year is fixed at 0 (=1980) or can’t be set reliably. This matches your observation perfectly.

So:

GEMDOS Tsetdate/Tsettime works (you proved it: 5C49/0000)

XBIOS Settime does NOT accept/store the year on your current configuration (it returns year=0)

Control Panel is showing the IKBD/XBIOS clock, not GEMDOS.

That also explains why removing your separate RTC chip changed behaviour earlier: CP is fundamentally tied to the “hardware clock” path (IKBD/XBIOS), and GEMDOS is a separate software-maintained system clock unless TOS syncs them.

Bottom line

Your GEMDOS code is correct.

CP is reading XBIOS Gettime, which on your setup is effectively stuck at year 1980 (year field 0).

To make CP show 2026, you need a tool/patch that fixes the IKBD/XBIOS year handling, or a CP that displays GEMDOS time instead.

There are existing “Y2K/Y2K+” style patches/utilities that intercept XBIOS time calls and apply an offset so modern years display correctly (e.g., fixes that map 2024↔1992 internally).
You do not have the required permissions to view the files attached to this post.
User avatar
mrbombermillzy
Moderator
Moderator
Posts: 2259
Joined: 03 Jun 2018 19:37

Re: Converting HISOFT to 68K ASM "almost" works

Post by mrbombermillzy »

My next step would be to break out the debugger and work back (if its incorrect) from the final number - stored as a string - in a1 to check the string is correct values before it goes into the GEMDOS 'set date' funtion ($2b). Just above the rts in PRINT_NUM function would be a good place to look at the location 'BUFFER' or the a1 stream working back from its current position.

Also, Im not sure about all that rotating.for the 'set date' function. Very hard to read. Simplify by changing:

Code: Select all

* ---- Pack date into d2.w ----
        move.w  d2,d3           ; save DAY into d3

        move.w  d7,d2           ; year 00-99
        andi.w  #$00FF,d2       ; safety mask
        addi.w  #20,d2          ; years since 1980 (assumes 2000-2099)

        lsl.w   #8,d2           ; <<9 (part 1)
        lsl.w   #1,d2           ; <<9 (part 2)

        andi.w  #$00FF,d1       ; safety mask month
        lsl.w   #5,d1           ; month<<5  (d1 saved by movem)
        or.w    d1,d2
        andi.w  #$00FF,d3       ; safety mask day
        or.w    d3,d2           ; OR in day

        move.w  d2,-(sp)
        move.w  #$2B,-(sp)      ; Tsetdate
        trap    #1
        addq.l  #4,sp
to:

Code: Select all

* ---- Pack date into d2.w ----

        move.w  #%0101110001001001,-(sp)
        move.w  #$2B,-(sp)      ; Tsetdate
        trap    #1
        addq.l  #4,sp
Ive (hopefully correctly) calculated the packed date to give 9th Feb 2026. Try this 'hardwired' date with this changed and see what happens.
User avatar
exxos
Site Admin
Site Admin
Posts: 27960
Joined: 16 Aug 2017 23:19
Location: UK

Re: Converting HISOFT to 68K ASM "almost" works

Post by exxos »

@mrbombermillzy we crossed streams a bit..
viewtopic.php?p=139581#p139581

Its a TOS issue it seems..
User avatar
mrbombermillzy
Moderator
Moderator
Posts: 2259
Joined: 03 Jun 2018 19:37

Re: Converting HISOFT to 68K ASM "almost" works

Post by mrbombermillzy »

I see. I will let Anders take the baton then. :D
User avatar
agranlund
Site sponsor
Site sponsor
Posts: 1706
Joined: 18 Aug 2019 22:43
Location: Sweden

Re: Converting HISOFT to 68K ASM "almost" works

Post by agranlund »

mrbombermillzy wrote: 09 Feb 2026 23:28 I see. I will let Anders take the baton then. :D
No, no, i dont want a baton :D
Just posted some ancient code that may or may not be relevant in case it would be useful to someone :)
User avatar
stephen_usher
Site sponsor
Site sponsor
Posts: 7229
Joined: 13 Nov 2017 19:19
Location: Oxford, UK.

Re: Converting HISOFT to 68K ASM "almost" works

Post by stephen_usher »

Oh, and not that it matters in this case, but the STe ROM sets the time differently to the original ST, giving a different time when read back.
Intro retro computers since before they were retro...
ZX81->Spectrum->Memotech MTX->Sinclair QL->520STM->BBC Micro->TT030->PCs & Sun Workstations.
Added code to the MiNT kernel (still there the last time I checked) + put together MiNTOS.
Collection now with added Macs, Amigas, Suns and Acorns.
User avatar
exxos
Site Admin
Site Admin
Posts: 27960
Joined: 16 Aug 2017 23:19
Location: UK

Re: Converting HISOFT to 68K ASM "almost" works

Post by exxos »

Well that didn't work then, it just loads and then just resets the machine :(

Code: Select all

;--------------------------------------------------------------
; DS12885 RTC driver for agranlund/rtc framework (CORE.S)
; GenST Macro Assembler compatible
;--------------------------------------------------------------

DEV_BASE_ADDR	EQU	$FF89F0
DEV_WRITE_ADDR	EQU	$FF89F0
DEV_READ_ADDR	EQU	$FF89F2
DEV_NVRAM_SIZE	EQU	$80
DEV_CONF4	EQU	0
DEV_CONF5	EQU	0
DEV_CONF6	EQU	0
DEV_CONF7	EQU	0

	include "CORE.S"

RTC_ADDR	EQU	$FF89F0
RTC_DATA	EQU	$FF89F2

	SECTION TEXT

;--------------------------------------------------------------
; Low-level helpers
;--------------------------------------------------------------
rtc_read:			; d0.w = reg, returns d0.w = value (0-255)
	move.w	d0,(RTC_ADDR)
	move.w	(RTC_DATA),d0
	andi.w	#$00FF,d0
	rts

rtc_write:			; d0.w = reg, d1.w = value (low byte used)
	move.w	d0,(RTC_ADDR)
	move.w	d1,(RTC_DATA)
	rts

;--------------------------------------------------------------
devInit:				; d0.l = return status, 0=failed, 1=ok
;--------------------------------------------------------------
	moveq	#1,d0
	rts

;--------------------------------------------------------------
;devGetTime:			; d0.l = return in TOS format (date<<16 | time)
;--------------------------------------------------------------
devGetTime:
	movem.l	d1-d7,-(sp)

	; read RTC fields (binary assumed)
	moveq	#0,d0
	bsr	rtc_read
	move.w	d0,d6			; sec

	moveq	#2,d0
	bsr	rtc_read
	move.w	d0,d5			; min

	moveq	#4,d0
	bsr	rtc_read
	move.w	d0,d4			; hour

	moveq	#7,d0
	bsr	rtc_read
	move.w	d0,d2			; day

	moveq	#8,d0
	bsr	rtc_read
	move.w	d0,d1			; month

	moveq	#9,d0
	bsr	rtc_read
	move.w	d0,d7			; year 00-99

	; pack date
	addi.w	#20,d7			; year_since_1980 = 20 + year (assume 2000-2099)
	move.w	d7,d3
	lsl.w	#8,d3
	lsl.w	#1,d3			; <<9 total
	lsl.w	#5,d1			; month<<5
	or.w	d1,d3
	or.w	d2,d3			; day

	; pack time
	move.w	d4,d0			; hour
	lsl.w	#8,d0
	lsl.w	#3,d0			; <<11 total
	lsl.w	#5,d5			; min<<5
	or.w	d5,d0
	lsr.w	#1,d6			; sec>>1
	or.w	d6,d0

	; combine long
	swap	d3
	move.w	d0,d3
	move.l	d3,d0

	movem.l	(sp)+,d1-d7
	rts

;--------------------------------------------------------------
;devSetTime:			; d0.l = input in TOS format (date<<16 | time)
;--------------------------------------------------------------
devSetTime:
	movem.l	d1-d7,-(sp)

	; split input
	move.l	d0,d3
	swap	d3				; d3.w = packed date
	move.w	d0,d4			; d4.w = packed time

	; unpack date
	move.w	d3,d7
	lsr.w	#8,d7
	lsr.w	#1,d7			; >>9 total
	subi.w	#20,d7			; back to 00-99

	move.w	d3,d1
	lsr.w	#5,d1
	andi.w	#$000F,d1		; month

	move.w	d3,d2
	andi.w	#$001F,d2		; day

	; unpack time
	move.w	d4,d6
	andi.w	#$001F,d6
	lsl.w	#1,d6			; sec

	move.w	d4,d5
	lsr.w	#5,d5
	andi.w	#$003F,d5		; min

	lsr.w	#8,d4
	lsr.w	#3,d4			; hour >>11

	; freeze updates (SET=1)
	moveq	#$0B,d0
	bsr	rtc_read
	ori.w	#$0080,d0
	move.w	d0,d1
	moveq	#$0B,d0
	bsr	rtc_write

	; write RTC regs
	moveq	#0,d0
	move.w	d6,d1
	bsr	rtc_write

	moveq	#2,d0
	move.w	d5,d1
	bsr	rtc_write

	moveq	#4,d0
	move.w	d4,d1
	bsr	rtc_write

	moveq	#7,d0
	move.w	d2,d1
	bsr	rtc_write

	moveq	#8,d0
	move.w	d1,d1			; month still in d1
	bsr	rtc_write

	moveq	#9,d0
	move.w	d7,d1
	bsr	rtc_write

	; unfreeze (SET=0)
	moveq	#$0B,d0
	bsr	rtc_read
	andi.w	#$007F,d0
	move.w	d0,d1
	moveq	#$0B,d0
	bsr	rtc_write

	movem.l	(sp)+,d1-d7
	rts

;--------------------------------------------------------------
;devReadNVram:		; a0 = buffer, d0 = start, d1 = length (stub)
;--------------------------------------------------------------
devReadNVram:
	rts

;--------------------------------------------------------------
;devWriteNVram:		; a0 = buffer, d0 = start, d1 = length (stub)
;--------------------------------------------------------------
devWriteNVram:
	rts

Return to “SOFTWARE PROGRAMMING & DISCUSSION”

Who is online

Users browsing this forum: CCBot and 57 guests