; a program to modify the monitor
;
;   1. add real time clock
;   2. change shift lock to caps lock
;   3. fix crt ram
;   4. fix trktab for double sided drives
;         used as two drives
;
;
cpm     equ     0
freptr  equ     0ff7ah
rtclk   equ     0f800h
;
jmps    equ     0c3h
ldas    equ     03ah
nops    equ     00h
stas    equ     032h
;
;
; move new code to monitor memory
;
	org	100h
start:	lhld	6
	sphl
 	lxi     b,last-first
        lxi     d,rtclk
        lxi     h,first
move:	mov	a,m
	stax	d
	inx	h
	inx	d
        dcx     b
	mov	a,b
	ora	c
	jnz	move
;
; move last address used into "freptr"
;
        lxi     h,rtclk+last-first
        shld    freptr
;
; wait until the next one second tick
;
motor   equ     0ff6ch
        lxi     h,motor
        mov     b,m
loop:   mov     a,m
        cmp     b
        jz      loop
;
; move the address of the new monitor code into "ticvec"
;
ticvec  equ     0ff57h
        lxi     h,rtclk
        shld    ticvec
;
; inform time program that the real time clock has 
;    been installed
;
sec     equ     0ff64h
min     equ     0ff63h
hour    equ     0ff62h
day     equ     0ff5fh
month   equ     0ff60h
year    equ     0ff61h
        mvi     a,1
        sta     day
        sta     month
        sta     year
        sta     hour
        sta     min
        sta     sec
;
; change shift lock to caps lock
;
        mvi     a,'a'
        sta     0f452h
        mvi     a,'z'+1
        sta     0f456h
;
; fix access to crt ram
;
        mvi     a,stas
        sta     0f530h
        lxi     h,rtclk+pstore-first
        shld    0f531h
        mvi     a,jmps
        sta     0f533h
        lxi     h,rtclk+crtram-first
        shld    0f534h
        mvi     a,ldas
        sta     0f55ah
        lxi     h,rtclk+pstore-first
        shld    0f55bh
        mvi     a,nops
        sta     0f55dh
;
; fix trktab for double sided drives
;    used as two drives
;
sel2    equ     0f6cbh
        mvi     a,jmps
        sta     sel2
        lxi     h,rtclk+nsel2-first
        shld    sel2+1
;
; exit from program to cpm
;
        jmp     cpm
;
; the following code is added to the monitor
;
dsktmr  equ     0f480h
first:  lda     sec
        cpi     59
        jz      rtclk+t1-first
        inr     a               ; increment sec
        sta     sec
        jmp     dsktmr
t1:     mvi     a,0             ; reset sec and incr min
        sta     sec
        lda     min
        cpi     59
        jz      rtclk+t2-first
        inr     a               ; increment min
        sta     min
        jmp     dsktmr
t2:     mvi     a,0             ; reset min and incr hour
        sta     min
        lda     hour
        cpi     23
        jz      rtclk+t3-first
        inr     a               ; increment hour
        sta     hour
        jmp     dsktmr
t3:     mvi     a,0             ; reset hour and incr day
        sta     hour
        lda     month           ; get month
        cpi     2               ; is it feb?
	jz	rtclk+t5-first  ;   yes
        cpi     4               ; is it apr
        jz      rtclk+t4-first  ;   yes
        cpi     6               ; is it jun
        jz      rtclk+t4-first  ;   yes
        cpi     9               ; is it sep
        jz      rtclk+t4-first  ;   yes
        cpi     11              ; is it nov
        jz      rtclk+t4-first  ;   yes
        lda     day
        cpi     31              ; month has 31 days
        jz      rtclk+t8-first
        jmp     rtclk+t7-first
t4:     lda     day             ; here if apr, jun, sep, nov
        cpi     30              ; month has 30 days
        jz      rtclk+t8-first
        jmp     rtclk+t7-first
t5:     lda     year            ; here if feb
        rrc                     ; check for leap year
        jc      rtclk+t6-first  ;   no
        rrc                     ; check for leap year
        jc      rtclk+t6-first  ;   no
        lda     day
        cpi     29              ; month has 29 days
        jz      rtclk+t8-first
        jmp     rtclk+t7-first
t6:     lda     day             ; here if no leap year
        cpi     28              ; month has 28 days
        jz      rtclk+t8-first
t7:     inr     a               ; increment day
        sta     day
        jmp     dsktmr
t8:     mvi     a,1             ; reset day and incr month
        sta     day
        lda     month
        cpi     12
        jz      rtclk+t9-first
        inr     a               ; increment month
        sta     month
        jmp     dsktmr
t9:     mvi     a,1             ; reset month and incr year
        sta     month
        lda     year
        inr     a
        sta     year
        jmp     dsktmr
;
; code to make crt ram work properly
;
pstore: db      0
crtram: ori     10000000b
        out     01ch            ; "bitdat"
        lxi     h,0ff75h
        jmp     0f537h
;
; fix it so that drives 0 & 1 and drives 2 & 3
;  share the same entry in the trktab
;
unit    equ     0ff65h
nsel2:  mov     a,c
        ani     11111110b
        mov     c,a
        lxi     h,unit
        jmp     sel2+3
;
last:   db      0
        end	start
