mirror of
https://github.com/mgcaret/davex-mg-utils.git
synced 2024-10-10 11:23:37 +00:00
181 lines
5.5 KiB
ArmAsm
181 lines
5.5 KiB
ArmAsm
; %help
|
|
; setyear - Patch the ProDOS year table in-memory
|
|
;
|
|
; usage: setyear <00-99> [-v] [-n]
|
|
;
|
|
; Patches the ProDOS year table to include the given year plus at least
|
|
; 4 more years beyond.
|
|
;
|
|
; Options: -v Show generated year table
|
|
; -n Don't actually patch ProDOS.
|
|
; %hend
|
|
|
|
.p02
|
|
.include "davex-mg.inc"
|
|
|
|
tmp = xczpage
|
|
year = tmp+1
|
|
count = year+1
|
|
|
|
prbyte = $fdda
|
|
;cout = $fded
|
|
|
|
DX_start dx_mg_auto_origin ; load address
|
|
DX_info $01,$12,dx_cc_any,$00
|
|
DX_ptab
|
|
DX_parm $00,t_int1 ; year (two-digit)
|
|
DX_parm 'v',t_nil ; verbose
|
|
DX_parm 'n',t_nil ; no-patch
|
|
DX_end_ptab
|
|
DX_desc "Set ProDOS year table."
|
|
DX_main
|
|
lda #$00 ; parm
|
|
jsr xgetparm_n ; davex ensures this is here
|
|
cpy #100
|
|
bcs badparms
|
|
jsr mkyt
|
|
lda #'v'|$80 ; "verbose"
|
|
jsr xgetparm_ch
|
|
bcs :+ ; not given, don't display
|
|
jsr dispyt
|
|
: lda #'n'|$80 ; "no patch"
|
|
jsr xgetparm_ch
|
|
bcs :+ ; not given, do it
|
|
rts
|
|
; see if we can patch the driver
|
|
: lda $c08b
|
|
lda $c08b
|
|
ldx #$03
|
|
: lda $d7b4,x ; tdays table, at september
|
|
cmp tdaysv,x ; that what ProDOS has?
|
|
bne setyterr ; not the thunderclock driver
|
|
dex
|
|
bpl :-
|
|
; go ahead and patch
|
|
ldx #6
|
|
: lda yeartab,x
|
|
sta $d7b8,x ; address of year table in P8
|
|
dex
|
|
bpl :-
|
|
bit $c082 ; ROM back before exit
|
|
rts
|
|
setyterr: bit $c082 ; ROM back before death
|
|
lda #$01
|
|
jsr xredirect
|
|
jsr xmess
|
|
asc_hi "Can't patch clock driver!"
|
|
.byte $00
|
|
jmp exiterr
|
|
badparms: lda #$01
|
|
jsr xredirect
|
|
jsr xmess
|
|
asc_hi "Bad year!"
|
|
.byte $00
|
|
exiterr: lda #$ff
|
|
jsr xredirect
|
|
jmp xerr
|
|
;
|
|
.proc mkyt
|
|
tya
|
|
and #%00000011 ; divisible by 4?
|
|
bne :+ ; nope
|
|
dey ; avoid starting table on leap year
|
|
bpl :+ ; did't wrap around
|
|
ldy #99 ; 1999
|
|
: sty year
|
|
lda #$06 ; do for 6 years
|
|
sta count
|
|
yloop: lda year
|
|
cmp #40 ; 40 or greater?
|
|
bcs :+ ; Do not adjust for 1940-1999
|
|
adc #100 ; add 100 years for 2000-2039
|
|
: tay ; year
|
|
lda #1 ; day
|
|
tax ; month
|
|
jsr weekday
|
|
tax
|
|
ldy dayidx,x ; get index into ProDOS year table
|
|
lda year
|
|
cmp #100 ; need to account for incrementing past 100
|
|
bcc :+
|
|
sbc #100
|
|
: sta yeartab,y ; put year in the appropriate slot
|
|
inc year
|
|
dec count
|
|
bne yloop
|
|
; now fix leap year gap
|
|
ldy yeartab ; first year
|
|
ldx #$06 ; index of last year
|
|
lloop: lda yeartab,x
|
|
cmp #$ff ; not filled in?
|
|
bne :+
|
|
tya ; yes, use previous value
|
|
: sta yeartab,x ; write back
|
|
tay ; and save as new 'previous' value
|
|
dex
|
|
bpl lloop
|
|
rts
|
|
.endproc
|
|
.proc dispyt
|
|
lda #$00
|
|
sta year
|
|
lda #$07
|
|
sta count
|
|
prloop: ldx year
|
|
ldy yeartab,x
|
|
sty tmp
|
|
lda #$20
|
|
cpy #40
|
|
bcc :+
|
|
lda #$19
|
|
: jsr prbyte
|
|
lda tmp
|
|
cmp #$10
|
|
bcs :+
|
|
lda #'0'|$80
|
|
jsr cout
|
|
: ldy tmp
|
|
lda #$00
|
|
jsr xprdec_2
|
|
lda #$8d
|
|
jsr cout
|
|
inc year
|
|
dec count
|
|
bne prloop
|
|
rts
|
|
.endproc
|
|
; table to index into year-starts in P8 tclock driver
|
|
dayidx: .byte 1,0,6,5,4,3,2 ; MonSunSatFriThuWedTue
|
|
; Table we will copy into ProDOS
|
|
yeartab: .res 7,$ff
|
|
; table to validate the P8 tclock driver, 4 bytes at $d7b4
|
|
tdaysv: .byte 242,20,51,81
|
|
; adapted from http://6502.org/source/misc/dow.htm
|
|
; inputs: y = year (0-255 = 1900-2155)
|
|
; x = month
|
|
; a = day
|
|
; output: a = weekday (0 = Sunday)
|
|
.proc weekday
|
|
cpx #3 ; year starts in march to bypass
|
|
bcs march ; leap year problem
|
|
dey ; if jan or feb, decrement year
|
|
march: eor #$7f ; invert a so carry works right
|
|
cpy #200 ; carry will be 1 if 22nd century
|
|
adc mtab-1,x ; a is now day+month offset
|
|
sta tmp
|
|
tya ; get the year
|
|
jsr mod7 ; do a modulo to prevent overflow
|
|
sbc tmp ; combine with day+month
|
|
sta tmp
|
|
tya ; get the year again
|
|
lsr ; divide it by 4
|
|
lsr
|
|
clc ; add it to y+m+d and fall through
|
|
adc tmp
|
|
mod7: adc #7 ; returns (a+3) modulo 7
|
|
bcc mod7 ; for a in 0..255
|
|
rts
|
|
mtab: .byte 1,5,6,3,1,5,3,0,4,2,6,4 ; month offsets
|
|
.endproc
|
|
DX_end
|