0BF6|                               .PAGE
0BF6|                       ;--------------------------------------------------------------------------
0BF6|                       ;
0BF6|                       ;  Routine to read system serial # from video prom.
0BF6|                       ;  Written by Ken Schmal and Ron Hochsprung.
0BF6|                       ;
0BF6|                       ;       Register Usage:
0BF6|                       ;
0BF6|                       ;       temporary and iterative                  D0
0BF6|                       ;       temporary and iterative                  D1
0BF6|                       ;       temporary and iterative                  D2
0BF6|                       ;       temporary and iterative                  D3
0BF6|                       ;       boolean FOUND to be returned             D4
0BF6|                       ;       pointer to save area for serial #        A0
0BF6|                       ;       SN1 & SN2 pointer                        A1
0BF6|                       ;       STATUS REGISTER pointer                  A2
0BF6|                       ;       SCRACH array pointer                     A3
0BF6|                       ;       SCRACH END pointer                       A4
0BF6|                       ;       Tag const                                A5
0BF6|                       ;       static link and stack frame
0BF6|                       ;         base pointer register                  A6
0BF6|                       ;
0BF6|                       ;  Returns with carry bit set if all OK.
0BF6|                       ;  All registers except D7 and A0 trashed.
0BF6|                       ;
0BF6|                       ;--------------------------------------------------------------------------
0BF6|
0BF6|                       RDSERN
0BF6|
0BF6| 48E7 0180                     MOVEM.L         D7/A0,-(SP)             ;save regs
0BFA|
0BFA|                       ;       turn off all interrupts
0BFA| 40E7                          move            SR, -(sp)               ;save the present status register
0BFC| 007C 0700                     ori.w           #$0700, SR              ;set interrupt to level 7
0C00|
0C00|                       ;--------------------------------------------------------------------------
0C00|                       ;       now set up registers for the algorithm
0C00|                       ;--------------------------------------------------------------------------
0C00|
0C00| 227C 00FE 8000                move.l          #Snum, a1               ;location in MMU of SN1 & SN2
0C06| 247C 00FC F801                move.l          #Statreg,a2             ;Status Register pointer
0C0C| 4E56 FF18                     link            a6, #dStack             ;make room for SCRACH
0C10| 47EE FF18                     lea             dScrach(a6), a3         ;get pointer for SCRACH
0C14| 49FA 0142                     lea             Tag,a4
0C18| 2D48 FFF8                     move.l          a0,dSavArry(a6)
0C1C|
0C1C|                       ;--------------------------------------------------------------------------
0C1C|                       ;       first we get the block out of the vertical half
0C1C|                       ;--------------------------------------------------------------------------
0C1C|                       ;
0C1C|                       ;       sync up to the vertical retrace bit
0C1C|                       ;
0C1C|
0C1C|                       GetBits1:
0C1C|
0C1C| 7202                          moveq           #2, d1                  ;vertical retrace is bit #2
0C1E| 2D7C 0000 0007 FFFC           move.l          #BytesPerRead,dLcnt(a6) ;read this many bytes
0C26| 4279 00FC E018                clr             VTIRDIS                 ;clear vertical retrace bit
0C2C| 4279 00FC E01A                clr             VTIRENB                 ;set vertical retrace interrupt
0C32| 0312                  @1:     btst            d1, (a2)                ;wait until it's true
0C34| 66FC                          bne.s           @1
0C36|
0C36|                       ;
0C36|                       ;------ read the first block ------
0C36|                       ;
0C36|
0C36| 4C91 00FF             @3:     movem           (a1), d0-d7             ; ;;d0-d3=0xf00, d4-d7=0
0C3A| 4893 00FF                     movem           d0-d7, (a3)             ; ;; a3=0x386
0C3E| 508B                          addq.l          #8, a3                    ;; a3+=16
0C40| 508B                          addq.l          #8, a3                    ;; a3=0x396
0C42| 4E71                          nop                                       ;;
0C44| 7008                          moveq           #dlycnst-1, d0            ;; d0=8
0C46| 53AE FFFC                     subq.l          #1, dLcnt(a6)             ;; (0x46A)=7 new =6
0C4A| 5FC8 FFFE             @4:     dble            d0, @4                    ;; loop to @3 until d0=0
0C4E| 6EE6                          bgt.s           @3
0C50|                                                                         ;;;; d0=ffff
0C50|                       ;--------------------------------------------------------------------------
0C50|                       ;       then we get the block out of the horizontal half
0C50|                       ;--------------------------------------------------------------------------
0C50|                       ;
0C50|                       ;       kill time until we're near the last vertical retrace line
0C50|                       ;                              ;;;;; filled 0x386-0x3f6 with 0f00,0f00,0f00,0f00,0000,0000,0000,0000
0C50|
0C50|                       GetBits2:
0C50| 2D7C 0000 0007 FFFC           move.l          #BytesPerRead, dLcnt(a6);get the last few bytes    ;; 046A<-7 (long)
0C58| 303C 00AB                     move.w          #TKiller-1, d0          ;time killer constant
0C5C| 51C8 FFFE             @1:     dbra            d0, @1                  ;loop                      ;; loop 00AB times
0C60|
0C60|                       ;
0C60|                       ;------ read the second or last block ------
0C60|                       ;
0C60|
0C60| 4C91 00FF             @2:     movem           (a1), d0-d7             ;;; fill d0-d7 with mmu 0f00,0f00,0f00,0f00,0000,0000,0000,0000
0C64| 4893 00FF                     movem           d0-d7, (a3)             ;;; write them to a3 (0x3f6)
0C68| 508B                          addq.l          #8, a3
0C6A| 508B                          addq.l          #8, a3                  ;;; a3+=16 == 0x406
0C6C| 4E71                          nop
0C6E| 7008                          moveq           #dlycnst-1, d0          ;;; d0=8
0C70| 53AE FFFC                     subq.l          #1, dLcnt(a6)           ;;; (a6)-- (a6=46e)  (46e)=6 was 7
0C74| 5FC8 FFFE             @3:     dble            d0, @3                  ;;;
0C78| 6EE6                          bgt.s           @2                      ;;;
0C7A|
0C7A|                       ;--------------------------------------------------------------------------
0C7A|                       ;       now we have to find sync bytes and extract the bit stream
0C7A|                       ;--------------------------------------------------------------------------
0C7A|
0C7A| 4279 00FC E018                clr             VTIRDIS                 ;turn off vertical retrace
0C80| 7801                          moveq           #1, d4                  ;initialize FOUND to true   ;; d4=1
0C82|
0C82|                       GetBytes:
0C82| 47EE FF18                     lea             dScrach(a6), a3         ;pointer to 1/2 Scrach Array pointer  ;; a3=0x386 again start of scratch
0C86| 284B                          move.l          a3, a4                   ;; a4=copy of scratch
0C88| D8FC 0070                     adda            #HalfSize, a4           ;pointer to end of 1/2 Scrach Array     RM000 ;; a4=0x3f6
0C8C|                       ;
0C8C|                       ;       find the first sync byte
0C8C|                       ;
0C8C| 6100 007C                     bsr             FindSync
0C90| 4A44                          tst.w           d4
0C92| 6764                          beq.s           Exit                    ;exit if no sync byte found
0C94|                       ;
0C94|                       ;       now pull out the first block from the bit stream
0C94|                       ;
0C94| 6100 009E                     bsr             GetNibbles
0C98|                       ;       here we look for the second sync byte.
0C98|                       ;
0C98| 47EE FF18                     lea             dScrach(a6), a3
0C9C| D6FC 0070                     adda            #HalfSize, a3           ;pointer to 2/2 Scrach Array pointer    RM000
0CA0| 284B                          move.l          a3,a4
0CA2| D8FC 0070                     adda            #HalfSize,a4            ;pointer to end of 2/2 Scrach Array     RM000
0CA6|                       ;
0CA6| 6100 0062                     bsr             FindSync
0CAA| 4A44                          tst.w           d4

