diff level1/modules/clock.asm @ 2631:442795681807

o Fixed Atari SIO DWRead to timeout longer o Commented out call to InitVIRQ in dw3.sb for Atari due to issues o VTIO for Atari now properly handles IRQ shadow registers o Level 1 clock now merged to include Atari
author Boisy Pitre <boisy.pitre@nuance.com>
date Sun, 26 Feb 2012 21:39:44 -0600
parents b8c7b7fbf3c9
children 2ebf5e737ceb
line wrap: on
line diff
--- a/level1/modules/clock.asm	Sun Feb 26 16:22:27 2012 -0600
+++ b/level1/modules/clock.asm	Sun Feb 26 21:39:44 2012 -0600
@@ -1,10 +1,6 @@
 ********************************************************************
 * Clock - NitrOS-9 System Clock
 *
-* CoCo 3 notes:
-* Includes support for several different RTC chips, GIME Toggle
-* IRQ fix, numerous minor changes.
-*
 * $Id$
 *
 * Edt/Rev  YYYY/MM/DD  Modified by
@@ -46,9 +42,6 @@
                          
          ifp1            
          use   defsfile  
-         ifgt  Level-1   
-         use   cocovtio.d
-         endc            
          endc            
                          
 tylg     set   Systm+Objct
@@ -67,11 +60,7 @@
          fcb   edition   
                          
                          
-         ifeq  Level-1   
 TkPerTS  equ   TkPerSec/10 ticks per time slice
-         else            
-TkPerTS  equ   2          ticks per time slice
-         endc            
                          
 *
 * Table to set up Service Calls
@@ -80,15 +69,11 @@
          fdb   FTime-*-2 
          fcb   F$VIRQ    
          fdb   FVIRQ-*-2 
-         ifgt  Level-1   
-         fcb   F$Alarm   
-         fdb   FALARM-*-2
-         endc            
          fcb   F$STime   
          fdb   FSTime-*-2
          fcb   $80        end of service call installation table
-                         
-                         
+
+
 *------------------------------------------------------------
 *
 * Handle F$STime system call
@@ -97,14 +82,6 @@
 * variables, then fall through to code to update RTC.
 *
 FSTime   equ   *         
-         ifgt  Level-1   
-         ldx   <D.Proc    caller's process descriptor
-         lda   P$Task,x   source is in user map
-         ldx   R$X,u      address of caller's time packet
-         ldu   #D.Time    destination address
-         ldb   <D.SysTsk  destination is in system map
-         lbsr  STime.Mv   get time packet (ignore errors)
-         else            
          ldx   R$X,u     
          ldd   ,x        
          std   <D.Year   
@@ -112,14 +89,12 @@
          std   <D.Day    
          ldd   4,x       
          std   <D.Min    
-         endc            
          lda   #TkPerSec  reset to start of second
          sta   <D.Tick   
          ldx   <D.Clock2  get entry point to Clock2
          clra             clear carry
          jmp   $06,x      and call SetTime entry point
                          
-                         
 *--------------------------------------------------
 *
 * Clock Initialization
@@ -133,56 +108,56 @@
                          
 Clock2   fcs   "Clock2"  
                          
-init                     
-         ifeq  Level-1   
+init
          pshs  dp,cc      save DP and CC
          clra            
          tfr   a,dp       set DP to zero
-         else            
-         ldx   <D.Proc    save user proc
-         pshs  x         
-         ldx   <D.SysPrc  make sys for link
-         stx   <D.Proc   
-         endc            
-                         
          leax  <Clock2,pcr
          lda   #Sbrtn+Objct
          os9   F$Link    
-                         
          bcc   LinkOk    
-                         
-         ifeq  Level-1   
          jmp   >$FFFE     level 1: jump to reset vector
-         else            
-         lda   #E$MNF    
-         jmp   <D.Crash   level 2: jump to CRASH vector
-         endc            
                          
 LinkOk                   
-         ifeq  Level-1   
          puls  cc,dp      ; Restore saved dp and cc
-         else            
-         puls  x         
-         stx   <D.Proc    restore user proc
-         endc            
-                         
          sty   <D.Clock2  save entry point
 InitCont                 
