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
I tried setting it to 18 early on, made no odds.