diff --git a/Makefile b/Makefile index 8b43123..6846dda 100755 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ BOOTDSK=~/vii_hd.2mg CA65=ca65 LD65=utils/auto_origin.sh ld65 GENHELP=utils/gen_help.sh -MG_CMDS=at.info.p8c at.zones.p8c afp.userprefix.p8c afp.sessions.p8c alias.p8c at.boot.p8c deschw.p8c dmem.p8c nbp.lookup.p8c tardis.p8c nbp.parse.p8c iie.card.p8c idemu.p8c mig.insp.p8c fastchip.p8c afp.timezone.p8c +MG_CMDS=at.info.p8c at.zones.p8c afp.userprefix.p8c afp.sessions.p8c alias.p8c at.boot.p8c deschw.p8c dmem.p8c nbp.lookup.p8c tardis.p8c nbp.parse.p8c iie.card.p8c idemu.p8c mig.insp.p8c fastchip.p8c afp.timezone.p8c setyear.p8c .PHONY: all all: shk ; diff --git a/README.md b/README.md index 3455637..625a170 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,10 @@ Optionally, use undocumented features to display the user-selected startup slot. View the contents of the Apple IIc Plus MIG RAM. +#### setyear + +Patches the ProDOS ThunderClock driver year table in-memory. + ## Building Building the utilities requires a Unix-like environment with GNU Make and the usual set of Unix utilities such as sed, awk, egrep, etc. diff --git a/setyear.s b/setyear.s new file mode 100644 index 0000000..4576082 --- /dev/null +++ b/setyear.s @@ -0,0 +1,180 @@ +; %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-2040 +: 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