# HG changeset patch # User boisy # Date 1100210544 0 # Node ID 043d330e2f0e424cdec08b7a7b2a454c19ba2f26 # Parent 93328dc6e3f4286e4ccbfd12d66adcbd7cbf83e0 Recomposed source lines to share more common code between Level 1 and Level 2 clocks diff -r 93328dc6e3f4 -r 043d330e2f0e level1/modules/clock.asm --- a/level1/modules/clock.asm Sat Sep 04 23:07:01 2004 +0000 +++ b/level1/modules/clock.asm Thu Nov 11 22:02:24 2004 +0000 @@ -21,601 +21,52 @@ * * 9r6 2003/09/04 Boisy G. Pitre * Combined Level One and Level Two sources - - nam Clock - ttl OS-9 System Clock - - IFP1 - use defsfile - IFGT Level-1 - use cc3iodefs - ENDC - ENDC - -Edtn equ 9 -rev equ 6 - - + + nam Clock + ttl OS-9 System Clock + + ifp1 + use defsfile + ifgt Level-1 + use cc3iodefs + endc + endc + +Edtn equ 9 +rev equ 6 + + *------------------------------------------------------------ * * Start of module * - mod len,name,Systm+Objct,ReEnt+rev,Init,0 - -name fcs "Clock" - fcb Edtn - - IFEQ Level-1 - -*TkPerTS equ 2 ticks per time slice -TkPerTS equ TkPerSec/10 ticks per time slice - -NewSvc fcb F$Time - fdb FTime-*-2 - fcb F$VIRQ - fdb FVIRQ-*-2 - fcb F$STime - fdb FSTime-*-2 - fcb $80 - -FSTime ldx R$X,u - ldd ,x - std D.SvcIRQ] -L0032 lda PIA0Base+2 clear interrupt? - dec D.Poll] - bcc L00AE -L00B4 jmp [>D.AltIRQ] -L00B8 bsr L00DD - bra L0096 -L00BC leay >L00C4,pcr - jmp [>D.URtoSs] -L00C4 jsr [>D.Poll] - bcc L00C4 - ldx $FFFE reset -LinkOk sty ClockIRQ,pcr - stx NewSvc,pcr - os9 F$SSvc - ldx #PIA0Base - clra - sta 1,x change PIA0Base side A to DDR - sta ,x clear PIA0Base side A - sta 3,x change PIA0Base side B to DDR - coma complement A side A - sta 2,x write all 1's to PIA0Base side B - lda #$34 - sta 1,x PIA0Base side A to I/O reg - lda #$3F - sta 3,x PIA0Base side B to I/O reg - lda 2,x - - puls pc,dp,cc - - -* F$Time system call code -FTime ldx R$X,u - ldd IRQEnR Get GIME IRQ Status and save it. - ora $0643 - stb >$0645 - std >$FFA1 - andcc #^IntMasks - ENDC - - ldd Vi.Cnt,x Decrement tick count - IFNE H6309 - decd --- subd #1 - ELSE - subd #$0001 - ENDC - bne notzero Is this one done? - lda Vi.Stat,x Should we reset? - bmi doreset - lbsr DelVIRQ No, delete this entry -doreset ora #$01 Mark this VIRQ as triggered. - sta Vi.Stat,x - lda #$80 Add VIRQ as interrupt source - sta ,s - ldd Vi.Rst,x Reset from Reset count. -notzero std Vi.Cnt,x -virqent ldx ,y++ - bne virqloop - - IFGT Level-2 - puls d - orcc #Carry - stb >$0643 - stb >$FFA1 - incb - stb >$0645 - stb >$FFA1 - andcc #^IntMasks - ELSE - puls a Get VIRQ status flag: high bit set if VIRQ - ENDC - - ora $0643 grab current map type - ldb >$0645 - pshs d save it - orcc #IntMasks IRQs off - lda >$0660 SCF local memory ---x - sta >$0643 into DAT image ---x - sta >$FFA1 and into RAM ---x - inca - sta >$0645 - sta >$FFA2 map in SCF, CC3IO, WindInt, etc. - ENDC - - jsr [>D.AltIRQ] go update mouse, gfx cursor, keyboard, etc. - - IFGT Level-2 - puls d restore original map type ---x - orcc #IntMasks - sta >$0643 into system DAT image ---x - stb >$0645 - std >$FFA1 and into RAM ---x - andcc #$AF - ENDC - - dec WGlobal+G.AlPID - ble VIRQend Quit if no Alarm set - ldd >WGlobal+G.AlPckt+3 Does Hour/Minute agree? - cmpd WGlobal+G.AlPckt+1 Does Month/Day agree? - cmpd WGlobal+G.AlPckt+0 Does Year agree? - cmpb WGlobal+G.AlPID - cmpd #1 - beq checkbel - os9 F$Send - bra endalarm -checkbel ldb WGlobal+G.AlPID - bra VIRQend -dobell ldx >WGlobal+G.BelVec - beq VIRQend - jsr ,x -VIRQend jmp [>D.Clock] Jump to kernel's timeslice routine - -*------------------------------------------------------------ -* Interrupt polling and GIME reset code -* - -* -* Call [D.Poll] until all interrupts have been handled +* Table to set up Service Calls * -Dopoll - IFGT Level-2 - lda >$0643 Level 3: get map type - ldb >$0645 - pshs d save for later - ENDC -Dopoll.i - jsr [>D.Poll] Call poll routine - bcc DoPoll.i Until error (error -> no interrupt found) - - IFGT Level-2 - puls d - orcc #IntMasks - sta >$0643 - stb >$0645 - std >$FFA1 - andcc #^IntMasks - ENDC - -* -* Reset GIME to avoid missed IRQs -* -DoToggle lda #^GI.Toggl Mask off CART* bit - anda IRQEnR Disable CART - stb >IRQEnR Enable CART - clrb - rts - - -*------------------------------------------------------------ -* -* Handle F$VIRQ system call -* -F.VIRQ pshs cc - orcc #IntMasks Disable interrupts - ldy $0643 - ldb >$0645 - std 2,y - ELSE - leay -2,y point to first null VIRQ entry - ldx R$Y,u - stx ,y - ENDC - ldy R$D,u - sty ,x - bra virqexit - - IFGT Level-2 -v.chk leay 4,y -RemVIRQ ldx ,y - ELSE -RemVIRQ ldx ,y++ - ENDC - beq virqexit - cmpx R$Y,u - bne RemVIRQ - bsr DelVIRQ -virqexit puls cc - clrb - rts - -DelVIRQ pshs x,y -DelVLup - IFGT Level-2 - ldq ,y++ move entries up in table - leay 2,y - stq -8,y - bne DelVLup - puls x,y,pc - ELSE - ldx ,y++ move entries up in table - stx -4,y - bne DelVLup - puls x,y - leay -2,y - rts - ENDC - - IFGT Level-1 -*------------------------------------------------------------ -* -* Handle F$Alarm call -* -F.Alarm ldx #WGlobal+G.AlPckt - ldd R$D,u - bne DoAlarm - std G.AlPID-G.AlPckt,x Erase F$Alarm PID, Signal. - rts - -DoAlarm tsta If PID != 0, set alarm for this process - bne SetAlarm - cmpd #1 1 -> Set system-wide alarm - bne GetAlarm -SetAlarm std G.AlPID-G.AlPckt,x - ldy $FFFE level 1: jump to reset vector + else + lda #E$MNF + jmp $FF98 set 50 Hz VSYNC - ENDC - ENDC + ifeq TkPerSec-50 + ldb $FF98 set 50 Hz VSYNC + endc + endc + + sta 1,x enable DDRA + sta ,x set port A all inputs + sta 3,x enable DDRB + coma + sta 2,x set port B all outputs + ldd #$343C [A]=PIA0 CRA contents, [B]=PIA0 CRB contents + sta 1,x CA2 (MUX0) out low, port A, disable HBORD high-to-low IRQs + stb 3,x CB2 (MUX1) out low, port B, disable VBORD low-to-high IRQs + ifgt Level-1 + lda ,x clear possible pending PIA0 HBORD IRQ + endc + lda 2,x clear possible pending PIA0 VBORD IRQ + +* Don't need to explicitly read RTC during initialization + ldd #59*256+TkPerTS last second and time slice in minute + std IRQEnR enable GIME VBORD IRQs + endc +* Call Clock2 init routine + ldy IRQEnR enable GIME VBORD IRQs - ENDC - -* Call Clock2 init routine - ldy D.SvcIRQ] else service other possible IRQ +L0032 lda PIA0Base+2 clear interrupt + dec D.Poll] poll ISRs + bcc L00AE keep polling until carry set +GoAltIRQ + jmp [>D.AltIRQ] jump into an alternate IRQ if available +DelEntry + bsr DelVIRQ delete the VIRQ entry + bra L0096 + +UsrPoll leay >up@,pcr point to routine to execute + jmp [>D.URtoSs] User to System +up@ jsr [>D.Poll] call polling routine + bcc up@ keep polling until carry set + ldx IRQEnR get GIME IRQ Status and save it. + ora $0643 + stb >$0645 + std >$FFA1 + andcc #^IntMasks + endc + + ldd Vi.Cnt,x decrement tick count + ifne H6309 + decd --- subd #1 + else + subd #$0001 + endc + bne notzero is this one done? + lda Vi.Stat,x should we reset? + bmi doreset + lbsr DelVIRQ no, delete this entry +doreset ora #$01 mark this VIRQ as triggered. + sta Vi.Stat,x + lda #$80 add VIRQ as interrupt source + sta ,s + ldd Vi.Rst,x reset from Reset count. +notzero std Vi.Cnt,x +virqent ldx ,y++ + bne virqloop + + ifgt Level-2 + puls d + orcc #Carry + stb >$0643 + stb >$FFA1 + incb + stb >$0645 + stb >$FFA1 + andcc #^IntMasks + else + puls a get VIRQ status flag: high bit set if VIRQ + endc + + ora $0643 grab current map type + ldb >$0645 + pshs d save it + orcc #IntMasks IRQs off + lda >$0660 SCF local memory ---x + sta >$0643 into DAT image ---x + sta >$FFA1 and into RAM ---x + inca + sta >$0645 + sta >$FFA2 map in SCF, CC3IO, WindInt, etc. + endc + + jsr [>D.AltIRQ] go update mouse, gfx cursor, keyboard, etc. + + ifgt Level-2 + puls d restore original map type ---x + orcc #IntMasks + sta >$0643 into system DAT image ---x + stb >$0645 + std >$FFA1 and into RAM ---x + andcc #$AF + endc + + dec WGlobal+G.AlPID + ble VIRQend Quit if no Alarm set + ldd >WGlobal+G.AlPckt+3 does Hour/Minute agree? + cmpd WGlobal+G.AlPckt+1 does Month/Day agree? + cmpd WGlobal+G.AlPckt+0 does Year agree? + cmpb WGlobal+G.AlPID + cmpd #1 + beq checkbel + os9 F$Send + bra endalarm +checkbel ldb WGlobal+G.AlPID + bra VIRQend +dobell ldx >WGlobal+G.BelVec + beq VIRQend + jsr ,x +VIRQend jmp [>D.Clock] jump to kernel's timeslice routine + +*------------------------------------------------------------ +* Interrupt polling and GIME reset code +* + +* +* Call [D.Poll] until all interrupts have been handled +* +DoPoll + ifgt Level-2 + lda >$0643 Level 3: get map type + ldb >$0645 + pshs d save for later + endc +d@ jsr [>D.Poll] call poll routine + bcc d@ until error (error -> no interrupt found) + + ifgt Level-2 + puls d + orcc #IntMasks + sta >$0643 + stb >$0645 + std >$FFA1 + andcc #^IntMasks + endc + +* +* Reset GIME to avoid missed IRQs +* +DoToggle + lda #^GI.Toggl mask off CART* bit + anda IRQEnR disable CART + stb >IRQEnR enable CART + clrb + rts + + +*------------------------------------------------------------ +* +* Handle F$VIRQ system call +* +FVIRQ pshs cc + orcc #IntMasks disable interrupts + ldy $0643 + ldb >$0645 + std 2,y + else + leay -2,y point to first null VIRQ entry + ldx R$Y,u + stx ,y + endc + ldy R$D,u + sty ,x + bra virqexit + + ifgt Level-2 +v.chk leay 4,y +RemVIRQ ldx ,y + else +RemVIRQ ldx ,y++ + endc + beq virqexit + cmpx R$Y,u + bne RemVIRQ + bsr DelVIRQ +virqexit puls cc + clrb + rts + +DelVIRQ pshs x,y +DelVLup + ifgt Level-2 + ldq ,y++ move entries up in table + leay 2,y + stq -8,y + bne DelVLup + puls x,y,pc + else + ldx ,y++ move entries up in table + stx -4,y + bne DelVLup + puls x,y + leay -2,y + rts + endc + + ifgt Level-1 +*------------------------------------------------------------ +* +* Handle F$Alarm call +* +FAlarm ldx #WGlobal+G.AlPckt + ldd R$D,u + bne DoAlarm + std G.AlPID-G.AlPckt,x erase F$Alarm PID, Signal. + rts + +DoAlarm tsta if PID != 0, set alarm for this process + bne SetAlarm + cmpd #1 1 -> Set system-wide alarm + bne GetAlarm +SetAlarm + std G.AlPID-G.AlPckt,x + ldy