diff --git a/ns.clock.system.s b/ns.clock.system.s index 4dd5d92..138ec8f 100644 --- a/ns.clock.system.s +++ b/ns.clock.system.s @@ -1,8 +1,11 @@ .setcpu "65C02" + .linecont + -CR := $8D -BELL := $87 + ;; ASCII +BELL := $07 +CR := $0D + ;; Constants MAX_DW := $FFFF ;; Softswitches @@ -13,7 +16,7 @@ CLRALTCHAR := $C00E ; Primary Character Set ROMIN2 := $C082 ; Read ROM; no write RWRAM1 := $C08B ; Read/write RAM bank 1 - ;; ProDOS Equates + ;; ProDOS PRODOS := $BF00 DATETIME := $BF06 DEVNUM := $BF30 @@ -36,7 +39,7 @@ MLI_CLOSE := $CC .addr params .endmacro - ;; Monitor Equates + ;; Monitor INIT := $FB2F MON_HOME := $FC58 CROUT := $FD8E @@ -46,21 +49,40 @@ SETNORM := $FE84 SETKBD := $FE89 SETVID := $FE93 +;;; -------------------------------------------------- + .macro PASCAL_STRING arg .byte .strlen(arg) .byte arg .endmacro -.macro HIASCII arg - .repeat .strlen(arg), i - .byte .strat(arg, i) | $80 - .endrep +.macro HIASCII arg, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + .if .blank(arg) + .exitmacro + .endif + .if .match ({arg}, "") ; string? + .repeat .strlen(arg), i + .byte .strat(arg, i) | $80 + .endrep + .else ; otherwise assume number/char/identifier + .byte (arg | $80) + .endif + HIASCII arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 +.endmacro + +.macro HIASCIIZ arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + HIASCII arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + .byte 0 .endmacro .define HI(c) ((c)|$80) +;;; -------------------------------------------------- + data_buffer = $1800 + .define SYSTEM_SUFFIX ".SYSTEM" + ;;; -------------------------------------------------- @@ -70,18 +92,22 @@ SETVID := $FE93 ;;; -------------------------------------------------- -init: sec - bcs :+ +sys_start: + sec + bcs relocate .byte $04, $21, $91 ; 4/21/91 ;;; -------------------------------------------------- +;;; Relocate this code from $2000 (.SYSTEM start location) to $1000 +;;; and start executing there. This is done so that the next .SYSTEM +;;; file can be loaded/run at $2000. .proc relocate src := SYS_ADDR dst := $1000 -: ldx #5 ; pages + ldx #(sys_end - sys_start + $FF) / $100 ; pages ldy #0 load: lda src,y ; self-modified load_hi := *-1 @@ -92,11 +118,14 @@ load: lda src,y ; self-modified inc load_hi inc store_hi dex - beq find_self_name + beq find_self_name ; done jmp load .endproc ;;; -------------------------------------------------- +;;; Identify the name of this SYS file, which should be present at +;;; $280 with or without a path prefix. This is used when searching +;;; for the next .SYSTEM file to execute. ;; Search pathname buffer backwards for '/', then ;; copy name into |self_name|; this is used later @@ -115,7 +144,7 @@ floop: inc $A8 asl a bne floop - ;; copy name into |self_name| buffer + ;; Copy name into |self_name| buffer copy: ldy #0 cloop: iny inx @@ -125,7 +154,7 @@ cloop: iny bcc cloop sty self_name .endproc - ;; fall through... + ;; Fall through... ;;; -------------------------------------------------- @@ -133,7 +162,7 @@ cloop: iny cld bit ROMIN2 - ;; Update reset vector + ;; Update reset vector - re-invokes this code. lda #pre_install @@ -174,44 +203,45 @@ cloop: iny jsr MON_HOME jsr zstrout + HIASCIIZ CR, "Previous Clock Installed!", BELL, CR - .byte CR - HIASCII "Previous Clock Installed!" - .byte BELL, CR, 0 - - jmp exit + jmp launch_next_sys_file .endproc ;;; -------------------------------------------------- -;;; Detect NSC +;;; Detect NSC. Scan slot ROMs and main ROMs. Try reading +;;; each location several times, and validate results before +;;; installing driver. .proc detect_nsc ;; Preserve date/time ldy #3 ; copy 4 bytes : lda DATELO,y - sta saved_dt,y + sta saved,y dey bpl :- ;; Check slot ROMs - lda #$CF - ldy #$FF + lda #>$CFFF + ldy #<$CFFF sta ld4+2 sty ld4+1 sta st4+2 sty st4+1 - lda #$00 + lda #0 sta slot - lda #$03 -L10DF: ora #$C0 + lda #3 ; treat slot 0 as slot 3 + +sloop: ora #$C0 ; A=$Cs sta st1+2 -L10E4: sta ld1+2 +rloop: sta ld1+2 sta ld2+2 sta st2+2 - lda #3 + + lda #3 ; 3 tries - need valid results each time sta tries -try: jsr driver - lda DATELO+1 +try: jsr driver ; try reading date/time + lda DATELO+1 ; check result ror a lda DATELO rol a @@ -220,31 +250,31 @@ try: jsr driver rol a and #$0F beq next - cmp #$0D + cmp #13 ; month bcs next lda DATELO and #$1F beq next - cmp #$20 + cmp #32 ; day bcs next - .byte $AD - .byte $93 - bbs3 $C9,$1130 + lda TIMELO+1 + cmp #24 ; hours bcs next lda TIMELO - cmp #$3C + cmp #60 ; minutes bcs next dec tries bne try - .byte $F0 - .byte $75 + beq install_driver ; all tries look valid next: inc slot lda slot cmp #8 - bcc L10DF + bcc sloop ; next slot bne not_found - lda #$C0 - ldy #$15 + + ;; Not found in slot ROM, try main ROMs ??? + lda #>$C015 + ldy #<$C015 sta ld4+2 sty ld4+1 ldy #$07 @@ -253,13 +283,13 @@ next: inc slot dey sta st4+2 sty st4+1 - lda #$C8 - bne L10E4 + lda #>$C800 + bne rloop ;; Restore date/time not_found: ldy #3 -: lda saved_dt,y +: lda saved,y sta DATELO,y dey bpl :- @@ -267,23 +297,19 @@ not_found: ;; Show failure message jsr MON_HOME jsr zstrout + HIASCIIZ CR, "No-SLot Clock Not Found.", CR, CR,\ + "Clock Not Installed!", BELL, CR + jmp launch_next_sys_file - .byte CR - HIASCII "No-SLot Clock Not Found." - .byte CR, CR - HIASCII "Clock Not Installed!" - .byte BELL, CR, 0 - - jmp exit - -saved_dt: - .byte 0, 0, 0, 0 +saved: .byte 0, 0, 0, 0 tries: .byte 3 slot: .byte 0 .endproc ;;; -------------------------------------------------- -;;; Install NSC Date Driver +;;; Install NSC Driver. Copy into address at DATETIME vector, +;;; update the vector and update MACHID bits to signal a clock +;;; is present. .proc install_driver ptr := $A5 @@ -321,10 +347,7 @@ loop: lda driver,y bit ROMIN2 jsr MON_HOME jsr zstrout - - .byte CR - HIASCII "No-Slot Clock Installed " - .byte 0 + HIASCIIZ CR, "No-Slot Clock Installed " ;; Display the current date lda DATELO+1 ; month @@ -355,9 +378,10 @@ loop: lda driver,y .endproc ;;; -------------------------------------------------- +;;; Find and invoke the next .SYSTEM file -exit: - ;; Update reset vector +.proc launch_next_sys_file + ;; Update reset vector - now terminates. lda #quit @@ -365,12 +389,6 @@ exit: eor #$A5 sta $03F4 -;;; -------------------------------------------------- -;;; Invoke next .SYSTEM file - -.define SYSTEM_SUFFIX ".SYSTEM" - -.proc find_next_sys_file ptr := $A5 len := $A8 @@ -497,11 +515,7 @@ append: ldy #0 not_found: jsr zstrout - - .byte CR, CR, CR - HIASCII "* Unable to find next '.SYSTEM' file *" - .byte CR, 0 - + HIASCIIZ CR, CR, CR, "* Unable to find next '.SYSTEM' file *", CR bit KBDSTRB : lda KBD bpl :- @@ -576,7 +590,7 @@ lowercase_mask: .proc quit PRODOS_CALL MLI_QUIT, quit_params - .byte 0 ; ??? + .byte 0 ; crash if QUIT fails rts .proc quit_params .byte 4 ; param_count @@ -629,19 +643,12 @@ block_num: .word 2 ; block_num - block 2 is volume directory .proc on_error pha jsr zstrout - - .byte CR, CR, CR - HIASCII "** Disk Error $" - .byte 0 - + HIASCIIZ CR, CR, CR, "** Disk Error $" pla jsr PRBYTE jsr zstrout - - HIASCII " **" - .byte CR, 0 - - bit KBDSTRB + HIASCIIZ " **", CR + bit KBDSTRB : lda KBD bpl :- bit KBDSTRB @@ -683,7 +690,7 @@ self_name: PASCAL_STRING "NS.CLOCK.SYSTEM" ;;; -------------------------------------------------- -;;; The driver - copied into ProDOS +;;; NSC driver - copied into ProDOS driver: php @@ -760,7 +767,9 @@ unlock: sizeof_driver := * - driver - .assert (* - init <= $500), error, "Must fit in 5 pages" +;;; -------------------------------------------------- + +sys_end: ;;; -------------------------------------------------- ;;; Junk from here on...