                         .area text
                       ;      semaphore -> 2,x
 0000                 _bWait::
 0000 87                        clra
 0001 181CE30002          loop: maxm [2,x]
 0006 24F9                    bcc loop
                         
 0008                 spin12.10::	
                       ; /* ****************SPIN12.C********
                       ;   Jonathan W. Valvano   April 21, 1998
                       ;   Spinlock binary semaphore, 
                       ;   without disabling interrupts */
                       ; #include "spin12.h"
                       ; void bWait(char *semaphore){
                       ; asm("      clra\n"          // new value for semaphore
                       ;     "loop: maxm [2,x]\n"    // test and set           
                       ;     "      bcc loop\n");            
                       ; }                            
 0008                 L1:
 0008 3D                  rts
                       ;      semaphore -> 2,x
 0009                 _bSignal::
 0009 3B                  pshd
 000A 34                  pshx
 000B B775              tfr s,x
 000D                 spin12.12::	
                       ; void bSignal(char *semaphore){
                       ;      (*semaphore)=1;  // compiler makes this atomic
 000D C601              ldab #1
 000F ED02              ldy 2,x
 0011 6B40              stab 0,y
 0013                 spin12.13::	
                       ; }
 0013                 L2:
 0013 B757              tfr x,s
 0015 30                  pulx
 0016 1B82              leas 2,sp
 0018 3D                  rts
                       ;      semaphore -> 2,x
 0019                 _Wait::
 0019 3B                  pshd
 001A 34                  pshx
 001B B775              tfr s,x
 001D                 spin12.29::	
                       ; /* Example Usage:
                       ; //-------------------------Start of OutString------------------------
                       ; char mutex=1;    // 1 means free, 0 means in use
                       ; // Output String (NULL termination)
                       ; void OutString(char *pt){ char letter;
                       ;    bWait(&mutex);
                       ;    while (letter=*pt++)
                       ;        OutChar(letter);
                       ;    bSignal(&mutex);} 
                       ; void main(void){
                       ;    mutex=1;     // initially free
                       ;    OutString("Hello World");}
                       ;    */
                       ; // reference Silberschatz Section 6.4.4
                       ; void Wait(sema4Ptr semaphore){
                       ;      bWait(&semaphore->s3);  // wait if other caller to Wait gets here first
 001D EC02              ldd 2,x
 001F C30004              addd #4
 0022 160000              jsr _bWait
 0025                 spin12.30::	
                       ;      bWait(&semaphore->s1);  // mutual exclusive access to value
 0025 EC02              ldd 2,x
 0027 C30002              addd #2
 002A 160000              jsr _bWait
 002D                 spin12.31::	
                       ;      (semaphore->value)--;  // basic function of Wait
 002D ECE30002          ldd [2,x]
 0031 830001              subd #1
 0034 ED02              ldy 2,x
 0036 6C40              std 0,y
 0038                 spin12.32::	
                       ;      if((semaphore->value)<0){
 0038 ECE30002          ldd [2,x]
 003C 2C12              bge L4
 003E                 spin12.33::	
                       ;          bSignal(&semaphore->s1); // end of mutual exclusive access to value
 003E EC02              ldd 2,x
 0040 C30002              addd #2
 0043 160009              jsr _bSignal
 0046                 spin12.34::	
                       ;          bWait(&semaphore->s2);   // wait for value to go above 0
 0046 EC02              ldd 2,x
 0048 C30003              addd #3
 004B 160000              jsr _bWait
 004E                 spin12.35::	
                       ;          }
 004E 2008              bra L5
 0050                 L4:
 0050                 spin12.37::	
                       ;      else
                       ;          bSignal(&semaphore->s1); // end of mutual exclusive access to value
 0050 EC02              ldd 2,x
 0052 C30002              addd #2
 0055 160009              jsr _bSignal
 0058                 L5:
 0058                 spin12.38::	
                       ;      bWait(&semaphore->s3);       // let other callers to Wait get in
 0058 EC02              ldd 2,x
 005A C30004              addd #4
 005D 160000              jsr _bWait
 0060                 spin12.39::	
                       ; }                            
 0060                 L3:
 0060 B757              tfr x,s
 0062 30                  pulx
 0063 1B82              leas 2,sp
 0065 3D                  rts
                       ;      semaphore -> 2,x
 0066                 _Signal::
 0066 3B                  pshd
 0067 34                  pshx
 0068 B775              tfr s,x
 006A                 spin12.41::	
                       ; void Signal(sema4Ptr semaphore){
                       ;      bWait(&semaphore->s1);  // mutual exclusive access to value
 006A EC02              ldd 2,x
 006C C30002              addd #2
 006F 160000              jsr _bWait
 0072                 spin12.42::	
                       ;      (semaphore->value)++;  // basic function of Signal
 0072 ECE30002          ldd [2,x]
 0076 C30001              addd #1
 0079 ED02              ldy 2,x
 007B 6C40              std 0,y
 007D                 spin12.43::	
                       ;      if((semaphore->value)<=0)
 007D ECE30002          ldd [2,x]
 0081 2E08              bgt L7
 0083                 spin12.44::	
                       ;         bSignal(&semaphore->s2);   // allow S2 spinner to continue
 0083 EC02              ldd 2,x
 0085 C30003              addd #3
 0088 160009              jsr _bSignal
 008B                 L7:
 008B                 spin12.45::	
                       ;      bSignal(&semaphore->s1); // end of mutual exclusive access to value
 008B EC02              ldd 2,x
 008D C30002              addd #2
 0090 160009              jsr _bSignal
 0093                 spin12.46::	
                       ; }
 0093                 L6:
 0093 B757              tfr x,s
 0095 30                  pulx
 0096 1B82              leas 2,sp
 0098 3D                  rts
                       ;        initial -> 6,x
                       ;      semaphore -> 2,x
 0099                 _Initialize::
 0099 3B                  pshd
 009A 34                  pshx
 009B B775              tfr s,x
 009D                 spin12.48::	
                       ; void Initialize(sema4Ptr semaphore, int initial){
                       ;     semaphore->s1=1;   // first one to bWait(s1) continues
 009D C601              ldab #1
 009F ED02              ldy 2,x
 00A1 6B42              stab 2,y
 00A3                 spin12.49::	
                       ;     semaphore->s2=0;   // first one to bWait(s2) spins
 00A3 ED02              ldy 2,x
 00A5 6943              clr 3,y
 00A7                 spin12.50::	
                       ;     semaphore->s3=1;   // first one to bWait(s3) continues
 00A7 C601              ldab #1
 00A9 ED02              ldy 2,x
 00AB 6B44              stab 4,y
 00AD                 spin12.51::	
                       ;     semaphore->value=initial;}
 00AD EC06              ldd 6,x
 00AF ED02              ldy 2,x
 00B1 6C40              std 0,y
 00B3                 L9:
 00B3 B757              tfr x,s
 00B5 30                  pulx
 00B6 1B82              leas 2,sp
 00B8 3D                  rts
 00B9                 _InitFifo::
 00B9 34                  pshx
 00BA B775              tfr s,x
 00BC 1B9E              leas -2,sp
 00BE                 spin12.63::	
                       ; // Example
                       ; unsigned int *PutPt;    /* Pointer of where to put next */
                       ; unsigned int *GetPt;    /* Pointer of where to get next
                       ; /* FIFO is empty when Available is less than or equal to zero */
                       ; /* FIFO is full  when RoomLeft is less than or equal to zero */
                       ; sema4Type RoomLeft;  /* Semaphore counting empty spaces */
                       ; sema4Type Available; /* Semaphore counting data in fifo */
                       ; char Mutex;          // binary semaphore for mutual exclusion
                       ; #define FifoSize 10
                       ; unsigned int Fifo[FifoSize];     /* The statically allocated fifo data */
                       ; void InitFifo(void) {
                       ;    Initialize(&RoomLeft,FifoSize-1);    /* Maximum storage capability */
 00BE 1800800009          movw #9,0,sp
 00C3 CC001B              ldd #_RoomLeft
 00C6 160099              jsr _Initialize
 00C9                 spin12.64::	
                       ;    Initialize(&Available,0);            /* Initially empty */
 00C9 1800800000          movw #0,0,sp
 00CE CC0015              ldd #_Available
 00D1 160099              jsr _Initialize
 00D4                 spin12.65::	
                       ;    Mutex=1;
 00D4 180B010014          movb #1,_Mutex
 00D9                 spin12.66::	
                       ;    PutPt=GetPt=&Fifo[0];
 00D9 180300000021      movw #_Fifo,_GetPt
 00DF 180300000023      movw #_Fifo,_PutPt
 00E5                 spin12.67::	
                       ; }
 00E5                 L10:
 00E5 B757              tfr x,s
 00E7 30                  pulx
 00E8 3D                  rts
                       ;           data -> 2,x
 00E9                 _Put::
 00E9 3B                  pshd
 00EA 34                  pshx
 00EB B775              tfr s,x
 00ED 1B9C              leas -4,sp
 00EF                 spin12.70::	
                       ; 
                       ; void Put(unsigned int data) { 
                       ;    Wait(&RoomLeft);
 00EF CC001B              ldd #_RoomLeft
 00F2 160019              jsr _Wait
 00F5                 spin12.71::	
                       ;    bWait(&Mutex);
 00F5 CC0014              ldd #_Mutex
 00F8 160000              jsr _bWait
 00FB                 spin12.72::	
                       ;    *(PutPt++)=data;  // Put data into fifo
 00FB 18011E0023          movw _PutPt,-2,x
 0100 EC1E              ldd -2,x
 0102 C30002              addd #2
 0105 7C0023              std _PutPt
 0108 EC02              ldd 2,x
 010A ED1E              ldy -2,x
 010C 6C40              std 0,y
 010E                 spin12.73::	
                       ;    if (PutPt==&Fifo[FifoSize]) PutPt = &Fifo[0];
 010E CC0014              ldd #_Fifo+20
 0111 6C1C              std -4,x
 0113 FC0023              ldd _PutPt
 0116 AC1C              cpd -4,x
 0118 2606              bne L12
 011A 180300000023      movw #_Fifo,_PutPt
 0120                 L12:
 0120                 spin12.74::	
                       ;    bSignal(&Mutex);
 0120 CC0014              ldd #_Mutex
 0123 160009              jsr _bSignal
 0126                 spin12.75::	
                       ;    Signal(&Available);
 0126 CC0015              ldd #_Available
 0129 160066              jsr _Signal
 012C                 spin12.76::	
                       ; }
 012C                 L11:
 012C B757              tfr x,s
 012E 30                  pulx
 012F 1B82              leas 2,sp
 0131 3D                  rts
                       ;           data -> -2,x
 0132                 _Get::
 0132 34                  pshx
 0133 B775              tfr s,x
 0135 1B9A              leas -6,sp
 0137                 spin12.79::	
                       ; 
                       ; unsigned int Get(void) { unsigned int data;  
                       ;    Wait(&Available);
 0137 CC0015              ldd #_Available
 013A 160019              jsr _Wait
 013D                 spin12.80::	
                       ;    bWait(&Mutex);
 013D CC0014              ldd #_Mutex
 0140 160000              jsr _bWait
 0143                 spin12.81::	
                       ;    data=*(GetPt++);
 0143 18011C0021          movw _GetPt,-4,x
 0148 EC1C              ldd -4,x
 014A C30002              addd #2
 014D 7C0021              std _GetPt
 0150 ECE3FFFC          ldd [-4,x]
 0154 6C1E              std -2,x
 0156                 spin12.82::	
                       ;    if (GetPt==&Fifo[FifoSize]) GetPt = &Fifo[0];
 0156 CC0014              ldd #_Fifo+20
 0159 6C1A              std -6,x
 015B FC0021              ldd _GetPt
 015E AC1A              cpd -6,x
 0160 2606              bne L16
 0162 180300000021      movw #_Fifo,_GetPt
 0168                 L16:
 0168                 spin12.83::	
                       ;    bSignal(&Mutex);
 0168 CC0014              ldd #_Mutex
 016B 160009              jsr _bSignal
 016E                 spin12.84::	
                       ;    Signal(&RoomLeft);
 016E CC001B              ldd #_RoomLeft
 0171 160066              jsr _Signal
 0174                 spin12.85::	
                       ;    return(data);}
 0174 EC1E              ldd -2,x
 0176 B757              tfr x,s
 0178 30                  pulx
 0179 3D                  rts
 017A                 L15:
                       ;              n -> -2,x
 017A                 _main::
 017A 34                  pshx
 017B B775              tfr s,x
 017D 1B9A              leas -6,sp
 017F                 spin12.87::	
                       ; void main(void){ unsigned int n;
                       ;    InitFifo();
 017F 1600B9              jsr _InitFifo
 0182                 spin12.88::	
                       ;    Put(5);
 0182 CC0005              ldd #5
 0185 1600E9              jsr _Put
 0188                 spin12.89::	
                       ;    Put(6);
 0188 CC0006              ldd #6
 018B 1600E9              jsr _Put
 018E                 spin12.90::	
                       ;    n=Get();
 018E 160132              jsr _Get
 0191 6C1C              std -4,x
 0193 B746              tfr d,y
 0195 6D1E              sty -2,x
 0197                 spin12.91::	
                       ;    n=Get();}
 0197 160132              jsr _Get
 019A 6C1A              std -6,x
 019C B746              tfr d,y
 019E 6D1E              sty -2,x
 01A0                 L19:
 01A0 B757              tfr x,s
 01A2 30                  pulx
 01A3 3D                  rts
                         .area bss
 0000                 _Fifo::
 0000                   .blkb 20
 0014                 _Mutex::
 0014                   .blkb 1
 0015                 _Available::
 0015                   .blkb 6
 001B                 _RoomLeft::
 001B                   .blkb 6
 0021                 _GetPt::
 0021                   .blkb 2
 0023                 _PutPt::
 0023                   .blkb 2