0CAE|                       ;       beq.s           Exit                    ;again, exit if no sync byte found
0CAE|                       ;       now pull out second block from the bit stream
0CAE|                       ;
0CAE| 6100 0084                     bsr             GetNibbles
0CB2|
0CB2|                       ;----------------------------------------------------------------------
0CB2|                       ;       Check the checksum of the read data
0CB2|                       ;----------------------------------------------------------------------
0CB2|
0CB2|                       CheckSum:                                           ; my comments!
0CB2| 206E FFF8                     move.l          dSavArry(a6),a0             ;8sn1 8scratch 8sn2 8 scratch  a0=sn2
0CB6| 4240                          clr.w           d0                          ;d0=0
0CB8|
0CB8| 1028 0018                     move.b          24(a0),d0                   ;d0=sn2[0]
0CBC| 343C 0064                     move.w          #100,d2
0CC0| C0C2                          mulu            d2,d0                       ;d0=d0 * 100
0CC2|
0CC2| 1228 0019                     move.b          25(a0),d1                   ;d1=sn2[1]
0CC6| 343C 000A                     move.w          #10,d2
0CCA| C2C2                          mulu            d2,d1                       ;d1=d1 * 10
0CCC| D041                          add.w           d1,d0
0CCE|
0CCE| 1228 001A                     move.b          26(a0),d1                   ;d1=sn2[2]
0CD2| D041                          add.w           d1,d0                       ;d0=d0+d1
0CD4|
0CD4| 4241                          clr.w           d1                          ;d1=0
0CD6| 4242                          clr.w           d2
0CD8| 4243                          clr.w           d3
0CDA| 1630 1000             @2:     move.b          0(a0,d1),d3                 ;d3= what? (a0+d1?) d3=(a0) d3=sn1[0]
0CDE| D443                          add.w           d3,d2                       ;d2+=d3
0CE0| 5241                          addq.w          #1,d1                       ;d1++
0CE2| 0C41 0018                     cmpi.w          #24,d1                      ;24 bytes done?, no loop some more
0CE6| 66F2                          bne.s           @2
0CE8|
0CE8| 1628 001B                     move.b          27(a0), d3                  ;d3=sn2[3]
0CEC| D443                          add.w           d3,d2                       ;d2+=d3
0CEE| 0442 003C                     subi.w          #4 * $F, d2                 ;d2-=0x3c (=60 dec)
0CF2| B440                          cmp.w           d0,d2                       ;is d0=d2?, yes? we can quit.
0CF4| 6702                          beq.s           @3
0CF6| 4244                          clr.w           d4
0CF8|                       @3:
0CF8|                       ;---------------------------------------------------------------------------
0CF8|                       ;       job well done, lets go home
0CF8|                       ;---------------------------------------------------------------------------
0CF8|
0CF8|                       Exit:
0CF8| 4E5E                          unlk            a6
0CFA| 46DF                          move            (sp)+, SR               ;restore status reg
0CFC| 4CDF 0180                     MOVEM.L         (SP)+,D7/A0             ;and regs
0D00| 4279 00FC E01A                clr             VTIRENB                 ;re-enable interrupts
0D06| E24C                          LSR             #1,D4                   ;shift to set/reset error indicator
0D08| 4E75                  @1      RTS                                     ; and exit
0D0A|
0D0A|                               .PAGE
0D0A|                       ;---------------------------------------------------------------------------
0D0A|                       ;       subroutine to find a sync byte
0D0A|                       ;---------------------------------------------------------------------------
0D0A|
0D0A|                       FindSync:
0D0A| 4280                          clr.l           d0
0D0C| 7202                          moveq           #2, d1                  ;two passes to find the sync byte
0D0E| 341B                  @1:     move.w          (a3)+, d2               ;
0D10| E34A                          lsl.w           #1, d2                  ;
0D12| E310                          roxl.b          #1, d0                  ;get SN1
0D14| B9CB                          cmpa.l          a3, a4                  ;assure the buffer's circular
0D16| 660A                          bne.s           @2                      ;
0D18| D7FC FFFF FF90                adda.l          #-HalfSize, a3          ;if it's at the end then
0D1E| 5341                          subq            #1, d1                  ; check if it's the second try
0D20| 670E                          beq.s           @3                      ; and exit if so
0D22| 0C00 00FF             @2:     cmpi.b          #$0ff, d0               ;test here if it's a sync byte
0D26| 66E6                          bne.s           @1                      ;no: loop again
0D28| E948                          lsl.w           #4, d0                  ;yes: adjust the byte
0D2A| E808                          lsr.b           #4, d0                  ;
0D2C| 30C0                          move.w          d0, (a0)+               ;save it
0D2E| 4E75                          rts                                     ;and return
0D30|
0D30| 4244                  @3:     clr.w           d4                      ;uh, oh. No sync byte.
0D32| 4E75                          rts                                     ;clear FOUND and return
0D34|                       ;--------------------------------------------------------------------------
0D34|                       ;       subroutine to pull out a 14 nibble block from the bit stream
0D34|                       ;--------------------------------------------------------------------------
0D34|
0D34|                       GetNibbles:
0D34| 7406                          moveq           #BytesPerRead-1, d2     ;
0D36| 7208                  @1:     moveq           #8, d1                  ;8 bits/byte
0D38| 4280                          clr.l           d0                      ;
0D3A| E3DB                  @2:     lsl             (a3)+                   ;get SN1 in the next scrach word
0D3C| E310                          roxl.b          #1, d0                  ;shift it into the save buffer
0D3E| B9CB                          cmpa.l          a3, a4                  ;assure a circular bufer
0D40| 6606                          bne.s           @3                      ;
0D42| D7FC FFFF FF90                adda.l          #-HalfSize, a3          ;
0D48| 5341                  @3      subq            #1, d1                  ;decrement bit/byte counter
0D4A| 66EE                          bne.s           @2                      ;loop again if still in byte
0D4C| E948                          lsl.w           #4, d0                  ;separate the nibbles
0D4E| E808                          lsr.b           #4, d0                  ;
0D50| 30C0                          move            d0, (a0)+               ;save these nibbles
0D52| 5342                          subq            #1, d2                  ;decrement byte/SN counter
0D54| 66E0                          bne.s           @1                      ;loop again if still more to go
0D56| 4E75                          rts
0D58|
0D58| 4B41 5300             Tag     .word           $4b41,$5300
0D5C|