+* Do not need to explicitly read RTC during initialization
+         ldd   #59*256+$01 last second and last tick
+         std   <D.Sec     will prompt RTC read at next time slice
+         ldb   #TkPerSec
+         stb   <D.TSec    set ticks per second
+         ldb   #TkPerTS   get ticks per time slice
+         stb   <D.TSlice  set ticks per time slice
+         stb   <D.Slice   set first time slice
+         IFNE  atari
+* Atari gets its clock source from the NMI
+         leax  SvcIRQ,pcr set NMI handler
+         stx   <D.NMI    
+         ELSE
+         leax  SvcIRQ,pcr set IRQ handler
+         stx   <D.IRQ    
+         ENDC
+                         
+         leay  NewSvc,pcr insert syscalls
+         os9   F$SSvc    
+                         
+* Call Clock2 init routine
+         ldy   <D.Clock2  get entry point to Clock2
+         jsr   ,y         call init entry point of Clock2
+
+* Initialize clock hardware
+          IFNE atari
+* Atari - Tell ANTIC to assert NMI on Vertical Blank
+     	lda     #$40
+     	sta     $D40E		enable VBlank NMI
+          rts
+          ELSE
          ldx   #PIA0Base  point to PIA0
          clra             no error for return...
          pshs  cc         save IRQ enable status (and Carry clear)
          orcc  #IntMasks  stop interrupts
                          
-         ifgt  Level-1   
-* Note: this code can go away once we have a rel_50hz
-         ifeq  TkPerSec-50
-         ldb   <D.VIDMD   get video mode register copy
-         orb   #$08       set 50 Hz VSYNC bit
-         stb   <D.VIDMD   save video mode register copy
-         stb   >$FF98     set 50 Hz VSYNC
-         endc            
-         endc            
-                         
          sta   1,x        enable DDRA
          sta   ,x         set port A all inputs
          sta   3,x        enable DDRB
@@ -191,58 +166,15 @@
                          
 ;	ldd	#$343C		[A]=PIA0 CRA contents, [B]=PIA0 CRB contents
                          
-         ifgt  Level-1   
-         ldd   #$3434     as per Robert Gault's suggestion
-         else            
          ldd   #$3435     IRQ needs to be left enabled for Level1, as no GIME generated IRQ
-         endif            
                          
          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+$01 last second and last tick
-         std   <D.Sec     will prompt RTC read at next time slice
-         ifeq  Level-1
-         ldb   #TkPerSec
-         stb   <D.TSec    set ticks per second
-         endc
-         ldb   #TkPerTS   get ticks per time slice
-         stb   <D.TSlice  set ticks per time slice
-         stb   <D.Slice   set first time slice
-         leax  SvcIRQ,pcr set IRQ handler
-         stx   <D.IRQ    
+          puls  cc,pc      recover IRQ enable status and return
+          ENDC       
                          
-         ifgt  Level-1   
-         leax  SvcVIRQ,pcr set VIRQ handler
-         stx   <D.VIRQ   
-         endc            
-                         
-         leay  NewSvc,pcr insert syscalls
-         os9   F$SSvc    
-                         
-         ifgt  Level-1   
-         ifne  H6309     
-         oim              #$08,<D.IRQER
-         else            
-         lda   <D.IRQER   get shadow GIME IRQ enable register
-         ora   #$08       set VBORD bit
-         sta   <D.IRQER   save shadow register
-         endc            
-         sta   >IRQEnR    enable GIME VBORD IRQs
-         endc            
-                         
-* Call Clock2 init routine
-         ldy   <D.Clock2  get entry point to Clock2
-         jsr   ,y         call init entry point of Clock2
-InitRts  puls  cc,pc      recover IRQ enable status and return
-                         
-         ifeq  Level-1   
 *
 * Clock IRQ Entry Point
 *
@@ -250,10 +182,14 @@
 SvcIRQ                   
          clra            
          tfr   a,dp       set direct page to zero
+         IFNE  atari
+          sta   $D40F     clear NMI interrupt
+         ELSE
          tst   PIA0Base+3 get hw byte
          bmi   L0032      branch if sync flag on
          jmp   [>D.SvcIRQ] else service other possible IRQ
 L0032    tst   PIA0Base+2 clear interrupt
