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|