+          ENDC
          dec   <D.Tick    decrement tick counter
          bne   L007F      go around if not zero
          ldb   <D.Sec     get minutes/seconds
@@ -291,7 +227,7 @@
          beq   GoAltIRQ   branch if zero
          ldx   <D.Proc    else get pointer to current process descriptor
          beq   L00AE      branch if none
-         tst   P$State,x  test process' state
+         tst   P$State,x  test process state
          bpl   UsrPoll    branch if system state not set
 L00AE    jsr   [>D.Poll]  poll ISRs
          bcc   L00AE      keep polling until carry set
@@ -373,372 +309,6 @@
          clrb            
          rts             
                          
-                         
-                         
-                         
-         else            
-                         
-                         
-                         
-                         
-* NitrOS-9 Level 2 Clock
-                         
-GI.Toggl equ   %00000001  GIME CART* IRQ enable bit, for CC3
-                         
-* TC9 needs to reset more interrupt sources
-*GI.Toggl equ %00000111 GIME SERINT*, KEYINT*, CART* IRQ enable bits
-                         
-                         
-*---------------------------------------------------------
-* IRQ Handling starts here.
-*
-* Caveat: There may not be a stack at this point, so avoid using one.
-*         Stack is set up by the kernel between here and SvcVIRQ.
-*
-SvcIRQ   lda   >IRQEnR    get GIME IRQ Status and save it.
-         ora   <D.IRQS   
-         sta   <D.IRQS   
-         bita  #$08       check for clock interrupt
-         beq   NoClock   
-         anda  #^$08      drop clock interrupt
-         sta   <D.IRQS   
-         ldx   <D.VIRQ    set VIRQ routine to be executed
-         clr   <D.QIRQ    ---x IS clock IRQ
-         bra   ContIRQ   
-                         
-NoClock  leax  DoPoll,pcr if not clock IRQ, just poll IRQ source
-         ifne  H6309     
-         oim              #$FF,<D.QIRQ	---x set flag to NOT clock IRQ
-         else            
-         lda   #$FF      
-         sta   <D.QIRQ   
-         endc            
-ContIRQ  stx   <D.SvcIRQ 
-         jmp   [D.XIRQ]   chain through Kernel to continue IRQ handling
-                         
-*------------------------------------------------------------
-*
-* IRQ handling re-enters here on VSYNC IRQ.
-*
-* - Count down VIRQ timers, mark ones that are done
-* - Call DoPoll/DoToggle to service VIRQs and IRQs and reset GIME
-* - Call Keyboard scan
-* - Update time variables
-* - At end of minute, check alarm
-*
-SvcVIRQ  clra             flag if we find any VIRQs to service
-         pshs  a         
-         ldy   <D.CLTb    get address of VIRQ table
-         bra   virqent   
-                         
-virqloop                 
-         ifgt  Level-2   
-         ldd   2,y        get Level 3 extended map type
-         orcc  #IntMasks 
-         sta   >$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   <D.IRQS    Check to see if other hardware IRQ pending.
-         bita  #%10110111 any V/IRQ interrupts pending?
-         beq   toggle    
-         ifgt  Level-2   
-         lbsr  DoPoll     yes, go service them.
-         else            
-         bsr   DoPoll     yes, go service them.
-         endc            
-         bra   KbdCheck  
-toggle   equ   *         
-         ifgt  Level-2   
-         lbsr  DoToggle   no, toggle GIME anyway
-         else            
-         bsr   DoToggle   no, toggle GIME anyway
-         endc            
-                         
-KbdCheck                 
-         ifgt  Level-2   
-         lda   >$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   <D.Tick    end of second?
-         bne   VIRQend    no, skip time update and alarm check
-         lda   #TkPerSec  reset tick count
-         sta   <D.Tick   
-                         
-* ATD: Modified to call real time clocks on every minute ONLY.
-         inc   <D.Sec     go up one second
-         lda   <D.Sec     grab current second
-         cmpa  #60        end of minute?
-         blo   VIRQend    no, skip time update and alarm check
-         clr   <D.Sec     reset second count to zero
-                         
-*
-* Call GetTime entry point in Clock2
-*
-         ldx   <D.Clock2  get entry point to Clock2
-         jsr   $03,x      call GetTime entry point
-                         
-NoGet    ldd   >WGlobal+G.AlPID
-         ble   VIRQend    Quit if no Alarm set
-         ldd   >WGlobal+G.AlPckt+3 does Hour/Minute agree?
-         cmpd  <D.Hour   
-         bne   VIRQend   
-         ldd   >WGlobal+G.AlPckt+1 does Month/Day agree?
-         cmpd  <D.Month  
-         bne   VIRQend   
-         ldb   >WGlobal+G.AlPckt+0 does Year agree?
-         cmpb  <D.Year   
-         bne   VIRQend   
-         ldd   >WGlobal+G.AlPID
-         cmpd  #1        
-         beq   checkbel  
-         os9   F$Send    
-         bra   endalarm  
-checkbel ldb   <D.Sec     sound bell for 15 seconds
-         andb  #$F0      
-         beq   dobell    
-endalarm ldd   #$FFFF    
-         std   >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  <D.IRQS   
-         sta   <D.IRQS   
-         lda   <D.IRQER   get current enable register status
-         tfr   a,b       
-         anda  #^GI.Toggl mask off CART* bit
-         orb   #GI.Toggl  --- ensure that 60Hz IRQ's are always enabled
-         sta   >IRQEnR    disable CART
-         stb   >IRQEnR    enable CART
-         clrb            
-         rts             
-                         
-                         
-*------------------------------------------------------------
-*
-* Handle F$VIRQ system call
-*
-FVIRQ    pshs  cc        
-         orcc  #IntMasks  disable interrupts
-         ldy   <D.CLTb    address of VIRQ table
-         ldx   <D.Init    address of INIT
-         ldb   PollCnt,x  number of polling table entries from INIT
-         ldx   R$X,u      zero means delete entry
-         beq   RemVIRQ   
-         ifgt  Level-2   
-         bra   FindVIRQ   ---x
-                         
-v.loop   leay  4,y        ---x
-         endc            
-FindVIRQ                 
-         ldx   ,y++       is VIRQ entry null?
-         beq   AddVIRQ    if yes, add entry here
-         decb            
-         bne   FindVIRQ  
-         puls  cc        
-         comb            
-         ldb   #E$Poll   
-         rts             
-                         
-AddVIRQ                  
-         ifgt  Level-2   
-         ldx   R$Y,u     
-         stx   ,y        
-         lda   >$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                  
-         IFEQ  H6309-1   
-         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   <D.Proc   
-         lda   P$Task,y   move from process task
-         ldb   <D.SysTsk  to system task
-         ldx   R$X,u      from address given in X
-         ldu   #WGlobal+G.AlPckt
-         ldy   #5         move 5 bytes
-         bra   FMove     
-                         
-GetAlarm                 
-         cmpd  #2        
-         bne   AlarmErr  
-         ldd   G.AlPID-G.AlPckt,x
-         std   R$D,u     
-         bra   RetTime   
-AlarmErr                 
-         comb            
-         ldb   #E$IllArg 
-         rts             
-         endc            
-                         
-*------------------------------------------------------------
-*
-* Handle F$Time System call
-*
-FTime    equ   *         
-         ifgt  Level-1   
-         ldx   #D.Time    address of system time packet
-RetTime  ldy   <D.Proc    get pointer to current proc descriptor
-         ldb   P$Task,y   process Task number
-         lda   <D.SysTsk  from System Task
-         ldu   R$X,u     
-STime.Mv                 
-         ldy   #6         move 6 bytes
-FMove    os9   F$Move    
-         else            
-         ldx   R$X,u      get pointer to caller's space
-         ldd   <D.Year    get year and month
-         std   ,x        
-         ldd   <D.Day     get day and hour
-         std   2,x       
-         ldd   <D.Min     get minute and second
-         std   4,x       
-         clrb            
-         endc            
-         rts             
-                         
-         endc            
-                         
          emod            
 len      equ   *         
          end